// ****************************************************** // DecayTreeFitter Package // We thank the original author Wouter Hulsbergen // (BaBar, LHCb) for providing the sources. // http://arxiv.org/abs/physics/0503191v1 (2005) // Adaptation & Development for PANDA: Ralf Kliemt (2015) // ****************************************************** #include "FitParams.h" #include "InteractionPoint.h" #include "RecoTrack.h" //#include "Event/Particle.h" //#include "Event/VertexBase.h" #include //#include #include "TVector3.h" #include "TMath.h" #include "RhoVector3Err.h" #include "RhoCalculationTools.h" #include "SortTool.h" using namespace DecayTreeFitter; extern int vtxverbose ; ClassImp(InteractionPoint); DecayTreeFitter::InteractionPoint::InteractionPoint(RhoCandidate* cand, const Configuration& config) : ParticleBase("IP"), m_ipPosCov(3), m_ipPosCovInv(3), m_ipMomCov(4), m_ipMomCovInv(4), m_haspos(false), m_hasmom(false) { if(vtxverbose>=2) std::cout << "InteractionPoint: start"<=2) std::cout << "InteractionPoint: daughters done"<PosWCov(); if(vtx.Mag()>0){ if(vtxverbose>=3) std::cout << "InteractionPoint: Found a vertex in RhoCandidate"<=2) { std::cout << "InteractionPoint: without initial beam spot" <name() << std::endl ; } } DecayTreeFitter::InteractionPoint::InteractionPoint(const RhoVector3Err& ipvertex, RhoCandidate* cand, const Configuration& config) : ParticleBase("IP"), m_ipPosCov(3), m_ipPosCovInv(3), m_ipMomCov(4), m_ipMomCovInv(4), m_haspos(true), m_hasmom(false) { if(vtxverbose>=2) std::cout << "InteractionPoint: start"<=2) std::cout << "InteractionPoint: daughters done"<=2) std::cout << "InteractionPoint: inverting matrix"<=2) { std::cout << "InteractionPoint: initial beam spot = (" <=5){ std::cout<<"m_ipPosCov"; RhoCalculationTools::PrintMatrix(m_ipPosCov); } std::cout << "daughter: " << daughters().front()->name() << std::endl ; } } DecayTreeFitter::InteractionPoint::InteractionPoint(const RhoLorentzVectorErr& ipmom, RhoCandidate* cand, const Configuration& config) : ParticleBase("IP"), m_ipPosCov(3), m_ipPosCovInv(3), m_ipMomCov(4), m_ipMomCovInv(4), m_haspos(false), m_hasmom(true) { if(vtxverbose>=2) std::cout << "InteractionPoint: start"<=2) std::cout << "InteractionPoint: daughters done"<=2) std::cout << "InteractionPoint: inverting matrix"<PosWCov(); if(vtx.Mag()>0){ if(vtxverbose>=3) std::cout << "InteractionPoint: Found a vertex in RhoCandidate"<=2) { std::cout << "InteractionPoint: initial mom = (" <=5){ std::cout<<"m_ipMomCov"; RhoCalculationTools::PrintMatrix(m_ipMomCov); } std::cout << "daughter: " << daughters().front()->name() << std::endl ; } } DecayTreeFitter::InteractionPoint::InteractionPoint(const RhoLorentzVectorErr& ipmom, const RhoVector3Err& ipvertex, RhoCandidate* cand, const Configuration& config) : ParticleBase("IP"), m_ipPosCov(3), m_ipPosCovInv(3), m_ipMomCov(4), m_ipMomCovInv(4), m_haspos(true), m_hasmom(true) { if(vtxverbose>=2) std::cout << "InteractionPoint: start"<=2) std::cout << "InteractionPoint: daughters done"<=2) std::cout << "InteractionPoint: inverting matrix"<=2) std::cout << "InteractionPoint: inverting matrix"<=2) { std::cout << "InteractionPoint: initial beam spot = (" <=5){ std::cout<<"m_ipPosCov"; RhoCalculationTools::PrintMatrix(m_ipPosCov); std::cout<<"m_ipMomCov"; RhoCalculationTools::PrintMatrix(m_ipMomCov); } std::cout << "daughter: " << daughters().front()->name() << std::endl ; } } ErrCode DecayTreeFitter::InteractionPoint::initPar1(FitParams* fitparams) { ErrCode status ; if(vtxverbose>5){std::cout<<"InteractionPoint::initPar1: - start"<5){std::cout<<"InteractionPoint::initPar1: - calling daughter initPar1"<initPar1(fitparams) ; } // Step 2: initialize the vertex. // initialize our IP measurement if there int posindex = posIndex() ; if(m_haspos) { for(int row=0; row<3; row++) fitparams->par()(posindex+row) = m_ipPos(row) ; } else if( fitparams->par()(posindex+0)==0 && fitparams->par()(posindex+1)==0 && fitparams->par()(posindex+2)==0 ) { // if we are lucky, we had a 'resonant' daughter, and we are already done. if(vtxverbose>=3) std::cout << "InteractionPoint::initPar1: B"<=3) std::cout << "InteractionPoint::initPar1(): number of daughters for initializing vertex: " << name() << " " << alldaughters.size() << std::endl ; // select daughters that are either charged, or have an initialized vertex daucontainer vtxdaughters ; std::vector trkdaughters ; for(daucontainer::const_iterator it = alldaughters.begin() ; it != alldaughters.end() ; ++it) { if( (*it)->type()==ParticleBase::kRecoTrack ) { trkdaughters.push_back( static_cast(*it) ) ; } else if( (*it)->hasPosition() && fitparams->par((*it)->posIndex()+0)!=0 ) { vtxdaughters.push_back( *it ) ; } } if( trkdaughters.size() >=2 ) { if(vtxverbose>=3) std::cout << "InteractionPoint::initPar1(): B -a?"<2 ) std::sort(trkdaughters.begin(),trkdaughters.end(),compTrkTransverseMomentum) ; // now, just take the first two ... RecoTrack* dau1 = trkdaughters[0] ; RecoTrack* dau2 = trkdaughters[1] ; // get the poca of the two statevectors const DecayTreeFitter::State& state1 = dau1->state() ; const DecayTreeFitter::State& state2 = dau2->state() ; DecayTreeFitter::Line line1(state1.position(),state1.slopes()) ; DecayTreeFitter::Line line2(state2.position(),state2.slopes()) ; double mu1(0),mu2(0) ; DecayTreeFitter::closestPointParams(line1,line2,mu1,mu2) ; TVector3 p1 = line1.position(mu1) ; TVector3 p2 = line2.position(mu2) ; fitparams->par()(posindex+0) = 0.5*(p1.x()+p2.x()) ; fitparams->par()(posindex+1) = 0.5*(p1.y()+p2.y()) ; fitparams->par()(posindex+2) = 0.5*(p1.z()+p2.z()) ; dau1->setFlightLength( mu1 ) ; dau2->setFlightLength( mu2 ) ; } } if(vtxverbose>=3) std::cout << "InteractionPoint::initPar1(): big code chunk passed"<5){std::cout<<"InteractionPoint::initPar1: - calling daughter initPar2"<initPar2(fitparams) ; } return status ; } ErrCode DecayTreeFitter::InteractionPoint::initPar2(FitParams* /*fitparams*/) { if(vtxverbose>5){std::cout<<"InteractionPoint::initPar2: - "<cov()(posindex+row,posindex+col) = m_ipPosCov(row,col) ; } else fitpar->cov()(posindex+row,posindex+row) = 1.; //1cm default? } for(daucontainer::const_iterator it = daughters().begin() ; it != daughters().end() ; ++it) status |= (*it)->initCov(fitpar) ; return status ; } //ErrCode //DecayTreeFitter::InteractionPoint::projectIPConstraint(const FitParams* fitparams, //Projection& p) const //{ //int posindex = posIndex() ; //if(vtxverbose>6){std::cout<<"InteractionPoint::projectIPConstraint(): posindex="<par()(posindex+row) - m_ipPos(row); //p.H(row,posindex+row) = 1 ; ////if(m_hasposcov) //for(int col=0; col<3; ++col) //p.Vfast(row,col) = m_ipPosCov(row,col) ; //} //} //if(vtxverbose>6){ //std::cout<<"InteractionPoint::projectIPConstraint(): projection is:"<6){std::cout<<"InteractionPoint::projectIPConstraint(): daumomindex="<par()(momindex+row) - m_ipMom(row); p.H(row,momindex+row) = 1 ; if(m_hasmomcov) for(int col=0; col<4; ++col) p.Vfast(row,col) = m_ipMomCov(row,col) ; } } if(vtxverbose>6){ std::cout<<"InteractionPoint::projectBeamConstraint(): projection is:"<dim(),3) ; //projectIPConstraint(fitparams,pPos) ; //chisq+=pPos.chiSquare(); //} if(m_hasmom&&m_hasmomcov) { // no covariance, no chi2 contribution! Projection pMom(fitparams->dim(),4) ; projectBeamConstraint(fitparams,pMom) ; chisq+=pMom.chiSquare(); } return chisq ; } //double //DecayTreeFitter::InteractionPoint::chiSquare(const FitParams* fitparams) const //{ //double chisq=0.; //if(m_haspos&&m_hasposcov) //{ // no covariance, no chi2 contribution! //int posindex = posIndex() ; //TVectorD residualpos(3) ; //for(int row=0; row<3; ++row) //residualpos(row) = fitparams->par()(posindex+row) - m_ipPos(row) ; //chisq += m_ipPosCovInv.Similarity(residualpos); //} //if(m_hasmom&&m_hasmomcov) //{ // no covariance, no chi2 contribution! //int momindex = momIndex() ; //TVectorD residualmom(4) ; //for(int row=0; row<4; ++row) //residualmom(row) = m_ipMom(row) - fitparams->par()(momindex+row) ; //chisq += m_ipMomCovInv.Similarity(residualmom); //} //// add the daughters' chi2 //chisq += ParticleBase::chiSquareD(fitparams) ; //return chisq ; //} void DecayTreeFitter::InteractionPoint::addToConstraintList(constraintlist& alist, int depth) const { // first the daughters for(daucontainer::const_iterator it = daughters().begin() ; it != daughters().end() ; ++it) (*it)->addToConstraintList(alist,depth-1) ; // then the beamspot //if(m_haspos) alist.push_back(Constraint(this,Constraint::beamspot,depth,3)) ; if(m_hasmom) alist.push_back(Constraint(this,Constraint::beamenergy,depth,4)) ; } std::string DecayTreeFitter::InteractionPoint::parname(int thisindex) const { int id = thisindex ; // skip the lifetime parameter name if(id>=3) ++id ; return ParticleBase::parname(id) ; }