//----------------------------------------------------------- // File and Version Information: // $Id$ // // Description: // Implementation of class PndTpcRiemannTrackFinder // see PndTpcRiemannTrackFinder.h for details // // Environment: // Software developed for the PANDA Detector at FAIR. // // Author List: // Sebastian Neubert TUM (original author) // Johannes Rauch TUM // // //----------------------------------------------------------- // Panda Headers ---------------------- // This Class' Header ------------------ #include "PndTpcRiemannTrackFinder.h" // C/C++ Headers ---------------------- #include #include // Collaborating Class Headers -------- #include "DebugLogger.h" //#include "PndTpcClusterRadius.h" #include "PndTpcClusterZ.h" #include "GFTrackCand.h" #include "PndTpcCluster.h" #include "PndTpcRiemannTrack.h" #include "PndTpcRiemannHit.h" #include "PndTpcProximityHTCorrelator.h" #include "PndTpcRiemannTTCorrelator.h" #include "TMath.h" using namespace std; //#define DEBUGHT //#define DEBUGTT #define UPTOHIT // Class Member definitions ----------- PndTpcRiemannTrackFinder::PndTpcRiemannTrackFinder() : _minHitsForFit(5), _sortingMode(false), _sorting(3), _interactionZ(0.), _MaxNumHitsForPR(2147483646), _TTproxcut(500), fRiemannScale(24.6), _initTrks(false), _initDip(0), _skipCrossingAreas(false) { } PndTpcRiemannTrackFinder::PndTpcRiemannTrackFinder(double scale) : _minHitsForFit(5), _sortingMode(false), _sorting(3), _interactionZ(0.), _MaxNumHitsForPR(2147483646), _TTproxcut(500), fRiemannScale(scale), _initTrks(false), _initDip(0), _skipCrossingAreas(false) { } PndTpcRiemannTrackFinder::~PndTpcRiemannTrackFinder() { for(int i=0;i<_correlators.size();++i){ if(_correlators[i]!=NULL){ delete _correlators[i]; _correlators[i]=NULL; } } _correlators.clear(); for(int i=0;i<_TTcorrelators.size();++i){ if(_TTcorrelators[i]!=NULL){ delete _TTcorrelators[i]; _TTcorrelators[i]=NULL; } } _TTcorrelators.clear(); } void PndTpcRiemannTrackFinder::addCorrelator(PndTpcAbsHitTrackCorrelator* c) { _correlators.push_back(c); _found.push_back(false); _bestMatchQuality.push_back(9999); _bestMatchIndex.push_back(0); } void PndTpcRiemannTrackFinder::addTTCorrelator(PndTpcAbsTrackTrackCorrelator* c) { _TTcorrelators.push_back(c); } unsigned int PndTpcRiemannTrackFinder::buildTracks(std::vector& cll, std::vector& candlist) { #ifdef DEBUGHT std::cout<<"PndTpcRiemannTrackFinder::buildTracks"< 1){ cout << "At cluster " << icl << endl; cout << "Active Tracklets: "<< candlist.size() << endl; cout << "Mean number of hits/track: "<< (double)icl/(double)candlist.size() << endl; } #endif PndTpcRiemannHit* rhit=new PndTpcRiemannHit(cll[icl],fRiemannScale); unsigned int ntrks=candlist.size(); unsigned int matchTrks(0); unsigned int maxlevel=0; // index of track with highest number of applicable correlators bool foundAtAll=false; for(int i=0;i matchQualities(ncor, 99999.); // for saving the match qualities for each correlator int level = 0; // number of survived correlators #ifdef DEBUGHT if(icl==_MaxNumHitsForPR-1) std::cout<<"Testing hit "<corr(trk,rhit,survive,matchQuality); #ifdef DEBUGHT if(icl==_MaxNumHitsForPR-1){ if(!applicable){std::cout<<" correlator "< can be excluded } // track survived this correlator level = icor; trksurvive = true; matchQualities[icor] = matchQuality; } // end loop over correlator if(trksurvive){ // update best values if(level==ncor-1) ++matchTrks; // number matching tracks that survived all corrs if(level>maxlevel) maxlevel=level; for(unsigned int i=0; i<=level; ++i){ if(matchQualities[i]<_bestMatchQuality[i]){ _bestMatchQuality[i]=matchQualities[i]; _bestMatchIndex[i]=itrk; } } } #ifdef DEBUGHT if(icl==_MaxNumHitsForPR-1 && trksurvive) std::cout<<" Track "<setSort(_sortingMode); candlist.push_back(trk); //std::cout<<"Creating new track"<addHit(rhit); #ifdef DEBUGHT if(icl==_MaxNumHitsForPR-1) std::cout<<"-> creating new track Nr "<initSL(_initDip); } else { // if more than one track matches, hit lies in crossing section -> skip if(_skipCrossingAreas && matchTrks>1) { #ifdef DEBUGHT if(icl==_MaxNumHitsForPR-1){ std::cout<<" "< hit lies in crossing area -> skip hit"< adding hit to track"<<_bestMatchIndex[maxlevel]<addHit(rhit); if(theTrk->getNumHits()>=_minHitsForFit){ theTrk->fitAndSort(); #ifdef DEBUGHT if(icl==_MaxNumHitsForPR-1){ std::cout<<" track parameters: _c="<c()<<" R="<r()<<" dip °="<<(theTrk->dip())*180/TMath::Pi()<center().Print(); } #endif } } resetFlags(); } // end loop over hits #ifdef DEBUGHT std::cout<& candlist){ #ifdef DEBUGTT std::cout<<"PndTpcRiemannTrackFinder::mergeTracks"<getFirstHit()->cluster()->pos().Z(); zTemp = trk1->getLastHit()->cluster()->pos().Z(); if (zTemp>z1max) z1max=zTemp; } for(unsigned int itrk2=itrk1+1; itrk2getFirstHit()->cluster()->pos().Z(); zTemp = trk2->getLastHit()->cluster()->pos().Z(); if (zTemp (z1max + _TTproxcut + 0.1) ) { #ifdef DEBUGTT std::cout<<" (z2min > (z1max + _TTproxcut + 0.1) ), skipping rest of trk2 tracklets (" << ntr-itrk2 << ")" <getNumHits()>=trk2->getNumHits()) applicable=_TTcorrelators[icor]->corr(trk1,trk2,survive,matchQuality); else applicable=_TTcorrelators[icor]->corr(trk2,trk1,survive,matchQuality); #ifdef DEBUGTT if(!applicable){std::cout<<" correlator "<getNumHits(); unsigned int nhits2 = trk2->getNumHits(); if(!_sortingMode){ // we have to collect clusters from both tracks, sort them and build a new track // collect clusters from both tracks and sort std::vector clusters; for(unsigned int i=0; igetHit(i)->cluster()); } for(unsigned int i=0; igetHit(i)->cluster()); } sortClusters(clusters); // fill clusters into new RiemannTrack and refit PndTpcRiemannTrack* mergedTrack = new PndTpcRiemannTrack(fRiemannScale); mergedTrack->setSort(false); for(unsigned int i=0; iaddHit(rhit); } if(mergedTrack->getNumHits()>=_minHitsForFit) mergedTrack->fitAndSort(); // delete old trackcands and store new trackcand delete candlist[itrk1]; trk1=mergedTrack; candlist[itrk1]=mergedTrack; } else { // we can just add the hits from trk2 to trk1 and the sorting is done internally for(unsigned int i=0; iaddHit(trk2->getHit(i)); // refit if we have enough hits if(trk1->getNumHits()>=_minHitsForFit) trk1->fitAndSort(); } // update max z of trk1 if(_sorting==3){ z1max = trk1->getFirstHit()->cluster()->pos().Z(); zTemp = trk1->getLastHit()->cluster()->pos().Z(); if (zTemp>z1max) z1max=zTemp; } // delete trk2 delete candlist[itrk2]; candlist[itrk2]=NULL; } // end loop over the other tracks to be tested } // end loop over tracks // clean up candlist for(int i=0; i& candlist, double szcut, double planecut){ std::cout<<"WARNING: PndTpcRiemannTrackFinder::cleanTracks - no functionality!"<isFitted() || !candlist[i]->isFitted()) continue; // skip track for(unsigned int j=0; jgetNumHits(); ++j){ // loop over hits hit = candlist[i]->getHit(j); if (TMath::Abs(candlist[i]->dist(hit)) > planecut || TMath::Abs(candlist[i]->szDist(hit)) > szcut){ candlist[i]->removeHit(j); candlist[i]->refit(); --j; } if(!candlist[i]->isFitted() || !candlist[i]->isFitted()) break; // skip track } // end loop over hits } // end loop over trackcands*/ } void PndTpcRiemannTrackFinder::sortClusters(std::vector& cll){ if(_sorting==-1) return; sortClusterClass sortCluster; sortCluster.setSorting(_sorting); sortCluster.setInteractionZ(_interactionZ); std::sort(cll.begin(),cll.end(),sortCluster); } void PndTpcRiemannTrackFinder::sortTracklets(std::vector& tracklets){ if(_sorting==-1) return; sortTrackletsClass sortTracklet; sortTracklet.setSorting(_sorting); std::sort(tracklets.begin(),tracklets.end(),sortTracklet); } void PndTpcRiemannTrackFinder::resetFlags(){ // reset all flags for(int k=0;k<_correlators.size();++k){ _found[k]=false; _bestMatchQuality[k]=99999; _bestMatchIndex[k]=0; } } bool sortClusterClass::operator() (PndTpcCluster* s1, PndTpcCluster* s2){ double a1; double a2; TVector3 d1; TVector3 d2; switch (sorting){ case -1: //no sorting return false; break; case 0: a1=s1->pos().X(); a2=s2->pos().X(); return a1>a2; break; case 1: a1=s1->pos().Y(); a2=s2->pos().Y(); return a1>a2; break; case 2: a1=s1->pos().Z(); a2=s2->pos().Z(); return a1>a2; break; case 4: d1 = s1->pos(); d1(2) -= interactionZ; d2 = s2->pos(); d2(2) -= interactionZ; a1=d1.Mag(); a2=d2.Mag(); return a1>a2; break; case 3: default: a1=s1->pos().Perp(); a2=s2->pos().Perp(); return a1>a2; } } bool sortTrackletsClass::operator() (PndTpcRiemannTrack* t1, PndTpcRiemannTrack* t2){ double a1; double a12; double a2; double a22; TVector3 d1; TVector3 d2; switch (sorting){ case -1: //no sorting return false; // if clusters are NOT sorted by R, sort tracklets by R case 0: case 1: case 2: case 4: a1=t1->getFirstHit()->cluster()->pos().Perp(); a12=t1->getLastHit()->cluster()->pos().Perp(); if (a12getFirstHit()->cluster()->pos().Perp(); a22=t2->getLastHit()->cluster()->pos().Perp(); if (a22getFirstHit()->cluster()->pos().Z(); a12=t1->getLastHit()->cluster()->pos().Z(); if (a12getFirstHit()->cluster()->pos().Z(); a22=t2->getLastHit()->cluster()->pos().Z(); if (a22