96 std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
97 constexpr int topoN = 2;
98 std::array<xAOD::VertexContainer*, topoN> Vtxwritehandles;
99 std::array<xAOD::VertexAuxContainer*, topoN> Vtxwritehandlesaux;
102 for(
int i =0; i<topoN;i++){
105 Vtxwritehandles[i]->setStore(Vtxwritehandlesaux[i]);
118 if (pvContainer->
size()==0){
120 return StatusCode::RECOVERABLE;
122 primaryVertex = (*pvContainer)[0];
139 refPvContainer->setStore(refPvAuxContainer);
149 return StatusCode::FAILURE;
156 SG::AuxElement::Decorator<VertexLinkVector> CascadeLinksDecor(
"CascadeVertexLinks");
157 SG::AuxElement::Decorator<MuonsLinkVector> MuonsLinksDecor(
"MuonsLinks");
158 SG::AuxElement::Decorator<VertexLinkVector> DxLinksDecor(
"DxVertexLinks");
159 SG::AuxElement::Decorator<float> chi2_decor(
"ChiSquared");
160 SG::AuxElement::Decorator<float> ndof_decor(
"NumberDoF");
161 SG::AuxElement::Decorator<float> Pt_decor(
"Pt");
162 SG::AuxElement::Decorator<float> PtErr_decor(
"PtErr");
163 SG::AuxElement::Decorator<float> Mass_svdecor(
"Dx_mass");
164 SG::AuxElement::Decorator<float> MassErr_svdecor(
"Dx_massErr");
165 SG::AuxElement::Decorator<float> Pt_svdecor(
"Dx_Pt");
166 SG::AuxElement::Decorator<float> PtErr_svdecor(
"Dx_PtErr");
167 SG::AuxElement::Decorator<float> Lxy_svdecor(
"Dx_Lxy");
168 SG::AuxElement::Decorator<float> LxyErr_svdecor(
"Dx_LxyErr");
169 SG::AuxElement::Decorator<float> Tau_svdecor(
"Dx_Tau");
170 SG::AuxElement::Decorator<float> TauErr_svdecor(
"Dx_TauErr");
171 SG::AuxElement::Decorator<float> Dx_chi2_svdecor(
"Dx_chi2");
172 SG::AuxElement::Decorator<float> Dx_ndof_svdecor(
"Dx_ndof");
179 SG::AuxElement::Decorator<float> massKX1_svdecor(
"KX_mass");
180 SG::AuxElement::Decorator<float> massKX1X2_svdecor(
"KXpi_mass");
181 SG::AuxElement::Decorator<float> RapidityKX1X2_svdecor(
"KXpi_Rapidity");
183 SG::AuxElement::Decorator<float> MuMass_decor(
"Mu_mass");
184 SG::AuxElement::Decorator<float> MuPt_decor(
"Mu_pt");
185 SG::AuxElement::Decorator<float> MuEta_decor(
"Mu_eta");
186 SG::AuxElement::Decorator<float> MuChi2_decor(
"Mu_chi2");
187 SG::AuxElement::Decorator<float> MunDoF_decor(
"Mu_nDoF");
189 SG::AuxElement::Decorator<float> MuChi2B_decor(
"Mu_chi2_B");
190 SG::AuxElement::Decorator<float> MunDoFB_decor(
"Mu_nDoF_B");
192 SG::AuxElement::Decorator<float> ChargeK_decor(
"K_charge");
193 SG::AuxElement::Decorator<float> ChargeX1_decor(
"X_charge");
194 SG::AuxElement::Decorator<float> ChargeX2_decor(
"Pi_charge");
195 SG::AuxElement::Decorator<float> ChargeMu_decor(
"Mu_charge");
197 ATH_MSG_DEBUG(
"cascadeinfoContainer size " << cascadeinfoContainer.size());
232 const std::vector<xAOD::Vertex*> &cascadeVertices =
x->vertices();
234 if(cascadeVertices.size()!=topoN)
ATH_MSG_ERROR(
"Incorrect number of vertices");
235 if(cascadeVertices[0] ==
nullptr || cascadeVertices[1] ==
nullptr)
ATH_MSG_ERROR(
"Error null vertex");
237 for(
int i =0;i<topoN;i++) Vtxwritehandles[i]->push_back(cascadeVertices[i]);
239 x->setSVOwnership(
false);
240 const auto mainVertex = cascadeVertices[1];
242 const std::vector< std::vector<TLorentzVector> > &moms =
x->getParticleMoms();
246 std::vector<const xAOD::Vertex*> verticestoLink;
247 verticestoLink.push_back(cascadeVertices[0]);
248 if(Vtxwritehandles[1] ==
nullptr)
ATH_MSG_ERROR(
"Vtxwritehandles[1] is null");
254 typedef std::vector<const xAOD::Muon*> MuonBag;
255 MuonBag selectedMuons; selectedMuons.clear();
258 const xAOD::TrackParticle* muonTrk = mu->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle );
259 if (muonTrk == cascadeVertices[1]->trackParticle(0)) selectedMuons.push_back(mu);
269 auto muItr = selectedMuons.begin();
270 for(; muItr != selectedMuons.end(); muItr++) {
277 if( !muLink.
isValid() )
continue;
280 preMuLinks.push_back( muLink );
285 MuonsLinksDecor(*cascadeVertices[1]) = preMuLinks;
292 ATH_MSG_DEBUG(
"1 pt D_(s)+/Lambda_c+ tracks " << cascadeVertices[1]->trackParticle(0)->pt()<<
", "
293 << cascadeVertices[0]->trackParticle(0)->pt()<<
", "<< cascadeVertices[0]->trackParticle(1)->pt()<<
", "
294 << cascadeVertices[0]->trackParticle(2)->pt());
298 std::vector<const xAOD::Vertex*> dxVerticestoLink;
299 if (dxVertex) dxVerticestoLink.push_back(dxVertex);
302 ATH_MSG_ERROR(
"Error decorating with D_(s)+/Lambda_c+ vertices");
313 std::vector<double> massesMu;
315 std::vector<double> massesDx;
324 std::vector<double> Masses;
345 PtErr_decor(*mainVertex) =
m_CascadeTools->pTError(moms[1],
x->getCovariance()[1]);
347 chi2_decor(*mainVertex) =
x->fitChi2();
348 ndof_decor(*mainVertex) =
x->nDoF();
349 Dx_chi2_svdecor(*mainVertex) = cascadeVertices[0]->chiSquared();
350 Dx_ndof_svdecor(*mainVertex) = cascadeVertices[0]->numberDoF();
353 float muM = 0., mupt = 0., mueta = 0.;
354 if (selectedMuons.size()==1) {
355 TLorentzVector p4_mu1;
356 p4_mu1.SetPtEtaPhiM(selectedMuons.at(0)->pt(),
357 selectedMuons.at(0)->eta(),
361 mueta = p4_mu1.Eta();
363 MuMass_decor(*mainVertex) = muM;
364 MuPt_decor(*mainVertex) = mupt;
365 MuEta_decor(*mainVertex) = mueta;
366 ChargeMu_decor(*mainVertex) = selectedMuons.at(0)->charge();
367 MuChi2_decor(*mainVertex) = cascadeVertices[1]->trackParticle(0)->chiSquared();
368 MunDoF_decor(*mainVertex) = cascadeVertices[1]->trackParticle(0)->numberDoF();
371 std::vector< Trk::VxTrackAtVertex > trkAtB = cascadeVertices[1]->vxTrackAtVertex();
372 MuChi2B_decor(*mainVertex) = trkAtB.at(0).trackQuality().chiSquared();
373 MunDoFB_decor(*mainVertex) = trkAtB.at(0).trackQuality().numberDoF();
378 float massKX1X2 = 0.;
379 float RapidityKX1X2 = 0.;
381 TLorentzVector p4_h1, p4_h2, p4_h3;
407 massKX1 = (p4_h1 + p4_h2).M();
408 massKX1X2 = (p4_h1 + p4_h2 + p4_h3).M();
409 RapidityKX1X2 = (p4_h1 + p4_h2 + p4_h3).Rapidity();
411 massKX1_svdecor(*mainVertex) = massKX1;
412 massKX1X2_svdecor(*mainVertex) = massKX1X2;
413 RapidityKX1X2_svdecor(*mainVertex) = RapidityKX1X2;
422 Mass_svdecor(*mainVertex) =
m_CascadeTools->invariantMass(moms[0]);
423 MassErr_svdecor(*mainVertex) =
m_CascadeTools->invariantMassError(moms[0],
x->getCovariance()[0]);
425 PtErr_svdecor(*mainVertex) =
m_CascadeTools->pTError(moms[0],
x->getCovariance()[0]);
426 Lxy_svdecor(*mainVertex) =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
427 LxyErr_svdecor(*mainVertex) =
m_CascadeTools->lxyError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
428 Tau_svdecor(*mainVertex) =
m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1]);
429 TauErr_svdecor(*mainVertex) =
m_CascadeTools->tauError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
433 <<
" chi2_1 " <<
m_V0Tools->chisq(cascadeVertices[0])
434 <<
" chi2_2 " <<
m_V0Tools->chisq(cascadeVertices[1])
438 <<
" error " <<
m_V0Tools->invariantMassError(cascadeVertices[0],massesDx)
439 <<
" mass_J " <<
m_V0Tools->invariantMass(cascadeVertices[1],massesMu)
440 <<
" error " <<
m_V0Tools->invariantMassError(cascadeVertices[1],massesMu));
444 double Mass_B_err =
m_CascadeTools->invariantMassError(moms[1],
x->getCovariance()[1]);
445 double Mass_D_err =
m_CascadeTools->invariantMassError(moms[0],
x->getCovariance()[0]);
447 ATH_MSG_DEBUG(
"Mass_B_err " << Mass_B_err <<
" Mass_D_err " << Mass_D_err);
448 double mprob_B =
m_CascadeTools->massProbability(mass_b,Mass_B,Mass_B_err);
449 double mprob_D =
m_CascadeTools->massProbability(mass_d,Mass_D,Mass_D_err);
450 ATH_MSG_DEBUG(
"mprob_B " << mprob_B <<
" mprob_D " << mprob_D);
453 <<
" Mass_d " <<
m_CascadeTools->invariantMass(moms[0],massesDx));
455 <<
" Mass_d_err " <<
m_CascadeTools->invariantMassError(moms[0],
x->getCovariance()[0],massesDx));
458 <<
" pt_dp " <<
m_V0Tools->pT(cascadeVertices[0]));
460 <<
" ptErr_d " <<
m_CascadeTools->pTError(moms[0],
x->getCovariance()[0])
461 <<
" ptErr_dp " <<
m_V0Tools->pTError(cascadeVertices[0]));
465 <<
" lxyErr_d " <<
m_CascadeTools->lxyError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
466 <<
" lxyErr_dp " <<
m_V0Tools->lxyError(cascadeVertices[0],cascadeVertices[1]));
468 <<
" tau_dp " <<
m_V0Tools->tau(cascadeVertices[0],cascadeVertices[1],massesDx));
470 <<
" tau_d " <<
m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1])
471 <<
" tau_D " <<
m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1],mass_d));
473 <<
" tauErr_d " <<
m_CascadeTools->tauError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
474 <<
" tauErr_dp " <<
m_V0Tools->tauError(cascadeVertices[0],cascadeVertices[1],massesDx));
476 <<
" TauErr_d " <<
m_CascadeTools->tauError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1],mass_d)
477 <<
" TauErr_dp " <<
m_V0Tools->tauError(cascadeVertices[0],cascadeVertices[1],massesDx,mass_d));
479 ATH_MSG_DEBUG(
"CascadeTools main vert wrt PV " <<
" CascadeTools SV " <<
" V0Tools SV");
481 <<
", " <<
m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1])
482 <<
", " <<
m_V0Tools->a0z(cascadeVertices[0],cascadeVertices[1]));
484 <<
", " <<
m_CascadeTools->a0zError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
485 <<
", " <<
m_V0Tools->a0zError(cascadeVertices[0],cascadeVertices[1]));
487 <<
", " <<
m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1])
488 <<
", " <<
m_V0Tools->a0xy(cascadeVertices[0],cascadeVertices[1]));
490 <<
", " <<
m_CascadeTools->a0xyError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
491 <<
", " <<
m_V0Tools->a0xyError(cascadeVertices[0],cascadeVertices[1]));
493 <<
", " <<
m_CascadeTools->a0(moms[0],cascadeVertices[0],cascadeVertices[1])
494 <<
", " <<
m_V0Tools->a0(cascadeVertices[0],cascadeVertices[1]));
496 <<
", " <<
m_CascadeTools->a0Error(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
497 <<
", " <<
m_V0Tools->a0Error(cascadeVertices[0],cascadeVertices[1]));
500 ATH_MSG_DEBUG(
"X0 " << primaryVertex->
x() <<
" Y0 " << primaryVertex->
y() <<
" Z0 " << primaryVertex->
z());
503 ATH_MSG_DEBUG(
"Rxy0 wrt PV " <<
m_V0Tools->rxy(cascadeVertices[0],primaryVertex) <<
" RxyErr0 wrt PV " <<
m_V0Tools->rxyError(cascadeVertices[0],primaryVertex));
504 ATH_MSG_DEBUG(
"Rxy1 wrt PV " <<
m_V0Tools->rxy(cascadeVertices[1],primaryVertex) <<
" RxyErr1 wrt PV " <<
m_V0Tools->rxyError(cascadeVertices[1],primaryVertex));
505 ATH_MSG_DEBUG(
"number of covariance matrices " << (
x->getCovariance()).size());
511 for (
auto x : cascadeinfoContainer)
delete x;
513 return StatusCode::SUCCESS;
584 assert(cascadeinfoContainer!=
nullptr);
588 ATH_CHECK(evtStore()->retrieve(trackContainer ,
"InDetTrackParticles" ));
595 std::vector<const xAOD::TrackParticle*> tracksMu;
596 std::vector<const xAOD::TrackParticle*> tracksDx;
597 std::vector<double> massesMu;
599 std::vector<double> massesDx;
603 std::vector<double> massesDm;
607 std::vector<double> Masses;
619 return StatusCode::SUCCESS;;
626 typedef std::vector<const xAOD::Muon*> MuonBag;
630 MuonBag theMuonsAfterSelection;
631 for (
auto mu : *importedMuonCollection) {
633 const xAOD::TrackParticle* muonTrk = mu->trackParticle(xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle);
634 if ( !muonTrk)
continue;
637 if (
m_mcpCuts && !mu->passesIDCuts())
continue;
638 if (
m_combOnly && mu->muonType() != xAOD::Muon::MuonType::Combined )
continue;
639 if ( mu->muonType() == xAOD::Muon::MuonType::SiliconAssociatedForwardMuon && !
m_useCombMeasurement)
continue;
641 theMuonsAfterSelection.push_back(mu);
643 if (theMuonsAfterSelection.size() == 0)
return StatusCode::SUCCESS;;
644 ATH_MSG_DEBUG(
"Number of muons after selection: " << theMuonsAfterSelection.size());
649 std::vector<const xAOD::Vertex*> selectedDxCandidates;
652 for(
auto vxcItr : *dxContainer){
657 SG::AuxElement::Accessor<Char_t> flagAcc1(
"passed_Ds");
658 if(flagAcc1.isAvailable(*vtx)){
659 if(!flagAcc1(*vtx))
continue;
664 SG::AuxElement::Accessor<Char_t> flagAcc1(
"passed_Dp");
665 SG::AuxElement::Accessor<Char_t> flagAcc2(
"passed_Dm");
668 if(flagAcc1.isAvailable(*vtx)){
669 if(!flagAcc1(*vtx)) isDp =
false;
671 if(flagAcc2.isAvailable(*vtx)){
672 if(!flagAcc2(*vtx)) isDm =
false;
674 if(!(isDp||isDm))
continue;
679 ATH_MSG_DEBUG(
" Original Dx/Lambda_c candidate rejected by the track's cut level - loose ");
683 ATH_MSG_DEBUG(
" Original Dx/Lambda_c candidate rejected by the track's cut level - loose ");
687 ATH_MSG_DEBUG(
" Original Dx/Lambda_c candidate rejected by the track's cut level - loose ");
692 if( std::abs( vxcItr->trackParticle(0)->charge()+vxcItr->trackParticle(1)->charge()+vxcItr->trackParticle(2)->charge() ) != 1 ){
693 ATH_MSG_DEBUG(
" Original Dx/Lambda_c candidate rejected by the charge requirement: "
694 << vxcItr->trackParticle(0)->charge() <<
", " << vxcItr->trackParticle(1)->charge() <<
", " << vxcItr->trackParticle(2)->charge() );
700 if( (std::abs(
m_Dx_pid) == 411 || std::abs(
m_Dx_pid) == 4122) && vxcItr->trackParticle(2)->charge()<0)
701 mass_D =
m_V0Tools->invariantMass(vxcItr,massesDm);
703 mass_D =
m_V0Tools->invariantMass(vxcItr,massesDx);
706 ATH_MSG_DEBUG(
" Original D_(s)/Lambda_c candidate rejected by the mass cut: mass = "
713 TLorentzVector p4Kp_in, p4Km_in;
714 p4Kp_in.SetPtEtaPhiM( vxcItr->trackParticle(0)->pt(),
715 vxcItr->trackParticle(0)->eta(),
717 p4Km_in.SetPtEtaPhiM( vxcItr->trackParticle(1)->pt(),
718 vxcItr->trackParticle(1)->eta(),
720 double mass_phi = (p4Kp_in + p4Km_in).M();
722 if(mass_phi > 1600) {
723 ATH_MSG_DEBUG(
" Original phi candidate rejected by the mass cut: mass = " << mass_phi );
731 if (vxcItr->trackParticle(2)->pt() < 2400)
continue;
735 if(std::abs(
m_Dx_pid)==411 && selectedDxCandidates.size()>0) {
737 for(
auto dxItr : selectedDxCandidates){
738 if(vxcItr->trackParticle(2)->charge()>0) {
739 if ( vxcItr->trackParticle(2) == dxItr->trackParticle(0) && vxcItr->trackParticle(0) == dxItr->trackParticle(2)
740 && vxcItr->trackParticle(1) == dxItr->trackParticle(1) ) Dpmcopy =
true;
742 if ( vxcItr->trackParticle(2) == dxItr->trackParticle(1) && vxcItr->trackParticle(1) == dxItr->trackParticle(2)
743 && vxcItr->trackParticle(0) == dxItr->trackParticle(0) ) Dpmcopy =
true;
746 if (Dpmcopy)
continue;
749 selectedDxCandidates.push_back(vxcItr);
751 if(selectedDxCandidates.size()<1)
return StatusCode::SUCCESS;
757 for(
auto muItr : theMuonsAfterSelection){
760 auto TrkMuon = muItr->trackParticle( xAOD::Muon::TrackParticleType::InnerDetectorTrackParticle );
761 tracksMu.push_back(TrkMuon);
762 if (tracksMu.size() != 1 || massesMu.size() != 1 ) {
767 for(
auto dxItr : selectedDxCandidates){
769 if(std::find(tracksMu.cbegin(), tracksMu.cend(), dxItr->trackParticle(0)) != tracksMu.cend())
continue;
770 if(std::find(tracksMu.cbegin(), tracksMu.cend(), dxItr->trackParticle(1)) != tracksMu.cend())
continue;
771 if(std::find(tracksMu.cbegin(), tracksMu.cend(), dxItr->trackParticle(2)) != tracksMu.cend())
continue;
773 size_t dxTrkNum = dxItr->nTrackParticles();
775 for(
unsigned int it=0; it<dxTrkNum; it++) tracksDx.push_back(dxItr->trackParticle(it));
776 if (tracksDx.size() != 3 || massesDx.size() != 3 ) {
780 if(std::find(tracksDx.cbegin(), tracksDx.cend(), TrkMuon) != tracksDx.cend())
continue;
782 ATH_MSG_DEBUG(
"Using tracks" << tracksMu[0] <<
", " << tracksDx[0] <<
", " << tracksDx[1] <<
", " << tracksDx[2]);
785 std::unique_ptr<Trk::IVKalState> state (
m_iVertexFitter->makeState(ctx));
791 std::vector<Trk::VertexID> vrtList;
795 if((std::abs(
m_Dx_pid)==411 || std::abs(
m_Dx_pid)==4122 ) && dxItr->trackParticle(2)->charge()<0)
800 if((std::abs(
m_Dx_pid)==411 || std::abs(
m_Dx_pid)==4122 ) && dxItr->trackParticle(2)->charge()<0)
805 vrtList.push_back(vID);
813 std::unique_ptr<Trk::VxCascadeInfo> result(
m_iVertexFitter->fitCascade(*state));
818 ATH_MSG_DEBUG(
"storing tracks " << ((result->vertices())[0] )->trackParticle(0) <<
", "
819 << ((result->vertices())[0])->trackParticle(1) <<
", "
820 << ((result->vertices())[0])->trackParticle(2) <<
", "
821 << ((result->vertices())[1])->trackParticle(0));
824 result->setSVOwnership(
true);
827 double bChi2DOF = result->fitChi2()/result->nDoF();
831 const std::vector<xAOD::Vertex*> &cascadeVertices = result->vertices();
832 const std::vector< std::vector<TLorentzVector> > &moms = result->getParticleMoms();
842 if (pvContainer->
size()==0){
844 return StatusCode::RECOVERABLE;
846 primaryVertex = (*pvContainer)[0];
851 TLorentzVector p4Kp_in, p4Km_in;
852 p4Kp_in.SetPtEtaPhiM( cascadeVertices[0]->trackParticle(0)->pt(),
853 cascadeVertices[0]->trackParticle(0)->
eta(),
855 p4Km_in.SetPtEtaPhiM( cascadeVertices[0]->trackParticle(1)->pt(),
856 cascadeVertices[0]->trackParticle(1)->
eta(),
858 double mass_phi = (p4Kp_in + p4Km_in).M();
860 if(mass_phi > 1100) {
861 ATH_MSG_DEBUG(
" Original phi candidate rejected by the mass cut: mass = " << mass_phi );
869 if (
m_CascadeTools->lxy(moms[1],cascadeVertices[1],primaryVertex) > 0.09){
871 if (
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]) > 0){
872 if (std::abs(
m_Dx_pid)!=411) cascadeinfoContainer->push_back(result.release());
873 else if (
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]) > 0.09){
874 cascadeinfoContainer->push_back(result.release());
891 ATH_MSG_DEBUG(
"cascadeinfoContainer size " << cascadeinfoContainer->size());
893 return StatusCode::SUCCESS;