// ------------------------------------------------------------------------- // ----- PndLmdTrackFinderCATask ----- // ----- Created 18/05/11 by A. Karavdina ----- // ------------------------------------------------------------------------- #include #include "TClonesArray.h" #include "TArrayD.h" #include "TVectorD.h" #include "TGeoManager.h" #include "FairRootManager.h" #include "FairRun.h" #include "FairRuntimeDb.h" #include "PndLmdTrackFinderCATask.h" #include "PndSdsDigiStrip.h" #include "TStopwatch.h" #include "PndLmdDim.h" // #include "PndSdsPixelCluster.h" // ----- Default constructor ------------------------------------------- PndLmdTrackFinderCATask::PndLmdTrackFinderCATask() : FairTask("LMD Track Finding Task (Cellular Automation)") { missPlAlgo = false; flagTrkCandCuts=true; fHitBranchStrip = "LMDHitsStrip"; fClusterBranchStrip = "LMDStripClusterCand"; fDigiBranchStrip = "LMDStripDigis"; dXY = 0.5; d_max = 0.01; hdist = new TH1D("hdist","distance from common point",1e4,0,10.); htheta = new TH2D("htheta",";length;#theta angle",1e3,0,25,1e3,0,3.15); nSensPP = 8; nP = 4; flagStipSens = false; flagPixelSens = false; // dXY = 0.01;//TEST } // ------------------------------------------------------------------------- // ----- Constructor ------------------------------------------- PndLmdTrackFinderCATask::PndLmdTrackFinderCATask(const bool missPl, const double setdmax, int innSensPP, int innP, TString hitBranch, TString clusterBranch, TString digiBranch) : FairTask("LMD Track Finding Task (Cellular Automation) with/without <> algoritm") { missPlAlgo = missPl; // fHitBranchStrip = "LMDHitsStrip"; // fClusterBranchStrip = "LMDStripClusterCand"; // fDigiBranchStrip = "LMDStripDigis"; fHitBranchStrip = hitBranch; fClusterBranchStrip = clusterBranch; fDigiBranchStrip = digiBranch; dXY = 0.5; hdist = new TH1D("hdist","distance from common point",1e3,0,1.); htheta = new TH2D("htheta",";length;#theta angle",1e3,0,25,1e3,0,3.15); d_max = setdmax; nSensPP = innSensPP; nP = innP; flagStipSens = false;//default flagPixelSens = true;//default // dXY = 0.01;//TEST } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- PndLmdTrackFinderCATask::~PndLmdTrackFinderCATask() {} // ------------------------------------------------------------------------- // ----- Initialization of Parameter Containers ------------------------- void PndLmdTrackFinderCATask::SetParContainers() { // Get Base Container /* FairRun* ana = FairRun::Instance(); FairRuntimeDb* rtdb=ana->GetRuntimeDb(); fGeoPar = (PndSdsGeoPar*)(rtdb->getContainer("PndSdsGeoPar")); */ } InitStatus PndLmdTrackFinderCATask::ReInit() { InitStatus stat=kERROR; return stat; /* FairRun* ana = FairRun::Instance(); FairRuntimeDb* rtdb=ana->GetRuntimeDb(); fGeoPar=(PndSdsGeoPar*)(rtdb->getContainer("PndSdsGeoPar")); return kSUCCESS; */ } // ----- Private method SortHitsByDet -------------------------------------------- bool PndLmdTrackFinderCATask::SortHitsByDet(std::vector< std::vector < std::pair > > &hitsd, Int_t nStripHits) { Int_t nPlanes=0; //sort in plane's for(Int_t iHit = 0; iHit < nStripHits; iHit++){ PndSdsHit* myHit = (PndSdsHit*)(fStripHitArray->At(iHit)); Int_t sensid = myHit->GetSensorID(); // Sensors: 1..32 Int_t planeid = floor((sensid)/(double)nSensPP); //nSensPP sensors/plane => Planes: 0..3 hitsd.at(planeid).push_back( make_pair (iHit,false) ); } for(Int_t iPlane = 0; iPlane < nP; iPlane++){ if(hitsd.at(iPlane).size()>0) nPlanes++; } // cout << "Hits: " << nStripHits << endl; if(fVerbose>2) { cout << "Hits: " << nStripHits << " in " << nPlanes << " plane(s)." << endl; for(Int_t idet = 0; idet < nP; idet++) cout << "Plane: "<< idet <<" DiscHits: "<< hitsd.at(idet).size() <2) return true; return false; } // ------------------------------------------------------------------------- // ----- Private method SortHitsByDet -------------------------------------------- bool PndLmdTrackFinderCATask::SortHitsByDetSimple(std::vector< std::vector< Int_t > > &hitsd, Int_t nStripHits) { // cout<<"PndLmdTrackFinderCATask::SortHitsByDetSimple! nStripHits = "<At(iHit)); Int_t sensid = myHit->GetSensorID(); // Sensors: 1..32 // cout<<"sensid = "< Planes: 0..3 // cout<<" planeid = "<< planeid<0) nPlanes++; // cout<<"nPlanes = "<2) { cout << "Hits: " << nStripHits << " in " << nPlanes << " plane(s)." << endl; for(Int_t idet = 0; idet < nP; idet++) cout << "Plane: "<< idet <<" DiscHits: "<< hitsd.at(idet).size() <2) return true; return false; } // ------------------------------------------------------------------------- // ----- Private method SortHitsByDet -------------------------------------------- bool PndLmdTrackFinderCATask::SortHitsByDetSimple2(std::vector< std::vector< Int_t > > &hitsd, Int_t nStripHits) { // cout<<"PndLmdTrackFinderCATask::SortHitsByDetSimple! nStripHits = "<At(iHit)); Int_t sensid = myHit->GetSensorID(); // Sensors: 1..32 // cout<<"sensid = "< Planes: 0..3 // cout<<" planeid = "<< planeid<Get_sensor_by_id(sensid,ihalf,iplane,imodule,iside,idie,isensor); // hitsd.at(iplane).push_back(iHit); int virtplane = iplane;//merged hits if(nP>4) virtplane = 2*iplane+iside;// single hits hitsd.at(virtplane).push_back(iHit); } for(Int_t iPlane = 0; iPlane < nP; iPlane++){ if(hitsd.at(iPlane).size()>0) nPlanes++; // cout<<"nPlanes = "<2) { cout << "Hits: " << nStripHits << " in " << nPlanes << " plane(s)." << endl; for(Int_t idet = 0; idet < nP; idet++) cout << "Plane: "<< idet <<" DiscHits: "<< hitsd.at(idet).size() <2) return true; return false; } // ------------------------------------------------------------------------- // ----- Private method SortHitsByZ -------------------------------------------- bool PndLmdTrackFinderCATask::SortHitsByZ(std::vector< std::vector< std::pair > > &hitsd, Int_t nStripHits) { std::vector detZ; //find plane positions for (Int_t iHit = 0; iHit < nStripHits; iHit++){ Double_t tmp = ((PndSdsHit*) (fStripHitArray->At(iHit)))->GetZ(); bool newZ = true; for(Int_t idet = 0; idet < detZ.size(); idet++){ // if(tmp == detZ.at(idet)){ //check if already found // cout<<"tmp = "<2) { cout << "Hits: " << nStripHits << " in " << detZ.size() << " plane(s)." << endl; for(Int_t idet = 0; idet < detZ.size(); idet++) cout << "Plane: "<< idet <<" DiscHits: "<< hitsd.at(idet).size() <3) return true; return false; } // ------------------------------------------------------------------------- // ----- Public method Init -------------------------------------------- InitStatus PndLmdTrackFinderCATask::Init() { lmddim = PndLmdDim::Instance(); // lmddim -> Read_transformation_matrices("matrices.txt", true); lmddim -> Read_transformation_matrices("matrices_perfect.txt", false); FairRootManager* ioman = FairRootManager::Instance(); if ( ! ioman ) { std::cout << "-E- PndLmdTrackFinderCATask::Init: " << "RootManager not instantiated!" << std::endl; return kFATAL; } // Get input array fStripHitArray = (TClonesArray*) ioman->GetObject(fHitBranchStrip); if ( !fStripHitArray){ std::cout << "-W- PndLmdTrackFinderCATask::Init: " << "No fStripHitArray!" << std::endl; return kERROR; } fStripClusterArray = (TClonesArray*) ioman->GetObject(fClusterBranchStrip); if ( !fStripClusterArray){ std::cout << "-W- PndLmdTrackFinderCATask::Init: " << "No StripclusterArray!" << std::endl; return kERROR; } fStripDigiArray = (TClonesArray*) ioman->GetObject(fDigiBranchStrip); if ( !fStripDigiArray){ std::cout << "-W- PndLmdTrackFinderCATask::Init: " << "No StripdigiArray!" << std::endl; return kERROR; } // fTrackCandArrayTemp = new TClonesArray("PndTrackCand"); //delete it! fTrackCandArray = new TClonesArray("PndTrackCand"); ioman->Register("LMDTrackCand", "PndLmd", fTrackCandArray, kTRUE); std::cout << "-I- PndLmdTrackFinderCATask: Initialisation successfull" << std::endl; if(missPlAlgo) std::cout << "-I- PndLmdTrackFinderCATask: missing plane(s) algorithm will be used" << std::endl; return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Public method Exec -------------------------------------------- void PndLmdTrackFinderCATask::Exec(Option_t* opt) { TStopwatch *timer_exec = new TStopwatch(); if(fVerbose>2){ timer_exec->Start(); cout << "Evt started--------------"<Clear(); Int_t nStripHits = fStripHitArray->GetEntriesFast(); if(nStripHits<2){ if(fVerbose>2) cout << "Evt finsihed: too less hits-----"< > hitsd(nP); //hit'ids splitted by detectorplane // std::vector< std::vector< std::pair > > hitsd(4); bool resSortHits; if(flagStipSens) resSortHits = SortHitsByDetSimple(hitsd, nStripHits);//! strip sensors else{ if(flagPixelSens) resSortHits = SortHitsByDetSimple2(hitsd, nStripHits);//! pixel sensors else{ std::cout<<"Algorithm depend on sensor type! Please, set it via SetSensStripFlag(bool fS) or SetSensPixelFlag(bool fS)"<2) cout << "Evt finsihed: too less planes-----"<At(iHit)); // Int_t sensid = myHit->GetSensorID(); // Sensors: 1..32 // Int_t planeid = floor((sensid)/8.); //8 sensors/plane => Planes: 0..3 // hitsd.at(planeid).push_back(iHit); // } // Int_t nPlanes=0; // for(Int_t iPlane = 0; iPlane < 4; iPlane++){ // if(hitsd.at(iPlane).size()>0) nPlanes++; // } // if(nPlanes<3){ // if(fVerbose>2) cout << "Evt finsihed: too less planes-----"<2){ for(Int_t iPlane = 0; iPlane < nP; iPlane++){ if(hitsd.at(iPlane).size()>0){ for (Int_t i=0; iAt(hitsd.at(iPlane).at(i)); cout<<"Plane"<GetX()<<", "<GetY()<<", "<GetZ()<<") with err=(" <GetDx()<<", "<GetDy()<<", "<GetDz()<<")"<Start(); int Npoints=0; const int nplanes = nP; int NpointsI[nplanes]; int cell_arr_size=0; for(int i=0;i0) cell_arr_size+= NpointsI[i]* NpointsI[i-1]; if(i>1) cell_arr_size+= NpointsI[i]* NpointsI[i-2]; if(i>2) cell_arr_size+= NpointsI[i]* NpointsI[i-3]; // if(i>3) cell_arr_size+= NpointsI[i]* NpointsI[i-4]; if(hitsd.at(i).size()>Npoints) Npoints=hitsd.at(i).size(); } // cell_arr_size++; if(fVerbose>4) cout<<"Number of possible cells = "<NpointsI[0] || NpointsI[nplanes-2]>NpointsI[0]) cell_arr_size*=10000; // if(cell_arr_size>1100) return; if(cell_arr_size>100000) cell_arr_size*=0.5; ///Build all cells std::vector< std::vector > cells(11,vector(cell_arr_size)); int count = 0; for(int j=0;j<(nplanes-1);j++){ int maxI = NpointsI[j]; int maxK1 = NpointsI[j+1]; int maxK2 = 0; int maxK3 = 0; if(j<(nplanes-2)) maxK2 = NpointsI[j+2]; if(j<(nplanes-3)) maxK3 = NpointsI[j+3]; int maxK = maxK1; if(maxK2>maxK) maxK=maxK2; if(maxK3>maxK) maxK=maxK3; // if(fVerbose>4) cout<<" maxI[j] = "<GetX(); double y1 = hit1->GetY(); double z1 = hit1->GetZ(); TVector3 dirc(x1-x0,y1-y0,z1-z0); // dirc *= 1./dirc.Mag(); ///dTheta of cells to reduce wrong combination htheta->Fill(dirc.Mag(),dirc.Theta()); // if((dirc.Theta()>0.01 && dirc.Mag()>1.) || (dirc.Mag()<0.1 && dirc.Theta()>1.5)){ //in LUMI frame //for point between diff.planes or for point between diff. layes bool goodDir = true; if(dirc.Mag()>1.){ if(flagTrkCandCuts && ((dirc.Theta()<0.03 || dirc.Theta()>0.05) || fabs(dirc.Phi())>0.25)){ goodDir = false; // if(fVerbose>6) cout<<" dirc.Mag()>1. && (dirc.Theta()<0.03 && dirc.Theta()>0.05) || fabs(dirc.Phi())>0.25)"<0.5){ if(dirc.Theta()>2){ goodDir = false; // if(fVerbose>6) cout<<" dirc.Mag()<1.&& dirc.Theta()>0.5"<1){ //TEST if(fVerbose>4){ cout<<"For cell between #"<<(j)<<"."<GetX(); double y2 = hit2->GetY(); double z2 = hit2->GetZ(); TVector3 dirc2(x2-x0,y2-y0,z2-z0); // dirc2 *= 1./dirc2.Mag(); ///dTheta of cells to reduce wrong combination // if(dirc2.Theta()>0.01){ //in LUMI frame htheta->Fill(dirc2.Mag(),dirc2.Theta()); // if((dirc2.Theta()>0.01 && dirc2.Mag()>1.) || (dirc2.Mag()<0.1 && dirc2.Theta()>1.5)){ //in LUMI frame //for point between diff.planes or for point between diff. layes // if((dirc2.Theta()<0.03 && dirc2.Theta()>0.05 && fabs(dirc2.Phi())>0.25 && dirc2.Mag()>1.) || (dirc2.Mag()<0.1 && dirc2.Theta()>0.5)){ //in LUMI frame //for point between diff.planes or for point between diff. layes bool goodDir = true; if(dirc2.Mag()>1.){ if(flagTrkCandCuts && ((dirc2.Theta()<0.03 || dirc2.Theta()>0.05) || fabs(dirc2.Phi())>0.25)){ goodDir = false; // if(fVerbose>6) cout<<" dirc2.Mag()>1. && (dirc2.Theta()<0.03 && dirc2.Theta()>0.05) || fabs(dirc2.Phi())>0.25)"<0.5){ if(dirc2.Theta()>2){ // if(fVerbose>6) cout<<" dirc2.Mag()<1.&& dirc2.Theta()>0.5"<1){ //TEST if(fVerbose>4){ cout<<"For cell between #"<<(j)<<"."<4) // cout<<"Number of good cells:"<4) // cout<<"Number of cells after cleaning:"<Stop(); // Double_t rtime_cook_cells = timer_cook_cells->RealTime(); // Double_t ctime_cook_cells = timer_cook_cells->CpuTime(); // cout << "Real time for Cells cooking:" << rtime_cook_cells << " s, CPU time " << ctime_cook_cells << " s" << endl; // TStopwatch *timer_neighbors_cells = new TStopwatch(); // timer_cook_cells->Start(); //Find neighbors between cells vector connect;//save position connected cells // for(int itter=0; itter<1; itter++){ for(int ic=0; ic4) // cout<<"Cells #"<= 0; jc--){ if(fabs(cells.at(9).at(ic)-cells.at(8).at(jc))>1e-1) continue; if(fabs(cells.at(7).at(ic)-cells.at(6).at(jc))>1e-1) continue; // if(fVerbose>4) // cout<<" still Cells #"<Fill(d); if(d4) // cout<<"BINGO! Cells #"<4) // cout<<"Ooops, smth wrong with cells #"<4) cout<<"Cells #"<= dmax!"<Stop(); // Double_t rtime_neighbors_cells = timer_neighbors_cells->RealTime(); // Double_t ctime_neighbors_cells = timer_neighbors_cells->CpuTime(); // cout << "Real time for neighbors between cells search :" << rtime_neighbors_cells << " s, CPU time " << ctime_neighbors_cells << " s" << endl; // if(fVerbose>4) // cout<<"Number of connected cells "<4){ cout<<"connect:"<Start(); //Build track from cells combination -------------------------------- //find max number of cells in a track int pcmax = 0; for(int cid=1;cidpcmax) pcmax = tag_cur; } if(fVerbose>4) cout<<"track can contain "< > trk_cells(trk_arr_size); int trk_count=-1; for(int newpcmax=pcmax;newpcmax>0;newpcmax--){// loop over possible number of cells in trk int cur_max_tag = newpcmax; if(fVerbose>4) cout<<"Now we are looking for trk with max "<=0;){// loop over all connections between cells bool nextloop=false; int con1,con2; int curr_arr; if(newtrk){// here we check both cells //check last array in trk_cells was filled by data bool add_new=false; if(trk_count<0) add_new=true; else{ curr_arr=trk_arr_size; while(curr_arr>0){ // cout<<"curr_arr = "<0) add_new=true; } } if(add_new){ if(fVerbose>4) cout<<"**************** Hey, here comes new trk-cand! *****************"<0){ curr_arr--; trk_cells.at(curr_arr).push_back(-1); } } cur_max_tag = newpcmax; con2 = connect[con]; con--; con1 = connect[con]; con--; if((cells.at(10).at(con2))==cur_max_tag) nextloop=true; } else{// here we check only one cell, another one is already known con2 = con1; //trk should be connected to cell from previous part for(int coni=connect.size()-1;coni>=0;){ if(con2==connect[coni]){ coni--; con1 = connect[coni]; nextloop=true; } coni -=2; } if(con2==con1) break; // cout<<" con2 = "<0) continue; // else{ // for(int conN=0;conN4) cout<<" con3:"<4) cout<<" con2:"<0) newtrk=false; // if(cur_max_tag>0) continue; // else{ // for(int conN=0;conN4) cout<<" con3:"<4) cout<<" Attention each trk candidate contain repeated cell, but smaller cells number will be deleted!"< cell_parts; vector trk_accept; for(int itrk=0;itrk0){ curr_arr--; if(fVerbose>4) cout<<" we have: trk_cells.at("<0) trk_accept.push_back(true); else trk_accept.push_back(false); // trk_accept.push_back(true); if(fVerbose>4) cout<<" with:"<0){ curr_arr--; if(trk_cells.at(curr_arr).at(itrc)<0 || trk_cells.at(curr_arr).at(itrc2)<0) continue; if(trk_cells.at(curr_arr).at(itrc)==trk_cells.at(curr_arr).at(itrc2)) count_re++; } if(count_re>0.3*cell_parts[itrc]){ trk_accept[itrc]=false; if(fVerbose>4){ // cout<<"Delete: trk-cand#"<0){ curr_arr--; if(trk_cells.at(curr_arr).at(itrc)<0 || trk_cells.at(curr_arr).at(itrc2)<0) continue; if(trk_cells.at(curr_arr).at(itrc)==trk_cells.at(curr_arr).at(itrc2)){ count_re++; } } if(count_re>0.7*cell_parts[itrc]){ trk_accept[itrc]=false; if(fVerbose>4){ cout<<"Delete: trk-cand#"<Stop(); // Double_t rtime_build_trk_combinations = timer_build_trk_combinations->RealTime(); // Double_t ctime_build_trk_combinations = timer_build_trk_combinations->CpuTime(); // cout << "Real time for build trk combinations :" << rtime_build_trk_combinations << " s, CPU time " << ctime_build_trk_combinations << " s" << endl; // TStopwatch *timer_save_trks = new TStopwatch(); // timer_save_trks->Start(); //save trk-cands ---------------------------------------- int NtrkRec = 0; // for(int itrk=0;itrk3) cout<<"Trk uses hit#"<At(hitsd.at(pl).at(id))); PndSdsClusterStrip* myCluster = (PndSdsClusterStrip*)(fStripClusterArray->At(myHit->GetClusterIndex())); PndSdsDigiStrip* astripdigi = (PndSdsDigiStrip*)fStripDigiArray->At(myCluster->GetDigiIndex(0)); myTCand->AddHit(astripdigi->GetDetID(),hitsd.at(pl).at(id),myHit->GetPosition().Z()); // myTCand->AddHit(0,hitsd.at(pl).at(id),myHit->GetPosition().Z()); double startX = cells.at(0).at(cellNum); double startY = cells.at(1).at(cellNum); double startZ = cells.at(2).at(cellNum); TVector3 posSeed(startX,startY,startZ); int cellNumNext=trk_cells.at(icell+1).at(itrk); if(cellNumNext<0){//next plane is missing cellNumNext=trk_cells.at(icell+2).at(itrk); } double dirX = cells.at(3).at(cellNumNext)-cells.at(0).at(cellNum); double dirY = cells.at(4).at(cellNumNext)-cells.at(1).at(cellNum); double dirZ = cells.at(5).at(cellNumNext)-cells.at(2).at(cellNum); dir.SetXYZ(dirX,dirY,dirZ); if(fVerbose>3) cout<<"Trk-cand direction is taking based on "<2){ // cout<<"posSeed:"<setTrackSeed(posSeed,dir,-1); firstHit=false; } int id = cells.at(7).at(cellNum); int pl = cells.at(9).at(cellNum); if(fVerbose>3) cout<<"Trk uses hit#"<At(hitsd.at(pl).at(id))); PndSdsClusterStrip* myCluster = (PndSdsClusterStrip*)(fStripClusterArray->At(myHit->GetClusterIndex())); PndSdsDigiStrip* astripdigi = (PndSdsDigiStrip*)fStripDigiArray->At(myCluster->GetDigiIndex(0)); myTCand->AddHit(astripdigi->GetDetID(),hitsd.at(pl).at(id),myHit->GetPosition().Z()); // myTCand->AddHit(0,hitsd.at(pl).at(id),myHit->GetPosition().Z()); } if(fVerbose>3){ if(flagTrkCandCuts && ((dir.Theta()<0.03 || dir.Theta()>0.05) || fabs(dir.Phi())>0.25)) cout<<"Ooops, trk-cand has: theta="<3) cout<<"Ntrk No. "<Stop(); // Double_t rtime_save_trks = timer_save_trks->RealTime(); // Double_t ctime_save_trks = timer_save_trks->CpuTime(); // cout << "Real time for save trks :" << rtime_save_trks << " s, CPU time " << ctime_save_trks << " s" << endl; if(fVerbose>2){ Int_t ntcandFin=fTrackCandArray->GetEntriesFast(); cout<<"Number of Trk-Cands is "<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; cout<< "Evt finsihed--------------"<GetMomentum(); return (2/TMath::Sqrt(p.Px()*p.Px() + p.Py()*p.Py())); } // ------------------------------------------------------------------------- Double_t PndLmdTrackFinderCATask::GetTrackDip(PndMCTrack* myTrack) { TVector3 p= myTrack->GetMomentum(); return (p.Mag()/TMath::Sqrt(p.Px()*p.Px() + p.Py()*p.Py())); } // ------------------------------------------------------------------------- ClassImp(PndLmdTrackFinderCATask);