#include #include "PndChiVtxFitter.h" #include "RhoBase/TCandListIterator.h" #include "RhoBase/TRho.h" #include "RhoBase/TFactory.h" #include "TDecompLU.h" #include "TMatrixD.h" #include "TMatrixDSym.h" using namespace std; ClassImp(PndChiVtxFitter) TBuffer &operator>>(TBuffer &buf, PndChiVtxFitter *&obj) { obj = (PndChiVtxFitter *) buf.ReadObject(PndChiVtxFitter::Class()); return buf; } PndChiVtxFitter::PndChiVtxFitter( const TCandidate& b) : VAbsFitter( b ) { } PndChiVtxFitter::~PndChiVtxFitter() { //if(fHeadOfTree) delete fHeadOfTree; } void PndChiVtxFitter::Fit() { fDaughters.Cleanup(); FindAndAddGenericDaughters(fHeadOfTree); // fHeadOfTree->RemoveAssociations(); for (int i=0;iAddDaughterLinkSimple(&(fDaughters[i])); /* TCandidate *tc; TCandidate theHead=*fHeadOfTree; TCandListIterator iter=theHead.DaughterIterator(); fDaughters.Cleanup(); while (tc=iter.Next()) { fDaughters.Add(*tc); } */ int nd=fDaughters.GetLength(); NumCon=0; fdgf =0; NumCon = NumCon +2*nd; SetMatrices(); ResetMatrices(); ReadMatrix(); // Solve(); // FindVertex(); Compute(); SetOutput(); } void PndChiVtxFitter::FindAndAddGenericDaughters(TCandidate *head) { TCandidate *tc; TCandListIterator iter=head->DaughterIterator(); while ((tc=iter.Next())) { if (!tc->IsComposite()) fDaughters.Add(*tc); else FindAndAddGenericDaughters(tc); } } void PndChiVtxFitter::SetMatrices(){ int nd=fDaughters.GetLength(); fNvar=7; fNpart=nd; fNpar =nd*fNvar; fNcon=NumCon; // cout << fNcon << "Num " << endl; fNc=0; fNiter=0; al0.ResizeTo(7*nd,1); V_al0.ResizeTo(fNpar,fNpar); // mPull.ResizeTo(7*nd,1); // covC.ResizeTo(7,7); vtxPos.ResizeTo(3,1); vtxMom.ResizeTo(3,1); xxCov.ResizeTo(3,3); xpCov.ResizeTo(3,3); ppCov.ResizeTo(3,3); } void PndChiVtxFitter::ResetMatrices(){ al0.Zero(); V_al0.Zero(); vtxMom.Zero(); vtxPos.Zero(); xxCov.Zero(); xpCov.Zero(); ppCov.Zero(); } void PndChiVtxFitter::Compute() { TVector3 startVtx; GetStartVtx(&startVtx); TMatrixD last(3,1); last[0][0]=startVtx.X();last[1][0]=startVtx.Y();last[2][0]=startVtx.Z(); cout<<"Initial vertex Position is"<SetP7(vtx,sum); //fHeadOfTree->SetP4(sum); cout << "Energy" << vtxEnergy<< endl; cout << "vtxMom" << sum.X() <<" .." << sum.Y() <<" .." << sum.Z(); cout << "vtxPos" << vtx.X() <<" .." << vtx.Y() <<" .." << vtx.Z(); // fHeadOfTree->SetPos(vtx); TVector3 vtxP(vtxMom[0][0],vtxMom[1][0],vtxMom[2][0]); double mass(vtxEnergy*vtxEnergy-vtxP.Mag2()); mass = ( mass > 0 ) ? sqrt(mass):0; // TLorentzVector sum1; // sum1.SetXYZM(vtxMom[0][0],vtxMom[1][0],vtxMom[2][0],mass); // fHeadOfTree->SetP4(sum1); cout << " mass" << mass << endl; } bool PndChiVtxFitter::FindVertex() { int nd=fDaughters.GetLength(); TMatrixD x0(3*nd,1); TMatrixD p0(3*nd,1); TMatrixD xxw(3*nd,3*nd); TMatrixD xpw(3*nd,3*nd); TMatrixD ppw(3*nd,3*nd); TMatrixD ppwnew(3,3); // TMatrixD xxCov(3,3); // TMatrixD xpCov(3,3); // TMatrixD ppCov(3,3); TMatrixD Tx(3,1); TMatrixD OmegaI(3,3); TMatrixD tempDI(3,3); TMatrixD x0I(3,1); //Double_t problems=0; double fChi2=1e7; cout << "niter" << niter << endl; if (niter==0){ for (int k=0;kSetXYZ(0.,0.,0.); TCandidate a=fDaughters[0]; TCandidate b=fDaughters[1]; // SVtx->SetXYZ( 0.5, 0.5, 1.0 ); SVtx->SetXYZ( 0.0, 0.0, 0.0 ); //Float_t bField = TRho::Instance()->GetMagnetField(); Double_t bField=2.0; // Position vectors TVector3 position1 = a.GetPosition(); TVector3 position2 = b.GetPosition(); // Momentum vectors TVector3 ap3 = a.P3(); Double_t pPerp1 = ap3.Perp(); TVector3 d1 = ap3; d1.SetZ(0); d1*=1.0/pPerp1; TVector3 bp3 = b.P3(); Double_t pPerp2 = bp3.Perp(); TVector3 d2 = bp3; d2.SetZ(0); d2*=1.0/pPerp2; TVector3 dB(0,0,1.0); // Radius and center Double_t rho1 = pPerp1/(0.0029979246*bField); // Radius in cm TVector3 r1=d1.Cross(dB); r1 *= -a.Charge()*rho1; TVector3 center1 = position1 - r1; center1.SetZ(0); Double_t rho2 = pPerp2/(0.0029979246*bField); // Radius in cm TVector3 r2=d2.Cross(dB); r2 *= -b.Charge()*rho2; TVector3 center2 = position2 - r2; center2.SetZ(0); // distance and angle of the axis between the two centers TVector3 ab = center2 - center1; Double_t dab = ab.Perp(); Double_t cosTheAB = ab.X()/dab; Double_t sinTheAB = ab.Y()/dab; // x value of intersect at reduced system Double_t x = dab/2 + ( rho1*rho1 - rho2*rho2 )/(2*dab); // y*y value of intersect at reduced system for helix A Double_t y2 = (rho1+x)*(rho1-x); // both circles do not intersect (only one solution) Int_t nSolMax=1; Double_t y=0; if (y2 > 0) { nSolMax=2; y = sqrt(y2); } // now we compute the solution(s) TVector3 newapos[2]; TVector3 newbpos[2]; Int_t best=0; double fActualDoca=1.E8; // fActualDoca=0.99999999; for (Int_t ns=0; ns0 ? 1.0 : -1.0; Double_t aangle=adir * r1.Angle(rs1); // intersection point Double_t newaz=position1.Z() + rho1*aangle/pPerp1 * ap3.Z(); newapos[ns].SetX( center1.X() + rs1.X() ); newapos[ns].SetY( center1.Y() + rs1.Y() ); newapos[ns].SetZ( newaz ); // same for b Double_t bdir=(rs2-r2).Dot(bp3)>0 ? 1.0 : -1.0; Double_t bangle=bdir * r2.Angle(rs2); Double_t newbz=position2.Z() + rho2*bangle/pPerp2 * bp3.Z(); newbpos[ns].SetX( center2.X() + rs2.X()); // ==newapos[ns].X() newbpos[ns].SetY( center2.Y() + rs2.Y()); // ==newapos[ns].Y() newbpos[ns].SetZ( newbz ); Double_t delta = (newapos[ns]-newbpos[ns]).Mag(); // take the solution of minimal deltaZ if ( delta < fActualDoca ) { best=ns; fActualDoca = delta; } } TVector3 fVertex=0.5*(newapos[best]+newbpos[best]); SVtx->SetXYZ( fVertex.X(), fVertex.Y(), fVertex.Z()); }