MarlinTrk  02.08
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MarlinTrkUtils.cc
Go to the documentation of this file.
2 
3 #include <vector>
4 #include <algorithm>
5 #include <memory>
6 #include <math.h>
7 
10 #include "MarlinTrk/HelixTrack.h"
11 #include "MarlinTrk/Factory.h"
12 
14 
15 #include "lcio.h"
16 #include <IMPL/TrackImpl.h>
17 #include <IMPL/TrackStateImpl.h>
18 #include <EVENT/TrackerHit.h>
19 
20 #include <UTIL/BitField64.h>
21 #include "UTIL/LCTrackerConf.h"
22 #include <UTIL/ILDConf.h>
23 #include <UTIL/BitSet32.h>
24 #include <UTIL/Operators.h>
25 
26 #include "streamlog/streamlog.h"
27 
28 #include "TMatrixD.h"
29 
30 #define MIN_NDF 6
31 
32 
33 namespace MarlinTrk {
34 
35  using namespace lcio ;
36  using namespace UTIL ;
37 
38 // // Check if a square matrix is Positive Definite
39 // bool Matrix_Is_Positive_Definite(const EVENT::FloatVec& matrix){
40 //
41 // std::cout << "\n MarlinTrk::Matrix_Is_Positive_Definite(EVENT::FloatVec& matrix): " << std::endl;
42 //
43 // int icol,irow;
44 //
45 // int nrows = 5;
46 //
47 // TMatrixD cov(nrows,nrows) ;
48 //
49 // bool matrix_is_positive_definite = true;
50 //
51 // int icov = 0;
52 // for(int irow=0; irow<nrows; ++irow ){
53 // for(int jcol=0; jcol<irow+1; ++jcol){
54 // cov(irow,jcol) = matrix[icov];
55 // cov(jcol,irow) = matrix[icov];
57 // ++icov ;
58 // }
60 // }
61 //
63 //
64 // double *pU = cov.GetMatrixArray();
65 //
66 // for (icol = 0; icol < nrows; icol++) {
67 // const int rowOff = icol * nrows;
68 //
69 // //Compute fU(j,j) and test for non-positive-definiteness.
70 // double ujj = pU[rowOff+icol];
71 // double diagonal = ujj;
73 //
74 // for (irow = 0; irow < icol; irow++) {
75 // const int pos_ij = irow*nrows+icol;
76 // std::cout << " " << pU[pos_ij] ;
77 // ujj -= pU[pos_ij]*pU[pos_ij];
78 // }
79 // std::cout << " " << diagonal << std::endl;
80 //
81 //
82 // if (ujj <= 0) {
83 // matrix_is_positive_definite = false;
84 // }
85 // }
86 //
87 // std::cout << std::endl;
88 //
89 // if ( matrix_is_positive_definite == false ) {
90 // std::cout << "******************************************************" << std::endl;
91 // std::cout << "** ERROR: matrix shown not to be positive definite **" << std::endl;
92 // std::cout << "******************************************************" << std::endl;
93 // }
94 //
95 // return matrix_is_positive_definite;
96 //
97 // }
98 
99 
100 
101  int createTrackStateAtCaloFace( IMarlinTrack* marlinTrk, IMPL::TrackStateImpl* track, EVENT::TrackerHit* trkhit, bool tanL_is_positive );
102 
103  int createFinalisedLCIOTrack( IMarlinTrack* marlinTrk, std::vector<EVENT::TrackerHit*>& hit_list, IMPL::TrackImpl* track, bool fit_direction, const EVENT::FloatVec& initial_cov_for_prefit, float bfield_z, double maxChi2Increment){
104 
106  // check inputs
108  if ( hit_list.empty() ) return IMarlinTrack::bad_intputs ;
109 
110  if( track == 0 ){
111  throw EVENT::Exception( std::string("MarlinTrk::finaliseLCIOTrack: TrackImpl == NULL ") ) ;
112  }
113 
114  int return_error = 0;
115 
116 
118  // produce prefit parameters
120 
121  IMPL::TrackStateImpl pre_fit ;
122 
123  return_error = createPrefit(hit_list, &pre_fit, bfield_z, fit_direction);
124 
125  pre_fit.setCovMatrix(initial_cov_for_prefit);
126 
127  streamlog_out( DEBUG3 ) << " **** createFinalisedLCIOTrack - created pre-fit: " << toString( &pre_fit ) << std::endl ;
128 
129 
131  // use prefit parameters to produce Finalised track
133 
134  if( return_error == 0 ) {
135 
136  return_error = createFinalisedLCIOTrack( marlinTrk, hit_list, track, fit_direction, &pre_fit, bfield_z, maxChi2Increment);
137 
138  } else {
139  streamlog_out(DEBUG3) << "MarlinTrk::createFinalisedLCIOTrack : Prefit failed error = " << return_error << std::endl;
140  }
141 
142 
143  return return_error;
144 
145  }
146 
147  int createFinalisedLCIOTrack( IMarlinTrack* marlinTrk, std::vector<EVENT::TrackerHit*>& hit_list, IMPL::TrackImpl* track, bool fit_direction, EVENT::TrackState* pre_fit, float bfield_z, double maxChi2Increment){
148 
149 
151  // check inputs
153  if ( hit_list.empty() ) return IMarlinTrack::bad_intputs ;
154 
155  if( track == 0 ){
156  throw EVENT::Exception( std::string("MarlinTrk::finaliseLCIOTrack: TrackImpl == NULL ") ) ;
157  }
158 
159  // if( pre_fit == 0 ){
160  // throw EVENT::Exception( std::string("MarlinTrk::finaliseLCIOTrack: TrackStateImpl == NULL ") ) ;
161  // }
162 
163 
164  int fit_status = createFit(hit_list, marlinTrk, pre_fit, bfield_z, fit_direction, maxChi2Increment);
165 
166  if( fit_status != IMarlinTrack::success ){
167 
168  streamlog_out(DEBUG3) << "MarlinTrk::createFinalisedLCIOTrack fit failed: fit_status = " << fit_status << std::endl;
169 
170  return fit_status;
171 
172  }
173 
174  int error = finaliseLCIOTrack(marlinTrk, track, hit_list, fit_direction );
175 
176 
177  return error;
178 
179  }
180 
181 
182 
183 
184  int createFit( std::vector<EVENT::TrackerHit*>& hit_list, IMarlinTrack* marlinTrk, EVENT::TrackState* pre_fit, float bfield_z, bool fit_direction, double maxChi2Increment){
185 
186 
188  // check inputs
190  if ( hit_list.empty() ) return IMarlinTrack::bad_intputs;
191 
192  if( marlinTrk == 0 ){
193  throw EVENT::Exception( std::string("MarlinTrk::createFit: IMarlinTrack == NULL ") ) ;
194  }
195 
196  // if( pre_fit == 0 ){
197  // throw EVENT::Exception( std::string("MarlinTrk::createFit: TrackStateImpl == NULL ") ) ;
198  // }
199 
200  int return_error = 0;
201 
202 
203 // ///////////////////////////////////////////////////////
204 // // check that the prefit has the reference point at the correct location
205 // ///////////////////////////////////////////////////////
206 //
207 // if (( fit_direction == IMarlinTrack::backward && pre_fit->getLocation() != lcio::TrackState::AtLastHit )
208 // ||
209 // ( fit_direction == IMarlinTrack::forward && pre_fit->getLocation() != lcio::TrackState::AtFirstHit )) {
210 // std::stringstream ss ;
211 //
212 // ss << "MarlinTrk::createFinalisedLCIOTrack track state must be set at either first or last hit. Location = ";
213 // ss << pre_fit->getLocation();
214 //
215 // throw EVENT::Exception( ss.str() );
216 //
217 // }
218 
220  // add hits to IMarlinTrk
222 
223  EVENT::TrackerHitVec::iterator it = hit_list.begin();
224 
225  // start by trying to add the hits to the track we want to finally use.
226  streamlog_out(DEBUG2) << "MarlinTrk::createFit Start Fit: AddHits: number of hits to fit " << hit_list.size() << std::endl;
227 
228  EVENT::TrackerHitVec added_hits;
229  unsigned int ndof_added = 0;
230 
231  for( it = hit_list.begin() ; it != hit_list.end() ; ++it ) {
232 
233  EVENT::TrackerHit* trkHit = *it;
234  bool isSuccessful = false;
235 
236  if( UTIL::BitSet32( trkHit->getType() )[ UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] ){ //it is a composite spacepoint
237 
238  //Split it up and add both hits to the MarlinTrk
239  const EVENT::LCObjectVec rawObjects = trkHit->getRawHits();
240 
241  for( unsigned k=0; k< rawObjects.size(); k++ ){
242 
243  EVENT::TrackerHit* rawHit = dynamic_cast< EVENT::TrackerHit* >( rawObjects[k] );
244 
245  if( marlinTrk->addHit( rawHit ) == IMarlinTrack::success ){
246 
247  isSuccessful = true; //if at least one hit from the spacepoint gets added
248  ++ndof_added;
249  streamlog_out(DEBUG4) << "MarlinTrk::createFit ndof_added = " << ndof_added << std::endl;
250  }
251  }
252  }
253  else { // normal non composite hit
254 
255  if (marlinTrk->addHit( trkHit ) == IMarlinTrack::success ) {
256  isSuccessful = true;
257  ndof_added += 2;
258  streamlog_out(DEBUG4) << "MarlinTrk::createFit ndof_added = " << ndof_added << std::endl;
259  }
260  }
261 
262  if (isSuccessful) {
263  added_hits.push_back(trkHit);
264  }
265  else{
266  streamlog_out(DEBUG2) << "Hit " << it - hit_list.begin() << " Dropped " << std::endl;
267  }
268 
269  }
270 
271  if( ndof_added < MIN_NDF ) {
272  streamlog_out(DEBUG2) << "MarlinTrk::createFit : Cannot fit less with less than " << MIN_NDF << " degrees of freedom. Number of hits = " << added_hits.size() << " ndof = " << ndof_added << std::endl;
274  }
275 
276 
277 
279  // set the initial track parameters
281 
282 
283  if( pre_fit == 0 ) {
284 
285  streamlog_out(DEBUG5) << "MarlinTrk::createFit : null pointer for pre_fit given - will fall back "
286  << " to default initialisation ..." << std::endl ;
287 
288  return_error = marlinTrk->initialise( fit_direction ) ;
289 
290  } else {
291 
292  return_error = marlinTrk->initialise( *pre_fit, bfield_z, fit_direction ) ;//IMarlinTrack::backward ) ;
293  }
294 
295 
296  if (return_error != IMarlinTrack::success) {
297 
298  streamlog_out(DEBUG5) << "MarlinTrk::createFit Initialisation of track fit failed with error : " << return_error << std::endl;
299 
300  return return_error;
301 
302  }
303 
304 
305 #if 0 // DEBUG code:
306 
308  double chi2(0) ;
309  int ndf(0) ;
310  int ii = marlinTrk->propagate( Vector3D(), ts, chi2, ndf ) ;
311 
312  streamlog_out(DEBUG5) << " MarlinTrk::createFit: pre-fit, propagated to the IP : " << ts << std::endl ;
313 
314 
315  return IMarlinTrack::success ;
316 #endif
317 
318 
320  // try fit and return error
322 
323  return marlinTrk->fit(maxChi2Increment) ;
324 
325  }
326 
327 
328 
329  int createPrefit( std::vector<EVENT::TrackerHit*>& hit_list, IMPL::TrackStateImpl* pre_fit, float bfield_z, bool fit_direction){
330 
332  // check inputs
334  if ( hit_list.empty() ) return IMarlinTrack::bad_intputs ;
335 
336  if( pre_fit == 0 ){
337  throw EVENT::Exception( std::string("MarlinTrk::finaliseLCIOTrack: TrackStateImpl == NULL ") ) ;
338  }
339 
341  // loop over all the hits and create a list consisting only 2D hits
343 
344  EVENT::TrackerHitVec twoD_hits;
345 
346  for (unsigned ihit=0; ihit < hit_list.size(); ++ihit) {
347 
348  // check if this a space point or 2D hit
349  if(UTIL::BitSet32( hit_list[ihit]->getType() )[ UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL ] == false ){
350  // then add to the list
351  twoD_hits.push_back(hit_list[ihit]);
352  }
353  }
354 
356  // check that there are enough 2-D hits to create a helix
358 
359  if (twoD_hits.size() < 3) { // no chance to initialise print warning and return
360  streamlog_out(WARNING) << "MarlinTrk::createFinalisedLCIOTrack Cannot create helix from less than 3 2-D hits" << std::endl;
362  }
363 
365  // make a helix from 3 hits to get a trackstate
367 
368  // SJA:FIXME: this may not be the optimal 3 hits to take in certain cases where the 3 hits are not well spread over the track length
369  const double* x1 = twoD_hits[0]->getPosition();
370  const double* x2 = twoD_hits[ twoD_hits.size()/2 ]->getPosition();
371  const double* x3 = twoD_hits.back()->getPosition();
372 
373  HelixTrack helixTrack( x1, x2, x3, bfield_z, HelixTrack::forwards );
374 
375  helixTrack.moveRefPoint(0.0, 0.0, 0.0);
376 
377  // if ( fit_direction == IMarlinTrack::backward ) {
378  // pre_fit->setLocation(lcio::TrackState::AtLastHit);
379  // helixTrack.moveRefPoint(hit_list.back()->getPosition()[0], hit_list.back()->getPosition()[1], hit_list.back()->getPosition()[2]);
380  // } else {
381  // pre_fit->setLocation(lcio::TrackState::AtFirstHit);
382  // helixTrack.moveRefPoint(hit_list.front()->getPosition()[0], hit_list.front()->getPosition()[1], hit_list.front()->getPosition()[2]);
383  // }
384 
385  const float referencePoint[3] = { float(helixTrack.getRefPointX()) , float(helixTrack.getRefPointY()) , float(helixTrack.getRefPointZ() )};
386 
387  pre_fit->setD0(helixTrack.getD0()) ;
388  pre_fit->setPhi(helixTrack.getPhi0()) ;
389  pre_fit->setOmega(helixTrack.getOmega()) ;
390  pre_fit->setZ0(helixTrack.getZ0()) ;
391  pre_fit->setTanLambda(helixTrack.getTanLambda()) ;
392 
393  pre_fit->setReferencePoint(referencePoint) ;
394 
395  return IMarlinTrack::success;
396 
397  }
398 
399  int finaliseLCIOTrack( IMarlinTrack* marlintrk, IMPL::TrackImpl* track, std::vector<EVENT::TrackerHit*>& hit_list, bool fit_direction, IMPL::TrackStateImpl* atLastHit, IMPL::TrackStateImpl* atCaloFace){
400 
402  // check inputs
404  if( marlintrk == 0 ){
405  throw EVENT::Exception( std::string("MarlinTrk::finaliseLCIOTrack: IMarlinTrack == NULL ") ) ;
406  }
407 
408  if( track == 0 ){
409  throw EVENT::Exception( std::string("MarlinTrk::finaliseLCIOTrack: TrackImpl == NULL ") ) ;
410  }
411 
412  if( atCaloFace && atLastHit == 0 ){
413  throw EVENT::Exception( std::string("MarlinTrk::finaliseLCIOTrack: atLastHit == NULL ") ) ;
414  }
415 
416  if( atLastHit && atCaloFace == 0 ){
417  throw EVENT::Exception( std::string("MarlinTrk::finaliseLCIOTrack: atCaloFace == NULL ") ) ;
418  }
419 
420 
421 
423  // error to return if any
425  int return_error = 0;
426 
427  int ndf = 0;
428  double chi2 = -DBL_MAX;
429 
431  // First check NDF to see if it make any sense to continue.
432  // The track will be dropped if the NDF is less than 0
434 
435  return_error = marlintrk->getNDF(ndf);
436 
437  if ( return_error != IMarlinTrack::success) {
438  streamlog_out(DEBUG3) << "MarlinTrk::finaliseLCIOTrack: getNDF returns " << return_error << std::endl;
439  return return_error;
440  } else if( ndf < 0 ) {
441  streamlog_out(DEBUG8) << "MarlinTrk::finaliseLCIOTrack: number of degrees of freedom less than 0 track dropped : NDF = " << ndf << std::endl;
442  return IMarlinTrack::error;
443  } else {
444  streamlog_out(DEBUG4) << "MarlinTrk::finaliseLCIOTrack: NDF = " << ndf << std::endl;
445  }
446 
447 
448 
450  // get the list of hits used in the fit
451  // add these to the track, add spacepoints as long as at least on strip hit is used.
453 
457 
458  hits_in_fit.reserve(300);
459  outliers.reserve(300);
460 
461  marlintrk->getHitsInFit(hits_in_fit);
462  marlintrk->getOutliers(outliers);
463 
465  // now loop over the hits provided for fitting
466  // we do this so that the hits are added in the
467  // order in which they have been fitted
469 
470  for ( unsigned ihit = 0; ihit < hit_list.size(); ++ihit) {
471 
472  EVENT::TrackerHit* trkHit = hit_list[ihit];
473 
474  if( UTIL::BitSet32( trkHit->getType() )[ UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ] ){ //it is a composite spacepoint
475 
476  // get strip hits
477  const EVENT::LCObjectVec rawObjects = trkHit->getRawHits();
478 
479  for( unsigned k=0; k< rawObjects.size(); k++ ){
480 
481  EVENT::TrackerHit* rawHit = dynamic_cast< EVENT::TrackerHit* >( rawObjects[k] );
482 
483  bool is_outlier = false;
484 
485  // here we loop over outliers as this will be faster than looping over the used hits
486  for ( unsigned ohit = 0; ohit < outliers.size(); ++ohit) {
487 
488  if ( rawHit == outliers[ohit].first ) {
489  is_outlier = true;
490  break; // break out of loop over outliers
491  }
492  }
493 
494  if (is_outlier == false) {
495  used_hits.push_back(hit_list[ihit]);
496  track->addHit(used_hits.back());
497  break; // break out of loop over rawObjects
498  }
499  }
500  } else {
501 
502  bool is_outlier = false;
503 
504  // here we loop over outliers as this will be faster than looping over the used hits
505  for ( unsigned ohit = 0; ohit < outliers.size(); ++ohit) {
506 
507  if ( trkHit == outliers[ohit].first ) {
508  is_outlier = true;
509  break; // break out of loop over outliers
510  }
511  }
512 
513  if (is_outlier == false) {
514  used_hits.push_back(hit_list[ihit]);
515  track->addHit(used_hits.back());
516  }
517 
518 
519  }
520 
521  }
522 
523 
524 // ///////////////////////////////////////////////////////////////////////////
525 // // We now need to find out at which point the fit is constrained
526 // // and therefore be able to provide well formed (pos. def.) cov. matrices
527 // ///////////////////////////////////////////////////////////////////////////
528 //
529 
530 
532  // first hit
534 
535  IMPL::TrackStateImpl* trkStateAtFirstHit = new IMPL::TrackStateImpl() ;
536  EVENT::TrackerHit* firstHit = ( fit_direction == IMarlinTrack::backward ? hits_in_fit.back().first : hits_in_fit.front().first ) ;
537 
539  // last hit
541 
542  EVENT::TrackerHit* lastHit = ( fit_direction == IMarlinTrack::backward ? hits_in_fit.front().first : hits_in_fit.back().first ) ;
543 
544  EVENT::TrackerHit* last_constrained_hit = 0 ;
545  marlintrk->getTrackerHitAtPositiveNDF(last_constrained_hit);
546 
547 
548  streamlog_out(DEBUG3) << "MarlinTrk::finaliseLCIOTrack: firstHit : " << toString( firstHit )
549  << " lastHit: " << toString( lastHit )
550  << " last constrained hit: " << toString( last_constrained_hit )
551  << " fit direction is forward : " << fit_direction << std::endl ;
552 
553  //fgx return_error = marlintrk->smooth(lastHit);
554  return_error = marlintrk->smooth( last_constrained_hit );
555 
556  streamlog_out(DEBUG4) << "MarlinTrk::finaliseLCIOTrack: return_code for smoothing to last constrained hit "
557  << last_constrained_hit << " = " << return_error << " NDF = " << ndf << std::endl;
558 
559  if ( return_error != IMarlinTrack::success ) {
560  delete trkStateAtFirstHit;
561  // delete trkStateAtLastHit;
562  return return_error ;
563  }
564 
565 
567  // first create trackstate at IP
569  const Vector3D point(0.,0.,0.); // nominal IP
570 
571  IMPL::TrackStateImpl* trkStateIP = new IMPL::
572  TrackStateImpl() ;
573 
574 
575 
576  streamlog_out(DEBUG4) << "MarlinTrk::finaliseLCIOTrack: finalised kaltest track : "
577  << marlintrk->toString() << std::endl ;
578 
579 
580 
582  // make sure that the track state can be propagated to the IP
584 
586 
587  bool usingAidaTT = ( trksystem->name() == "AidaTT" ) ;
588 
589  // if we fitted backwards, the firstHit is the last one used in the fit and we simply propagate to the IP:
590 
591  if( fit_direction == IMarlinTrack::backward || usingAidaTT ) {
592 
593  return_error = marlintrk->propagate(point, firstHit, *trkStateIP, chi2, ndf ) ;
594 
595  } else {
596 
597  // if we fitted forward, we start from the last_constrained hit
598  // and then add the last inner hits with a Kalman step ...
599 
600  // create a temporary IMarlinTrack
601 
602  auto mTrk = std::shared_ptr<MarlinTrk::IMarlinTrack>( trksystem->createTrack() ) ;
603 
605 
606  double chi2Tmp = 0 ;
607  int ndfTmp = 0 ;
608  return_error = marlintrk->getTrackState( last_constrained_hit, ts , chi2 , ndf ) ;
609 
610  streamlog_out( DEBUG3 ) << " MarlinTrk::finaliseLCIOTrack:-- TrackState at last constrained hit : " << std::endl
611  << toString( &ts ) << std::endl ;
612 
613  //need to add a dummy hit to the track
614  mTrk->addHit( last_constrained_hit ) ;
615 
616  double _bfield = 42.0 ;
617  // fixme: the implementation for DDKalTest does no longer need this value but the IMarlinTrk interface is not yet changed
618  mTrk->initialise( ts , _bfield , fit_direction ) ;
619 
620  std::vector<std::pair<EVENT::TrackerHit*, double> >::reverse_iterator hI = hits_in_fit.rbegin() ;
621 
622  while( (*hI).first != last_constrained_hit ){
623 
624  streamlog_out( DEBUG0 ) << " MarlinTrk::finaliseLCIOTrack:-- hit in reverse_iterator : " << std::endl
625  << toString( (*hI).first ) << std::endl ;
626  ++hI ;
627  }
628 
629  ++hI ;
630 
631  while( hI != hits_in_fit.rend() ){
632 
633  EVENT::TrackerHit* h = (*hI).first ;
634 
635 
636  double deltaChi ;
637  double maxChi2Increment = 1e10 ; // ???
638 
639  int addHit = mTrk->addAndFit( h , deltaChi, maxChi2Increment ) ;
640 
641 
642  streamlog_out( DEBUG3 ) << " MarlinTrk::finaliseLCIOTrack: hit " << toString( h )
643  << " added : " << MarlinTrk::errorCode( addHit )
644  << " deltaChi2: " << deltaChi
645  << std::endl ;
646 
647  if( addHit != MarlinTrk::IMarlinTrack::success ){
648 
649  streamlog_out( ERROR ) << " **** MarlinTrk::finaliseLCIOTrack: could not add inner hit to track !!! " << std::endl ;
650  }
651 
652  ++hI ;
653 
654  }//------------------------------------
655 
656  streamlog_out(DEBUG4) << "MarlinTrk::finaliseLCIOTrack: temporary kaltest track for track state at the IP: "
657  << mTrk->toString() << std::endl ;
658 
659  // now propagate the temporary track to the IP
660  return_error = mTrk->propagate( point, firstHit, *trkStateIP, chi2Tmp, ndfTmp ) ;
661 
662 
663  streamlog_out( DEBUG4 ) << " *** MarlinTrk::finaliseLCIOTrack: - propagated temporary track fromfirst hit to IP : " << toString( trkStateIP ) << std::endl ;
664  }
665 
666 
667  if ( return_error != IMarlinTrack::success ) {
668  streamlog_out(DEBUG4) << "MarlinTrk::finaliseLCIOTrack: return_code for propagation = " << return_error << " NDF = " << ndf << std::endl;
669  delete trkStateIP;
670  delete trkStateAtFirstHit;
671  // delete trkStateAtLastHit;
672 
673  return return_error ;
674  }
675 
676  trkStateIP->setLocation( lcio::TrackState::AtIP ) ;
677  track->trackStates().push_back(trkStateIP);
678  track->setChi2(chi2);
679  track->setNdf(ndf);
680 
681 
683  // set the track states at the first and last hits
685 
687  // @ first hit
689 
690  streamlog_out( DEBUG5 ) << " >>>>>>>>>>>MarlinTrk::finaliseLCIOTrack: create TrackState AtFirstHit" << std::endl ;
691 
692 
693  return_error = marlintrk->getTrackState(firstHit, *trkStateAtFirstHit, chi2, ndf ) ;
694 
695  if ( return_error == IMarlinTrack::success ) {
696  trkStateAtFirstHit->setLocation( lcio::TrackState::AtFirstHit ) ;
697  track->trackStates().push_back(trkStateAtFirstHit);
698  } else {
699  streamlog_out( WARNING ) << " >>>>>>>>>>>MarlinTrk::finaliseLCIOTrack: MarlinTrk::finaliseLCIOTrack: could not get TrackState at First Hit " << firstHit << std::endl ;
700  delete trkStateAtFirstHit;
701  }
702 
703  double r_first = firstHit->getPosition()[0]*firstHit->getPosition()[0] + firstHit->getPosition()[1]*firstHit->getPosition()[1];
704 
705  track->setRadiusOfInnermostHit(sqrt(r_first));
706 
707  if ( atLastHit == 0 && atCaloFace == 0 ) {
708 
710  // @ last hit
712 
713  streamlog_out( DEBUG5 ) << " >>>>>>>>>>> MarlinTrk::finaliseLCIOTrack: create TrackState AtLastHit : using trkhit " << last_constrained_hit << std::endl ;
714 
715  Vector3D last_hit_pos(lastHit->getPosition());
716 
717  IMPL::TrackStateImpl* trkStateAtLastHit = new IMPL::TrackStateImpl() ;
718 
719  return_error = marlintrk->propagate(last_hit_pos, last_constrained_hit, *trkStateAtLastHit, chi2, ndf);
720 
721 // return_error = marlintrk->getTrackState(lastHit, *trkStateAtLastHit, chi2, ndf ) ;
722 
723  if ( return_error == IMarlinTrack::success ) {
724  trkStateAtLastHit->setLocation( lcio::TrackState::AtLastHit ) ;
725  track->trackStates().push_back(trkStateAtLastHit);
726  } else {
727  streamlog_out( DEBUG5 ) << " >>>>>>>>>>> MarlinTrk::finaliseLCIOTrack: could not get TrackState at Last Hit " << last_constrained_hit << std::endl ;
728  delete trkStateAtLastHit;
729  }
730 
731 // const EVENT::FloatVec& ma = trkStateAtLastHit->getCovMatrix();
732 //
733 // Matrix_Is_Positive_Definite( ma );
734 
735 
736 
738  // set the track state at Calo Face
740 
741  IMPL::TrackStateImpl* trkStateCalo = new IMPL::TrackStateImpl;
742  bool tanL_is_positive = trkStateIP->getTanLambda()>0 ;
743 
744  return_error = createTrackStateAtCaloFace(marlintrk, trkStateCalo, last_constrained_hit, tanL_is_positive);
745  // return_error = createTrackStateAtCaloFace(marlintrk, trkStateCalo, lastHit, tanL_is_positive);
746 
747  if ( return_error == IMarlinTrack::success ) {
748  trkStateCalo->setLocation( lcio::TrackState::AtCalorimeter ) ;
749  track->trackStates().push_back(trkStateCalo);
750  } else {
751  streamlog_out( DEBUG9 ) << " >>>>>>>>>>> MarlinTrk::finaliseLCIOTrack: could not get TrackState at Calo Face " << std::endl ;
752  delete trkStateCalo;
753 
754  //FIXME: ignore track state at Calo face for debugging new tracking ...
755 #if 0
756  return_error = IMarlinTrack::success ;
757  streamlog_out( DEBUG9 ) << " MarlinTrk::finaliseLCIOTrack: ignore missing TrackState at Calo Face for debugging " << std::endl ;
758 #endif
759 
760  }
761 
762 
763  } else {
764  track->trackStates().push_back(atLastHit);
765  track->trackStates().push_back(atCaloFace);
766  }
767 
768 
769 
771  // done
773 
774 
775  return return_error;
776 
777  }
778 
779 
780 
781 
782 
783  int createTrackStateAtCaloFace( IMarlinTrack* marlintrk, IMPL::TrackStateImpl* trkStateCalo, EVENT::TrackerHit* trkhit, bool tanL_is_positive ){
784 
785  streamlog_out( DEBUG5 ) << " >>>>>>>>>>> createTrackStateAtCaloFace : using trkhit "
786  << UTIL::toString( trkhit ) << " tanL_is_positive = " << tanL_is_positive << std::endl ;
787 
789  // check inputs
791  if( marlintrk == 0 ){
792  throw EVENT::Exception( std::string("MarlinTrk::createTrackStateAtCaloFace: IMarlinTrack == NULL ") ) ;
793  }
794 
795  if( trkStateCalo == 0 ){
796  throw EVENT::Exception( std::string("MarlinTrk::createTrackStateAtCaloFace: TrackImpl == NULL ") ) ;
797  }
798 
799  if( trkhit == 0 ){
800  throw EVENT::Exception( std::string("MarlinTrk::createTrackStateAtCaloFace: TrackHit == NULL ") ) ;
801  }
802 
803  int return_error = 0;
804 
805  double chi2 = -DBL_MAX;
806  int ndf = 0;
807 
808  UTIL::BitField64 encoder( lcio::LCTrackerCellID::encoding_string() ) ;
809  encoder.reset() ; // reset to 0
810 
811  // ================== need to get the correct ID(s) for the calorimeter face ============================
812 
813  unsigned ecal_barrel_face_ID = lcio::ILDDetID::ECAL ;
814  unsigned ecal_endcap_face_ID = lcio::ILDDetID::ECAL_ENDCAP ;
815 
816  //=========================================================================================================
817 
818  encoder[lcio::LCTrackerCellID::subdet()] = ecal_barrel_face_ID ;
819  encoder[lcio::LCTrackerCellID::side()] = lcio::ILDDetID::barrel;
820  encoder[lcio::LCTrackerCellID::layer()] = 0 ;
821 
822  int detElementID = 0;
823 
824  return_error = marlintrk->propagateToLayer(encoder.lowWord(), trkhit, *trkStateCalo, chi2, ndf, detElementID, IMarlinTrack::modeForward ) ;
825 
826  if (return_error == IMarlinTrack::no_intersection ) { // try forward or backward
827 
828  encoder[lcio::LCTrackerCellID::subdet()] = ecal_endcap_face_ID ;
829 
830  if (tanL_is_positive) {
831  encoder[lcio::LCTrackerCellID::side()] = lcio::ILDDetID::fwd;
832  }
833  else{
834  encoder[lcio::LCTrackerCellID::side()] = lcio::ILDDetID::bwd;
835  }
836  return_error = marlintrk->propagateToLayer(encoder.lowWord(), trkhit, *trkStateCalo, chi2, ndf, detElementID, IMarlinTrack::modeForward ) ;
837  }
838 
839  //fg: for curling tracks the propagated track has the wrong z0 whereas it should be 0. really
840  if( std::abs( trkStateCalo->getZ0() ) > std::abs( 2.*M_PI/trkStateCalo->getOmega() * trkStateCalo->getTanLambda() ) ){
841 
842  streamlog_out( DEBUG2 ) << " >>>>>>>>>>> createTrackStateAtCaloFace : setting z0 to 0. for track state at calorimeter : "
843  << toString(trkStateCalo ) << std::endl ;
844 
845  trkStateCalo->setZ0( 0. ) ;
846  }
847 
848  if (return_error !=IMarlinTrack::success ) {
849  streamlog_out( DEBUG5 ) << " >>>>>>>>>>> createTrackStateAtCaloFace : could not get TrackState at Calo Face: return_error = " << return_error << std::endl ;
850  }
851 
852 
853  return return_error;
854 
855 
856  }
857 
858  void addHitNumbersToTrack(IMPL::TrackImpl* track, std::vector<EVENT::TrackerHit*>& hit_list, bool hits_in_fit, UTIL::BitField64& cellID_encoder){
859 
861  // check inputs
863  if( track == 0 ){
864  throw EVENT::Exception( std::string("MarlinTrk::addHitsToTrack: TrackImpl == NULL ") ) ;
865  }
866 
867  std::map<int, int> hitNumbers;
868 
869  for(unsigned int j=0; j<hit_list.size(); ++j) {
870 
871  cellID_encoder.setValue(hit_list.at(j)->getCellID0()) ;
872  int detID = cellID_encoder[UTIL::LCTrackerCellID::subdet()];
873  ++hitNumbers[detID];
874  }
875 
876  int offset = 2 ;
877  if ( hits_in_fit == false ) { // all hit atributed by patrec
878  offset = 1 ;
879  }
880 
881  // this assumes that there is no tracker with an index larger than the ecal ...
882  track->subdetectorHitNumbers().resize(2 * lcio::ILDDetID::ECAL);
883 
884 
885  for( std::map<int, int>::iterator it = hitNumbers.begin() ;
886  it != hitNumbers.end() ; ++it ){
887 
888  int detIndex = it->first ;
889  track->subdetectorHitNumbers().at( 2 * detIndex - offset ) = it->second ;
890 
891  }
892 
893  }
894 
896 
898  // check inputs
900  if( track == 0 ){
901  throw EVENT::Exception( std::string("MarlinTrk::addHitsToTrack: TrackImpl == NULL ") ) ;
902  }
903 
904  std::map<int, int> hitNumbers;
905 
906  for(unsigned int j=0; j<hit_list.size(); ++j) {
907 
908  cellID_encoder.setValue(hit_list.at(j).first->getCellID0()) ;
909  int detID = cellID_encoder[UTIL::LCTrackerCellID::subdet()];
910  ++hitNumbers[detID];
911  // streamlog_out( DEBUG1 ) << "Hit from Detector " << detID << std::endl;
912  }
913 
914  int offset = 2 ;
915  if ( hits_in_fit == false ) { // all hit atributed by patrec
916  offset = 1 ;
917  }
918 
919 
920  // this assumes that there is no tracker with an index larger than the ecal ...
921  track->subdetectorHitNumbers().resize(2 * lcio::ILDDetID::ECAL);
922 
923 
924  for( std::map<int, int>::iterator it = hitNumbers.begin() ;
925  it != hitNumbers.end() ; ++it ){
926 
927  int detIndex = it->first ;
928  track->subdetectorHitNumbers().at( 2 * detIndex - offset ) = it->second ;
929  }
930 
931  }
932 
933 }
virtual void addHit(EVENT::TrackerHit *hit)
virtual EVENT::TrackStateVec & trackStates()
T empty(T...args)
virtual void setD0(float d0)
virtual const double * getPosition() const =0
virtual void setNdf(int ndf)
double getRefPointZ() const
Definition: HelixTrack.h:27
virtual int smooth()=0
smooth all track states
virtual int getType() const =0
std::string toString(const T *obj)
virtual int propagateToLayer(int layerID, IMPL::TrackStateImpl &ts, double &chi2, int &ndf, int &detElementID, int mode=modeClosest)=0
propagate fit to numbered sensitive layer, returning TrackState, chi2, ndf and integer ID of the inte...
double getPhi0() const
Definition: HelixTrack.h:30
virtual int getTrackState(IMPL::TrackStateImpl &ts, double &chi2, int &ndf)=0
get track state, returning TrackState, chi2 and ndf via reference
T rend(T...args)
virtual EVENT::IntVec & subdetectorHitNumbers()
T front(T...args)
static const bool backward
boolean constant for defining backward direction - to be used for intitialise
Definition: IMarlinTrack.h:41
virtual int getNDF(int &ndf)=0
get the current number of degrees of freedom for the fit.
virtual void setTanLambda(float tanLambda)
#define M_PI
T endl(T...args)
virtual std::string toString()
Dump this track to a string for debugging - implementation dependant.
Definition: IMarlinTrack.cc:40
virtual int propagate(const Vector3D &point, IMPL::TrackStateImpl &ts, double &chi2, int &ndf)=0
propagate the fit to the point of closest approach to the given point, returning TrackState, chi2 and ndf via reference
T end(T...args)
double getZ0() const
Definition: HelixTrack.h:29
static const int bad_intputs
Definition: IMarlinTrack.h:55
dd4hep::rec::Vector3D Vector3D
the Vector3D used for the tracking interface
Definition: IMarlinTrack.h:26
virtual void setReferencePoint(const float *rPnt)
int createTrackStateAtCaloFace(IMarlinTrack *marlinTrk, IMPL::TrackStateImpl *track, EVENT::TrackerHit *trkhit, bool tanL_is_positive)
T resize(T...args)
STL class.
virtual void setLocation(int location)
double getRefPointX() const
Definition: HelixTrack.h:25
T at(T...args)
int createFit(std::vector< EVENT::TrackerHit * > &hit_list, IMarlinTrack *marlinTrk, EVENT::TrackState *pre_fit, float bfield_z, bool fit_direction, double maxChi2Increment=DBL_MAX)
Takes a list of hits and uses the IMarlinTrack inferface to fit them using a supplied prefit containi...
T push_back(T...args)
virtual int getTrackerHitAtPositiveNDF(EVENT::TrackerHit *&trkhit)=0
get TrackeHit at which fit became constrained, i.e.
virtual void setRadiusOfInnermostHit(float r)
virtual std::string name()
the name of the implementation
int finaliseLCIOTrack(IMarlinTrack *marlinTrk, IMPL::TrackImpl *track, std::vector< EVENT::TrackerHit * > &hit_list, bool fit_direction, IMPL::TrackStateImpl *atLastHit=0, IMPL::TrackStateImpl *atCaloFace=0)
Takes a fitted MarlinTrack, TrackImpl to record the fit and the hits which have been added to the fit...
Interface for generic tracks in MarlinTrk.
Definition: IMarlinTrack.h:36
double getOmega() const
Definition: HelixTrack.h:31
virtual void setCovMatrix(const float *cov)
virtual int fit(double maxChi2Increment=DBL_MAX)=0
perform the fit of all current hits, returns error code ( IMarlinTrack::success if no error ) ...
int createFinalisedLCIOTrack(IMarlinTrack *marlinTrk, std::vector< EVENT::TrackerHit * > &hit_list, IMPL::TrackImpl *track, bool fit_direction, EVENT::TrackState *pre_fit, float bfield_z, double maxChi2Increment=DBL_MAX)
Takes a list of hits and uses the IMarlinTrack inferface to fit them using a supplied prefit containi...
virtual int getOutliers(std::vector< std::pair< EVENT::TrackerHit *, double > > &hits)=0
get the list of hits which have been rejected by from the fit due to the a chi2 increment greater tha...
virtual float getTanLambda() const
static bool forwards
Definition: HelixTrack.h:35
virtual void setZ0(float z0)
virtual int getHitsInFit(std::vector< std::pair< EVENT::TrackerHit *, double > > &hits)=0
get the list of hits included in the fit, together with the chi2 contributions of the hits...
void setValue(lcio::long64 value)
virtual int getCellID0() const =0
virtual int addHit(EVENT::TrackerHit *hit)=0
add hit to track - the hits have to be added ordered in time ( i.e.
static const int success
Definition: IMarlinTrack.h:53
void addHitNumbersToTrack(IMPL::TrackImpl *track, std::vector< EVENT::TrackerHit * > &hit_list, bool hits_in_fit, UTIL::BitField64 &cellID_encoder)
Set the subdetector hit numbers for the TrackImpl.
static const int no_intersection
Definition: IMarlinTrack.h:56
virtual void setChi2(float chi2)
virtual void setPhi(float phi)
static IMarlinTrkSystem * getCurrentMarlinTrkSystem()
Return the current MarlinTrkSystem, i.e.
Definition: Factory.cc:87
T size(T...args)
int createPrefit(std::vector< EVENT::TrackerHit * > &hit_list, IMPL::TrackStateImpl *pre_fit, float bfield_z, bool fit_direction)
Provides the values of a track state from the first, middle and last hits in the hit_list.
std::string errorCode(int error)
Helper function to convert error return code to string.
Definition: IMarlinTrack.cc:26
unsigned lowWord() const
T begin(T...args)
double moveRefPoint(double x, double y, double z)
Definition: HelixTrack.cc:66
static const int modeForward
Definition: IMarlinTrack.h:50
T back(T...args)
Base class for tracking system implementations in MarlinTrk.
virtual MarlinTrk::IMarlinTrack * createTrack()=0
Return an instance of IMarlinTrack corresponding to the current implementation.
virtual void setOmega(float omega)
double getRefPointY() const
Definition: HelixTrack.h:26
#define MIN_NDF
static unsigned subdet()
double getTanLambda() const
Definition: HelixTrack.h:32
static const int COMPOSITE_SPACEPOINT
static const int ONE_DIMENSIONAL
virtual const LCObjectVec & getRawHits() const =0
double getD0() const
Definition: HelixTrack.h:28
T reserve(T...args)
static const int error
Definition: IMarlinTrack.h:54
virtual int initialise(bool fitDirection)=0
initialise the fit using the hits added up to this point - the fit direction has to be specified usin...
T rbegin(T...args)