#include #include "PndVtxPRG.h" #include "RhoBase/TCandListIterator.h" #include "RhoBase/TRho.h" #include "RhoBase/TFactory.h" #include "TMatrixT.h" #include "PndAnalysisCalcTools.h" ClassImp(PndVtxPRG) TBuffer &operator>>(TBuffer &buf, PndVtxPRG *&obj) { obj = (PndVtxPRG *) buf.ReadObject(PndVtxPRG::Class()); return buf; } PndVtxPRG::PndVtxPRG( const TCandidate& b) : VAbsFitter(b), fDebug(false), fExpansionPoint(0.,0.,0.), // Assume Zero origin as default fPrgCov(5,5), fJacobian(5,7) { std::cout<<"Creating PndVtxPRG. This class is preliminary."<NDaughters(); TVector3 vtx(0.,0.,0.); //TVector3 bkExpPoint = fExpansionPoint; // backup vertex seed TMatrixD tmpcov(3,3); bool verbi=fVerbose; fVerbose=false; bool debi=fDebug; fDebug=false; //for (int afast=0;afast<4;afast++) //{ FitVertexFast(vtx,tmpcov,false);//fast vertex seed (with expansion point used) //if(fVerbose) {std::cout<<" #$# Fit #$# Vertex before a, iteration"< B; std::vector CI; // only Ci^-1 is used std::vector BCI; // helper to save on multiplications (more memory needed, though) std::vector D; // helper std::vector E; //helper TMatrixD A(3,3); TMatrixD T(3,1); std::vector U; std::vector W; std::vector dq; // helper TMatrixD CovFitFull(3+3*nTrk,3+3*nTrk); //3 vtx coordinates, nTrk*3 momenta for(int i=0;iDaughter(i); // we assume here that track parameters are delivered at // distance of closest approach to the z axis of the extraction point. const double charge = tcand->GetCharge(); if (fVerbose) { printf("#$# Fit #$# Helix params:\n\t epsilon = %.4g cm\n\t Z0\t = %.4g cm\n\t theta\t = %.4g\n\t phi0\t = %.4g\n\t rho\t = %.4g 1/cm\n\t charge\t = %g e\n",fPrgParams[0],fPrgParams[1],fPrgParams[2],fPrgParams[3],fPrgParams[4],charge); std::cout<<" #$# Fit #$# Helix cov: "; fPrgCov.Print(); } TVector3 momi = tcand->GetMomentum(); if(fDebug) {printf(" ##$# Fit #$# momi: ");momi.Print();} TVector3 posi = tcand->GetPosition(); // (printout only!) posi -= fExpansionPoint; if(fDebug) {printf(" ##$# Fit #$# pocai:");posi.Print();} // all positions relative to fExpansionPoint !!!! // get parameters closest to vertex estimate Bool_t testvtx = CalcPrgParams(tcand,vtx); // Bool_t testvtx = CalcPrgParams(tcand,vtx+fExpansionPoint); if(!testvtx) return; TMatrixD qiv(3,1); qiv[0][0]=fPrgParams[0];//epsilon qiv[1][0]=fPrgParams[1];//z0 qiv[2][0]=fPrgParams[3];//phi0 double s = sin(fPrgParams[3]); double c = cos(fPrgParams[3]); double t = tan(fPrgParams[2]); if(t!=0) t = 1/t; else return; // make an iterative loop to update it TMatrixD xvi(1,3); // point closest to estimated vertex xvi[0][0]=s*fPrgParams[0]; xvi[0][1]=-c*fPrgParams[0]; xvi[0][2]=fPrgParams[1]; if(fVerbose) {std::cout<<" #$# Fit #$# xvi from seed "; xvi.Print();} xvi[0][0]+=vtx.X()-fExpansionPoint.X(); xvi[0][1]+=vtx.Y()-fExpansionPoint.Y(); xvi[0][2]+=vtx.Z()-fExpansionPoint.Z(); if(fVerbose) {std::cout<<" #$# Fit #$# xvi "; xvi.Print();} double Q=xvi[0][0]*c+xvi[0][1]*s; // at estimated vertex perigee double R=xvi[0][1]*c-xvi[0][0]*s; if(fDebug) printf(" #$# Fit #$# Helper variables: Q = %g , R = %g\n",Q,R); TMatrixD pvi(1,3); pvi[0][0]=c*momi.Perp(); pvi[0][1]=s*momi.Perp(); pvi[0][2]=momi.Z(); if(fVerbose) {std::cout<<" #$# Fit #$# pvi "; pvi.Print();} // get perigee parameters for measured track Bool_t testprg = CalcPrgParams(tcand,fExpansionPoint); if(!testprg) {printf("#$# Fit #$# CANNOT CALCULATE TRACK PARAMETERS"); return;} TMatrixD qip(3,1); qip[0][0]=fPrgParams[0];//epsilon qip[1][0]=fPrgParams[1];//z0 qip[2][0]=fPrgParams[3];//phi0 //TMatrixD xmi(1,3); // last measured position //xmi[0][0]=posi.X(); //xmi[0][1]=posi.Y(); //xmi[0][2]=posi.Z(); //if(fVerbose) {std::cout<<" #$# Fit #$# xmi "; xmi.Print();} TMatrixD xpi(1,3); // perigee position xpi[0][0]=sin(fPrgParams[3])*fPrgParams[0]; xpi[0][1]=-cos(fPrgParams[3])*fPrgParams[0]; xpi[0][2]=fPrgParams[1]; if(fVerbose) {std::cout<<" #$# Fit #$# xpi "; xpi.Print();} TMatrixD COVi(3,3); // track parameter cov for (epsilon,z_p,Phi_p) //double r=pocai.Perp(); COVi[0][0]=fPrgCov[0][0];// epsilon-epsilon COVi[0][1]=fPrgCov[0][1];// epsilon-z0 COVi[0][2]=fPrgCov[0][3];// epsilon-Phi0 COVi[1][0]=fPrgCov[1][0];// epsilon-z0 COVi[1][1]=fPrgCov[1][1];// z0-z0 COVi[1][2]=fPrgCov[1][3];// z0-Phi0 COVi[2][0]=fPrgCov[3][0];// epsilon-Phi0 COVi[2][1]=fPrgCov[3][1];// z0-Phi0 COVi[2][2]=fPrgCov[3][3];// phi0-phi0 if(fVerbose) {std::cout<<" #$# Fit #$# COVi "; COVi.Print();} //det(aA) = a^n det(A) TMatrixD Wi(COVi); //Wi *= 100000; // multiply with a biggish number to get reasonable numerics for the inversion //if(fVerbose) {std::cout<<" #$# Fit #$# Wi before inversion "< No check possible W.push_back(Wi); if(fDebug) {std::cout<<" #$# Fit #$# Wi (det(cov) = "< No check possible CI.push_back(CIi); for(int sdsd=0;sdsd<3;sdsd++) for(int asas=sdsd;asas<3;asas++){ printf("CI{%i}[%i][%i] = %6.9f\n",i,sdsd,asas,CI[i][sdsd][asas]); printf("CI{%i}[%i][%i] = %6.9f\n",i,asas,sdsd,CI[i][asas][sdsd]); } if(fDebug) {std::cout<<" #$# Fit #$# CIi = Ci^-1 "; CIi.Print();} TMatrixD BiCIi(Bi,TMatrixD::kMult,CIi); BCI.push_back(BiCIi); if(fDebug) {std::cout<<" #$# Fit #$# BiCIi "; BiCIi.Print();} TMatrixD Ti(DitWi,TMatrixD::kMult,dqi); T += Ti; if(fDebug) {std::cout<<" #$# Fit #$# Ti = DitWi*dqi "; Ti.Print();} TMatrixD Ui(EitWi,TMatrixD::kMult,dqi); U.push_back(Ui); if(fDebug) {std::cout<<" #$# Fit #$# Ui = EitWi*dqi"; Ui.Print();} } // loop tracks if(fDebug) {std::cout<<" #$# Fit #$# A = "; A.Print();} // Calculate Vertex update TMatrixD WV(A); if(fDebug) {std::cout<<" #$# Fit #$# WV = "; WV.Print();} TMatrixD Vpre(T); for(int i=0;i P; std::vector uq; //dV.T(); Double_t chisquare=0; for(int i=0;iDaughter(i); TCandidate* fitted = new TCandidate(*tcand); // set fitted values fitted->SetPos(vtx); TVector3 momi( (P[i])[0][0],(P[i])[1][0],(P[i])[2][0] ); fitted->SetP3(momi); for(int k=0;k<3;k++) for(int l=0;l<3;l++){ CovP7[k+3][l+3]=CovFitFull[3*(i+1)+k][3*(i+1)+l]; // momentum cov CovP7[k+3][l]=CovFitFull[3*(i+1)+k][l]; // momentum-position cov CovP7[l][k+3]=CovFitFull[l][3*(i+1)+k]; // momentum-position cov } CovP7[6][6]= (tcand->GetErrP7())[27];// error in e fitted->SetCov7(CovP7); fitted->SetChi2(chisquare); //TODO: Update helix parameters & cov here, too. // put fitted candidate tcand->SetFit(fitted); if(fDebug) {std::cout<<" #$# Fit #$# CovP7 with mom for tracj "<P4(); TVector3 pos= tcand->GetPosition(); double charge = tcand->GetCharge(); TMatrixD cov77 = tcand->Cov7(); Bool_t test = PndAnalysisCalcTools::P7toPRG(pos, mom, charge, cov77, expansionpoint, fPrgParams, fPrgCov, fJacobian, false); return test; } double PndVtxPRG::FitVertexFast(TVector3 &vtx, TMatrixD &cov, bool skipcov) { // Calculate a vertex of n tracks without considering the changes in momentum vector // the variables vtx & cov (3x3) are written and the Chi^2 is returned. int nTrk = fHeadOfTree->NDaughters(); std::vector w; std::vector xp; TMatrixD sumw(3,3); TMatrixD sumwx(3,1); Double_t determinant = 0.; for(int i=0;iDaughter(i); // get Helix in PRG notation from Billoir paper // (epsilon,z0,theta,phi0,rho) Bool_t testprg = CalcPrgParams(tcand,fExpansionPoint); if(!testprg) return -2; if (fVerbose) { printf("#$# Fast #$# Helix params:\n\t epsilon\t = %.4g cm\n\t Z0\t = %.4g cm\n\t theta\t = %.4g\n\t phi0\t = %.4g\n\t rho\t = %.4g\n",fPrgParams[0],fPrgParams[1],fPrgParams[2],fPrgParams[3],fPrgParams[4]); std::cout<<" #$# Fast #$# Helix cov: "; fPrgCov.Print(); } double s = sin(fPrgParams[3]); double c = cos(fPrgParams[3]); double t = TMath::Tan(fPrgParams[2]); if(t!=0.) t = 1/t; else return -3; // t = cot(theta) TMatrixD xpi(1,3); xpi[0][0]=s*fPrgParams[0]; xpi[0][1]=-c*fPrgParams[0]; xpi[0][2]=fPrgParams[1]; xp.push_back(xpi); // save for later use if(fVerbose) {std::cout<<" #$# Fast #$# xpi "; xpi.Print();} TMatrixD COVi(2,2); // track parameter cov for (epsilon,z0) COVi[0][0]=fPrgCov[0][0]; COVi[0][1]=COVi[1][0]=fPrgCov[1][0]; COVi[1][1]=fPrgCov[1][1]; if(fVerbose) {std::cout<<" #$# Fast #$# COVi "; COVi.Print();} //propagate to Vertex TMatrixD Wi(COVi); Wi.Invert(&determinant); if (determinant == 0.) { std::cout<<"PndVtxPRG: COVi Inversion failed, abort fit -888"< No check possible if(fDebug) {std::cout<<" #$# Fast #$# Wi"< No check possible if(fVerbose) {std::cout<<" #$# Fast #$# cV "; cV.Print();} TMatrixD V(cV,TMatrixD::kMult,sumwx);// result vertex V.T(); // make it a row vector if(fVerbose) {std::cout<<" #$# Fast #$# V "; V.Print();} vtx.SetXYZ(V[0][0],V[0][1],V[0][2]); vtx += fExpansionPoint; // move back to origin if(fVerbose) {std::cout<<" #$# Fast #$# Vtx: "; vtx.Print();} if (skipcov) return -1.; // skip chisqare calculation double chisq=0.; // calculate chisquare for(int i=0;i