//----------------------------------------------------------- // // Description: // 3D Straight Line fitter // // Author List: // Mathias Michel // Anastasia Karavdina //----------------------------------------------------------- // This Class' Header ------------------ #include "PndLmdLinFitTask.h" // C/C++ Headers ---------------------- #include // Collaborating Class Headers -------- #include "FairRootManager.h" #include "TClonesArray.h" #include "PndLinTrack.h" #include "TrackData/PndTrackCand.h" #include "PndSdsHit.h" #include "PndSdsMergedHit.h" #include "TrackData/PndTrackCandHit.h" #include "PndTrack.h" #include "FairTrackParP.h" #include "FairBaseParSet.h" #include "FairRuntimeDb.h" #include "TFile.h" #include "TGeoTrack.h" #include "TGeoManager.h" #include "TLorentzVector.h" // Fit Classes ----------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ROOT::Math; using namespace std; PndLmdLinFitTask* PndLmdLinFitTask::fInstance= 0; //_____________________________________________________________________________ PndLmdLinFitTask* PndLmdLinFitTask::Instance() { return fInstance; } PndLmdLinFitTask::PndLmdLinFitTask() : FairTask("3D-Straight-Line-Fit") { fTCandBranchName = "LMDTrackCand"; // fRecoBranchName = "LMDHitsStrip"; fRecoBranchName = "LMDHitsPixel"; // fRecoBranchName = "LmdHits"; fOutputBranchName = "LMDPndTrack"; fOutputFolder ="PndLmd"; fTruePointBranch = "LMDPoint"; //True Points only for drawing! fPbeam = 0; fPDGCode = -2212; //barp fCharge = -1;//barp fsigmaMSa = 0; fsigmaMSb = 0; ftotRadLen = 0; PndGeoHandling::Instance(); fInstance=this; // //TODO: flexiable matrix path&name! // mtxpath = "../../geometry/"; // mtx_perfect = mtxpath+"trafo_matrices_lmd.dat"; TVirtualFitter::SetDefaultFitter("Minuit2"); fmin = TVirtualFitter::Fitter(0,25); for(int ih=0;ih<4;ih++) hitMergedfl[ih] = false; } PndLmdLinFitTask::PndLmdLinFitTask(TString tTCandBranchName, TString tRecoBranchName, TString tOutputBranchName, TString tOutputFolder) : FairTask("3D-Straight-Line-Fit") { fTCandBranchName = tTCandBranchName; fRecoBranchName = tRecoBranchName; fOutputBranchName = tOutputBranchName; fOutputFolder = tOutputFolder; fTruePointBranch = "LMDPoint"; //True Points only for drawing! fPbeam = 0; fPDGCode = -2212; //barp fCharge = -1;//barp // fsigmaMS = 0; fsigmaMSa = 0; fsigmaMSb = 0; PndGeoHandling::Instance(); fInstance=this; // //TODO: flexiable matrix path&name! // mtxpath = "../../geometry/"; // mtx_perfect = mtxpath+"trafo_matrices_lmd.dat"; TVirtualFitter::SetDefaultFitter("Minuit2"); fmin = TVirtualFitter::Fitter(0,25); //fmin->SetPrintLevel(fVerbose);//0=suppression of printing for(int ih=0;ih<4;ih++) hitMergedfl[ih] = false; } PndLmdLinFitTask::~PndLmdLinFitTask() { delete fmin; cout<<"PndLmdLinFitTask::~PndLmdLinFitTask()"<GetObject(fTCandBranchName); if(fTCandArray==0) { Error("PndLmdLinFitTask::Init","trackcand-array not found!"); return kERROR; } fRecoArray=(TClonesArray*) ioman->GetObject(fRecoBranchName); if(fRecoArray==0) { Error("PndLmdLinFitTask::Init","reco-array not found!"); return kERROR; } fTrackArray = new TClonesArray("PndTrack"); ioman->Register(fOutputBranchName, fOutputFolder, fTrackArray, kTRUE); //read beam momentum from base FairRun* fRun = FairRun::Instance(); FairRuntimeDb* rtdb = fRun->GetRuntimeDb(); FairBaseParSet* par=(FairBaseParSet*) (rtdb->findContainer("FairBaseParSet")); fPbeam = par->GetBeamMom(); fPDGCode = -2212; //barp fCharge = -1;//barp fGeoH = PndGeoHandling::Instance(); // double totRadLen = 0.00306;//rad.length of whole plane cout<<"RadLeng = "<Cleanup(); // lmddim = PndLmdDim::Instance(); // // TString mtx_perfect = "../../../pandaroot/geometry/trafo_matrices_lmd.dat"; // lmddim -> Read_transformation_matrices(mtx_perfect.Data(), false); std::cout << "-I- PndLmdLinFitTask: Initialisation successfull" << std::endl; return kSUCCESS; } void PndLmdLinFitTask::Exec(Option_t* opt) { // std::cout<<"PndLmdLinFitTask::Exec"<Delete(); Int_t ntcand=fTCandArray->GetEntriesFast(); // Detailed output if(fVerbose>1)std::cout<<" -I- PndLmdLinFitTask: contains "<2){ std::cout<< " Detailed Debug info on the candidates:"<At(itr); std::cout<< "TrackCand no. "<GetNHits()<<" hits."<GetNHits(); ihit++){ //fill Graph PndTrackCandHit theHit = trcnd->GetSortedHit(ihit); //get hit index = theHit.GetHitId(); detid = theHit.GetDetId(); std::cout << ihit << "\t" << index <20){ // std::cout<<"ntcand="<1) // std::cout<<" -I- PndLmdLinFitTask: start Fitting "<At(track); const int numPts = trcnd->GetNHits(); //read how many points in this track TGraph2DErrors fitme(numPts); //new graph for fitting Int_t firstHit=-1, lastHit=-1; TVector3 hit0,hit1; for(unsigned int ihit=0; ihitGetSortedHit(ihit); //get hit Int_t index = theHit.GetHitId(); Int_t detId = theHit.GetDetId(); // if(fVerbose>2) std::cout << "Point: "<< ihit<< " index: "<< index <At(index); PndSdsMergedHit* addHit = (PndSdsMergedHit*) fRecoArray->At(index); // cout<<"IsMerged??? "<GetIsMerged()<GetIsMerged(); TVector3 addPos = addHit->GetPosition(); double xhit = addPos.X(); double yhit = addPos.Y(); double zhit = addPos.Z(); // lmddim->Transform_global_to_lmd_local(xhit,yhit,zhit,false); // TVector3 addPos2(xhit,yhit,zhit); if(ihit==0){ firstHit=index; hit0 = addPos; } else{ if(ihit==2) hit1 = addPos; // if(ihit==1) hit1 = addPos; // if(ihit==numPts-1) hit1 = addPos; if(ihit==numPts-1){ lastHit=index; // hit1 = addPos2; } } double errxhit = addHit->GetDx(); double erryhit = addHit->GetDy(); double errzhit = addHit->GetDz(); fitme.SetPoint(ihit, xhit,yhit,zhit); fitme.SetPointError(ihit, errxhit,erryhit,errzhit); // fitme.SetPointError(ihit, 0.5*errxhit,0.5*erryhit,0.5*errzhit); cout<<"errxhit = "<GetSortedHit(0); //get 1st hit Int_t hitID = theHit.GetHitId(); int sysID = theHit.GetDetId(); PndSdsHit* myHit = (PndSdsHit*)(fRecoArray->At(hitID)); Int_t id = myHit->GetSensorID(); TString path = fGeoH->GetPath(id); TVector3 oo, uu, vv; fGeoH->GetOUVShortId(id, oo,uu,vv); // TVector3 o = oo; TVector3 o = FitPoint; TVector3 dj = uu; TVector3 dk = vv; FairTrackParP *trkfitp = new FairTrackParP(FitPoint,FitMom,COVmatrixPosMom,fCharge,o,dj,dk); int flagpndtrk=0; if(accuracy>1e3) flagpndtrk=-1;//quality of track: bad if chi2 is too large int ndf = 2*(trcnd->GetNHits())-4;//number d.o.f int pid = fPDGCode; PndTrack *trackfit = new PndTrack(*trkfitp,*trkfitp, *trcnd,flagpndtrk,accuracy,ndf,pid,track,sysID);//TODO: FairTrackParP at 1st and last point??? new((*fTrackArray)[rec_tkr]) PndTrack(*(trackfit)); //save Track delete trackfit;//TEST rec_tkr++; //} }// end of TCand's // Done-------------------------------------------------------------------------------------- if(fVerbose>2) std::cout<<"Fitting done"<SetObjectFit(gr); min->SetFCN(*LocalFCN);//using local coordinate in FCN Double_t arglist[100]; arglist[0] = 1; min->ExecuteCommand("SET PRINT",arglist,0);//no output double pStart[4] = {25.15,0.04,0.09,8.4e-5}; double pStartErr[4] = {4.5,0.004,4.5,0.004}; min->SetParameter(0,"x0",pStart[0],pStartErr[0],0,0); min->SetParameter(1,"Ax",pStart[1],pStartErr[1],0,0); min->SetParameter(2,"y0",pStart[2],pStartErr[2],0,0); min->SetParameter(3,"Ay",pStart[3],pStartErr[3],0,0); // //minimize step 1 arglist[0] = 1000; //number of functiona calls arglist[1] = 0.001; //tolerance min->ExecuteCommand("MIGRAD", arglist ,2); int nvpar,nparx; double amin,edm, errdef; min->GetStats(amin,edm,errdef,nvpar,nparx); if(fVerbose>1) min->PrintResults(1,amin); // get fit parameters and errors for (int i = 0; i <4; ++i){ fitpar[i] = min->GetParameter(i); fitparerr[i] = min->GetParError(i); } // return amin; Double_t chi2 = amin/(2.*Npoint-4); return chi2; } double PndLmdLinFitTask::line3Dfit(Int_t nd, TGraph2DErrors* gr, TVector3 posSeed, TVector3 dirSeed, Double_t* fitpar, TMatrixDSym *covmatrix) { if(fVerbose>2) cout<<"PndLmdLinFitTask::line3Dfit with SEED is used"<GetN(); Double_t ErrX1 = gr->GetErrorX(0); Double_t ErrY1 = gr->GetErrorY(0); Double_t ErrZ1 = gr->GetErrorZ(0); Double_t ErrX2 = gr->GetErrorX(1); Double_t ErrY2 = gr->GetErrorY(1); Double_t ErrZ2 = gr->GetErrorY(1); Double_t errRx = 0.1*TMath::Hypot(ErrX1,ErrX2); Double_t errRy = 0.1*TMath::Hypot(ErrY1,ErrY2); Double_t errRz = 0.1*TMath::Hypot(ErrZ1,ErrZ2); //The default minimizer is Minuit TVirtualFitter::SetDefaultFitter("Minuit"); TVirtualFitter *min = TVirtualFitter::Fitter(0,5); min->SetObjectFit(gr); min->SetFCN(*LocalFCN);//using local coordinate in FCN Double_t arglist[100]; arglist[0] = 1; min->ExecuteCommand("SET PRINT",arglist,0);//no output if(fVerbose>2){ cout<<"posSeed:"<2){ for(int i=0;i<6;i++) cout<<"pStartErr["<SetParameter(0,"x0",pStart[0],pStartErr[0],0,0); min->SetParameter(1,"Ax",pStart[1],pStartErr[1],0,0); min->SetParameter(2,"y0",pStart[2],pStartErr[2],0,0); min->SetParameter(3,"Ay",pStart[3],pStartErr[3],0,0); min->SetParameter(4,"z0",pStart[4],0,0,0); min->SetParameter(5,"Az",pStart[5],0,0,0); // Now ready for minimization step arglist[0] = 1500; arglist[1] = 1.; min->ExecuteCommand("MIGRAD", arglist,2); ///Get results --------------------------------------------- int nvpar,nparx; double amin,edm, errdef; min->GetStats(amin,edm,errdef,nvpar,nparx); if(fVerbose>1) min->PrintResults(1,amin); Double_t fitparerr[6]; // get fit parameters for (int i = 0; i <6; ++i){ fitpar[i] = min->GetParameter(i); fitparerr[i] = min->GetParError(i); } if((fitpar[1]*fitpar[1]+fitpar[3]*fitpar[3])<1.){ fitpar[5]=sqrt(1-fitpar[1]*fitpar[1]-fitpar[3]*fitpar[3]); } else{ fitpar[5]=0; amin=1e9; } for(size_t i=0;i<4;i++){ for(size_t j=0;j<4;j++){ (*covmatrix)(i,j)= min->GetCovarianceMatrixElement(i,j); } } (*covmatrix)(4,4) = gr->GetErrorZ(0)*gr->GetErrorZ(0)/12.; double dp5_dp1 = fitpar[1]/fitpar[5]; double dp5_dp3 = fitpar[3]/fitpar[5]; double errdz2 = pow(dp5_dp1,2)*(*covmatrix)(1,1) + pow(dp5_dp3,2)*(*covmatrix)(3,3) + 2*fabs(dp5_dp1*dp5_dp3*(*covmatrix)(1,3)); (*covmatrix)(5,5) = errdz2; Double_t chi2 = amin/(2.*Npoint-4); ///------------------------------------------------------------- return chi2; } double PndLmdLinFitTask::ScatteredAngle(double radLen){ //Calculation of ThetaMS ------------------------------------- //Charge & mass of particle Int_t PDGCode = -2212; //barp Double_t fMass = 0.938272046; Double_t Ebeam = TMath::Hypot(fPbeam,fMass); TLorentzVector LorMom(0, 0, fPbeam, Ebeam); Double_t beta = LorMom.Beta(); Double_t X_to_X0 = radLen; Double_t thetaMS = 13.6*1e-3*TMath::Sqrt(X_to_X0)*(1+0.038*TMath::Log(X_to_X0))/(beta*fPbeam); //cout<<"for Pbeam = "<GetN(); Double_t ErrX1 = gr->GetErrorX(0); Double_t ErrY1 = gr->GetErrorY(0); Double_t ErrZ1 = gr->GetErrorZ(0); TVector3 ErrPosSeed(ErrX1,ErrY1,ErrZ1); Double_t ErrX2 = gr->GetErrorX(2); Double_t ErrY2 = gr->GetErrorY(2); Double_t ErrZ2 = gr->GetErrorY(2); Double_t errRx = 1*TMath::Hypot(ErrX1,ErrX2); Double_t errRy = 1*TMath::Hypot(ErrY1,ErrY2); Double_t errRz = 1*TMath::Hypot(ErrZ1,ErrZ2); fmin->SetObjectFit(gr); fmin->SetFCN(*LocalFCN_MS); Double_t arglist[100]; arglist[0] = 1; // fmin->ExecuteCommand("SET PRINT",arglist,10);//output // fmin->ExecuteCommand("SET PRINT",arglist,0);//no output if(fVerbose>5){ cout<<"Number of hits = "<SetParameter(0,"x0",pStart[0],pStartErr[0],0,0); fmin->SetParameter(1,"Ax",pStart[1],pStartErr[1],0,0); fmin->SetParameter(2,"y0",pStart[2],pStartErr[2],0,0); fmin->SetParameter(3,"Ay",pStart[3],pStartErr[3],0,0); fmin->SetParameter(4,"z0",pStart[4],0,0,0); fmin->SetParameter(5,"Az",pStart[5],0,0,0); // fmin->SetParameter(5,"Az",pStart[5],pStartErr[1],0,0);//TEST fmin->SetParameter(6,"al0x_a",pStart[6],1e-4*fsigmaMSa,0,0); fmin->SetParameter(7,"al0x_b",pStart[7],1e-4*fsigmaMSb,0,0); fmin->SetParameter(8,"al1x_a",pStart[8],1e-4*fsigmaMSa,0,0); fmin->SetParameter(9,"al1x_b",pStart[9],1e-4*fsigmaMSb,0,0); fmin->SetParameter(10,"al2x_a",pStart[10],1e-4*fsigmaMSa,0,0); fmin->SetParameter(11,"al2x_b",pStart[11],1e-4*fsigmaMSb,0,0); fmin->SetParameter(12,"al3x_a",pStart[12],1e-4*fsigmaMSa,0,0); fmin->SetParameter(13,"al3x_b",pStart[13],1e-4*fsigmaMSb,0,0); fmin->SetParameter(14,"al0y_a",pStart[14],1e-4*fsigmaMSa,0,0); fmin->SetParameter(15,"al0y_b",pStart[15],1e-4*fsigmaMSb,0,0); fmin->SetParameter(16,"al1y_a",pStart[16],1e-4*fsigmaMSa,0,0); fmin->SetParameter(17,"al1y_b",pStart[17],1e-4*fsigmaMSb,0,0); fmin->SetParameter(18,"al2y_a",pStart[18],1e-4*fsigmaMSa,0,0); fmin->SetParameter(19,"al2y_b",pStart[19],1e-4*fsigmaMSb,0,0); fmin->SetParameter(20,"al3y_a",pStart[20],1e-4*fsigmaMSa,0,0); fmin->SetParameter(21,"al3y_b",pStart[21],1e-4*fsigmaMSb,0,0); fmin->FixParameter(8); fmin->FixParameter(10); fmin->FixParameter(12); fmin->FixParameter(16); fmin->FixParameter(18); fmin->FixParameter(20); // fmin->FixParameter(6); // fmin->FixParameter(7); fmin->FixParameter(13); // fmin->FixParameter(14); // fmin->FixParameter(15); fmin->FixParameter(21); // fmin->FixParameter(6); // fmin->FixParameter(7); // //fmin->FixParameter(13); // fmin->FixParameter(14); // fmin->FixParameter(15); // //fmin->FixParameter(21); if(Npoint<4){ fmin->FixParameter(11); fmin->FixParameter(19); } double recpres = 1e-7; // Now ready for minimization step // arglist[0] = 5000; arglist[0] = 50000; //arglist[0] = 2; arglist[1] = recpres; fmin->ExecuteCommand("MIGRAD", arglist,3); fmin->ExecuteCommand("SET PRI", arglist,5); ///Get results --------------------------------------------- int nvpar,nparx; double amin,edm, errdef; fmin->GetStats(amin,edm,errdef,nvpar,nparx); if(edm>1e2*recpres) return 1e6; if(fVerbose>1){ cout<<"------------- Final result ---------------- "<PrintResults(fVerbose,amin); } // if(fVerbose>1){ // cout<<"------------- Final result ---------------- "<PrintResults(1,amin); // } Double_t fitparerr[nparams]; // get fit parameters for (int i = 0; i GetParameter(i); fitparerr[i] = fmin->GetParError(i); } for(size_t i=0;i<6;i++){ for(size_t j=0;j<6;j++){ (*covmatrix)(i,j)= fmin->GetCovarianceMatrixElement(i,j); } } //!!!!!!!!!!!!!!!!!! z0, dz weren't fitted (*covmatrix)(4,4) = (gr->GetErrorZ(0)*gr->GetErrorZ(0))/12.; // if((fitpar[1]*fitpar[1]+fitpar[3]*fitpar[3])<1.){ // fitpar[5]=sqrt(1-fitpar[1]*fitpar[1]-fitpar[3]*fitpar[3]); // } // else{ // fitpar[5]=0; // amin=1e9; // } fitpar[5]=sqrt(1-fitpar[1]*fitpar[1]-fitpar[3]*fitpar[3]); double dp5_dp1 = fitpar[1]/fitpar[5]; double dp5_dp3 = fitpar[3]/fitpar[5]; double errdz2 = pow(dp5_dp1,2)*(*covmatrix)(1,1) + pow(dp5_dp3,2)*(*covmatrix)(3,3) + 2*fabs(dp5_dp1*dp5_dp3*(*covmatrix)(1,3)); (*covmatrix)(5,5) = errdz2; //!!!!!!!!!!!!!!!!!! Double_t chi2 = amin/(2.*Npoint-4); if(fVerbose>2){ cout<<" chi2 = "<