19 #include "TStopwatch.h"
21 #include "Sti/Base/Parameter.h"
22 #include "Sti/Base/EditableParameter.h"
23 #include "Sti/Base/EditableFilter.h"
26 #include "StiHitContainer.h"
27 #include "StiDetector.h"
28 #include "StiDetectorContainer.h"
29 #include "StiTrackContainer.h"
31 #include "StiTrackFinder.h"
34 #include "StiKalmanTrackFinder.h"
35 #include "StiTrackContainer.h"
37 #include "StiKalmanTrackNode.h"
38 #include "StiDefaultTrackFilter.h"
39 #include "StiTrackFinderFilter.h"
41 #include "StDetectorDbMaker/StiKalmanTrackFinderParameters.h"
42 #include "StMessMgr.h"
44 #define TIME_StiKalmanTrackFinder
45 #ifdef TIME_StiKalmanTrackFinder
49 #include "StiKalmanTrackFitter.h"
50 #include "StiTrackFinderFilter.h"
51 #include "StiHitTest.h"
54 enum {kSeedTimg,kTrakTimg,kPrimTimg};
55 enum {kMaxTrackPerm = 10000,kMaxEventPerm=10000000};
57 static const double kRMinTpc =55;
58 int StiKalmanTrackFinder::_debug = 0;
59 ostream& operator<<(ostream&,
const StiTrack&);
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();
86 cout <<
"StiKalmanTrackFinder::initialize() -I- Done"<<endl;
89 StiKalmanTrackFinder::StiKalmanTrackFinder(
StiToolkit*toolkit)
94 _detectorContainer(0),
98 cout <<
"StiKalmanTrackFinder::StiKalmanTrackFinder() - Started"<<endl;
99 memset(mTimg,0,
sizeof(mTimg));
101 cout <<
"StiKalmanTrackFinder::StiKalmanTrackFinder() - Done"<<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();}
136 _hitContainer->
clear();
137 _detectorContainer->clear();
138 _trackContainer->clear();
139 for (
int j=0;j<(int)_seedFinders.size();j++) { _seedFinders[j]->clear();}
155 mEventPerm = kMaxEventPerm;
156 assert(_trackContainer );
161 int errType = kNoErrors;
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;
168 int opt = StiKalmanTrack::kAppRR|StiKalmanTrack::kAppUPD;
169 status = track->approx(opt);
170 StiDebug::Count(
"Xi2Helx2",track->getXi2());
171 if (status) {nTSeed++; errType = abs(status)*100 + kApproxFail;
break;}
173 status = track->fit(kOutsideIn);
174 if (status) {nTSeed++; errType = abs(status)*100 + kFitFail;
break;}
176 if (!status) status = _trackFilter->filter(track);
177 if (status) {nTFilt++; errType = abs(status)*100 + kCheckFail;}
178 if (errType!=kNoErrors) {track->reduce();
return errType;}
185 track->
add(extenDca,kOutsideIn);
192 _trackContainer->push_back(track);
193 track->setId(_trackContainer->size());
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)
212 static int nCall=0;nCall++;
215 for (
int isf = 0; isf<(int)_seedFinders.size();isf++) {
216 _seedFinders[isf]->startEvent();
221 if (mTimg[kSeedTimg]) mTimg[kSeedTimg]->Start(0);
225 if (mTimg[kSeedTimg]) mTimg[kSeedTimg]->Stop();
230 if (mTimg[kTrakTimg]) mTimg[kTrakTimg]->Start(0);
231 Int_t errType = Fit(track,rMin);
232 _seedFinders[isf]->FeedBack(errType == kNoErrors);
238 if (nHits>=15) nTok++;
241 if (mTimg[kTrakTimg]) mTimg[kTrakTimg]->Stop();
243 Info(
"extendSeeds:",
"Pass_%d NSeeds=%d NTraks=%d",isf,nTtot,nTok);
245 Info(
"extendSeeds",
"nTTot = %d nTOK = %d\n",nTTot,nTOK);
249 void StiKalmanTrackFinder::extendTracks(
double rMin)
256 static int nCall=0; nCall++;
257 int trackExtended =0;
258 int trackExtendedOut=0;
263 if (debug()) cout <<
"StiKalmanTrack::find seed " << *((
StiTrack *) track);
264 trackExtended =
find(track,kOutsideIn,rMin);
266 status = track->refit();
267 if(status)
return kNotRefitedIn;
277 if (outerMostNode->getX()<185. )
279 trackExtendedOut=
find(track,kInsideOut);
280 if (!trackExtendedOut)
return kExtended;
281 status = track->
refit();
282 if(status)
return kNotRefitedOut;
287 void StiKalmanTrackFinder::extendTracksToVertices(
const std::vector<StiHit*> &vertices)
289 static const double RMAX2d=StiKalmanTrackFinderParameters::instance()->maxDca2dZeroXY();
290 static const double DMAX3d=StiKalmanTrackFinderParameters::instance()->maxDca3dVertex();
293 int goodCount= 0, plus=0, minus=0;
294 int nTracks = _trackContainer->size();
295 int nVertex = vertices.size();
296 if (!nVertex || !nTracks)
return;
298 for (
int iTrack=0;iTrack<nTracks;iTrack++) {
306 if (!dcaNode->isDca())
continue;
308 if (nearBeam.perp2()>RMAX2d*RMAX2d)
continue;
309 for (
int iVertex=0;iVertex<nVertex;iVertex++) {
311 if (fabs(track->
getDca(vertex)) > DMAX3d)
continue;
312 if (mTimg[kPrimTimg]) mTimg[kPrimTimg]->Start(0);
315 if (mTimg[kPrimTimg]) mTimg[kPrimTimg]->Stop();
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;
322 bestNode = extended; bestVertex=iVertex+1;
325 if(!bestNode)
continue;
326 track->
add(bestNode,kOutsideIn);
327 track->setPrimary(bestVertex);
329 static int REFIT=2005;
330 bestNode->setUntouched();
332 ifail = track->
refit();
337 if (ifail) { track->removeLastNode(); track->setPrimary(0);
continue;}
339 if (track->
getCharge()>0) plus++;
else minus++;
342 _nPrimTracks = goodCount;
344 cout <<
"SKTF::extendTracksToVertices(...) -I- rawCount:"<<nTracks<<endl
345 <<
" extendedCount:"<<goodCount<<endl
346 <<
" plus:"<<plus<<endl
347 <<
" minus:"<<minus<<endl;
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 ;}
360 int hits()
const {
return mHits;}
361 int nits()
const {
return mNits;}
362 int sits()
const {
return mSits;}
363 int wits()
const {
return mWits;}
364 int qa()
const {
return mQA ;}
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());}
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;
394 int StiKalmanTrackFinder::QAFind::compQA(
const QAFind &qaTry)
const
402 if (!mWits && qaTry.wits() && qaTry.wits() < tfp->sumWeight())
return -999;
403 if (!qaTry.wits() && mWits && mWits < tfp->sumWeight())
return 999;
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;
416 static int nCall=0; nCall++;
421 if(direction) rmin=0;
423 nnBef = track->getNNodes(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();
435 if (direction && qa.hits()<5)
return 0;
436 find(track,direction,leadNode,qa);
439 track->setCombUsed(mUseComb);
440 track->setFirstLastNode(leadNode);
441 nnAft = track->getNNodes(kGoodHit);
443 return (nnAft>nnBef || lnAft>(lnBef+0.5));
449 static int nCall=0; nCall++;
451 static const double degToRad = 3.1415927/180.;
452 static const double radToDeg = 180./3.1415927;
453 static const double ref1 = 50.*degToRad;
455 static const double ref1a = 110.*degToRad;
456 assert(direction || leadNode==track->
getLastNode());
463 assert(mEventPerm>=0 &&
"FATAL::TOO MANY permutations");
464 if (--mTrackPerm==0) { mUseComb = 0; }
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;}
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;
483 vector<StiDetectorNode*>::const_iterator layer;
484 vector<StiDetectorNode*>::const_reverse_iterator rlayer;
487 if (debug() > 2) cout <<endl<<
"out-in"<<endl;
488 rlayer=_detectorContainer->rbeginRadial(leadDet); rlayer++;
490 if (debug() > 2) cout <<endl<<
"in-out"<<endl;
491 layer=_detectorContainer->beginRadial(leadDet); layer++;
494 if (debug() > 2) cout <<endl<<
"lead node:" << *leadNode<<endl<<
"lead det:"<<*leadDet<<endl;
497 while (((!direction)? rlayer!=_detectorContainer->rendRadial() : layer!=_detectorContainer->endRadial()))
499 vector<StiDetectorNode*>::const_iterator sector;
500 vector<StiDetector*> detectors;
501 if (debug() > 2) cout << endl<<
"lead node:" << *leadNode<<endl<<
" lead det:"<<*leadDet;
504 sector = (!direction)? _detectorContainer->beginPhi(rlayer):_detectorContainer->beginPhi(layer);
505 for ( ; (!direction)? sector!=_detectorContainer->endPhi(rlayer):sector!=_detectorContainer->endPhi(layer); ++sector)
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;
520 Int_t shapeCode = detector->getShape()->getShapeCode();
521 Double_t OpenAngle = ref1;
522 if (shapeCode >= kCylindrical) {
525 if (radius <= 50 ) OpenAngle = ref1a;
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);
534 int nDets = detectors.size();
535 if (!nDets)
continue;
537 if (nDets>1) sort(detectors.begin(),detectors.end(),
CloserAngle(projAngle) );
540 int foundInDetLoop = 0;
541 for (
int nowActive=1; nowActive>=0; nowActive--) {
543 for (vector<StiDetector*>::const_iterator d=detectors.begin();d!=detectors.end();++d)
546 if ((tDet->isActive() != nowActive))
continue;
548 cout << endl<<
"target det:"<< *tDet;
549 cout << endl<<
"lead angle:" << projAngle*radToDeg
550 <<
" this angle:" << radToDeg*(*d)->getPlacement()->getNormalRefAngle()<<endl;
553 testNode.reduce();testNode.
reset();
554 testNode.setChi2(1e55);
555 position = testNode.
propagate(leadNode,tDet,direction);
559 testNode.setDetector(tDet);
560 foundInDetLoop = 2016;
561 int active = tDet->isActive(testNode.getY(),testNode.getZ());
563 double maxChi2 = tDet->getTrackingParameters()->getMaxChi2ForSelection();
569 if (debug() > 2)cout<<
" search hits";
571 vector<StiHit*> & candidateHits = _hitContainer->
getHits(testNode);
572 vector<StiHit*>::iterator hitIter;
573 for (hitIter=candidateHits.begin();hitIter!=candidateHits.end();++hitIter)
577 status = testNode.nudge(stiHit);
579 if (status)
continue;
581 if (chi2>maxChi2)
continue;
582 hitCont.add(stiHit,chi2,testNode.getDeterm());
583 if (debug() > 2) cout <<
" hit selected"<<endl;
587 int nHits = hitCont.getNHits();
589 testNode.setHitCand(nHits);
593 int flg = (testNode.getX()< kRMinTpc)? mUseComb &3:mUseComb>>2;
594 if ((flg&2) || !nHits) nHits++;
595 if ((flg&1)==0) nHits=1;
599 QAFind qaBest(qa),qaTry;
600 for (
int jHit=0;jHit<nHits; jHit++)
602 stiHit = hitCont.getHit(jHit);
608 node->setIHitCand(jHit);
609 node->setHit(stiHit);
612 node->setChi2(hitCont.getChi2(jHit));
613 if (!direction && node->getX()< kRMinTpc) node->saveInfo();
615 if (status) {_trackNodeFactory->
free(node);
continue;}
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;}
626 qa = qaBest; gLevelOfFind--; qa.setQA(-4);
return;
628 if (foundInDetLoop)
break;
631 if(!direction){++rlayer;}
else{++layer;}}
633 gLevelOfFind--;qa.setQA(-4);
638 ,
int active,QAFind &qa)
640 int maxNullCount = StiKalmanTrackFinderParameters::instance()->maxNullCount()+3;
641 int maxContiguousNullCount = StiKalmanTrackFinderParameters::instance()->maxContiguousNullCount()+3;
645 if (debug() > 2)cout <<
" got Hit! "<<endl ;
647 qa.addXi2(node->getChi2() + log(node->getDeterm()));
650 node->incContigHitCount();
652 if (node->getContigHitCount()>StiKalmanTrackFinderParameters::instance()->minContiguousHitCountForNullReset())
653 node->setContigNullCount();
655 }
else if (position>0 || !active) {
659 if (debug() > 2) cout <<
" no hit but expected one"<<endl;
660 node->incNullCount();
661 node->incContigNullCount();
662 node->setContigHitCount();
664 if (node->getNullCount()>maxNullCount) qa.setQA(-3);
665 if (node->getContigNullCount()>maxContiguousNullCount) qa.setQA(-3);
679 for (
int it=0;it<(int)(
sizeof(mTimg)/
sizeof(mTimg[0]));it++){
680 mTimg[it]=
new TStopwatch(); mTimg[it]->Stop(); }
685 static const char *timg[] = {
"SeedFnd",
"TrakFnd",
"PrimFnd",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());
695 {
return _trackContainer->size();}
698 CloserAngle::CloserAngle(
double refAngle)
699 : _refAngle(refAngle)
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;
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 "p" to the given detector "tDet".
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.
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.
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.
virtual void reset()
Reset the tracker.
const Float_t & x() const
Return the local x, y, z values.
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 "null" 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
virtual void finish() const
Finish the tracker.
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.
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.
virtual void add(StiTrackNode *node, int direction, StiTrackNode *near=0)
void remove(int childIndex)
const string & getName() const
Get the name of the object.