00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "Stiostream.h"
00013 #include <stdexcept>
00014 #include <math.h>
00015 #include "TMath.h"
00016 #include "TError.h"
00017 #include "TStopwatch.h"
00018 #include "StEnumerations.h"
00019 using namespace std;
00020 #include "Sti/Base/Parameter.h"
00021 #include "Sti/Base/EditableParameter.h"
00022 #include "Sti/Base/EditableFilter.h"
00023 #include "StiToolkit.h"
00024 #include "StiHit.h"
00025 #include "StiHitContainer.h"
00026 #include "StiDetector.h"
00027 #include "StiDetectorContainer.h"
00028 #include "StiTrackContainer.h"
00029 #include "StiTrack.h"
00030 #include "StiTrackFinder.h"
00031
00032 #include "StiTrack.h"
00033 #include "StiKalmanTrackFinder.h"
00034 #include "StiTrackContainer.h"
00035 #include "StiKalmanTrack.h"
00036 #include "StiKalmanTrackNode.h"
00037 #include "StiDefaultTrackFilter.h"
00038 #include "StiTrackFinderFilter.h"
00039 #include "StiUtilities/StiDebug.h"
00040 #include "StDetectorDbMaker/StiKalmanTrackFinderParameters.h"
00041 #include "StMessMgr.h"
00042 #include "StTpcHit.h"
00043 #ifdef DO_TPCCATRACKER
00044 #include "StiTpcSeedFinder.h"
00045 #endif
00046 #define TIME_StiKalmanTrackFinder
00047 #ifdef TIME_StiKalmanTrackFinder
00048 #include "Sti/StiTimer.h"
00049 #endif
00050
00051 #include "StiKalmanTrackFitter.h"
00052 #include "StiTrackFinderFilter.h"
00053 #ifdef DO_TPCCATRACKER
00054 #include "StiTPCCATrackerInterface.h"
00055 #endif
00056 enum {kSeedTimg,kTrakTimg,kPrimTimg};
00057 enum {kMaxTrackPerm = 10000,kMaxEventPerm=10000000};
00058
00059 static const double kRMinTpc =55;
00060 int StiKalmanTrackFinder::_debug = 0;
00061 ostream& operator<<(ostream&, const StiTrack&);
00062 int gLevelOfFind = 0;
00063
00064 void StiKalmanTrackFinder::initialize()
00065 {
00066 cout << "StiKalmanTrackFinder::initialize() -I- Started"<<endl;
00067 _toolkit = StiToolkit::instance();
00068 _trackNodeFactory = _toolkit->getTrackNodeFactory();
00069 _detectorContainer = _toolkit->getDetectorContainer();
00070 _detectorContainer->reset();
00071 _trackSeedFinder = _toolkit->getTrackSeedFinder();
00072 _hitContainer = _toolkit->getHitContainer();
00073 _trackContainer = _toolkit->getTrackContainer();
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 _trackFilter = new StiTrackFinderFilter();
00088
00089 cout << "StiKalmanTrackFinder::initialize() -I- Done"<<endl;
00090 }
00091
00092 StiKalmanTrackFinder::StiKalmanTrackFinder(StiToolkit*toolkit)
00093 :
00094 _toolkit(toolkit),
00095 _trackFilter(0),
00096 _trackSeedFinder(0),
00097 _trackNodeFactory(0),
00098 _detectorContainer(0),
00099 _hitContainer(0),
00100 _trackContainer(0)
00101 {
00102 cout << "StiKalmanTrackFinder::StiKalmanTrackFinder() - Started"<<endl;
00103 memset(mTimg,0,sizeof(mTimg));
00104 if (!_toolkit)
00105 throw runtime_error("StiKalmanTrackFinder::StiKalmanTrackFinder(...) - FATAL - toolkit==0");
00106 cout << "StiKalmanTrackFinder::StiKalmanTrackFinder() - Done"<<endl;
00107 }
00108
00116
00117 void StiKalmanTrackFinder::reset()
00118 {
00119
00120 _detectorContainer->reset();
00121 _trackContainer->clear();
00122 _trackNodeFactory->reset();
00123 _hitContainer->reset();
00124 _trackSeedFinder->reset();
00125
00126 }
00127
00128
00137
00138 void StiKalmanTrackFinder::clear()
00139 {
00140
00141 _hitContainer->clear();
00142 reset();
00143
00144 }
00145
00146
00155
00156 void StiKalmanTrackFinder::findTracks()
00157 {
00158 mEventPerm = kMaxEventPerm;
00159
00160 assert(_trackContainer );
00161 assert(_trackSeedFinder);
00162 _trackSeedFinder->reset();
00163 _trackContainer->clear();
00164 if (_trackFilter) _trackFilter->reset();
00165 #ifdef DO_TPCCATRACKER
00166 StiTPCCATrackerInterface& caTrackerInt = StiTPCCATrackerInterface::Instance();
00167 caTrackerInt.SetNewEvent();
00168 findTpcTracks(caTrackerInt);
00169 #endif
00170 findAllTracks();
00171 #ifdef DO_TPCCATRACKER
00172 caTrackerInt.SetStiTracks(_trackContainer);
00173 caTrackerInt.RunPerformance();
00174 #endif
00175 }
00176 #ifdef DO_TPCCATRACKER
00177
00178 void StiKalmanTrackFinder::findTpcTracks(StiTPCCATrackerInterface &caTrackerInt) {
00179 StiTpcSeedFinder::findTpcTracks(caTrackerInt);
00180 }
00181 #endif
00182
00183 void StiKalmanTrackFinder::findAllTracks() {
00184
00185
00186
00187
00188
00189 extendSeeds (0.);
00190
00191
00192 }
00193
00194 Int_t StiKalmanTrackFinder::Fit(StiKalmanTrack *track, Double_t rMin) {
00195 int errType = kNoErrors;
00196
00197 Int_t nTSeed=0,nTAdd=0,nTFail=0,nTFilt=0,status = kNoErrors;
00198 Int_t nTpcHits=0,nSvtHits=0,nSsdHits=0,nIstHits=0,nPxlHits=0;
00199
00200 do {
00201 track->setFlag(-1);
00202 #ifndef DO_TPCCATRACKER
00203 status = track->approx(0);
00204 if (status) {nTSeed++; errType = abs(status)*100 + kApproxFail; break;}
00205 #endif
00206 status = track->fit(kOutsideIn);
00207 if (status) {nTSeed++; errType = abs(status)*100 + kFitFail; break;}
00208 status = extendTrack(track,rMin);
00209 #ifndef DO_TPCCATRACKER
00210 if (status != kExtended) {nTFail++; errType = abs(status)*100 + kExtendFail; break;}
00211 #else
00212 if ((status != kExtended) && (status != kNotExtended)) {nTFail++; errType = abs(status)*100 + kExtendFail; break;}
00213 #endif
00214 if (_trackFilter){
00215 status = _trackFilter->filter(track);
00216 if (status) {nTFilt++; errType = abs(status)*100 + kCheckFail; break;}
00217 }
00218
00219
00220 StiHit dcaHit; dcaHit.makeDca();
00221 StiTrackNode *extenDca = track->extendToVertex(&dcaHit);
00222 if (extenDca) {
00223 track->add(extenDca,kOutsideIn);
00224 if (debug() >= 1) StiKalmanTrackNode::PrintStep();
00225 }
00226
00227 track->reduce();
00228 nTAdd++;
00229 track->setFlag(1);
00230 _trackContainer->push_back(track);
00231 track->setId(_trackContainer->size());
00232 track->reserveHits();
00233 nTpcHits+=track->getFitPointCount(kTpcId);
00234 nSvtHits+=track->getFitPointCount(kSvtId);
00235 nSsdHits+=track->getFitPointCount(kSsdId);
00236 nIstHits+=track->getFitPointCount(kIstId);
00237 nPxlHits+=track->getFitPointCount(kPxlId);
00238
00239 LOG_DEBUG << Form("StiKalmanTrackFinder::Fit:nbSeed=%d nTFail=%d nTFilt=%d nTAdd=%d",
00240 nTSeed,nTFail,nTFilt,nTAdd) << endm;
00241 LOG_DEBUG << Form("StiKalmanTrackFinder::Fit:nTpcHits=%d nSvtHits=%d nSsdHits=%d nPxlHits=%d nIstHits=%d",
00242 nTpcHits,nSvtHits,nSsdHits,nPxlHits,nIstHits)
00243 << endm;
00244 } while(0);
00245 return errType;
00246 }
00247
00248 void StiKalmanTrackFinder::extendSeeds(double rMin)
00249 {
00250 static int nCall=0;nCall++;
00251 StiKalmanTrack *track;
00252 Int_t nTTot=0;
00253
00254 while (true ){
00255
00256
00257 if (mTimg[kSeedTimg]) mTimg[kSeedTimg]->Start(0);
00258
00259 track = (StiKalmanTrack*)_trackSeedFinder->findTrack(rMin);
00260
00261 if (mTimg[kSeedTimg]) mTimg[kSeedTimg]->Stop();
00262 if (!track) break;
00263 nTTot++;
00264 if (mTimg[kTrakTimg]) mTimg[kTrakTimg]->Start(0);
00265 Int_t errType = Fit(track,rMin);
00266 if (errType != kNoErrors) BFactory::Free(track);
00267 if (mTimg[kTrakTimg]) mTimg[kTrakTimg]->Stop();
00268 }
00269 }
00270
00271 void StiKalmanTrackFinder::extendTracks(double rMin)
00272 {
00273 static int nCall=0;nCall++;
00274
00275 int nTKeep=0;
00276 int ntr = _trackContainer->size();
00277 int nTpcHits=0,nSvtHits=0,nSsdHits=0,nPxlHits=0,nIstHits=0, extended=0;
00278
00279 for ( int itr=0;itr < ntr;itr++) {
00280 StiKalmanTrack *track = (StiKalmanTrack*)(*_trackContainer)[itr];
00281 if (track->getFlag()<=0) continue;
00282
00283 extended = extendTrack(track,rMin);
00284 track->reduce();
00285 if (extended<0 || track->getFlag()<=0) {
00286 track->reduce(); continue;
00287 } else {
00288 StiHit dcaHit; dcaHit.makeDca();
00289 StiTrackNode *extenDca = track->extendToVertex(&dcaHit);
00290 if (extenDca) track->add(extenDca,kOutsideIn);
00291 track->reduce();
00292 }
00293 nTKeep++;
00294 nTpcHits+=track->getFitPointCount(kTpcId);
00295 nSvtHits+=track->getFitPointCount(kSvtId);
00296 nSsdHits+=track->getFitPointCount(kSsdId);
00297 nPxlHits+=track->getFitPointCount(kPxlId);
00298 nIstHits+=track->getFitPointCount(kIstId);
00299 track->reserveHits();
00300 }
00301 LOG_DEBUG << Form("***extendTracks***: nTKeep=%d", nTKeep) << endm;
00302 LOG_DEBUG << Form("***extendTracks***: nTpcHits=%d nSvtHits=%d nSsdHits=%d nPxlHits=%d nIstHits=%d",
00303 nTpcHits,nSvtHits,nSsdHits,nPxlHits,nIstHits) << endm;
00304 }
00305
00306 int StiKalmanTrackFinder::extendTrack(StiKalmanTrack *track,double rMin)
00307 {
00308 static int nCall=0; nCall++;
00309 StiDebug::Break(nCall);
00310 int trackExtended =0;
00311 int trackExtendedOut=0;
00312 int status = 0;
00313
00314
00315 {
00316 if (debug()) cout << "StiKalmanTrack::find seed " << *((StiTrack *) track);
00317 trackExtended = find(track,kOutsideIn,rMin);
00318 if (trackExtended) {
00319 status = 0;
00320 if(status) return abs(status)*100 + kRefitInFail;
00321 }
00322
00323 }
00324
00325 const StiKalmanTrackNode * outerMostNode = track->getOuterMostNode(2);
00326 if (!outerMostNode)
00327 {
00328 track->setFlag(-1);
00329 return 0;
00330 }
00331 if (outerMostNode->getX()<185. )
00332 {
00333 trackExtendedOut= find(track,kInsideOut);
00334 if (debug()) cout << "StiKalmanTrackFinder::extendTrack (track,kInsideOut)" << *((StiTrack *) track);
00335 }
00336 trackExtended |=trackExtendedOut;
00337 if (trackExtended) {
00338 status = track->approx(1);
00339
00340 status = track->refit();
00341 if (status) return abs(status)*100 + kRefitOutFail;
00342 }
00343
00344 if ( trackExtended ) return kExtended;
00345 return kNotExtended;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 void StiKalmanTrackFinder::extendTracksToVertex(StiHit* vertex)
00368 {
00369
00370
00371 int rawCount = 0;
00372 int goodCount= 0;
00373 int plus=0;
00374 int minus=0;
00375 int ntr = _trackContainer->size();
00376 for (int itr=0;itr<ntr;itr++) {
00377 StiKalmanTrack* track = (StiKalmanTrack*)(*_trackContainer)[itr];
00378 rawCount++;
00379 StiTrackNode *extended = track->extendToVertex(vertex);
00380 if (extended) {
00381 track->add(extended,kOutsideIn);
00382 static int myRefit=0;
00383 if (myRefit && track->refit()) extended=0;
00384 if (extended && !extended->isValid()) extended=0;
00385 if (extended && extended->getChi2()>1000) extended=0;
00386 }
00387 track->reduce();
00388
00389 if (extended) goodCount++;
00390 if (track->getCharge()>0) plus++;else minus++;
00391 }
00392 cout << "SKTF::extendTracksToVertex(StiHit* vertex) -I- rawCount:"<<rawCount<<endl
00393 << " extendedCount:"<<goodCount<<endl
00394 << " plus:"<<plus<<endl
00395 << " minus:"<<minus<<endl;
00396 }
00397
00398 void StiKalmanTrackFinder::extendTracksToVertices(const std::vector<StiHit*> &vertices)
00399 {
00400 static const double RMAX2d=StiKalmanTrackFinderParameters::instance()->maxDca2dZeroXY();
00401 static const double DMAX3d=StiKalmanTrackFinderParameters::instance()->maxDca3dVertex();
00402
00403 StiKalmanTrackNode *extended=0;
00404 int goodCount= 0, plus=0, minus=0;
00405 int nTracks = _trackContainer->size();
00406 int nVertex = vertices.size();
00407 if (!nVertex || !nTracks) return;
00408
00409 for (int iTrack=0;iTrack<nTracks;iTrack++) {
00410 StiKalmanTrack * track = (StiKalmanTrack*)(*_trackContainer)[iTrack];
00411 StiDebug::tally("Tracks");
00412
00413 StiKalmanTrackNode *bestNode=0;
00414 int bestVertex=0;
00415 StThreeVectorD nearBeam;
00416 track->getNearBeam(&nearBeam);
00417 if (nearBeam.perp2()>RMAX2d*RMAX2d) continue;
00418 for (int iVertex=0;iVertex<nVertex;iVertex++) {
00419 StiHit *vertex = vertices[iVertex];
00420 if (fabs(track->getDca(vertex)) > DMAX3d) continue;
00421 StiDebug::tally("PrimCandidates");
00422 if (mTimg[kPrimTimg]) mTimg[kPrimTimg]->Start(0);
00423
00424 extended = (StiKalmanTrackNode*)track->extendToVertex(vertex);
00425 if (mTimg[kPrimTimg]) mTimg[kPrimTimg]->Stop();
00426
00427 if (!extended) continue;
00428 StiDebug::tally("PrimExtended");
00429 if (!bestNode) {bestNode=extended;bestVertex=iVertex+1;continue;}
00430 if (bestNode->getChi2()+log(bestNode->getDeterm())
00431 <extended->getChi2()+log(extended->getDeterm()))continue;
00432 BFactory::Free(bestNode);
00433 bestNode = extended; bestVertex=iVertex+1;
00434 }
00435
00436 if(!bestNode) continue;
00437 track->add(bestNode,kOutsideIn);
00438 track->setPrimary(bestVertex);
00439 StiDebug::tally("PrimAdded");
00440 int ifail = 0;
00441 static int REFIT=2005;
00442 bestNode->setUntouched();
00443 if (REFIT) {
00444 ifail = track->refit();
00445 ifail |= (track->getInnerMostHitNode(3)!=bestNode);
00446 }
00447 track->reduce();
00448
00449 if (ifail) { track->removeLastNode(); track->setPrimary(0); continue;}
00450 goodCount++;
00451 StiDebug::tally("PrimRefited");
00452 if (track->getCharge()>0) plus++; else minus++;
00453
00454 }
00455 _nPrimTracks = goodCount;
00456 if (debug()) {
00457 cout << "SKTF::extendTracksToVertices(...) -I- rawCount:"<<nTracks<<endl
00458 << " extendedCount:"<<goodCount<<endl
00459 << " plus:"<<plus<<endl
00460 << " minus:"<<minus<<endl;
00461 }
00462 }
00463
00466
00467 class StiKalmanTrackFinder::QAFind {
00468 public:
00469 double rmin;
00470 double sum;
00471 int hits;
00472 int nits;
00473 int wits;
00474 int qa;
00475
00476
00477
00478
00479
00480
00481
00482 QAFind() {reset(); }
00483 void reset() {rmin=0; sum=0; hits =0; nits=0; qa=0;wits=0;}
00484 };
00485
00486
00487 bool StiKalmanTrackFinder::find(StiTrack * t, int direction,double rmin)
00488 {
00489 static int nCall=0; nCall++;
00490 gLevelOfFind = 0;
00491 StiKalmanTrackNode::Break(nCall);
00492 int nnBef,nnAft;
00493 double lnBef,lnAft;
00494
00495 if(direction) rmin=0;
00496 StiKalmanTrack *track = dynamic_cast<StiKalmanTrack *> (t);
00497 nnBef = track->getNNodes(3);
00498 lnBef = track->getTrackLength();
00499
00500 StiKalmanTrackNode *leadNode = track->getInnOutMostNode(direction,2);
00501 if (!leadNode) return 0;
00502 leadNode->cutTail(direction);
00503 assert(leadNode->isValid());
00504 QAFind qa; qa.rmin = rmin;
00505 mTrackPerm = kMaxTrackPerm;
00506 mUseComb = useComb();
00507 find(track,direction,leadNode,qa);
00508
00509 track->setFirstLastNode(leadNode);
00510 nnAft = track->getNNodes(3);
00511 lnAft = track->getTrackLength();
00512 return (nnAft>nnBef || lnAft>(lnBef+0.5));
00513 }
00514
00515 void StiKalmanTrackFinder::find(StiKalmanTrack * track, int direction
00516 ,StiKalmanTrackNode *leadNode,QAFind &qa)
00517 {
00518 static int nCall=0; nCall++;
00519 StiKalmanTrackNode::Break(nCall);
00520
00521 static const double degToRad = 3.1415927/180.;
00522 static const double radToDeg = 180./3.1415927;
00523 static const double ref1 = 50.*degToRad;
00524
00525 static const double ref1a = 110.*degToRad;
00526
00527 gLevelOfFind++;
00528 if (--mEventPerm <0) throw runtime_error("FATAL::TOO MANY permutations");
00529 if (--mTrackPerm==0) { mUseComb = 0; }
00530
00531 StiDetector *tDet=0;
00532 int status;
00533 StiKalmanTrackNode testNode;
00534 int position;
00535 StiHit * stiHit;
00536 double leadAngle,leadRadius;
00537
00538 assert(leadNode->isValid());
00539 const StiDetector *leadDet = leadNode->getDetector();
00540 leadRadius = leadDet->getPlacement()->getNormalRadius();
00541 assert(leadRadius>0 && leadRadius<1000);
00542 if (leadRadius < qa.rmin) {gLevelOfFind--;return;}
00543 leadAngle = leadDet->getPlacement()->getNormalRefAngle();
00544
00545
00549
00550
00551 double xg = leadNode->x_g();
00552 double yg = leadNode->y_g();
00553 double projAngle = atan2(yg,xg);
00554 if(debug() > 2)cout << "Projection Angle:"<<projAngle*180/3.1415<<endl;
00555
00556 vector<StiDetectorNode*>::const_iterator layer;
00557 vector<StiDetectorNode*>::const_reverse_iterator rlayer;
00558
00559 if ((!direction)) {
00560 if (debug() > 2) cout <<endl<< "out-in"<<endl;
00561 rlayer=_detectorContainer->rbeginRadial(leadDet); rlayer++;
00562 } else {
00563 if (debug() > 2) cout <<endl<< "in-out"<<endl;
00564 layer=_detectorContainer->beginRadial(leadDet); layer++;
00565 }
00566
00567 if (debug() > 2) cout <<endl<< "lead node:" << *leadNode<<endl<<"lead det:"<<*leadDet<<endl;
00568
00569
00570 while (((!direction)? rlayer!=_detectorContainer->rendRadial() : layer!=_detectorContainer->endRadial()))
00571 {do{
00572 vector<StiDetectorNode*>::const_iterator sector;
00573 vector<StiDetector*> detectors;
00574 if (debug() > 2) cout << endl<<"lead node:" << *leadNode<<endl<<" lead det:"<<*leadDet;
00575
00576
00577
00578
00579 sector = (!direction)? _detectorContainer->beginPhi(rlayer):_detectorContainer->beginPhi(layer);
00580 for ( ; (!direction)? sector!=_detectorContainer->endPhi(rlayer):sector!=_detectorContainer->endPhi(layer); ++sector)
00581 {
00582 StiDetector * detector = (*sector)->getData();
00583 double angle = detector->getPlacement()->getNormalRefAngle();
00584 double radius = detector->getPlacement()->getNormalRadius();
00585 assert(radius>0 && radius<1000);
00586 if (radius < qa.rmin) {gLevelOfFind--;return;}
00587 double diff = radius-leadRadius;if (!direction) diff = -diff;
00588 if (diff<-1e-6 && debug()>3) {
00589 LOG_DEBUG << Form("TrackFinder: Wrong order: (%s).(%g) and (%s).(%g)"
00590 ,leadDet->getName().c_str(),leadRadius
00591 ,detector->getName().c_str(),radius) << endm;
00592 }
00593
00594
00595 Int_t shapeCode = detector->getShape()->getShapeCode();
00596 Double_t OpenAngle = ref1;
00597 if (shapeCode >= kCylindrical) {
00598 OpenAngle = ((StiCylindricalShape *) detector->getShape())->getOpeningAngle();
00599 } else {
00600 if (radius <= 50 ) OpenAngle = ref1a;
00601 }
00602 diff = projAngle-angle;
00603 if (diff > M_PI) diff -= 2*M_PI;
00604 if (diff < -M_PI) diff += 2*M_PI;
00605 if (fabs(diff) > OpenAngle) continue;
00606 detectors.push_back(detector);
00607 }
00608
00609 int nDets = detectors.size();
00610 if (debug() > 2 && nDets==0) cout << "no detector of interest on this layer"<<endl;
00611 if (!nDets) continue;
00612 if (nDets>1) sort(detectors.begin(),detectors.end(),CloserAngle(projAngle) );
00613 for (vector<StiDetector*>::const_iterator d=detectors.begin();d!=detectors.end();++d)
00614 {
00615 tDet = *d;
00616 if (debug() > 2) {
00617 cout << endl<< "target det:"<< *tDet;
00618 cout << endl<< "lead angle:" << projAngle*radToDeg
00619 <<" this angle:" << radToDeg*(*d)->getPlacement()->getNormalRefAngle()<<endl;
00620 }
00621
00622 testNode.reduce();testNode.reset();
00623 testNode.setChi2(1e55);
00624 position = testNode.propagate(leadNode,tDet,direction);
00625 if (position == kEnded) { gLevelOfFind--; return;}
00626 if (debug() > 2) cout << "propagate returned:"<<position<<endl<< "testNode:"<<testNode;
00627 if (position<0 || position>kEdgeZplus) {
00628
00629 if (debug() > 2) cout << "TRACK DOES NOT REACH CURRENT volume"<<endl;
00630 if (debug() >= 1) StiKalmanTrackNode::PrintStep();
00631 continue;
00632 }
00633 if (debug() > 2) cout << "position " << position << "<=kEdgeZplus";
00634 assert(testNode.isValid());
00635 testNode.setDetector(tDet);
00636 int active = tDet->isActive(testNode.getY(),testNode.getZ());
00637
00638 if (debug() > 2) cout << " vol active:" << active<<endl;
00639 double maxChi2 = tDet->getTrackingParameters()->getMaxChi2ForSelection();
00640
00641 StiHitContino hitCont;
00642
00643 if (active) {
00644
00645 if (debug() > 2)cout<<" search hits";
00646
00647 vector<StiHit*> & candidateHits = _hitContainer->getHits(testNode);
00648 vector<StiHit*>::iterator hitIter;
00649 if (debug() > 2) cout << " candidates:"<< candidateHits.size();
00650
00651 for (hitIter=candidateHits.begin();hitIter!=candidateHits.end();++hitIter)
00652 {
00653 stiHit = *hitIter;
00654 if (stiHit->detector() && stiHit->detector()!=tDet) continue;
00655 status = testNode.nudge(stiHit);
00656 testNode.setReady();
00657 if (status) continue;
00658 chi2 = testNode.evaluateChi2(stiHit);
00659 if (debug() > 2) cout<< " got chi2:"<< chi2 << " for hit:"<<*stiHit<<endl;
00660 if (chi2>maxChi2) continue;
00661 hitCont.add(stiHit,chi2,testNode.getDeterm());
00662 if (debug() > 2) cout << " hit selected"<<endl;
00663 }
00664 }
00665
00666 int nHits = hitCont.getNHits();
00667 assert(nHits<100);
00668 testNode.setHitCand(nHits);
00669 if (direction) {
00670 nHits=1;
00671 } else {
00672 int flg = (testNode.getX()< kRMinTpc)? mUseComb &3:mUseComb>>2;
00673 if ((flg&2) || !nHits) nHits++;
00674 if ((flg&1)==0) nHits=1;
00675
00676 }
00677
00678 QAFind qaBest,qaTry;
00679 for (int jHit=0;jHit<nHits; jHit++)
00680 {
00681 stiHit = hitCont.getHit(jHit);
00682 StiKalmanTrackNode * node = _trackNodeFactory->getInstance();
00683 *node = testNode;
00684 status = 0;
00685 do {
00686 if (!stiHit) break;
00687 node->setIHitCand(jHit);
00688 assert(node->getHitCand());
00689 node->setHit(stiHit);
00690 status = node->updateNode();
00691 if (status) break;
00692 node->setChi2(hitCont.getChi2(jHit));
00693 if (!direction && node->getX()< kRMinTpc) node->saveInfo();
00694 if (debug() > 0) {cout << Form("%5d ",status); StiKalmanTrackNode::PrintStep();}
00695 }while(0);
00696 if (status) {_trackNodeFactory->free(node); continue;}
00697
00698 qaTry = qa;
00699 nodeQA(node,position,active,qaTry);
00700 leadNode->add(node,direction);
00701 if (qaTry.qa>-2) find(track,direction,node,qaTry);
00702
00703 if (jHit==0) { qaBest=qaTry; continue;}
00704 int igor = compQA(qaBest,qaTry,maxChi2);
00705 if (igor<0) { leadNode->remove(0);}
00706 else { leadNode->remove(1);qaBest=qaTry;}
00707 }
00708 qa = qaBest; gLevelOfFind--; return;
00709 }
00710 }while(0);
00711 if(!direction){++rlayer;}else{++layer;}}
00712
00713 gLevelOfFind--;
00714 return;
00715 }
00716
00717 void StiKalmanTrackFinder::nodeQA(StiKalmanTrackNode *node, int position
00718 ,int active,QAFind &qa)
00719 {
00720 int maxNullCount = StiKalmanTrackFinderParameters::instance()->maxNullCount()+3;
00721 int maxContiguousNullCount = StiKalmanTrackFinderParameters::instance()->maxContiguousNullCount()+3;
00722
00723 StiHit *hit = node->getHit();
00724 if (hit) {
00725 if (debug() > 2)cout << " got Hit! "<<endl ;
00726
00727 qa.sum += node->getChi2() + log(node->getDeterm());
00728 qa.hits++; qa.qa=1;
00729 if (node->getRxy() < kRMinTpc) {
00730 qa.wits+=StiKalmanTrackFinderParameters::instance()->hitWeight((int)node->getRxy());
00731 }
00732 node->incHitCount();
00733 node->incContigHitCount();
00734
00735 if (node->getContigHitCount()>StiKalmanTrackFinderParameters::instance()->minContiguousHitCountForNullReset())
00736 node->setContigNullCount();
00737
00738 } else if (position>0 || !active) {
00739 qa.qa=0;
00740
00741 } else {
00742 if (debug() > 2) cout << " no hit but expected one"<<endl;
00743 node->incNullCount();
00744 node->incContigNullCount();
00745 node->setContigHitCount();
00746 qa.nits++; qa.qa=-1;
00747 if (node->getNullCount()>maxNullCount) qa.qa= -3;
00748 if (node->getContigNullCount()>maxContiguousNullCount) qa.qa= -3;
00749 }
00750
00751
00752
00753
00754
00755 }
00756
00757 int StiKalmanTrackFinder::compQA(QAFind &qaBest,QAFind &qaTry,double maxChi2)
00758 {
00759 int ians;
00760 ians = qaTry.wits-qaBest.wits;
00761
00762 if (!qaBest.wits && qaTry.wits && qaTry.wits < StiKalmanTrackFinderParameters::instance()->sumWeight()) return -1;
00763 if ( !qaTry.wits && qaBest.wits && qaBest.wits < StiKalmanTrackFinderParameters::instance()->sumWeight()) return 1;
00764 if (ians) return ians;
00765 ians = qaTry.hits-qaBest.hits; if (ians) return ians;
00766 ians = qaBest.nits- qaTry.nits; if (ians) return ians;
00767 if (qaBest.sum <= qaTry.sum ) return -1;
00768 return 1;
00769 }
00770
00771
00772 StiTrack * StiKalmanTrackFinder::findTrack(double rMin)
00773 {
00774 assert(0);
00775 StiTrack * track = 0;
00776 try
00777 {
00778 if (!_trackSeedFinder) throw runtime_error("StiKalmanTrackFinder::findTrack() -E- No Track seed finder instance available");
00779 track = _trackSeedFinder->findTrack(rMin);
00780 if (track)
00781 {
00782 track->find();
00783 if (!_trackFilter || _trackFilter->filter(track) ) _trackContainer->push_back(track);
00784 }
00785 }
00786 catch (runtime_error & rte)
00787 {
00788 cout << "StiKalmanTrackFinder::findTrack() - Run Time Error :\n" << rte.what() << endl;
00789 }
00790 return track;
00791 }
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814 void StiKalmanTrackFinder::setTiming()
00815 {
00816 for (int it=0;it<(int)(sizeof(mTimg)/sizeof(mTimg[0]));it++){
00817 mTimg[it]= new TStopwatch(); mTimg[it]->Stop(); }
00818 }
00819
00820 void StiKalmanTrackFinder::finish() const
00821 {
00822 static const char *timg[] = {"SeedFnd","TrakFnd","PrimFnd",0};
00823 if (mTimg[0]) {
00824 for (int i=0;timg[i];i++) {
00825 Info("TrackFinder::Timing","%s(%d) \tCpuTime = %6.2f seconds,\tPerTrak = %g seconds"
00826 ,timg[i],mTimg[i]->Counter(),mTimg[i]->CpuTime()
00827 ,mTimg[i]->CpuTime()/mTimg[i]->Counter());
00828 } }
00829 }
00830
00831 int StiKalmanTrackFinder::getNTracks() const
00832 { return _trackContainer->size();}
00833
00834
00835 CloserAngle::CloserAngle(double refAngle)
00836 : _refAngle(refAngle)
00837 { }
00838
00839
00840 bool CloserAngle::operator()(const StiDetector*lhs, const StiDetector* rhs)
00841 {
00842 double lhsa = lhs->getPlacement()->getNormalRefAngle();
00843 double rhsa = rhs->getPlacement()->getNormalRefAngle();
00844 double lhsda = fabs(lhsa-_refAngle); if (lhsda>3.1415) lhsda-=3.1415;
00845 double rhsda = fabs(rhsa-_refAngle); if (rhsda>3.1415) rhsda-=3.1415;
00846 return lhsda<rhsda;
00847 }
00848 #ifdef DO_TPCCATRACKER
00849 void StiKalmanTrackFinder::PrintFitStatus(const int status, const StiKalmanTrack* track)
00850 {
00851
00852 int status1 = status%100;
00853 int status1r = status/100;
00854 switch (status1) {
00855 case StiKalmanTrackFinder::kNoErrors: {
00856 if (track) cout << " fitted with " << track->getFitPointCount() << " hits."<< endl;
00857 else cout << " fitted." << endl;
00858 }
00859 break;
00860 case StiKalmanTrackFinder::kApproxFail: {
00861 cout << " fit failed:" << endl;
00862 cout << " Initial approximation of track failed." << endl;
00863 }
00864 break;
00865 case StiKalmanTrackFinder::kFitFail: {
00866 cout << " fit failed:" << endl;
00867 cout << " Track fit failed.";
00868 int status2 = status1r%100;
00869 switch (status2) {
00870 case StiKalmanTrackFitter::kNoErrors: {
00871 cout << " Check the code.";
00872 }
00873 break;
00874 case StiKalmanTrackFitter::kShortTrackBeforeFit: {
00875 cout << " Not enough hits in the track: ";
00876 }
00877 break;
00878 case StiKalmanTrackFitter::kShortTrackAfterFit: {
00879 if (track) cout << " Not enough hits can be fitted: " << track->getNNodes(3) << " .";
00880 else cout << " Not enough hits can be fitted.";
00881 }
00882 break;
00883 case StiKalmanTrackFitter::kManyErrors: {
00884 cout << " Too many problems with this track.";
00885 }
00886 break;
00887 }
00888 cout << endl;
00889 }
00890 break;
00891 case StiKalmanTrackFinder::kExtendFail: {
00892 cout << " fit failed: " << endl;
00893 cout << " Track extend failed.";
00894 int status2 = status1r%100;
00895 int status2r = status1r/100;
00896 switch (status2) {
00897 case StiKalmanTrackFinder::kExtended: {
00898 cout << " Check the code.";
00899 }
00900 break;
00901 case StiKalmanTrackFinder::kNotExtended: {
00902 cout << " Check the code.";
00903 }
00904 break;
00905 case StiKalmanTrackFinder::kRefitInFail:
00906 case StiKalmanTrackFinder::kRefitOutFail: {
00907 cout << " Track can't be refitted after extension ";
00908 if (status2 == StiKalmanTrackFinder::kRefitInFail) cout << "inside.";
00909 else cout << "outside.";
00910
00911 int status3 = status2r%100;
00912 switch (status3) {
00913 case StiKalmanTrack::kNoErrors: {
00914 cout << " Check the code.";
00915 }
00916 break;
00917 case StiKalmanTrack::kRefitFail: {
00918 cout << " Refit procedure fail.";
00919 }
00920 break;
00921 case StiKalmanTrack::kNotEnoughUsed: {
00922 cout << " sTNH.getUsed() <= 3 .";
00923 }
00924 break;
00925 case StiKalmanTrack::kInNodeNotValid: {
00926 cout << " Inner most node is not valid.";
00927 }
00928 break;
00929 case StiKalmanTrack::kBadQA: {
00930 cout << " qA is inappropriate.";
00931 }
00932 break;
00933 case StiKalmanTrack::kVertexNodeInvalid: {
00934 cout << " Prim node invalid.";
00935 }
00936 break;
00937 case StiKalmanTrack::kNodeNotValid: {
00938 cout << " Prim node Chi2 too big.";
00939 }
00940 break;
00941 case StiKalmanTrack::kTooManyDroppedNodes: {
00942 cout << " Too many dropped nodes.";
00943 }
00944 break;
00945 }
00946
00947 }
00948 break;
00949 }
00950 cout << endl;
00951 }
00952 break;
00953 case StiKalmanTrackFinder::kCheckFail: {
00954 cout << " fit failed " << endl;
00955 cout << " Track check failed.";
00956 int status2 = status1r%100;
00957 switch (status2) {
00958 case StiTrackFinderFilter::kNoErrors: {
00959 cout << " Check the code.";
00960 }
00961 break;
00962 case StiTrackFinderFilter::kNoEnoughValidHits: {
00963 if (track) cout << " Not enough valid hits in the track: " << track->getPointCount() << " .";
00964 else cout << " Not enough valid hits in the track.";
00965 }
00966 break;
00967 case StiTrackFinderFilter::kNoEnoughFittedValidHits: {
00968 if (track) cout << " Not enough fitted hits in the track: " << track->getFitPointCount() << " .";
00969 else cout << " Not enough fitted hits in the track.";
00970 }
00971 break;
00972 case StiTrackFinderFilter::kWeird: {
00973 cout << " Weird track, see StiTrackFinderFilter::accept().";
00974 }
00975 break;
00976 }
00977 cout << endl;
00978 }
00979 break;
00980 }
00981 }
00982 #endif