StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StiKalmanTrackFinder.cxx
1 
13 #include <cassert>
14 #include "Stiostream.h"
15 #include <stdexcept>
16 #include <math.h>
17 #include "TMath.h"
18 #include "TError.h"
19 #include "TStopwatch.h"
20 #include "StEnumerations.h"
21 #include "Sti/Base/Parameter.h"
22 #include "Sti/Base/EditableParameter.h"
23 #include "Sti/Base/EditableFilter.h"
24 #include "StiToolkit.h"
25 #include "StiHit.h"
26 #include "StiHitContainer.h"
27 #include "StiDetector.h"
28 #include "StiDetectorContainer.h"
29 #include "StiTrackContainer.h"
30 #include "StiTrack.h"
31 #include "StiTrackFinder.h"
32 //#include "StiTrackSeedFinder.h"
33 #include "StiTrack.h"
34 #include "StiKalmanTrackFinder.h"
35 #include "StiTrackContainer.h"
36 #include "StiKalmanTrack.h"
37 #include "StiKalmanTrackNode.h"
38 #include "StiDefaultTrackFilter.h"
39 #include "StiTrackFinderFilter.h"
40 #include "StiUtilities/StiDebug.h"
41 #include "StDetectorDbMaker/StiKalmanTrackFinderParameters.h"
42 #include "StMessMgr.h"
43 #include "StTpcHit.h"
44 #define TIME_StiKalmanTrackFinder
45 #ifdef TIME_StiKalmanTrackFinder
46 #include "Sti/StiTimer.h"
47 #endif
48 
49 #include "StiKalmanTrackFitter.h" // just for err check
50 #include "StiTrackFinderFilter.h" // just for err check
51 #include "StiHitTest.h"
52 
53 
54 enum {kSeedTimg,kTrakTimg,kPrimTimg};
55 enum {kMaxTrackPerm = 10000,kMaxEventPerm=10000000};
56 
57 static const double kRMinTpc =55;
58 int StiKalmanTrackFinder::_debug = 0;
59 ostream& operator<<(ostream&, const StiTrack&);
60 int gLevelOfFind = 0;
61 //______________________________________________________________________________
63 {
64  cout << "StiKalmanTrackFinder::initialize() -I- Started"<<endl;
65  _toolkit = StiToolkit::instance();
66  _trackNodeFactory = _toolkit->getTrackNodeFactory();
67  _detectorContainer = _toolkit->getDetectorContainer();
68  _detectorContainer->clear();
69  _hitContainer = _toolkit->getHitContainer();
70  _trackContainer = _toolkit->getTrackContainer();
71  /*
72  StiDefaultTrackFilter * trackFilter = new StiDefaultTrackFilter("FinderTrackFilter","Reconstructed Track Filter");
73  trackFilter->add( new EditableParameter("nPtsUsed","Use nPts", 1., 1., 0., 1., 1.,
74  Parameter::Boolean, StiTrack::kPointCount) );
75  trackFilter->add( new EditableParameter("nPtsMin", "Minimum nPts", 10., 10., 0., 100.,1.,
76  Parameter::Integer,StiTrack::kPointCount) );
77  trackFilter->add( new EditableParameter("nPtsMax", "Maximum nPts", 60., 60., 0., 100.,1.,
78  Parameter::Integer,StiTrack::kPointCount) );
79  trackFilter->add(new EditableParameter("lengthUsed","Use Length", 1., 1., 0.,1.,1.,Parameter::Boolean, StiTrack::kTrackLength));
80  trackFilter->add(new EditableParameter("lengthMin", "Min Length", 0., 0., -300., 300.,2,Parameter::Double, StiTrack::kTrackLength));
81  trackFilter->add(new EditableParameter("lengthMax", "Max Length", 300., 300., -300., 300.,2,Parameter::Double, StiTrack::kTrackLength));
82  _trackFilter = trackFilter;
83  */
84  _trackFilter = new StiTrackFinderFilter();
85  //_toolkit->setFinderTrackFilter(_trackFilter);
86  cout << "StiKalmanTrackFinder::initialize() -I- Done"<<endl;
87 }
88 
89 StiKalmanTrackFinder::StiKalmanTrackFinder(StiToolkit*toolkit)
90 :
91 _toolkit(toolkit),
92 _trackFilter(0),
93 _trackNodeFactory(0),
94 _detectorContainer(0),
95 _hitContainer(0),
96 _trackContainer(0)
97 {
98  cout << "StiKalmanTrackFinder::StiKalmanTrackFinder() - Started"<<endl;
99 memset(mTimg,0,sizeof(mTimg));
100  assert(_toolkit);
101  cout << "StiKalmanTrackFinder::StiKalmanTrackFinder() - Done"<<endl;
102 }
103 //______________________________________________________________________________
111 //______________________________________________________________________________
113 {
114  //cout << "StiKalmanTrackFinder::reset() -I- Starting" <<endl;
115  _detectorContainer->reset();
116  _trackContainer->clear();
117  _trackNodeFactory->reset();
118  _hitContainer->reset();
119  for (int j=0;j<(int)_seedFinders.size();j++) { _seedFinders[j]->reset();}
120  //cout << "StiKalmanTrackFinder::reset() -I- Done" <<endl;
121 }
122 
123 //______________________________________________________________________________
132 //______________________________________________________________________________
134 {
135  //cout << "StiKalmanTrackFinder::clear() -I- Starting" <<endl;
136  _hitContainer->clear();
137  _detectorContainer->clear();
138  _trackContainer->clear();
139  for (int j=0;j<(int)_seedFinders.size();j++) { _seedFinders[j]->clear();}
140  //cout << "StiKalmanTrackFinder::clear() -I- Done" <<endl;
141 }
142 
143 //______________________________________________________________________________
152 //______________________________________________________________________________
154 {
155  mEventPerm = kMaxEventPerm;
156  assert(_trackContainer );
157  extendSeeds (0.);
158 }
159 //________________________________________________________________________________
160 Int_t StiKalmanTrackFinder::Fit(StiKalmanTrack *track, Double_t rMin) {
161  int errType = kNoErrors; // no err by default
162 
163  Int_t nTSeed=0,nTAdd=0,nTFail=0,nTFilt=0,status = kNoErrors;
164  Int_t nTpcHits=0,nSvtHits=0,nSsdHits=0,nIstHits=0,nPxlHits=0;
165 
166  do { //technical do
167  track->setFlag(-1);
168  int opt = StiKalmanTrack::kAppRR|StiKalmanTrack::kAppUPD;
169  status = track->approx(opt); // should be filled by track->initialize()
170 StiDebug::Count("Xi2Helx2",track->getXi2());
171  if (status) {nTSeed++; errType = abs(status)*100 + kApproxFail; break;}
172 
173  status = track->fit(kOutsideIn);
174  if (status) {nTSeed++; errType = abs(status)*100 + kFitFail; break;}
175  status = extendTrack(track,rMin); // 0 = OK
176  if (!status) status = _trackFilter->filter(track);
177  if (status) {nTFilt++; errType = abs(status)*100 + kCheckFail;}
178  if (errType!=kNoErrors) {track->reduce(); return errType;}
179 
180  //cout << " ++++++++++++++++++++++++++++++ Adding Track"<<endl;
181  // Add DCA node
182  StiHit dcaHit; dcaHit.makeDca();
183  StiTrackNode *extenDca = track->extendToVertex(&dcaHit);
184  if (extenDca) {
185  track->add(extenDca,kOutsideIn);
186  }
187  // End DCA node
188  track->reduce();
189  nTAdd++;
190  track->test();
191  track->setFlag(1);
192  _trackContainer->push_back(track);
193  track->setId(_trackContainer->size());
194  track->reserveHits();
195  nTpcHits+=track->getFitPointCount(kTpcId);
196  nSvtHits+=track->getFitPointCount(kSvtId);
197  nSsdHits+=track->getFitPointCount(kSsdId);
198  nIstHits+=track->getFitPointCount(kIstId);
199  nPxlHits+=track->getFitPointCount(kPxlId);
200  //cout << " ++++++++++++++++++++++++++++++ Added Track"<<endl;
201  LOG_DEBUG << Form("StiKalmanTrackFinder::Fit:nbSeed=%d nTFail=%d nTFilt=%d nTAdd=%d",
202  nTSeed,nTFail,nTFilt,nTAdd) << endm;
203  LOG_DEBUG << Form("StiKalmanTrackFinder::Fit:nTpcHits=%d nSvtHits=%d nSsdHits=%d nPxlHits=%d nIstHits=%d",
204  nTpcHits,nSvtHits,nSsdHits,nPxlHits,nIstHits)
205  << endm;
206  } while(0);
207  return errType;
208 }
209 //______________________________________________________________________________
211 {
212  static int nCall=0;nCall++;
213  StiKalmanTrack *track;
214  int nTTot=0,nTOK=0;
215  for (int isf = 0; isf<(int)_seedFinders.size();isf++) {
216  _seedFinders[isf]->startEvent();
217  int nTtot=0,nTok=0;
218  while (true ){
219 // obtain track seed from seed finder
220 
221  if (mTimg[kSeedTimg]) mTimg[kSeedTimg]->Start(0);
222 
223  track = (StiKalmanTrack*)_seedFinders[isf]->findTrack(rMin);
224 
225  if (mTimg[kSeedTimg]) mTimg[kSeedTimg]->Stop();
226  if (!track) break; // no more seeds
227  track->reserveHits(0); //Set timesUsed hits to zero
228 
229  nTTot++;nTtot++;
230  if (mTimg[kTrakTimg]) mTimg[kTrakTimg]->Start(0);
231  Int_t errType = Fit(track,rMin);
232  _seedFinders[isf]->FeedBack(errType == kNoErrors);
233  if (errType) {
234  BFactory::Free(track);
235  }else {
236  nTOK++;
237  int nHits = track->getFitPointCount(kTpcId);
238  if (nHits>=15) nTok++;
239  assert(track->getChi2()<1000);
240  }
241  if (mTimg[kTrakTimg]) mTimg[kTrakTimg]->Stop();
242  }
243  Info("extendSeeds:","Pass_%d NSeeds=%d NTraks=%d",isf,nTtot,nTok);
244  }
245  Info("extendSeeds","nTTot = %d nTOK = %d\n",nTTot,nTOK);
246 
247 }
248 //______________________________________________________________________________
249 void StiKalmanTrackFinder::extendTracks(double rMin)
250 {
251 assert(0);
252 }
253 //______________________________________________________________________________
255 {
256  static int nCall=0; nCall++;
257  int trackExtended =0;
258  int trackExtendedOut=0;
259  int status = 0;
260  // invoke tracker to find or extend this track
261  //cout <<"StiKalmanTrack::find(int) -I- Outside-in"<<endl;
262  {
263  if (debug()) cout << "StiKalmanTrack::find seed " << *((StiTrack *) track);
264  trackExtended = find(track,kOutsideIn,rMin);
265  if (trackExtended){/* in CA case not extended is ok*/}
266  status = track->refit();
267  if(status) return kNotRefitedIn;
268 
269  }
270  // decide if an outward pass is needed.
271  const StiKalmanTrackNode * outerMostNode = track->getOuterMostNode(kGoodHit);
272  if (!outerMostNode)
273  {
274  track->setFlag(-1);
275  return kNotExtended;
276  }
277  if (outerMostNode->getX()<185. )
278  {
279  trackExtendedOut= find(track,kInsideOut);
280  if (!trackExtendedOut) return kExtended;
281  status = track->refit();
282  if(status) return kNotRefitedOut;
283  }
284  return kExtended;
285 }
286 //______________________________________________________________________________
287 void StiKalmanTrackFinder::extendTracksToVertices(const std::vector<StiHit*> &vertices)
288 {
289  static const double RMAX2d=StiKalmanTrackFinderParameters::instance()->maxDca2dZeroXY();
290  static const double DMAX3d=StiKalmanTrackFinderParameters::instance()->maxDca3dVertex();
291 
292  StiKalmanTrackNode *extended=0;
293  int goodCount= 0, plus=0, minus=0;
294  int nTracks = _trackContainer->size();
295  int nVertex = vertices.size();
296  if (!nVertex || !nTracks) return;
297 
298  for (int iTrack=0;iTrack<nTracks;iTrack++) {
299  StiKalmanTrack * track = (StiKalmanTrack*)(*_trackContainer)[iTrack];
300 
301  StiKalmanTrackNode *bestNode=0;
302  int bestVertex=0;
303  StThreeVectorD nearBeam;
304  track->getNearBeam(&nearBeam);
305  const StiKalmanTrackNode *dcaNode = track->getLastNode();
306  if (!dcaNode->isDca()) continue;
307 
308  if (nearBeam.perp2()>RMAX2d*RMAX2d) continue;
309  for (int iVertex=0;iVertex<nVertex;iVertex++) {
310  StiHit *vertex = vertices[iVertex];
311  if (fabs(track->getDca(vertex)) > DMAX3d) continue;
312  if (mTimg[kPrimTimg]) mTimg[kPrimTimg]->Start(0);
313 
314  extended = (StiKalmanTrackNode*)track->extendToVertex(vertex);
315  if (mTimg[kPrimTimg]) mTimg[kPrimTimg]->Stop();
316 
317  if (!extended) continue;
318  if (!bestNode) {bestNode=extended;bestVertex=iVertex+1;continue;}
319  if (bestNode->getChi2()+log(bestNode->getDeterm())
320  <extended->getChi2()+log(extended->getDeterm()))continue;
321  BFactory::Free(bestNode);
322  bestNode = extended; bestVertex=iVertex+1;
323  }//End vertex loop
324 
325  if(!bestNode) continue;
326  track->add(bestNode,kOutsideIn);
327  track->setPrimary(bestVertex);
328  int ifail = 0;
329 static int REFIT=2005;
330  bestNode->setUntouched();
331 if (REFIT) {
332  ifail = track->refit();
333  ifail |= (track->getInnerMostHitNode(kGoodHit)!=bestNode);
334 }
335  track->reduce();
336 // something is wrong. It is not a primary
337  if (ifail) { track->removeLastNode(); track->setPrimary(0); continue;}
338  goodCount++;
339  if (track->getCharge()>0) plus++; else minus++;
340 
341  }//End track loop
342  _nPrimTracks = goodCount;
343  if (debug()) {
344  cout << "SKTF::extendTracksToVertices(...) -I- rawCount:"<<nTracks<<endl
345  << " extendedCount:"<<goodCount<<endl
346  << " plus:"<<plus<<endl
347  << " minus:"<<minus<<endl;
348  }
349 }
350 
353 //______________________________________________________________________________
355 public:
356  QAFind() {reset(); }
357 void reset() {mRMin=0; mSum=0; mHits =0; mNits=0; mQA=0;mWits=0;mSits=0;}
358 double rmin() const {return mRMin;}
359 double sum() const {return mSum ;} //summ of chi2
360  int hits() const {return mHits;} //total number of hits
361  int nits() const {return mNits;} //total number of no hits
362  int sits() const {return mSits;} //total number of silicon hits
363  int wits() const {return mWits;} //total weight of precision hits
364  int qa() const {return mQA ;} // quality flag for current level
365  void setRMin(double rm) {mRMin = rm ;}
366  void addXi2(double Xi2) {mSum += Xi2 ;}
367  void addHit(const StiHit *hit){mHits++; mQA=1;
368  if (hit->x() < kRMinTpc) { mSits++;
369  mWits+=StiKalmanTrackFinderParameters::instance()->hitWeight((int)hit->x());}
370  }
371 
372  void setHits(int nHits){mHits=nHits; mQA=1;}
373  void setNits(int nNits){mNits=nNits;}
374  void addNit() {mNits++; mQA=-1;}
375  void setQA(int qa) {mQA = qa;}
376  int compQA(const QAFind &qaTry) const;
377 private:
378  double mRMin; //minimal radius allowed for search
379  double mSum; //summ of chi2
380  int mHits; //total number of hits
381  int mNits; //total number of no hits
382  int mSits; //total number of silicon hits
383  int mWits; //total weight of precision hits
384  int mQA; // quality flag for current level
385  // qa = 1 == new hit accepted
386  // qa = 0 == no hits was expected. dead material or edge
387  // qa = -1 == hit expected but not found
388  // qa = -2 == close to beam, stop processing of it
389  // qa = -3 == fake track, stop processing of it
390  // qa = -4 == track can not be continued, stop processing of it
391 
392 };
393 //______________________________________________________________________________
394 int StiKalmanTrackFinder::QAFind::compQA(const QAFind &qaTry) const
395 {
396 // return > 0 qaTry is better
397 // return < 0 qaTry is worse
398 // return== 0 qaTry is the same
399 
400 static const StiKalmanTrackFinderParameters *tfp = StiKalmanTrackFinderParameters::instance();
401 // One SVT hit is worse than zero
402  if (!mWits && qaTry.wits() && qaTry.wits() < tfp->sumWeight()) return -999;
403  if (!qaTry.wits() && mWits && mWits < tfp->sumWeight()) return 999;
404 
405  int ians = qaTry.wits()-mWits; if (ians) return ians;
406  ians = qaTry.sits()-mSits; if (ians) return ians;
407  ians = qaTry.hits()-mHits; if (ians) return ians;
408  ians = mNits- qaTry.nits(); if (ians) return ians;
409  if (mSum <= qaTry.sum() ) return -1;
410  return 1;
411 }
412 
413 //______________________________________________________________________________
414 bool StiKalmanTrackFinder::find(StiTrack * t, int direction,double rmin)
415 {
416 static int nCall=0; nCall++;
417  gLevelOfFind = 0;
418  int nnBef,nnAft;
419  double lnBef,lnAft;
420 
421  if(direction) rmin=0; //no limitation to outside
422  StiKalmanTrack *track = dynamic_cast<StiKalmanTrack *> (t);
423  nnBef = track->getNNodes(kGoodHit);
424  lnBef = track->getTrackLength();
425 
426  StiKalmanTrackNode *leadNode = track->getInnOutMostNode(direction,kGoodHit);
427  if (!leadNode) return 0;
428  leadNode->cutTail(direction);
429  track->setFirstLastNode(leadNode);
430  QAFind qa; qa.setRMin(rmin);
431  mTrackPerm = kMaxTrackPerm;
432  mUseComb = useComb();
433  qa.setHits(track->getPointCount());
434  qa.setNits(track->getGapCount() );
435  if (direction && qa.hits()<5) return 0;
436  find(track,direction,leadNode,qa);
437 assert(qa.hits()==track->getPointCount());
438 
439  track->setCombUsed(mUseComb);
440  track->setFirstLastNode(leadNode);
441  nnAft = track->getNNodes(kGoodHit);
442  lnAft = track->getTrackLength();
443  return (nnAft>nnBef || lnAft>(lnBef+0.5));
444 }
445 //______________________________________________________________________________
446 void StiKalmanTrackFinder::find(StiKalmanTrack * track, int direction
447  ,StiKalmanTrackNode *leadNode,QAFind &qa)
448 {
449 static int nCall=0; nCall++;
450 
451 static const double degToRad = 3.1415927/180.;
452 static const double radToDeg = 180./3.1415927;
453 static const double ref1 = 50.*degToRad;
454 //static const double ref2 = 2.*3.1415927-ref1;
455 static const double ref1a = 110.*degToRad;
456 assert(direction || leadNode==track->getLastNode());
457 
458 
459 
460  // const double ref2a = 2.*3.1415927-ref1a;
461  gLevelOfFind++;
462  --mEventPerm;
463  assert(mEventPerm>=0 && "FATAL::TOO MANY permutations");
464  if (--mTrackPerm==0) { mUseComb = 0; }
465 
466  StiDetector *tDet=0;
467  int status;
468  StiKalmanTrackNode testNode;
469  int position;
470  StiHit * stiHit;
471  double leadRadius;
472 
473  const StiDetector *leadDet = leadNode->getDetector();
474  leadRadius = leadDet->getPlacement()->getLayerRadius();
475  assert(leadRadius>0 && leadRadius<1000);
476  if (leadRadius < qa.rmin()) {gLevelOfFind--;qa.setQA(-4);return;}
477 
478  double xg = leadNode->x_g();
479  double yg = leadNode->y_g();
480  double projAngle = atan2(yg,xg);
481  if(debug() > 2)cout << "Projection Angle:"<<projAngle*180/3.1415<<endl;
482 
483  vector<StiDetectorNode*>::const_iterator layer;
484  vector<StiDetectorNode*>::const_reverse_iterator rlayer;
485 
486  if ((!direction)) {
487  if (debug() > 2) cout <<endl<< "out-in"<<endl;
488  rlayer=_detectorContainer->rbeginRadial(leadDet); rlayer++;
489  } else {
490  if (debug() > 2) cout <<endl<< "in-out"<<endl;
491  layer=_detectorContainer->beginRadial(leadDet); layer++;
492  }
493 
494  if (debug() > 2) cout <<endl<< "lead node:" << *leadNode<<endl<<"lead det:"<<*leadDet<<endl;
495 
496 
497  while (((!direction)? rlayer!=_detectorContainer->rendRadial() : layer!=_detectorContainer->endRadial()))
498  {do{//technical do
499  vector<StiDetectorNode*>::const_iterator sector;
500  vector<StiDetector*> detectors;
501  if (debug() > 2) cout << endl<<"lead node:" << *leadNode<<endl<<" lead det:"<<*leadDet;
502 
503  //find all relevant detectors to visit.
504  sector = (!direction)? _detectorContainer->beginPhi(rlayer):_detectorContainer->beginPhi(layer);
505  for ( ; (!direction)? sector!=_detectorContainer->endPhi(rlayer):sector!=_detectorContainer->endPhi(layer); ++sector)
506  {
507  StiDetector * detector = (*sector)->getData();
508  if (detector == leadDet) continue;
509  double angle = detector->getPlacement()->getLayerAngle();
510  double radius = detector->getPlacement()->getLayerRadius();
511  if (radius < qa.rmin()) {gLevelOfFind--; qa.setQA(-4);return;}
512  double diff = radius-leadRadius;if (!direction) diff = -diff;
513  if (diff<-1e-6 && debug()>3) {
514  LOG_DEBUG << Form("TrackFinder: Wrong order: (%s).(%g) and (%s).(%g)"
515  ,leadDet->getName().c_str(),leadRadius
516  ,detector->getName().c_str(),radius) << endm;
517  }
518 
519 
520  Int_t shapeCode = detector->getShape()->getShapeCode();
521  Double_t OpenAngle = ref1;
522  if (shapeCode >= kCylindrical) {
523  OpenAngle = ((StiCylindricalShape *) detector->getShape())->getOpeningAngle();
524  } else {
525  if (radius <= 50 ) OpenAngle = ref1a;
526  }
527  diff = projAngle-angle;
528  if (diff > M_PI) diff -= 2*M_PI;
529  if (diff < -M_PI) diff += 2*M_PI;
530  if (fabs(diff) > OpenAngle) continue;
531  detectors.push_back(detector);
532  }
533 // list of detectors candidates created
534  int nDets = detectors.size();
535  if (!nDets) continue;
536 // and sorted by Phi angle
537  if (nDets>1) sort(detectors.begin(),detectors.end(),CloserAngle(projAngle) );
538 
539 // There is additional loop. 1st loop for active only, second for non active
540  int foundInDetLoop = 0;
541  for (int nowActive=1; nowActive>=0; nowActive--) { //Additional activeNonActive loop
542 
543  for (vector<StiDetector*>::const_iterator d=detectors.begin();d!=detectors.end();++d)
544  {
545  tDet = *d;
546  if ((tDet->isActive() != nowActive)) continue;
547  if (debug() > 2) {
548  cout << endl<< "target det:"<< *tDet;
549  cout << endl<< "lead angle:" << projAngle*radToDeg
550  <<" this angle:" << radToDeg*(*d)->getPlacement()->getNormalRefAngle()<<endl;
551  }
552  //begin tracking here...
553  testNode.reduce();testNode.reset();
554  testNode.setChi2(1e55);
555  position = testNode.propagate(leadNode,tDet,direction);
556  if (position) {
557  continue; // missed, will try the next available volume on this layer
558  }
559  testNode.setDetector(tDet);
560  foundInDetLoop = 2016;
561  int active = tDet->isActive(testNode.getY(),testNode.getZ());
562 
563  double maxChi2 = tDet->getTrackingParameters()->getMaxChi2ForSelection();
564 
565  StiHitContino hitCont;
566 
567  if (active) {
568 
569  if (debug() > 2)cout<<" search hits";
570  // active detector may have a hit
571  vector<StiHit*> & candidateHits = _hitContainer->getHits(testNode);//,true);
572  vector<StiHit*>::iterator hitIter;
573  for (hitIter=candidateHits.begin();hitIter!=candidateHits.end();++hitIter)
574  {
575  stiHit = *hitIter;
576  if (stiHit->detector() && stiHit->detector()!=tDet) continue;
577  status = testNode.nudge(stiHit);
578  testNode.setReady();
579  if (status) continue;
580  chi2 = testNode.evaluateChi2(stiHit);
581  if (chi2>maxChi2) continue;
582  hitCont.add(stiHit,chi2,testNode.getDeterm());
583  if (debug() > 2) cout << " hit selected"<<endl;
584  }// for (hitIter)
585  }//if(active)
586 
587  int nHits = hitCont.getNHits();
588 
589  testNode.setHitCand(nHits);
590  if (direction) {
591  nHits=1;
592  } else {
593  int flg = (testNode.getX()< kRMinTpc)? mUseComb &3:mUseComb>>2;
594  if ((flg&2) || !nHits) nHits++;
595  if ((flg&1)==0) nHits=1;
596 
597  }
598 
599  QAFind qaBest(qa),qaTry;
600  for (int jHit=0;jHit<nHits; jHit++)
601  {//Loop over Hits
602  stiHit = hitCont.getHit(jHit);
603  StiKalmanTrackNode * node = _trackNodeFactory->getInstance();
604  *node = testNode;
605  status = 0;
606  do {//fake do
607  if (!stiHit) break;
608  node->setIHitCand(jHit);
609  node->setHit(stiHit);
610  status = node->updateNode();
611  if (status) break;
612  node->setChi2(hitCont.getChi2(jHit));
613  if (!direction && node->getX()< kRMinTpc) node->saveInfo(); //Save info for pulls
614  }while(0);
615  if (status) {_trackNodeFactory->free(node); continue;}
616 
617  qaTry = qa;
618  track->add(node,direction,leadNode);
619  nodeQA(node,position,active,qaTry);
620  find(track,direction,node,qaTry);
621  if (jHit==0) { qaBest=qaTry; continue;}
622  int igor = qaBest.compQA(qaTry);
623  if (igor<0) { leadNode->remove(0);}
624  else { leadNode->remove(1);qaBest=qaTry;}
625  }
626  qa = qaBest; gLevelOfFind--; qa.setQA(-4); return;
627  }//End Detectors
628  if (foundInDetLoop) break; //activeNonActive
629  } //End of activeNonActive loop;
630  }while(0);
631  if(!direction){++rlayer;}else{++layer;}}
632 //end layers
633  gLevelOfFind--;qa.setQA(-4);
634  return;
635 }
636 //______________________________________________________________________________
637 void StiKalmanTrackFinder::nodeQA(StiKalmanTrackNode *node, int position
638  ,int active,QAFind &qa)
639 {
640  int maxNullCount = StiKalmanTrackFinderParameters::instance()->maxNullCount()+3;
641  int maxContiguousNullCount = StiKalmanTrackFinderParameters::instance()->maxContiguousNullCount()+3;
642 // Check and count node
643  StiHit *hit = node->getHit();
644  if (hit) {
645  if (debug() > 2)cout << " got Hit! "<<endl ;
646 // const StiDetector *detector = hit->detector();
647  qa.addXi2(node->getChi2() + log(node->getDeterm()));
648  qa.addHit(hit);
649  node->incHitCount();
650  node->incContigHitCount();
651 
652  if (node->getContigHitCount()>StiKalmanTrackFinderParameters::instance()->minContiguousHitCountForNullReset())
653  node->setContigNullCount();
654 
655  } else if (position>0 || !active) {// detectors edge - don't really expect a hit here
656  qa.setQA(0);
657 
658  } else {// there should have been a hit but we found none
659  if (debug() > 2) cout << " no hit but expected one"<<endl;
660  node->incNullCount();
661  node->incContigNullCount();
662  node->setContigHitCount();
663  qa.addNit();
664  if (node->getNullCount()>maxNullCount) qa.setQA(-3);
665  if (node->getContigNullCount()>maxContiguousNullCount) qa.setQA(-3);
666  }
667 
668 }
669 
670 //______________________________________________________________________________
672 {
673 assert(0); return 0;
674 }
675 
676 //______________________________________________________________________________
678 {
679  for (int it=0;it<(int)(sizeof(mTimg)/sizeof(mTimg[0]));it++){
680  mTimg[it]= new TStopwatch(); mTimg[it]->Stop(); }
681 }
682 //______________________________________________________________________________
684 {
685 static const char *timg[] = {"SeedFnd","TrakFnd","PrimFnd",0};
686  if (mTimg[0]) {
687  for (int i=0;timg[i];i++) {
688  Info("TrackFinder::Timing","%s(%d) \tCpuTime = %6.2f seconds,\tPerTrak = %g seconds"
689  ,timg[i],mTimg[i]->Counter(),mTimg[i]->CpuTime()
690  ,mTimg[i]->CpuTime()/mTimg[i]->Counter());
691  } }
692 }
693 //______________________________________________________________________________
695 { return _trackContainer->size();}
696 
697 //______________________________________________________________________________
698 CloserAngle::CloserAngle(double refAngle)
699  : _refAngle(refAngle)
700 { }
701 
702 //______________________________________________________________________________
703 bool CloserAngle::operator()(const StiDetector*lhs, const StiDetector* rhs)
704 {
705  double lhsa = lhs->getPlacement()->getNormalRefAngle();
706  double rhsa = rhs->getPlacement()->getNormalRefAngle();
707  double lhsda = fabs(lhsa-_refAngle); if (lhsda>3.1415) lhsda-=3.1415;
708  double rhsda = fabs(rhsa-_refAngle); if (rhsda>3.1415) rhsda-=3.1415;
709  return lhsda<rhsda;
710 }
711 
StiKalmanTrackNode * getInnOutMostNode(int inot, int qua) const
Same for getNNodes(qua)
virtual void initialize()
Initialize the finder.
int propagate(StiKalmanTrackNode *p, const StiDetector *tDet, int dir)
Propagates a track encapsulated by the given node &quot;p&quot; to the given detector &quot;tDet&quot;.
virtual void findTracks()
Find all tracks of the currently loaded event.
StiKalmanTrackNode * getInnerMostHitNode(int qua=0) const
Accessor method returns the inner most hit node associated with the track.
Definition of Kalman Track.
vector< StiHit * > & getHits()
Get hits selected by the given filter. If no filter is given (i.e. filter==0)
void extendSeeds(double rMin)
Extend seeds to tracks.
void makeDca()
Make fake hit for dca calculation.
Definition: StiHit.cxx:279
double getNearBeam(StThreeVectorD *pnt=0, StThreeVectorD *dir=0) const
bool find(StiTrack *track, int direction, double rmin=0)
Find/extend the given track, in the given direction.
Abstract definition of a Track.
Definition: StiTrack.h:59
virtual StiTrack * findTrack(double rMin=0)
Find the next track.
StiTrackNode * extendToVertex(StiHit *vertex)
int getGapCount() const
Return the number of gaps on this track.
StiKalmanTrackNode * getLastNode() const
Accessor method returns the last node associated with the track.
Definition: StiHit.h:51
virtual void reset()
Reset the tracker.
const Float_t & x() const
Return the local x, y, z values.
Definition: StiHit.h:67
virtual void free(Abstract *obj)=0
Free an object for reuse.
StiKalmanTrackNode * getOuterMostNode(int qua=0) const
Accessor method returns the outer most node associated with the track.
void reset()
Resets the node to a &quot;null&quot; un-used state.
void reserveHits(int yes=1)
int getNTracks() const
get number of tracks
int extendTrack(StiKalmanTrack *track, double rMin)
Extend track.
const StiDetector * detector() const
Definition: StiHit.h:96
virtual void finish() const
Finish the tracker.
virtual void clear()
int getFitPointCount(int detectorId=0) const
Returns the number of hits associated and used in the fit of this track.
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
int getPointCount(int detectorId=0) const
Return the number of hits associated with this track.
void setTiming()
Set timing of tracking.
Definition of Kalman Track.
static void Free(void *obj)
Free an object for reuse.
Definition: Factory.h:73
double getChi2() const
double getDca() const
Abstract interface for a STI toolkit.
virtual void reset()=0
Reset this factory.
double evaluateChi2(const StiHit *hit)
void reset()
This performs a full internal reset of interator structure.
double getTrackLength() const
virtual void clear()
Clear the tracker.
Definition of toolkit.
Definition: StiToolkit.h:55
virtual void add(StiTrackNode *node, int direction, StiTrackNode *near=0)
void remove(int childIndex)
Definition: StiTreeNode.cxx:28
int getCharge() const
const string & getName() const
Get the name of the object.
Definition: Named.cxx:22