//################################################################ //# Macro for study difference between MC and REC tracks (with simple case: 1 trk per event) //# author: Anastasia Karavdina //# date: 14/04/2013 //# //# to compile it add in "# install #" part of CMakeLists.txt lines: //# add_executable(simple_mc_rec_match simpleMCandRECmatch.C) //# target_link_libraries(simple_mc_rec_match ${ROOT_LIBRARIES} Lmd GeoBase ParBase Geom PndData TrkBase VMC EG GeomPainter generalTools FairTools LmdReco LmdTrk Geane trackrep RecoHits genfitAdapters genfit SdsReco Sds Stt Fts Proof MathMore Minuit FairDB Base) //# //# to run it (and see options): //# ${PANDAROOT}/build/bin/./simple_mc_rec_match --help //################################################################ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "PndLmdDim.h" //lmd track #include #include #include #include #include #include #include #include #include // needed for geane backtracking #include #include #include #include #include #include #include #include #include using namespace std; int main(int __argc,char *__argv[]) { //gROOT->Macro("/PANDA/pandaroot/macro/lmd/Style_Imported_Style.C"); // gROOT->SetStyle("Imported_Style"); //TODO: read this like params! // const int nEvents=500000; int nEvents=1000; int nMCtracks=1; int startEvent=0; TString storePath="/data/FAIRsorf/pandaroot/trunk/macro/lmd/tmpOutput"; double Plab=15.; int verboseLevel=5; int mh = 0;//if>0 : use merged hit collection int dnu=0;//if>0 : use namespace for pixel std::string startStr="", momStr="", nStr="", pathStr="", verbStr="" , mcTrkStr="", useNewDStr="",usedMHStr=""; // decode arguments if( __argc>1 && ( strcmp( __argv[1], "-help" ) == 0 || strcmp( __argv[1], "--help" ) == 0 ) ){ std::cout << "This is script for comparision reconstructed and simulated tracks with parameters\n" <<"-s start event \n" <<"-n Number of events \n" <<"-mom Beam Momentum \n" <<"-path path to the file(s) \n" <<"-v verbose Level (if>0, print out some information) \n" <<"Have fun! \n" << std::endl; return 0; } while ((optind < (__argc-1) ) && (__argv[optind][0]=='-')) { bool found=false; std::string sw = __argv[optind]; if (sw=="-s") { optind++; startStr = __argv[optind]; found=true; } if (sw=="-n"){ optind++; nStr = __argv[optind]; found=true; } if (sw=="-path"){ optind++; pathStr = __argv[optind]; found=true; } if (sw=="-mom"){ optind++; momStr = __argv[optind]; found=true; } if (sw=="-v"){ optind++; verbStr = __argv[optind]; found=true; } if (!found){ std::cout<< "Unknown switch: " << __argv[optind] <> startEvent; momSStr >> Plab; nSStr >> nEvents; pathSStr >> storePath; verbSStr >> verboseLevel; nMCtracks=1; cout<<"====================================="<Macro("$VMCWORKDIR/gconfig/rootlogon.C"); gSystem->Load("libLmdTrk"); // gROOT->LoadMacro("line3Dfit.C"); // ------------------------------------------------------------------------ // ----- Timer -------------------------------------------------------- TStopwatch timer; timer.Start(); // ------------------------------------------------------------------------ // ---- Input files -------------------------------------------------------- TString simMC=storePath+"/Lumi_MC_"; simMC += startEvent; simMC += ".root"; TChain tMC("cbmsim"); tMC.Add(simMC); TString DigiFile = storePath+"/Lumi_digi_"; DigiFile += startEvent; DigiFile += ".root"; TChain tdigiHits("cbmsim"); tdigiHits.Add(DigiFile); TString recHit=storePath+"/Lumi_reco"; // if(dnu>0) recHit+="Merged"; recHit +="_"; recHit += startEvent; recHit += ".root"; TChain tHits("cbmsim"); tHits.Add(recHit); TString recHitmerged=storePath+"/Lumi_recoMerged_"; recHitmerged += startEvent; recHitmerged += ".root"; TChain tHitsMerged("cbmsim"); tHitsMerged.Add(recHitmerged); TString trkCand = storePath+"/Lumi_TCand_"; trkCand += startEvent; trkCand += ".root"; TChain tTrkCand("cbmsim"); tTrkCand.Add(trkCand); TString recTrack; TChain tTrkRec("cbmsim"); recTrack = storePath+"/Lumi_Track_"; recTrack += startEvent; recTrack += ".root"; tTrkRec.Add(recTrack); TString geaneFile = storePath+"/Lumi_Geane_"; geaneFile += startEvent; geaneFile += ".root"; TChain tgeane("cbmsim"); tgeane.Add(geaneFile); // --------------------------------------------------------------------------------- // ---- Output file ---------------------------------------------------------------- TString out=storePath+"/Lumi_compare_MC_and_REC_trks_"; out += startEvent; out += ".root"; TFile *f = new TFile(out,"RECREATE"); // --------------------------------------------------------------------------------- //--- MC info ----------------------------------------------------------------- TClonesArray* true_tracks=new TClonesArray("PndMCTrack"); tMC.SetBranchAddress("MCTrack",&true_tracks); //True Track to compare TClonesArray* true_points=new TClonesArray("PndSdsMCPoint"); tMC.SetBranchAddress("LMDPoint",&true_points); //True Points to compare //---------------------------------------------------------------------------------- //--- Digitization info ------------------------------------------------------------ TClonesArray* fStripClusterArray; fStripClusterArray = new TClonesArray("PndSdsClusterPixel"); tHits.SetBranchAddress("LMDPixelClusterCand",&fStripClusterArray); TClonesArray* fStripDigiArray; fStripDigiArray = new TClonesArray("PndSdsDigiPixel"); tdigiHits.SetBranchAddress("LMDPixelDigis",&fStripDigiArray); //---------------------------------------------------------------------------------- //--- Real Hits -------------------------------------------------------------------- TClonesArray* rechit_array; rechit_array = new TClonesArray("PndSdsMergedHit"); tHitsMerged.SetBranchAddress("LMDHitsMerged",&rechit_array); //Points for Tracks //---------------------------------------------------------------------------------- //--- Track Candidate --------------------------------------------------------------- TClonesArray* trkcand_array=new TClonesArray("PndTrackCand"); tTrkCand.SetBranchAddress("LMDTrackCand",&trkcand_array); //Points for Track Canidates //----------------------------------------------------------------------------------- //--- Real tracks ------------------------------------------------------------------- // TClonesArray* rec_trk=new TClonesArray("PndLinTrack"); // tTrkRec.SetBranchAddress("LMDTrack",&rec_trk); //Tracks TClonesArray* rec_trk=new TClonesArray("PndTrack"); tTrkRec.SetBranchAddress("LMDPndTrack",&rec_trk); //Tracks //---------------------------------------------------------------------------------- //--- Geane info ------------------------------------------------------------------ TClonesArray* geaneArray =new TClonesArray("FairTrackParH"); tgeane.SetBranchAddress("GeaneTrackFinal",&geaneArray); //Tracks with helix parametrisation cout<<"And we'll make some hists"<GetEntriesFast(); const int nParticles = true_tracks->GetEntriesFast(); const int numTrk = nGeaneTrks; const int nRecHits = rechit_array->GetEntriesFast(); const int nMCHits = true_points->GetEntriesFast(); const int nTrkCandidates = trkcand_array->GetEntriesFast(); const int nRecTrks = rec_trk->GetEntriesFast(); if(verboseLevel>0) cout<<"Event #"<At(iN); Double_t lyambda = fRes->GetLambda(); if(lyambda==0){ cout<<"GEANE didn't propagate this trk!"<Fill(1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6,1e6); } if(lyambda==0) continue; /// Read REC track parameters near IP ----------------------------------- TVector3 MomRecPCA = fRes->GetMomentum(); TVector3 MomRecPCAnotnorm = MomRecPCA; MomRecPCA *= Plab/MomRecPCA.Mag(); TVector3 PosRecPCA = fRes->GetPosition(); Double_t errPx = fRes->GetDPx(); Double_t errPy = fRes->GetDPy(); Double_t errPz = fRes->GetDPz(); TVector3 errMomRecPCA(errPx,errPy,errPz); Double_t errX = fRes->GetDX(); Double_t errY = fRes->GetDY(); Double_t errZ = fRes->GetDZ(); TVector3 errPosRecPCA(errX,errY,errZ); Double_t thetaBP = TMath::Pi()/2. - lyambda; // Double_t err_lyambda = fRes->GetDLambda(); Double_t phiBP = fRes->GetPhi(); // Double_t err_phi = fRes->GetDPhi(); //calculate theta & phi errors double fLmPCA = TMath::ASin(MomRecPCA.Z()/MomRecPCA.Mag()); double cLmPCA= TMath::Cos(fLmPCA); double sLmPCA= TMath::Sin(fLmPCA); Double_t fPPCA =sqrt(MomRecPCA.X()*MomRecPCA.X()+MomRecPCA.Y()*MomRecPCA.Y()+MomRecPCA.Z()*MomRecPCA.Z()); Double_t fDPPCA= (2*MomRecPCA.X()*errMomRecPCA.X()+2*MomRecPCA.Y()*errMomRecPCA.Y()+2*MomRecPCA.Z()*errMomRecPCA.Z())/(2*fPPCA); //dp Double_t err_lyambda = (-((MomRecPCA.Z()*fDPPCA)/pow(fPPCA,2)) + errMomRecPCA.Z()/fPPCA)/ TMath::Sqrt(1 - pow(MomRecPCA.Z(),2)/pow(fPPCA,2)); Double_t err_phi = (-((MomRecPCA.Y()*fDPPCA/cLmPCA)/pow(fPPCA,2)) + (errMomRecPCA.Y()/cLmPCA)/fPPCA +(MomRecPCA.Y()*err_lyambda*TMath::Tan(fLmPCA)/cLmPCA)/fPPCA) /TMath::Sqrt(1 - (pow(MomRecPCA.Y(),2)*pow(1/cLmPCA,2))/pow(fPPCA,2)); // Double_t CovGEANELAB[6][6]; // fRes->GetMARSCov(CovGEANELAB); // Double_t errMomRecBP = fRes->GetDQp(); // ///get rid from most probably ghost track ---------- // //TODO: find reason for such trks in Kalman // double pca_lim = 1.;//=10*sigma_Xpca~10*{0.093,0.11,0.12,0.22,0.55}; // if(Plab<5) pca_lim = 2.; // if(Plab<2) pca_lim = 5.; // if(fabs(PosRecPCA.X())>pca_lim && fabs(PosRecPCA.Y())>pca_lim) continue; // PCA_x and PCA_y should be < 10sigmaX // ///get rid from most probably ghost track (END) --- // ///------------------------------------------------------------------------------------ /// Read REC track parameters near LMD ----------------------------------- PndTrack *trkpnd = (PndTrack*)rec_trk->At(iN); double chi2 = trkpnd->GetChi2(); hchi2->Fill(chi2); FairTrackParP fFittedTrkP = trkpnd->GetParamFirst(); TVector3 PosRecLMD(fFittedTrkP.GetX(),fFittedTrkP.GetY(),fFittedTrkP.GetZ()); TVector3 MomRecLMD(fFittedTrkP.GetPx(),fFittedTrkP.GetPy(),fFittedTrkP.GetPz()); MomRecLMD *=Plab/MomRecLMD.Mag(); double covMARS[6][6]; fFittedTrkP.GetMARSCov(covMARS); TVector3 errMomRecLMD(sqrt(covMARS[0][0]),sqrt(covMARS[1][1]),sqrt(covMARS[2][2])); TVector3 errPosRecLMD(sqrt(covMARS[3][3]),sqrt(covMARS[4][4]),sqrt(covMARS[5][5])); //calculate theta & phi errors double fLm = TMath::ASin(MomRecLMD.Z()/MomRecLMD.Mag()); double cLm= TMath::Cos(fLm); double sLm= TMath::Sin(fLm); Double_t fP =sqrt(MomRecLMD.X()*MomRecLMD.X()+MomRecLMD.Y()*MomRecLMD.Y()+MomRecLMD.Z()*MomRecLMD.Z()); Double_t fDP= (2*MomRecLMD.X()*errMomRecLMD.X()+2*MomRecLMD.Y()*errMomRecLMD.Y()+2*MomRecLMD.Z()*errMomRecLMD.Z())/(2*fP); //dp Double_t err_lyambdaLMD = (-((MomRecLMD.Z()*fDP)/pow(fP,2)) + errMomRecLMD.Z()/fP)/ TMath::Sqrt(1 - pow(MomRecLMD.Z(),2)/pow(fP,2)); Double_t err_phiLMD = (-((MomRecLMD.Y()*fDP/cLm)/pow(fP,2)) + (errMomRecLMD.Y()/cLm)/fP +(MomRecLMD.Y()*err_lyambdaLMD*TMath::Tan(fLm)/cLm)/fP) /TMath::Sqrt(1 - (pow(MomRecLMD.Y(),2)*pow(1/cLm,2))/pow(fP,2)); ///--------------------------------------------------------------------------------------- //Matching between MC & Rec on 1st hit level----------------------------------- int candID = trkpnd->GetRefIndex(); PndTrackCand *trkcand = (PndTrackCand*)trkcand_array->At(candID); const int Ntrkcandhits= trkcand->GetNHits(); PndSdsMCPoint* MCPointHit; int MCid; bool hitmix = false; if(Ntrkcandhits<4) continue; //require trks with hits on all planes hhits->Fill(Ntrkcandhits); for (Int_t iHit = 0; iHit < Ntrkcandhits; iHit++){ // loop over rec.hits PndTrackCandHit candhit = (PndTrackCandHit)(trkcand->GetSortedHit(iHit)); Int_t hitID = candhit.GetHitId(); PndSdsHit* myHit = (PndSdsHit*)(rechit_array->At(hitID)); //for pixel design PndSdsClusterPixel* myCluster = (PndSdsClusterPixel*)(fStripClusterArray->At(myHit->GetClusterIndex())); PndSdsDigiPixel* astripdigi = (PndSdsDigiPixel*)(fStripDigiArray->At(myCluster->GetDigiIndex(0))); if (astripdigi->GetIndex(0) == -1) continue; PndSdsMCPoint* MCPoint = (PndSdsMCPoint*)(true_points->At(astripdigi->GetIndex(0))); int MCidTOP = MCPoint->GetTrackID(); // hMCidRefID->Fill(MCidTOP,myHit->GetRefIndex()); if(iHit<1){ MCPointHit = MCPoint; MCid = MCidTOP; } else if(MCid!=MCidTOP){ cout<<"REC trk contains hits from different MC trks! Skip this event."<At(MCid); Int_t mcID = mctrk->GetPdgCode(); int mvID = mctrk->GetMotherID(); TVector3 MomMCpca = mctrk->GetMomentum(); TVector3 PosMCpca = mctrk->GetStartVertex(); Double_t thetaMC = MomMCpca.Theta(); Double_t phiMC = MomMCpca.Phi(); ///------------------------------------------------------------------------------------ hResPointPx->Fill(MomMCpca.X()-MomRecPCA.X()); hResPointPy->Fill(MomMCpca.Y()-MomRecPCA.Y()); hResPointPz->Fill(MomMCpca.Z()-MomRecPCA.Z()); hErrPointPx->Fill(errMomRecPCA.X()); hErrPointPy->Fill(errMomRecPCA.Y()); hErrPointPz->Fill(errMomRecPCA.Z()); hPullPointPx->Fill((MomMCpca.X()-MomRecPCA.X())/errMomRecPCA.X()); hPullPointPy->Fill((MomMCpca.Y()-MomRecPCA.Y())/errMomRecPCA.Y()); hPullPointPz->Fill((MomMCpca.Z()-MomRecPCA.Z())/errMomRecPCA.Z()); hResPointX->Fill(PosMCpca.X()-PosRecPCA.X()); hResPointY->Fill(PosMCpca.Y()-PosRecPCA.Y()); hResPointZ->Fill(PosMCpca.Z()-PosRecPCA.Z()); hPullPointX->Fill((PosMCpca.X()-PosRecPCA.X())/errPosRecPCA.X()); hPullPointY->Fill((PosMCpca.Y()-PosRecPCA.Y())/errPosRecPCA.Y()); hPullPointZ->Fill((PosMCpca.Z()-PosRecPCA.Z())/errPosRecPCA.Z()); hResTheta->Fill(MomMCpca.Theta()-MomRecPCA.Theta()); hThetaResTheta->Fill(MomMCpca.Theta(),(MomMCpca.Theta()-MomRecPCA.Theta())); hResPhi->Fill(MomMCpca.Phi()-MomRecPCA.Phi()); hPullTheta->Fill((MomMCpca.Theta()-MomRecPCA.Theta())/err_lyambda); hPullPhi->Fill((MomMCpca.Phi()-MomRecPCA.Phi())/err_phi); //TNtuple *nBadTrks = new TNtuple("nBadTrks","Info about _bad_ rec.tracks ","xrec:yrec:zrec:pxrec:pyrec:pzrec:nrechits:xmc:ymc:zmc:pxmc:pymc:pzmc"); if(fabs(MomRecPCAnotnorm.Mag()-Plab)>0.1*Plab){ nBadTrks->Fill(PosRecPCA.X(),PosRecPCA.Y(),PosRecPCA.Z(),MomRecPCAnotnorm.X(),MomRecPCAnotnorm.Y(),MomRecPCAnotnorm.Z(),Ntrkcandhits,PosMCpca.X(),PosMCpca.Y(),PosMCpca.Z(),MomMCpca.X(),MomMCpca.Y(),MomMCpca.Z(),mvID); cout<<"Event #"<GetPosition(); double pxTrue = MCPointHit->GetPx(); double pyTrue = MCPointHit->GetPy(); double pzTrue = MCPointHit->GetPz(); TVector3 MomMClmd(pxTrue,pyTrue,pzTrue); TVector3 dirMClmd = MomMClmd; dirMClmd *=1./MomMClmd.Mag(); double deltaZ = -PosMClmd.Z()+PosRecLMD.Z(); // double deltaZ = 0; double xneu=PosMClmd.X()+dirMClmd.X()*deltaZ; double yneu=PosMClmd.Y()+dirMClmd.Y()*deltaZ; double zneu = PosMClmd.Z()+deltaZ; PosMClmd.SetXYZ(xneu,yneu,zneu); MomMClmd = dirMClmd*Plab; // hResLumiTrkPointP->Fill((MomMClmd.Mag()-MomRecLMD.Mag())); // hResLumiTrkPointPmcPrec->Fill(MomRecLMD.Mag(),MomMClmd.Mag()); // MomMClmd *=1./MomMClmd.Mag();//TEST // MomRecLMD *=1./MomRecLMD.Mag();//TEST // errMomRecLMD *=1./MomRecLMD.Mag();//TEST // cout<<"MomMClmd.Mag() = "<Fill(PosMClmd.X()-PosRecLMD.X()); hResLumiTrkPointY->Fill(PosMClmd.Y()-PosRecLMD.Y()); hResLumiTrkPointZ->Fill(PosMClmd.Z()-PosRecLMD.Z()); hResLumiTrkPointXPull->Fill((PosMClmd.X()-PosRecLMD.X())/errPosRecLMD.X()); hResLumiTrkPointYPull->Fill((PosMClmd.Y()-PosRecLMD.Y())/errPosRecLMD.Y()); hResLumiTrkPointZPull->Fill((PosMClmd.Z()-PosRecLMD.Z())/errPosRecLMD.Z()); hResLumiTrkPointPx->Fill(MomMClmd.X()-MomRecLMD.X()); hResLumiTrkPointPy->Fill(MomMClmd.Y()-MomRecLMD.Y()); hResLumiTrkPointPz->Fill(MomMClmd.Z()-MomRecLMD.Z()); hResLumiTrkPointPxPull->Fill((MomMClmd.X()-MomRecLMD.X())/errMomRecLMD.X()); hResLumiTrkPointPyPull->Fill((MomMClmd.Y()-MomRecLMD.Y())/errMomRecLMD.Y()); hResLumiTrkPointPzPull->Fill((MomMClmd.Z()-MomRecLMD.Z())/errMomRecLMD.Z()); hResLumiTrkTheta->Fill(MomMClmd.Theta()-MomRecLMD.Theta()); hResLumiTrkPhi->Fill(MomMClmd.Phi()-MomRecLMD.Phi()); hResLumiTrkThetaPull->Fill((MomMClmd.Theta()-MomRecLMD.Theta())/err_lyambdaLMD); hResLumiTrkPhiPull->Fill((MomMClmd.Phi()-MomRecLMD.Phi())/err_phiLMD); hResLumiTrkPointXErr->Fill(errPosRecLMD.X()); hResLumiTrkPointYErr->Fill(errPosRecLMD.Y()); hResLumiTrkPointZErr->Fill(errPosRecLMD.Z()); hResLumiTrkPointPxErr->Fill(errMomRecLMD.X()); hResLumiTrkPointPyErr->Fill(errMomRecLMD.Y()); hResLumiTrkPointPzErr->Fill(errMomRecLMD.Z()); /// Comporision between MC tracks, reconstructed tracks near LMD and back propagated tracks (END) ----- } } //Draw results on few canvases TCanvas *c1 = new TCanvas("pulls_before_bp"); c1->Divide(3,2); c1->cd(1); hResLumiTrkPointXPull->Draw(); c1->cd(2); hResLumiTrkPointYPull->Draw(); c1->cd(3); hResLumiTrkPointZPull->Draw(); c1->cd(4); hResLumiTrkPointPxPull->Draw(); c1->cd(5); hResLumiTrkPointPyPull->Draw(); c1->cd(6); hResLumiTrkPointPzPull->Draw(); c1->Write(); c1->Close(); TCanvas *c2 = new TCanvas("pulls_after_bp"); c2->Divide(3,2); c2->cd(1); hPullPointX->Draw(); c2->cd(2); hPullPointY->Draw(); c2->cd(3); hPullPointZ->Draw(); c2->cd(4); hPullPointPx->Draw(); c2->cd(5); hPullPointPy->Draw(); c2->cd(6); hPullPointPz->Draw(); c2->Write(); c2->Close(); hchi2->Write(); hResPointPx->Write(); hResPointPy->Write(); hResPointPz->Write(); hErrPointPx->Write(); hErrPointPy->Write(); hErrPointPz->Write(); hPullPointPx->Write(); hPullPointPy->Write(); hPullPointPz->Write(); hResPointX->Write(); hResPointY->Write(); hResPointZ->Write(); hPullPointX->Write(); hPullPointY->Write(); hPullPointZ->Write(); hResLumiTrkPointX->Write(); hResLumiTrkPointY->Write(); hResLumiTrkPointZ->Write(); hResLumiTrkPointXPull->Write(); hResLumiTrkPointYPull->Write(); hResLumiTrkPointZPull->Write(); hResLumiTrkPointPx->Write(); hResLumiTrkPointPy->Write(); hResLumiTrkPointPz->Write(); hResLumiTrkPointPxPull->Write(); hResLumiTrkPointPyPull->Write(); hResLumiTrkPointPzPull->Write(); hResTheta->Write(); hResPhi->Write(); hPullTheta->Write(); hPullPhi->Write(); hResLumiTrkTheta->Write(); hResLumiTrkPhi->Write(); hResLumiTrkThetaPull->Write(); hResLumiTrkPhiPull->Write(); hhits->Write(); hResLumiTrkPointXErr->Write(); hResLumiTrkPointYErr->Write(); hResLumiTrkPointZErr->Write(); hResLumiTrkPointPxErr->Write(); hResLumiTrkPointPyErr->Write(); hResLumiTrkPointPzErr->Write(); // hResLumiTrkPointP->Write(); // hResLumiTrkPointPmcPrec->Write(); // hMCidRefID->Write(); hThetaResTheta->Write(); nBadTrks->Write(); f->Close(); cout<<"Number of trks where GEANE failed: "<