#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.); std::vector momenta; TMatrixD tmpcov(3,3); Double_t chisquare=500000;//some high value Double_t determinant = 0.; TMatrixD qip(5,nTrk); // starting parameters of all tracks std::vector B; std::vector GI; // only Gi^-1 is used std::vector BGI; // 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 TMatrixD CovVV(3,3); // Find a nice seed value bool verbi=fVerbose; fVerbose=false; bool debi=fDebug; fDebug=false; // temporary silence FitVertexFast(vtx,tmpcov,false);//fast vertex seed (with expansion point used) fDebug=debi; fVerbose=verbi; if(fVerbose) {std::cout<<" #$# Fit #$# Vertex after fast prefit: "; vtx.Print();} // fExpansionPoint = vtx; // move to vincinity for (int iteration = 0 ; iteration < niterations ; iteration++) { if(fVerbose) { std::cout<<"Iteration "<Daughter(i); const Double_t charge = tcand->GetCharge(); if(iteration==0) { //On the first run fetch the starting values (being updated) //Bool_t testprg = CalcPrgParams(tcand,fExpansionPoint); Bool_t testprg = CalcPrgParams(tcand,vtx); if(!testprg) {printf("#$# Fit #$# CANNOT CALCULATE TRACK PARAMETERS (momenta at origin)"); return kFALSE;} qip[0][i]=0.;//fPrgParams[0];// the initial guess is AT the guess vertex. No epsilon_0 qip[1][i]=0.;//fPrgParams[1];// the initial guess is AT the guess vertex. No z_0 qip[2][i]=fPrgParams[2];// qip[3][i]=fPrgParams[3];//phi0 qip[4][i]=fPrgParams[4]; if(fDebug) {printf(" ##$# Fit #$# Measurement p: ");tcand->GetMomentum().Print();} if(fDebug) {printf(" ##$# Fit #$# Measurement x: ");tcand->GetPosition().Print();} momenta.push_back(tcand->GetMomentum()); momenta[i].SetPhi(fPrgParams[3]); // set phi while keeping magnitude and theta constant if(fDebug) {printf(" ##$# Fit #$# Momentum at Expansionpoint (phi=%g): ",fPrgParams[3]);momenta[i].Print();} } // get parameters closest to current vertex estimate Bool_t testvtx = CalcPrgParams(tcand,vtx); if(!testvtx) return kFALSE; 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(); } TMatrixD qiv(5,1); // parameters describing relative to expansion point the vertex seed qiv[0][0]=fPrgParams[0];//epsilon AT vertex zero qiv[1][0]=fPrgParams[1];//z0 AT vertex zero qiv[2][0]=fPrgParams[2];// qiv[3][0]=fPrgParams[3];//phi0 qiv[4][0]=fPrgParams[4];// //dqi = q_measured - F_0 == div-qip; TMatrixD qipi(5,1);for (int kk=0;kk<5;kk++)qipi[kk][0]=qip[kk][i]; TMatrixD dqi(qiv,TMatrixD::kMinus,qipi); dq.push_back(dqi); if(fDebug) {std::cout<<" #$# Fit #$# dqi "; dqi.Print();} TMatrixD COVi(5,5); // track parameter cov for (epsilon,z_p,Phi_p) //Double_t r=pocai.Perp(); COVi=fPrgCov; // 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[0][1];// epsilon-z0 // COVi[1][1]=fPrgCov[1][1];// z0-z0 // COVi[1][2]=fPrgCov[1][3];// z0-Phi0 // COVi[2][0]=fPrgCov[0][3];// epsilon-Phi0 // COVi[2][1]=fPrgCov[1][3];// z0-Phi0 // COVi[2][2]=fPrgCov[3][3];// Phi0-Phi0 // // COVi[0][3]=fPrgCov[0][2];// // COVi[0][4]=fPrgCov[0][4];// // COVi[1][3]=fPrgCov[1][2];// // COVi[1][4]=fPrgCov[1][4];// // COVi[2][3]=fPrgCov[3][2];// // COVi[2][4]=fPrgCov[3][4];// // // COVi[3][0]=fPrgCov[0][2];// // COVi[3][1]=fPrgCov[1][2];// // COVi[3][2]=fPrgCov[2][3];// // COVi[3][3]=fPrgCov[2][2];// // COVi[3][4]=fPrgCov[2][4];// // COVi[4][0]=fPrgCov[0][4];// // COVi[4][1]=fPrgCov[1][4];// // COVi[4][2]=fPrgCov[3][4];// // COVi[4][3]=fPrgCov[2][4];// // COVi[4][4]=fPrgCov[4][4];// if(fVerbose) {std::cout<<" #$# Fit #$# COVi "; COVi.Print();} // Double_t s = sin(fPrgParams[3]); // Double_t c = cos(fPrgParams[3]); // Double_t t = tan(momenta[i].Theta()); // if(t!=0) t = 1./t; else return kFALSE; // Double_t X = vtx.x()-s/fPrgParams[4]-fExpansionPoint.X(); // Double_t Y = vtx.y()+c/fPrgParams[4]-fExpansionPoint.Y(); //// Double_t X = s*fPrgParams[0]; //// Double_t Y = -c*fPrgParams[0]; // Double_t Q=X*c-Y*s; // Double_t R=Y*c+X*s; // if(fDebug) printf(" #$# Fit #$# Helper variables: Q = %g , R = %g\n",Q,R); //Take the derivatives at the current vertex estimate (seed) (cf. Avery1 p.4) TMatrixD Di(5,3); // Derivative in V Di[0][0]=fJacobian[0][0]; // dEpsilon / dvx Di[0][1]=fJacobian[0][1]; // dEpsilon /dvy Di[0][2]=fJacobian[0][2]; // dEpsilon /dvz Di[1][0]=fJacobian[1][0]; // dZ0 /dvx Di[1][1]=fJacobian[1][1]; // dZ0 /dvy Di[1][2]=fJacobian[1][2]; // dZ0 /dvz Di[2][0]=fJacobian[2][0]; // Di[2][1]=fJacobian[2][1]; // Di[2][2]=fJacobian[2][2]; // Di[3][0]=fJacobian[3][0]; // dPhi0 /dvx Di[3][1]=fJacobian[3][1]; // dPhi0 /dvy Di[3][2]=fJacobian[3][2]; // dPhi0 /dvz Di[4][0]=fJacobian[4][0]; // Di[4][1]=fJacobian[4][1]; // Di[4][2]=fJacobian[4][2]; // //Di.T(); D.push_back(Di); if(fDebug) {std::cout<<" #$# Fit #$# Di "; Di.Print();} TMatrixD Ei(5,3); // Derivative in p Ei[0][0]=fJacobian[0][3]; // dEpsilon /dpx Ei[0][1]=fJacobian[0][4]; // dEpsilon /dpy Ei[0][2]=fJacobian[0][5]; // dEpsilon /dpz Ei[1][0]=fJacobian[1][3]; // dZ0 /dpx Ei[1][1]=fJacobian[1][4]; // dZ0 /dpy Ei[1][2]=fJacobian[1][5]; // dZ0 /dpz Ei[2][0]=fJacobian[2][3]; // Ei[2][1]=fJacobian[2][4]; // Ei[2][2]=fJacobian[2][5]; // Ei[3][0]=fJacobian[3][3]; // dPhi0 /dpx Ei[3][1]=fJacobian[3][4]; // dPhi0 /dpy Ei[3][2]=fJacobian[3][5]; // dPhi0 /dpz Ei[4][0]=fJacobian[4][3]; // Ei[4][1]=fJacobian[4][4]; // Ei[4][2]=fJacobian[4][5]; // //Ei.T(); E.push_back(Ei); if(fDebug) {std::cout<<" #$# Fit #$# Ei "; Ei.Print();} //det(aA) = a^n det(A) TMatrixD Wi(COVi); determinant=0.; Wi.InvertFast(&determinant); if (determinant==0) { std::cout<<"PndVtxPRG: COVi Inversion failed, abort fit."< uq; //dV.T(); double chiq=0; for(int i=0;i0 && chiq<10000) chisquare=chiq; else chisquare = -20; // TODO: end iteration loop at satisfying chisq? }// end of iteratoin loop // calculating other cov matrices // POS COV for(int k=0;k<3;k++) for(int l=0;l<3;l++){ CovFitFull[k][l]=CovVV[k][l]; } // MOM-POS COV for(int i=0;iDaughter(i); TCandidate* fitted = TFactory::Instance()->NewCandidate(*tcand); // set fitted values fitted->SetPos(vtx); if(fDebug) {std::cout<<" #$# Fit #$# Final Momentum :("<SetP3(momenta[i]); 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 traj "<P4(); TVector3 pos= tcand->GetPosition(); Double_t charge = tcand->GetCharge(); TMatrixD cov77 = tcand->Cov7(); Bool_t test = PndAnalysisCalcTools::P7toPRG(pos, mom, charge, cov77, expansionpoint, fPrgParams, fPrgCov, fJacobian, false); //for(int i=0;i<5;i++)for(int j=0;j<5;j++){if(i==j)continue;fPrgCov[i][j]=0.;}// FIXME: Alert, cut off-diagonal elemetns for testing return test; } Double_t 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_t s = sin(fPrgParams[3]); Double_t c = cos(fPrgParams[3]); Double_t t = TMath::Tan(fPrgParams[2]); if(t!=0.) t = 1/t; else return -3; // t = cot(theta) TMatrixD COVi(2,2); // track parameter cov for (epsilon,z0) COVi[0][0]=fPrgCov[0][0]; COVi[0][1]=fPrgCov[0][1]; COVi[1][0]=fPrgCov[1][0]; COVi[1][1]=fPrgCov[1][1]; if(fVerbose) {std::cout<<" #$# Fast #$# COVi "; COVi.Print();} TMatrixD Di(2,3); // Derivative in V, 2x3 // Di[0][0]=s; // Di[0][1]=-c; // Di[0][2]=0.; // Di[1][0]=-t*c; // Di[1][1]=-t*s; // Di[1][2]=1.; Di[0][0]=fJacobian[0][0]; // dEpsilon / dvx Di[0][1]=fJacobian[0][1]; // dEpsilon /dvy Di[0][2]=fJacobian[0][2]; // dEpsilon /dvz Di[1][0]=fJacobian[1][0]; // dZ0 /dvx Di[1][1]=fJacobian[1][1]; // dZ0 /dvy Di[1][2]=fJacobian[1][2]; // dZ0 /dvz if(fDebug) {std::cout<<" #$# Fast #$# Di "; Di.Print();} 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();} //propagate to Vertex TMatrixD Wi(COVi); Wi.InvertFast(&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_t chisq=0.; // calculate chisquare for(int i=0;i