// ------------------------------------------------------------------------- // ----- PndMQStraightLineTrackFinder ----- // ----- Created 22/10/09 by M. Michel ----- // ------------------------------------------------------------------------- #include "TClonesArray.h" #include "TArrayD.h" #include "TGeoManager.h" #include "FairRootManager.h" #include "FairRun.h" #include "FairRuntimeDb.h" #include "PndMQStraightLineTrackFinder.h" #include "PndSdsDigiStrip.h" #include "TStopwatch.h" // #include "PndSdsPixelCluster.h" // ----- Default constructor ------------------------------------------- PndMQStraightLineTrackFinder::PndMQStraightLineTrackFinder() : fNLayers(4) { fdXY = 0.1; fHitsPerLayer.resize(fNLayers); } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- PndMQStraightLineTrackFinder::~PndMQStraightLineTrackFinder() { } // ------------------------------------------------------------------------- // ----- Private method SortHitsByDet -------------------------------------------- void PndMQStraightLineTrackFinder::SortHitsToLayers(std::vector& hits) { for (int i = 0; i < hits.size(); i++){ if (hits[i].GetSensorID() < fNLayers) fHitsPerLayer[hits[i].GetSensorID()].push_back(make_pair(hits[i], false)); } } // ------------------------------------------------------------------------- std::vector< std::vector > PndMQStraightLineTrackFinder::GetStartCombination(int firstLayer, int secondLayer) { std::vector< std::vector > result; for (int firstL = 0; firstL < fHitsPerLayer[firstLayer].size; firstL++){ for (int secondL = 0; secondL < fHitsPerLayer[secondLayer].size; secondL++){ std::vector singleCombi(4,-1); singleCombi[firstLayer] = firstL; singleCombi[seondLayer] = secondL; result.push_back(singleCombi); } } return result; } StraightLineParams PndMQStraightLineTrackFinder::GetLineParameters(std::vector startCombi) { StraightLineParams result; TVector3 first, second; bool firstFound = false; for (int i = 0; i < startCombi.size(); i++) { if (startCombi[i] > -1){ if (firstFound == false){ PndSdsHit firstHit = fHitsPerLayer[i][startCombi[i]].first; first = firstHit.GetPosition(); firstFound = true; result.origin = first; } else { PndSdsHit secondHit = fHitsPerLayer[i][startCombi[i]].first; second = secondHit.GetPosition(); result.direction = (second - first).Unit(); break; } } } return result; } TVector3 PndMQStraightLineTrackFinder::PropagateToXYPlane(StraightLineParams line, Double z) { double t = 0; t = (z - line.origin.Z()) / line.direction.Z(); TVector3 result; result = line.origin + line.direction * t; return result; } double PndMQStraightLineTrackFinder::DistanceOfPoints(TVector3 first, TVector3 second) { return (first - second).Mag(); } PndTrackCand PndMQStraightLineTrackFinder::FindTrack(std::vector startCombi){ } std::vector PndMQStraightLineTrackFinder::FindTracks(std::vector hits) { SortHitsToLayers(hits); std::vector > startCombi = GetStartCombination(0,1); for (int i = 0; i < startCombi.size(); i++){ } } // ----- Private method FindHitsII -------------------------------------------- void PndMQStraightLineTrackFinder::FindHitsII(std::vector &tofill, std::vector< std::vector< std::pair > > &hitsd, Int_t nStripHits) { std::vector trackStart, trackVec;//pseudo tracks std::vector trackStartd, trackVecd;//save errors std::vector< Int_t > trackID1, trackID3; //for TrackCand //iterate first discs-hits with all seconds, save pseudo-tracks TVector3 start, tmp, vec, dstart, dvec; //temp-vars if(hitsd.size()<3) return; for (Int_t i=0; iAt(hitsd.at(0).at(i).first); start.SetXYZ(hit1->GetX(), hit1->GetY(), hit1->GetZ()); dstart.SetXYZ(hit1->GetDx(), hit1->GetDy(), hit1->GetDz()); for (Int_t k=0; kAt(hitsd.at(2).at(k).first); tmp.SetXYZ(hit2->GetX(), hit2->GetY(), hit2->GetZ()); vec = tmp - start; //calc direction vector for FINDING dvec.SetXYZ(hit2->GetDx(), hit2->GetDy(), hit2->GetDz()); if(vec.Theta()>0.03 && vec.Theta()<0.05 && vec.Phi()>-0.25 && vec.Phi()<0.25){ //ignore vectors with theta outside 2-9 mrad // if(0<1){ // if(vec.Theta()<0.01){ //ignore vectors with theta outside 10 mrad trackStart.push_back(start); trackStartd.push_back(dstart); trackVec.push_back(vec); //save vector from start to second trackVecd.push_back(dvec); //save error of second point for FIT, NOT error of direction vector //trackID1.push_back(hitsd.at(0).at(i).first); //save Hit-Id's for TrackCand //trackID2.push_back(hitsd.at(1).at(k).first); trackID1.push_back(i); //save Hit-Id's for TrackCand trackID3.push_back(k); } }//end of disc 2 (or 3 if none in disc 2) hits }//end of disc 1 hits if(fVerbose>1) cout << "Pseudos L1L3: "<< trackStart.size() < ids; //check if other discs have hits in track, add points for fitting --------------- for (Int_t i=0; i > otherIDs; for (Int_t idet=3; idet < 4; idet++){ //i know this is not a loop, but in case we someday will have more planes Double_t distClosest = 2*idet*dXY; //just bigger as possible Bool_t firstp = true; for (Int_t ihit=0; ihitAt(hitsd.at(idet).at(ihit).first); Double_t scale = (hit->GetZ()-start.z())/vec.z(); tmp = start + scale*vec; //extend search-vector to hit-plane Double_t distTmp = sqrt((tmp.x()-hit->GetX())*(tmp.x()-hit->GetX()) + (tmp.y()-hit->GetY())*(tmp.y()-hit->GetY())); if( distTmp<(idet*dXY) ){ //if in diameter if(firstp){ pntcnt++; ids.push_back(hitsd.at(idet).at(ihit).first); otherIDs.push_back( make_pair (idet,ihit) ); distClosest=distTmp; firstp=false; }else{ if(distTmp2) cout << " Track L1L3: "<< i << "#Planes: " << ids.size() <2){ //third hit found <=> !track found! PndTrackCand *myTCand = new PndTrackCand(); for (Int_t id=0; idAt(ids.at(id))); PndSdsClusterStrip* myCluster; PndSdsDigiStrip* astripdigi; if ( !fStripClusterArray || !fStripDigiArray){ //for ideal/fast Hit-Reco myTCand->AddHit(0,ids.at(id),myHit->GetPosition().Mag()); }else{ myCluster = (PndSdsClusterStrip*)(fStripClusterArray->At(myHit->GetClusterIndex())); astripdigi = (PndSdsDigiStrip*)fStripDigiArray->At(myCluster->GetDigiIndex(0)); myTCand->AddHit(astripdigi->GetDetID(),ids.at(id),myHit->GetPosition().Mag()); } } //mark used hits--------- hitsd.at(0).at(trackID1.at(i)).second=true; hitsd.at(2).at(trackID3.at(i)).second=true; for(Int_t id=0; idAt(ids.at(0))); // PndSdsHit* myHit1 = (PndSdsHit*)(fStripHitArray->At(ids.at(1))); // TVector3 hit0 = myHit0->GetPosition(); TVector3 hit1 = myHit1->GetPosition(); // TVector3 posSeed(hit0.X(),hit0.Y(),hit0.Z()); // vec*=1./vec.Mag(); // //shift trk out of plane [needed for correct treatment in Kalman Fillter and GEANE] // double sh_z = -0.035; //350 mkm // double sh_x = vec.X()*sh_z; // double sh_y = vec.Y()*sh_y; // TVector3 sh_point(sh_x,sh_y,sh_z); // posSeed +=sh_point; // myTCand->setTrackSeed(posSeed,vec,-1); // ///------------------------------------- tofill.push_back(*(myTCand)); //save Track Candidate //new((*fTrackCandArray)[trackCnt]) PndTrackCand(*(myTCand)); delete myTCand; }//Track Cand build }//end of pseudo-tracks } // ------------------------------------------------------------------------- // ----- Private method FindHitsI -------------------------------------------- void PndMQStraightLineTrackFinder::FindHitsI(std::vector &tofill, std::vector< std::vector< std::pair > > &hitsd, Int_t nStripHits) { std::vector trackStart, trackVec;//pseudo tracks std::vector trackStartd, trackVecd;//save errors std::vector< Int_t > trackID1, trackID2; //for TrackCand //iterate first discs-hits with all seconds, save pseudo-tracks TVector3 start, tmp, vec, dstart, dvec; //temp-vars if(hitsd.size()<2) return; for (Int_t i=0; iAt(hitsd.at(0).at(i).first); start.SetXYZ(hit1->GetX(), hit1->GetY(), hit1->GetZ()); dstart.SetXYZ(hit1->GetDx(), hit1->GetDy(), hit1->GetDz()); for (Int_t k=0; kAt(hitsd.at(1).at(k).first); tmp.SetXYZ(hit2->GetX(), hit2->GetY(), hit2->GetZ()); vec = tmp - start; //calc direction vector for FINDING dvec.SetXYZ(hit2->GetDx(), hit2->GetDy(), hit2->GetDz()); // if(vec.Theta()>0.03 && vec.Theta()<0.05 && vec.Phi()>-0.25 && vec.Phi()<0.25){ //ignore vectors with theta outside 2-9 mrad // if(vec.Theta()<0.01){ //ignore vectors with theta outside 10 mrad trackStart.push_back(start); trackStartd.push_back(dstart); trackVec.push_back(vec); //save vector from start to second trackVecd.push_back(dvec); //save error of second point for FIT, NOT error of direction vector //trackID1.push_back(hitsd.at(0).at(i).first); //save Hit-Id's for TrackCand //trackID2.push_back(hitsd.at(1).at(k).first); trackID1.push_back(i); //save Hit-Id's for TrackCand trackID2.push_back(k); // } }//end of disc 2 (or 3 if none in disc 2) hits }//end of disc 1 hits if(fVerbose>1) cout << "Pseudos L1L2: "<< trackStart.size() < ids; //check if other discs have hits in track, add points for fitting --------------- for (Int_t i=0; i > otherIDs; for (Int_t idet=2; idet < 4; idet++){ Double_t distClosest = 2*idet*dXY; //just bigger as possible Bool_t firstp = true; for (Int_t ihit=0; ihitAt(hitsd.at(idet).at(ihit).first); Double_t scale = (hit->GetZ()-start.z())/vec.z(); tmp = start + scale*vec; //extend search-vector to hit-plane Double_t distTmp = sqrt((tmp.x()-hit->GetX())*(tmp.x()-hit->GetX()) + (tmp.y()-hit->GetY())*(tmp.y()-hit->GetY())); if( distTmp<(idet*dXY) ){ //if in diameter if(firstp){ pntcnt++; ids.push_back(hitsd.at(idet).at(ihit).first); otherIDs.push_back( make_pair (idet,ihit) ); distClosest=distTmp; firstp=false; }else{ if(distTmp2) cout << " Track L1L2: "<< i << "#Planes: " << ids.size() <2){ //third hit found <=> !track found! // if(ids.size()>3){ //4 hits are needed because 6 parameters are used in trk-fit! // // //third hit found <=> !track found! // // //check direction for reduction of ghost tracks // if(ids.size()>2 && // fabs(vec.Phi())<0.26 && vec.Theta()>3e-2 && vec.Theta()<5e-2){ if(fVerbose>2) cout << " Track: "<< i << "#Planes: " << ids.size() <At(ids.at(id))); PndSdsClusterStrip* myCluster; PndSdsDigiStrip* astripdigi; myTCand->AddHit(FairRootManager::Instance()->GetBranchId(fHitBranchStrip),ids.at(id),myHit->GetPosition().Mag()); } //mark used hits--------- hitsd.at(0).at(trackID1.at(i)).second=true; hitsd.at(1).at(trackID2.at(i)).second=true; for(Int_t id=0; idAt(ids.at(0))); // PndSdsHit* myHit1 = (PndSdsHit*)(fStripHitArray->At(ids.at(1))); // TVector3 hit0 = myHit0->GetPosition(); TVector3 hit1 = myHit1->GetPosition(); // double p1seed = (hit0.X()-hit1.X())/(hit0.Z()-hit1.Z()); // double p0seed = hit0.X() - p1seed*(hit0.Z()-Z0); // // double p0seed = 0.5*(hit0.X()+hit1.X()-p1seed*(hit0.Z()+hit1.Z()-2*1099.)); //TO DO: don't use const // double p3seed = (hit0.Y()-hit1.Y())/(hit0.Z()-hit1.Z()); // double p2seed = hit0.Y() - p3seed*(hit0.Z()-Z0); // //double p2seed = 0.5*(hit0.Y()+hit1.Y()-p1seed*(hit0.Z()+hit1.Z()-2*1099.)); //TO DO: don't use const // TVector3 posSeed(p0seed,p2seed,Z0); // TVector3 dirSeed(p1seed,p3seed,1.); // cout<<"posSeed:"<setTrackSeed(posSeed,vec,-1); // ///------------------------------------- tofill.push_back(*(myTCand)); //save Track Candidate //new((*fTrackCandArray)[trackCnt]) PndTrackCand(*(myTCand)); delete myTCand; }//Track Cand build }//end of pseudo-tracks } // ------------------------------------------------------------------------- // ----- Public method Exec -------------------------------------------- void PndMQStraightLineTrackFinder::Exec(Option_t*) { TStopwatch *timer_exec = new TStopwatch(); if(fVerbose>2) timer_exec->Start(); if(fVerbose>2) cout << "Evt " << FairRootManager::Instance()->GetEntryNr() << " started--------------"<Clear(); Int_t nStripHits = fHitArray->GetEntriesFast(); if(fVerbose>2) cout << "# Hits: \t"<< nStripHits <2) cout << "Evt finsihed: too less hits-----"< > > hitsd(4); bool resSortHits; if(flagStipSens) resSortHits = SortHitsByDet(hitsd, nStripHits);//!strip sensors else{ if(flagPixelSens) resSortHits = SortHitsByDet2(hitsd, nStripHits);//! pixel sensors else{ std::cout<<"Algorithm is needed sensor type! Please, set it via SetSensStripFlag(bool fS) or SetSensPixelFlag(bool fS)"<2) cout << "Evt finsihed: too less planes-----"<2){ cout<<"HitMap size: "<< hitsd.size() <0){ for (Int_t i=0; iAt(hitsd.at(0).at(i).first); cout<<"Plane0 Hit=("<GetX()<<", "<GetY()<<", "<GetZ()<<")"<1){ for (Int_t i=0; iAt(hitsd.at(1).at(i).first); cout<<"Plane1 Hit=("<GetX()<<", "<GetY()<<", "<GetZ()<<")"<2){ for (Int_t i=0; iAt(hitsd.at(2).at(i).first); cout<<"Plane2 Hit=("<GetX()<<", "<GetY()<<", "<GetZ()<<")"<3){ for (Int_t i=0; iAt(hitsd.at(3).at(i).first); cout<<"Plane3 Hit=("<GetX()<<", "<GetY()<<", "<GetZ()<<")"< theCands; //Track Candidates //--------find some tracks-------------- FindHitsI(theCands, hitsd, nStripHits); if(fFinderMode){  FindHitsII(theCands, hitsd, nStripHits); FindHitsIII(theCands, hitsd, nStripHits); } //fill tracklist für fitting for(int t=0; t2) cout << "Evt finsihed--------------"<2){ timer_exec->Stop(); Double_t rtime_exec = timer_exec->RealTime(); Double_t ctime_exec = timer_exec->CpuTime(); cout << "Real time for Exec:" << rtime_exec << " s, CPU time " << ctime_exec << " s" << endl; cout << endl; } } // ------------------------------------------------------------------------- Double_t PndMQStraightLineTrackFinder::GetTrackCurvature(PndMCTrack* myTrack) { TVector3 p = myTrack->GetMomentum(); return (2/TMath::Sqrt(p.Px()*p.Px() + p.Py()*p.Py())); } // ------------------------------------------------------------------------- Double_t PndMQStraightLineTrackFinder::GetTrackDip(PndMCTrack* myTrack) { TVector3 p= myTrack->GetMomentum(); return (p.Mag()/TMath::Sqrt(p.Px()*p.Px() + p.Py()*p.Py())); }