60 std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
61 constexpr int topoN = 2;
62 std::array<xAOD::VertexContainer*, topoN> Vtxwritehandles;
63 std::array<xAOD::VertexAuxContainer*, topoN> Vtxwritehandlesaux;
66 for(
int i =0; i<topoN;i++){
69 Vtxwritehandles[i]->setStore(Vtxwritehandlesaux[i]);
82 if (pvContainer->
size()==0){
84 return StatusCode::RECOVERABLE;
86 primaryVertex = (*pvContainer)[0];
103 refPvContainer->setStore(refPvAuxContainer);
113 return StatusCode::FAILURE;
119 SG::AuxElement::Decorator<VertexLinkVector> CascadeLinksDecor(
"CascadeVertexLinks");
120 SG::AuxElement::Decorator<VertexLinkVector> MuPiLinksDecor(
"MuPiVertexLinks");
121 SG::AuxElement::Decorator<VertexLinkVector> D0LinksDecor(
"D0VertexLinks");
122 SG::AuxElement::Decorator<float> chi2_decor(
"ChiSquared");
123 SG::AuxElement::Decorator<float> ndof_decor(
"NumberDoF");
124 SG::AuxElement::Decorator<float> Pt_decor(
"Pt");
125 SG::AuxElement::Decorator<float> PtErr_decor(
"PtErr");
126 SG::AuxElement::Decorator<float> Mass_svdecor(
"D0_mass");
127 SG::AuxElement::Decorator<float> MassErr_svdecor(
"D0_massErr");
128 SG::AuxElement::Decorator<float> Pt_svdecor(
"D0_Pt");
129 SG::AuxElement::Decorator<float> PtErr_svdecor(
"D0_PtErr");
130 SG::AuxElement::Decorator<float> Lxy_svdecor(
"D0_Lxy");
131 SG::AuxElement::Decorator<float> LxyErr_svdecor(
"D0_LxyErr");
132 SG::AuxElement::Decorator<float> Tau_svdecor(
"D0_Tau");
133 SG::AuxElement::Decorator<float> TauErr_svdecor(
"D0_TauErr");
135 SG::AuxElement::Decorator<float> massMuPi_decor(
"MuPi_mass");
136 SG::AuxElement::Decorator<float> MassKpi_svdecor(
"Kpi_mass");
137 SG::AuxElement::Decorator<float> MassMuPiAft_decor(
"MuPiAft_mass");
138 SG::AuxElement::Decorator<float> MassPiD0_decor(
"PiD0_mass");
139 SG::AuxElement::Decorator<float> MassMuPiPiK_decor(
"MuPiPiK_mass");
141 SG::AuxElement::Decorator<float> ChargePi_decor(
"Pi_charge");
142 SG::AuxElement::Decorator<float> ChargeMu_decor(
"Mu_charge");
143 SG::AuxElement::Decorator<float> ChargeK_decor(
"K_charge");
144 SG::AuxElement::Decorator<float> ChargePi_s_decor(
"Pi_s_charge");
145 SG::AuxElement::Decorator<float> Chi2Mu_decor(
"Mu_chi2");
146 SG::AuxElement::Decorator<float> nDoFMu_decor(
"Mu_nDoF");
148 SG::AuxElement::Decorator<float> MuChi2B_decor(
"Mu_chi2_B");
149 SG::AuxElement::Decorator<float> MunDoFB_decor(
"Mu_nDoF_B");
182 const std::vector<xAOD::Vertex*> &cascadeVertices =
x->vertices();
183 if(cascadeVertices.size()!=topoN)
185 if(cascadeVertices[0] ==
nullptr || cascadeVertices[1] ==
nullptr)
ATH_MSG_ERROR(
"Error null vertex");
187 for(
int i =0;i<topoN;i++) Vtxwritehandles[i]->push_back(cascadeVertices[i]);
189 x->setSVOwnership(
false);
190 const auto mainVertex = cascadeVertices[1];
191 const std::vector< std::vector<TLorentzVector> > &moms =
x->getParticleMoms();
194 std::vector<const xAOD::Vertex*> verticestoLink;
195 verticestoLink.push_back(cascadeVertices[0]);
196 if(Vtxwritehandles[1] ==
nullptr)
ATH_MSG_ERROR(
"Vtxwritehandles[1] is null");
202 ATH_MSG_DEBUG(
"1 pt mu+pi_soft tracks " << cascadeVertices[1]->trackParticle(0)->pt() <<
", " << cascadeVertices[1]->trackParticle(1)->pt());
207 ATH_MSG_DEBUG(
"1 pt D0 tracks " << cascadeVertices[0]->trackParticle(0)->pt() <<
", " << cascadeVertices[0]->trackParticle(1)->pt());
211 std::vector<const xAOD::Vertex*> MuPiVerticestoLink;
212 if (MuPiVertex) MuPiVerticestoLink.push_back(MuPiVertex);
217 std::vector<const xAOD::Vertex*> d0VerticestoLink;
218 if (d0Vertex) d0VerticestoLink.push_back(d0Vertex);
230 std::vector<double> massesMuPi;
233 std::vector<double> massesD0;
241 std::vector<double> Masses;
263 PtErr_decor(*mainVertex) =
m_CascadeTools->pTError(moms[1],
x->getCovariance()[1]);
265 chi2_decor(*mainVertex) =
x->fitChi2();
266 ndof_decor(*mainVertex) =
x->nDoF();
267 Chi2Mu_decor(*mainVertex) = cascadeVertices[1]->trackParticle(0)->chiSquared();
268 nDoFMu_decor(*mainVertex) = cascadeVertices[1]->trackParticle(0)->numberDoF();
271 std::vector< Trk::VxTrackAtVertex > trkAtB = cascadeVertices[1]->vxTrackAtVertex();
272 MuChi2B_decor(*mainVertex) = trkAtB.at(0).trackQuality().chiSquared();
273 MunDoFB_decor(*mainVertex) = trkAtB.at(0).trackQuality().numberDoF();
277 TLorentzVector p4_mu1, p4_pi_s;
284 massMuPi = (p4_mu1 + p4_pi_s).M();
288 massMuPi_decor(*mainVertex) = massMuPi;
292 TLorentzVector p4_ka, p4_pi;
315 MassMuPiAft_decor(*mainVertex) = (moms[1][0] + moms[1][1]).M();
316 MassPiD0_decor(*mainVertex) = (moms[1][1] + moms[0][0] + moms[0][1]).M();
317 MassKpi_svdecor(*mainVertex) = (moms[0][0] + moms[0][1]).M();
318 MassMuPiPiK_decor(*mainVertex) =
m_CascadeTools->invariantMass(moms[1]);
324 Mass_svdecor(*mainVertex) =
m_CascadeTools->invariantMass(moms[0]);
325 MassErr_svdecor(*mainVertex) =
m_CascadeTools->invariantMassError(moms[0],
x->getCovariance()[0]);
327 PtErr_svdecor(*mainVertex) =
m_CascadeTools->pTError(moms[0],
x->getCovariance()[0]);
328 Lxy_svdecor(*mainVertex) =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
329 LxyErr_svdecor(*mainVertex) =
m_CascadeTools->lxyError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
330 Tau_svdecor(*mainVertex) =
m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1]);
331 TauErr_svdecor(*mainVertex) =
m_CascadeTools->tauError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
336 <<
" chi2_1 " <<
m_V0Tools->chisq(cascadeVertices[0])
337 <<
" chi2_2 " <<
m_V0Tools->chisq(cascadeVertices[1])
341 <<
" error " <<
m_V0Tools->invariantMassError(cascadeVertices[0],massesD0)
342 <<
" mass_J " <<
m_V0Tools->invariantMass(cascadeVertices[1],massesMuPi)
343 <<
" error " <<
m_V0Tools->invariantMassError(cascadeVertices[1],massesMuPi));
347 double Mass_B_err =
m_CascadeTools->invariantMassError(moms[1],
x->getCovariance()[1]);
348 double Mass_D0_err =
m_CascadeTools->invariantMassError(moms[0],
x->getCovariance()[0]);
349 ATH_MSG_DEBUG(
"Mass_B " << Mass_B <<
" Mass_D0 " << Mass_D0);
350 ATH_MSG_DEBUG(
"Mass_B_err " << Mass_B_err <<
" Mass_D0_err " << Mass_D0_err);
351 double mprob_B =
m_CascadeTools->massProbability(mass_b,Mass_B,Mass_B_err);
352 double mprob_D0 =
m_CascadeTools->massProbability(mass_d0,Mass_D0,Mass_D0_err);
353 ATH_MSG_DEBUG(
"mprob_B " << mprob_B <<
" mprob_D0 " << mprob_D0);
356 <<
" Mass_d0 " <<
m_CascadeTools->invariantMass(moms[0],massesD0));
358 <<
" Mass_d0_err " <<
m_CascadeTools->invariantMassError(moms[0],
x->getCovariance()[0],massesD0));
361 <<
" pt_d0 " <<
m_V0Tools->pT(cascadeVertices[0]));
363 <<
" ptErr_d " <<
m_CascadeTools->pTError(moms[0],
x->getCovariance()[0])
364 <<
" ptErr_d0 " <<
m_V0Tools->pTError(cascadeVertices[0]));
368 <<
" lxyErr_d " <<
m_CascadeTools->lxyError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
369 <<
" lxyErr_d0 " <<
m_V0Tools->lxyError(cascadeVertices[0],cascadeVertices[1]));
371 <<
" tau_d0 " <<
m_V0Tools->tau(cascadeVertices[0],cascadeVertices[1],massesD0));
373 <<
" tau_d " <<
m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1])
374 <<
" tau_D " <<
m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1],mass_d0));
376 <<
" tauErr_d " <<
m_CascadeTools->tauError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
377 <<
" tauErr_d0 " <<
m_V0Tools->tauError(cascadeVertices[0],cascadeVertices[1],massesD0));
379 <<
" TauErr_d " <<
m_CascadeTools->tauError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1],mass_d0)
380 <<
" TauErr_d0 " <<
m_V0Tools->tauError(cascadeVertices[0],cascadeVertices[1],massesD0,mass_d0));
382 ATH_MSG_DEBUG(
"CascadeTools main vert wrt PV " <<
" CascadeTools SV " <<
" V0Tools SV");
384 <<
", " <<
m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1])
385 <<
", " <<
m_V0Tools->a0z(cascadeVertices[0],cascadeVertices[1]));
387 <<
", " <<
m_CascadeTools->a0zError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
388 <<
", " <<
m_V0Tools->a0zError(cascadeVertices[0],cascadeVertices[1]));
390 <<
", " <<
m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1])
391 <<
", " <<
m_V0Tools->a0xy(cascadeVertices[0],cascadeVertices[1]));
393 <<
", " <<
m_CascadeTools->a0xyError(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
394 <<
", " <<
m_V0Tools->a0xyError(cascadeVertices[0],cascadeVertices[1]));
396 <<
", " <<
m_CascadeTools->a0(moms[0],cascadeVertices[0],cascadeVertices[1])
397 <<
", " <<
m_V0Tools->a0(cascadeVertices[0],cascadeVertices[1]));
399 <<
", " <<
m_CascadeTools->a0Error(moms[0],
x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
400 <<
", " <<
m_V0Tools->a0Error(cascadeVertices[0],cascadeVertices[1]));
403 ATH_MSG_DEBUG(
"X0 " << primaryVertex->
x() <<
" Y0 " << primaryVertex->
y() <<
" Z0 " << primaryVertex->
z());
406 ATH_MSG_DEBUG(
"Rxy0 wrt PV " <<
m_V0Tools->rxy(cascadeVertices[0],primaryVertex) <<
" RxyErr0 wrt PV " <<
m_V0Tools->rxyError(cascadeVertices[0],primaryVertex));
407 ATH_MSG_DEBUG(
"Rxy1 wrt PV " <<
m_V0Tools->rxy(cascadeVertices[1],primaryVertex) <<
" RxyErr1 wrt PV " <<
m_V0Tools->rxyError(cascadeVertices[1],primaryVertex));
408 ATH_MSG_DEBUG(
"number of covariance matrices " << (
x->getCovariance()).size());
413 for (
auto x : cascadeinfoContainer)
delete x;
415 return StatusCode::SUCCESS;
489 assert(cascadeinfoContainer!=
nullptr);
493 ATH_CHECK(evtStore()->retrieve(trackContainer ,
"InDetTrackParticles" ));
504 std::vector<const xAOD::TrackParticle*> tracksMuPi;
505 std::vector<const xAOD::TrackParticle*> tracksD0;
506 std::vector<double> massesMuPi;
509 std::vector<double> massesD0;
512 std::vector<double> massesD0b;
515 std::vector<double> Masses;
523 std::vector<const xAOD::Vertex*> selectedMuPiCandidates;
524 for (
auto vxcItr : *MuPiContainer ){
526 TLorentzVector p4Mup_in, p4Mum_in;
527 p4Mup_in.SetPtEtaPhiM(vxcItr->trackParticle(0)->pt(),
528 vxcItr->trackParticle(0)->eta(),
530 p4Mum_in.SetPtEtaPhiM(vxcItr->trackParticle(1)->pt(),
531 vxcItr->trackParticle(1)->eta(),
533 double mass_MuPi = (p4Mup_in + p4Mum_in).M();
536 ATH_MSG_DEBUG(
" Original mu & pi_soft candidate rejected by the mass cut: mass = "
544 ATH_MSG_DEBUG(
" Original mu & pi_soft candidate rejected by the track's cut level - loose");
548 selectedMuPiCandidates.push_back(vxcItr);
550 if(selectedMuPiCandidates.size()<1)
return StatusCode::SUCCESS;
553 std::vector<const xAOD::Vertex*> selectedD0Candidates;
554 for(
auto vxcItr : *d0Container){
557 SG::AuxElement::Accessor<Char_t> flagAcc1(
"passed_D0");
558 SG::AuxElement::Accessor<Char_t> flagAcc2(
"passed_D0b");
561 if(flagAcc1.isAvailable(*vtx)){
562 if(!flagAcc1(*vtx)) isD0 =
false;
564 if(flagAcc2.isAvailable(*vtx)){
565 if(!flagAcc2(*vtx)) isD0b =
false;
567 if(!(isD0||isD0b))
continue;
571 ATH_MSG_DEBUG(
" Original D0/D0-bar candidate rejected by the track's cut level - loose ");
575 ATH_MSG_DEBUG(
" Original D0/D0-bar candidate rejected by the track's cut level - loose ");
581 if (vxcItr->trackParticle(0)->charge() != 1 || vxcItr->trackParticle(1)->charge() != -1) {
582 ATH_MSG_DEBUG(
" Original D0/D0-bar candidate rejected by the charge requirement: "
583 << vxcItr->trackParticle(0)->charge() <<
", " << vxcItr->trackParticle(1)->charge() );
588 double mass_D0 =
m_V0Tools->invariantMass(vxcItr,massesD0);
589 double mass_D0b =
m_V0Tools->invariantMass(vxcItr,massesD0b);
590 ATH_MSG_DEBUG(
"D0 mass " << mass_D0 <<
", D0b mass "<<mass_D0b);
592 ATH_MSG_DEBUG(
" Original D0/D0-bar candidate rejected by the mass cut: mass = "
598 selectedD0Candidates.push_back(vxcItr);
600 if(selectedD0Candidates.size()<1)
return StatusCode::SUCCESS;
604 for(
auto MuPiItr:selectedMuPiCandidates){
605 size_t MuPiTrkNum = MuPiItr->nTrackParticles();
608 for(
unsigned int it=0; it<MuPiTrkNum; it++) tracksMuPi.push_back(MuPiItr->trackParticle(it));
610 if (tracksMuPi.size() != 2 || massesMuPi.size() != 2 ) {
615 if(std::abs(
m_Dx_pid)==421 && MuPiItr->trackParticle(1)->charge()==-1) tagD0 =
false;
617 TLorentzVector p4_pi1;
618 p4_pi1.SetPtEtaPhiM(MuPiItr->trackParticle(1)->pt(),
619 MuPiItr->trackParticle(1)->eta(),
622 for(
auto d0Itr : selectedD0Candidates){
625 if(std::find(tracksMuPi.cbegin(), tracksMuPi.cend(), d0Itr->trackParticle(0)) != tracksMuPi.cend())
continue;
626 if(std::find(tracksMuPi.cbegin(), tracksMuPi.cend(), d0Itr->trackParticle(1)) != tracksMuPi.cend())
continue;
628 TLorentzVector p4_ka, p4_pi2;
630 p4_pi2.SetPtEtaPhiM(d0Itr->trackParticle(0)->pt(),
631 d0Itr->trackParticle(0)->eta(),
633 p4_ka.SetPtEtaPhiM( d0Itr->trackParticle(1)->pt(),
634 d0Itr->trackParticle(1)->eta(),
637 p4_pi2.SetPtEtaPhiM(d0Itr->trackParticle(1)->pt(),
638 d0Itr->trackParticle(1)->eta(),
640 p4_ka.SetPtEtaPhiM( d0Itr->trackParticle(0)->pt(),
641 d0Itr->trackParticle(0)->eta(),
645 double mass_Dst= (p4_pi1 + p4_ka + p4_pi2).M();
648 ATH_MSG_DEBUG(
" Original D*+/- candidate rejected by the mass cut: mass = "
653 size_t d0TrkNum = d0Itr->nTrackParticles();
655 for(
unsigned int it=0; it<d0TrkNum; it++) tracksD0.push_back(d0Itr->trackParticle(it));
656 if (tracksD0.size() != 2 || massesD0.size() != 2 ) {
667 std::unique_ptr<Trk::IVKalState> state (
m_iVertexFitter->makeState(ctx));
673 std::vector<Trk::VertexID> vrtList;
677 if(tagD0) vID =
m_iVertexFitter->startVertex(tracksD0,massesD0, *state,mass_d0);
678 else vID =
m_iVertexFitter->startVertex(tracksD0,massesD0b, *state,mass_d0);
680 if(tagD0) vID =
m_iVertexFitter->startVertex(tracksD0, massesD0,*state);
683 vrtList.push_back(vID);
687 std::vector<Trk::VertexID> cnstV;
696 std::unique_ptr<Trk::VxCascadeInfo> result(
m_iVertexFitter->fitCascade(*state));
698 if (result !=
nullptr) {
701 ATH_MSG_DEBUG(
"storing tracks " << ((result->vertices())[0])->trackParticle(0) <<
", "
702 << ((result->vertices())[0])->trackParticle(1) <<
", "
703 << ((result->vertices())[1])->trackParticle(0) <<
", "
704 << ((result->vertices())[1])->trackParticle(1));
706 result->setSVOwnership(
true);
709 double bChi2DOF = result->fitChi2()/result->nDoF();
713 const std::vector< std::vector<TLorentzVector> > &moms = result->getParticleMoms();
714 const std::vector<xAOD::Vertex*> &cascadeVertices = result->vertices();
717 double DstMassAft = (moms[1][1] + moms[0][0] + moms[0][1]).M();
722 if (
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]) > 0){
725 cascadeinfoContainer->push_back(result.release());
740 ATH_MSG_DEBUG(
"cascadeinfoContainer size " << cascadeinfoContainer->size());
741 return StatusCode::SUCCESS;