10 #include "GaudiKernel/IPartPropSvc.h"
16 #include "HepPDT/ParticleDataTable.hh"
27 m_vertexJXContainerKey(
"InputJXVertices"),
28 m_vertexV0ContainerKey(
"InputV0Vertices"),
29 m_vertexDisVContainerKey(
""),
30 m_cascadeOutputKeys({
"JpsiXPlusDisplacedVtx1_sub",
"JpsiXPlusDisplacedVtx1",
"JpsiXPlusDisplacedVtx2",
"JpsiXPlusDisplacedVtx3"}),
33 m_disVtxOutputKey(
""),
34 m_TrkParticleCollection(
"InDetTrackParticles"),
35 m_VxPrimaryCandidateName(
"PrimaryVertices"),
36 m_refPVContainerName(
"RefittedPrimaryVertices"),
37 m_eventInfo_key(
"EventInfo"),
38 m_beamSpotDecoKeys({
"EventInfo.beamPosX",
"EventInfo.beamPosY",
"EventInfo.beamPosZ"}),
40 m_jxMassUpper(30000.0),
42 m_jpsiMassUpper(20000.0),
43 m_diTrackMassLower(-1.0),
44 m_diTrackMassUpper(-1.0),
45 m_V0Hypothesis(
"Lambda"),
47 m_V0MassUpper(20000.0),
51 m_minMass_gamma(-1.0),
52 m_chi2cut_gamma(-1.0),
53 m_DisplacedMassLower(0.0),
54 m_DisplacedMassUpper(30000.0),
55 m_lxyDisV_cut(-999.0),
59 m_jxDaug1MassHypo(-1),
60 m_jxDaug2MassHypo(-1),
61 m_jxDaug3MassHypo(-1),
62 m_jxDaug4MassHypo(-1),
64 m_disVDaug3MassHypo(-1),
65 m_extraTrkMassHypo(-1),
89 m_maxDisVCandidates(0),
90 m_maxMainVCandidates(0),
91 m_iVertexFitter(
"Trk::TrkVKalVrtFitter"),
92 m_iV0Fitter(
"Trk::V0VertexFitter"),
93 m_iGammaFitter(
"Trk::TrkVKalVrtFitter"),
94 m_pvRefitter(
"Analysis::PrimaryVertexRefitter",
this),
95 m_V0Tools(
"Trk::V0Tools"),
96 m_trackToVertexTool(
"Reco::TrackToVertex"),
97 m_trkSelector(
"InDet::TrackSelectorTool"),
98 m_v0TrkSelector(
"InDet::TrackSelectorTool"),
99 m_CascadeTools(
"DerivationFramework::CascadeTools")
183 ATH_MSG_FATAL(
"Incorrect V0 container hypothesis - not recognized");
184 return StatusCode::FAILURE;
187 if(m_jxDaug_num<2 || m_jxDaug_num>4 || m_disVDaug_num<2 || m_disVDaug_num>3) {
189 return StatusCode::FAILURE;
193 ATH_MSG_FATAL(
"Can not retrieve an input displaced vertex container and ask for V0 refits at the same time");
194 return StatusCode::FAILURE;
236 IPartPropSvc* partPropSvc =
nullptr;
237 ATH_CHECK( service(
"PartPropSvc", partPropSvc,
true) );
238 auto pdt = partPropSvc->PDT();
263 return StatusCode::SUCCESS;
268 assert(cascadeinfoContainer!=
nullptr);
278 if (pvContainer.
cptr()->
size()==0) {
280 return StatusCode::RECOVERABLE;
282 else primaryVertex = (*pvContainer.
cptr())[0];
284 std::vector<double> massesJX;
289 std::vector<double> massesV0_ppi;
292 std::vector<double> massesV0_pip;
295 std::vector<double> massesV0_pipi;
314 auto ctx = Gaudi::Hive::currentContext();
321 std::vector<const xAOD::TrackParticle*> tracksDisplaced;
323 for(
auto tpIt=trackContainer.
cptr()->
begin(); tpIt!=trackContainer.
cptr()->
end(); ++tpIt) {
331 if(!
m_useTRT && nclus == 0)
continue;
333 bool trk_cut =
false;
334 if(nclus != 0) trk_cut =
true;
335 if(nclus == 0 && TP->
pt()>=
m_ptTRT) trk_cut =
true;
336 if(!trk_cut)
continue;
339 if(!
d0Pass(TP,primaryVertex,beamspot))
continue;
341 tracksDisplaced.push_back(TP);
369 std::vector<float> trk_px;
370 std::vector<float> trk_py;
371 std::vector<float> trk_pz;
372 std::vector<const xAOD::TrackParticle*> tracksV0;
375 std::vector<std::pair<const xAOD::Vertex*,V0Enum> > selectedV0Candidates_EXISTING;
376 std::vector<std::pair<xAOD::Vertex*,V0Enum> > selectedV0Candidates_CREATED;
394 double massSig_V0_Ks = std::abs(
m_V0Tools->invariantMass(vtx, massesV0_pipi)-
m_mass_Ks)/
m_V0Tools->invariantMassError(vtx, massesV0_pipi);
395 if(massSig_V0_Lambda1<=massSig_V0_Lambda2 && massSig_V0_Lambda1<=massSig_V0_Ks) {
397 massV0 =
m_V0Tools->invariantMass(vtx, massesV0_ppi);
399 else if(massSig_V0_Lambda2<=massSig_V0_Lambda1 && massSig_V0_Lambda2<=massSig_V0_Ks) {
401 massV0 =
m_V0Tools->invariantMass(vtx, massesV0_pip);
403 else if(massSig_V0_Ks<=massSig_V0_Lambda1 && massSig_V0_Ks<=massSig_V0_Lambda2) {
405 massV0 =
m_V0Tools->invariantMass(vtx, massesV0_pipi);
411 std::string type_V0Vtx;
412 if(mAcc_type.
isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
415 else if(type_V0Vtx ==
"Ks")
opt =
KS;
427 int gamma_fit = 0;
int gamma_ndof = 0;
428 double gamma_chisq = 999999., gamma_prob = -1., gamma_mass = -1., gamma_massErr = -1.;
430 gamma_fit = mAcc_gfit.
isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
431 gamma_mass = mAcc_gmass.
isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
432 gamma_massErr = mAcc_gmasserr.
isAvailable(*vtx) ? mAcc_gmasserr(*vtx) : -1;
433 gamma_chisq = mAcc_gchisq.
isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
434 gamma_ndof = mAcc_gndof.
isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
435 gamma_prob = mAcc_gprob.
isAvailable(*vtx) ? mAcc_gprob(*vtx) : -1;
438 std::unique_ptr<xAOD::Vertex> gammaVtx = std::unique_ptr<xAOD::Vertex>(
m_iGammaFitter->fit(tracksV0, vtxPos) );
443 gamma_chisq =
m_V0Tools->chisq(gammaVtx.get());
444 gamma_ndof =
m_V0Tools->ndof(gammaVtx.get());
445 gamma_prob =
m_V0Tools->vertexProbability(gammaVtx.get());
451 trk_px.clear(); trk_py.clear(); trk_pz.clear();
462 std::unique_ptr<xAOD::Vertex> V0vtx;
464 std::vector<double> massesV0;
465 if(
opt ==
LAMBDA) massesV0 = massesV0_ppi;
467 else if(
opt ==
KS) massesV0 = massesV0_pipi;
469 V0vtx = std::unique_ptr<xAOD::Vertex>(
m_iV0Fitter->fit(tracksV0, massesV0,
m_massV0, 0, vtxPos) );
472 V0vtx = std::unique_ptr<xAOD::Vertex>(
m_iV0Fitter->fit(tracksV0, vtxPos) );
491 mDec_gfit(*V0vtx.get()) = gamma_fit;
492 mDec_gmass(*V0vtx.get()) = gamma_mass;
493 mDec_gmasserr(*V0vtx.get()) = gamma_massErr;
494 mDec_gchisq(*V0vtx.get()) = gamma_chisq;
495 mDec_gndof(*V0vtx.get()) = gamma_ndof;
496 mDec_gprob(*V0vtx.get()) = gamma_prob;
497 if(
opt==
LAMBDA) mDec_type(*V0vtx.get()) =
"Lambda";
498 else if(
opt==
LAMBDABAR) mDec_type(*V0vtx.get()) =
"Lambdabar";
499 else if(
opt==
KS) mDec_type(*V0vtx.get()) =
"Ks";
501 trk_pxDeco(*V0vtx.get()) = trk_px;
502 trk_pyDeco(*V0vtx.get()) = trk_py;
503 trk_pzDeco(*V0vtx.get()) = trk_pz;
505 selectedV0Candidates_CREATED.push_back(std::pair<xAOD::Vertex*,V0Enum>{V0vtx.release(),
opt});
511 mDec_gfit(*vtx) = gamma_fit;
512 mDec_gmass(*vtx) = gamma_mass;
513 mDec_gmasserr(*vtx) = gamma_massErr;
514 mDec_gchisq(*vtx) = gamma_chisq;
515 mDec_gndof(*vtx) = gamma_ndof;
516 mDec_gprob(*vtx) = gamma_prob;
517 if(
opt==
LAMBDA) mDec_type(*vtx) =
"Lambda";
519 else if(
opt==
KS) mDec_type(*vtx) =
"Ks";
520 selectedV0Candidates_EXISTING.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,
opt});
525 if(selectedV0Candidates_CREATED.size()==0)
return StatusCode::SUCCESS;
526 std::sort( selectedV0Candidates_CREATED.begin(), selectedV0Candidates_CREATED.end(), [](std::pair<xAOD::Vertex*,V0Enum>
a, std::pair<xAOD::Vertex*,V0Enum>
b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
528 for(
auto it=selectedV0Candidates_CREATED.begin()+
m_maxV0Candidates;
it!=selectedV0Candidates_CREATED.end();
it++)
delete it->first;
529 selectedV0Candidates_CREATED.erase(selectedV0Candidates_CREATED.begin()+
m_maxV0Candidates, selectedV0Candidates_CREATED.end());
533 if(selectedV0Candidates_EXISTING.size()==0)
return StatusCode::SUCCESS;
534 std::sort( selectedV0Candidates_EXISTING.begin(), selectedV0Candidates_EXISTING.end(), [](std::pair<const xAOD::Vertex*,V0Enum>
a, std::pair<const xAOD::Vertex*,V0Enum>
b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
536 selectedV0Candidates_EXISTING.erase(selectedV0Candidates_EXISTING.begin()+
m_maxV0Candidates, selectedV0Candidates_EXISTING.end());
540 if(selectedV0Candidates_CREATED.size() && V0OutputContainer) {
541 for(
auto v0VItr=selectedV0Candidates_CREATED.begin(); v0VItr!=selectedV0Candidates_CREATED.end(); ++v0VItr) V0OutputContainer->
push_back(v0VItr->first);
545 std::vector<std::pair<const xAOD::Vertex*,size_t> > disVtxContainer_EXISTING;
546 std::vector<std::pair<xAOD::Vertex*,size_t> > disVtxContainer_CREATED;
550 for(
size_t it=0;
it<selectedV0Candidates_CREATED.size(); ++
it) {
551 std::pair<xAOD::Vertex*,V0Enum> elem = selectedV0Candidates_CREATED[
it];
552 for(
auto trkItr=tracksDisplaced.cbegin(); trkItr!=tracksDisplaced.cend(); ++trkItr) {
554 if(disVtx) disVtxContainer_CREATED.push_back(std::pair<xAOD::Vertex*,size_t>{disVtx,
it});
559 for(
size_t it=0;
it<selectedV0Candidates_EXISTING.size(); ++
it) {
560 std::pair<const xAOD::Vertex*,V0Enum> elem = selectedV0Candidates_EXISTING[
it];
561 for(
auto trkItr=tracksDisplaced.cbegin(); trkItr!=tracksDisplaced.cend(); ++trkItr) {
563 if(disVtx) disVtxContainer_CREATED.push_back(std::pair<xAOD::Vertex*,size_t>{disVtx,
it});
568 std::sort( disVtxContainer_CREATED.begin(), disVtxContainer_CREATED.end(), [](std::pair<xAOD::Vertex*,size_t>
a, std::pair<xAOD::Vertex*,size_t>
b) {
569 SG::AuxElement::Accessor<float> ChiSquared(
"ChiSquared_Cascade");
570 SG::AuxElement::Accessor<int> nDoF(
"nDoF_Cascade");
571 float chi2_a = ChiSquared.isAvailable(*a.first) ? ChiSquared(*a.first) : 999999;
572 int ndof_a = nDoF.isAvailable(*a.first) ? nDoF(*a.first) : 1;
573 float chi2_b = ChiSquared.isAvailable(*b.first) ? ChiSquared(*b.first) : 999999;
574 int ndof_b = nDoF.isAvailable(*b.first) ? nDoF(*b.first) : 1;
575 return chi2_a/ndof_a < chi2_b/ndof_b; } );
578 disVtxContainer_CREATED.erase(disVtxContainer_CREATED.begin()+
m_maxDisVCandidates, disVtxContainer_CREATED.end());
582 for(
auto vxcItr=disVtxInputContainer.
cptr()->
begin(); vxcItr!=disVtxInputContainer.
cptr()->
end(); ++vxcItr) {
586 const VertexLink& cascadeVertexLink = cascadeVertexLinkAcc(*vtx);
587 if(cascadeVertexLink.
isValid()) {
589 for(
size_t it=0;
it<selectedV0Candidates_EXISTING.size(); ++
it) {
590 std::pair<const xAOD::Vertex*,V0Enum> elem = selectedV0Candidates_EXISTING[
it];
591 if(BPhysPVCascadeTools::VerticesMatchTracks<2>(elem.first,
V0Vtx)) {
592 disVtxContainer_EXISTING.push_back(std::pair<const xAOD::Vertex*,size_t>{vtx,
it});
599 if(disVtxInputContainer.
cptr()->
size() != disVtxContainer_EXISTING.size())
ATH_MSG_ERROR(
"Input and selected displaced vertex containers have different sizes");
601 std::sort( disVtxContainer_EXISTING.begin(), disVtxContainer_EXISTING.end(), [](std::pair<const xAOD::Vertex*,size_t>
a, std::pair<const xAOD::Vertex*,size_t>
b) {
602 SG::AuxElement::Accessor<float> ChiSquared(
"ChiSquared_Cascade");
603 SG::AuxElement::Accessor<int> nDoF(
"nDoF_Cascade");
604 float chi2_a = ChiSquared.isAvailable(*a.first) ? ChiSquared(*a.first) : 999999;
605 int ndof_a = nDoF.isAvailable(*a.first) ? nDoF(*a.first) : 1;
606 float chi2_b = ChiSquared.isAvailable(*b.first) ? ChiSquared(*b.first) : 999999;
607 int ndof_b = nDoF.isAvailable(*b.first) ? nDoF(*b.first) : 1;
608 return chi2_a/ndof_a < chi2_b/ndof_b; } );
610 disVtxContainer_EXISTING.erase(disVtxContainer_EXISTING.begin()+
m_maxDisVCandidates, disVtxContainer_EXISTING.end());
615 if(!V0OutputContainer) {
616 for(
auto it=selectedV0Candidates_CREATED.begin();
it!=selectedV0Candidates_CREATED.end();
it++)
delete it->first;
618 return StatusCode::SUCCESS;
621 if(disVtxContainer_CREATED.size() && disVtxOutputContainer) {
622 for(
auto disVItr=disVtxContainer_CREATED.begin(); disVItr!=disVtxContainer_CREATED.end(); ++disVItr) {
623 disVtxOutputContainer->
push_back(disVItr->first);
627 if(V0OutputContainer) {
628 vertexLink.
setElement(V0OutputContainer->
at(disVItr->second));
636 cascadeVertexLinkDecor(*disVItr->first) = vertexLink;
642 std::vector<const xAOD::Vertex*> selectedJXCandidates;
643 for(
auto vxcItr=jxContainer.
ptr()->
begin(); vxcItr!=jxContainer.
ptr()->
end(); ++vxcItr) {
657 double mass_jx =
m_V0Tools->invariantMass(*vxcItr,massesJX);
658 if(mass_jx < m_jxMassLower || mass_jx >
m_jxMassUpper)
continue;
662 TLorentzVector p4_mu1, p4_mu2;
669 double mass_jpsi = (p4_mu1 + p4_mu2).M();
670 if (mass_jpsi < m_jpsiMassLower || mass_jpsi >
m_jpsiMassUpper)
continue;
673 TLorentzVector p4_trk1, p4_trk2;
680 double mass_diTrk = (p4_trk1 + p4_trk2).M();
687 selectedJXCandidates.push_back(vtx);
690 if(selectedJXCandidates.size()==0) {
691 if(!V0OutputContainer) {
692 for(
auto it=selectedV0Candidates_CREATED.begin();
it!=selectedV0Candidates_CREATED.end();
it++)
delete it->first;
694 if(!disVtxOutputContainer) {
695 for(
auto it=disVtxContainer_CREATED.begin();
it!=disVtxContainer_CREATED.end();
it++)
delete it->first;
697 return StatusCode::SUCCESS;
700 std::sort( selectedJXCandidates.begin(), selectedJXCandidates.end(), [](
const xAOD::Vertex*
a,
const xAOD::Vertex*
b) { return a->chiSquared()/a->numberDoF() < b->chiSquared()/b->numberDoF(); } );
702 selectedJXCandidates.erase(selectedJXCandidates.begin()+
m_maxJXCandidates, selectedJXCandidates.end());
707 for(
auto jxItr=selectedJXCandidates.begin(); jxItr!=selectedJXCandidates.end(); ++jxItr) {
711 for(
auto V0Itr=selectedV0Candidates_CREATED.begin(); V0Itr!=selectedV0Candidates_CREATED.end(); ++V0Itr) {
717 for(
auto V0Itr=selectedV0Candidates_EXISTING.begin(); V0Itr!=selectedV0Candidates_EXISTING.end(); ++V0Itr) {
725 for(
auto disVItr=disVtxContainer_CREATED.begin(); disVItr!=disVtxContainer_CREATED.end(); ++disVItr) {
729 V0Vtx = selectedV0Candidates_CREATED[disVItr->second].first;
730 V0 = selectedV0Candidates_CREATED[disVItr->second].second;
733 V0Vtx = selectedV0Candidates_EXISTING[disVItr->second].first;
734 V0 = selectedV0Candidates_EXISTING[disVItr->second].second;
741 for(
auto disVItr=disVtxContainer_EXISTING.begin(); disVItr!=disVtxContainer_EXISTING.end(); ++disVItr) {
743 const xAOD::Vertex*
V0Vtx = selectedV0Candidates_EXISTING[disVItr->second].first;
744 V0Enum V0 = selectedV0Candidates_EXISTING[disVItr->second].second;
753 if(!disVtxOutputContainer) {
754 for(
auto disVItr=disVtxContainer_CREATED.begin(); disVItr!=disVtxContainer_CREATED.end(); ++disVItr)
delete disVItr->first;
756 if(!V0OutputContainer) {
757 for(
auto v0VItr=selectedV0Candidates_CREATED.begin(); v0VItr!=selectedV0Candidates_CREATED.end(); ++v0VItr)
delete v0VItr->first;
760 return StatusCode::SUCCESS;
768 ATH_MSG_FATAL(
"Incorrect number of output cascade vertices");
769 return StatusCode::FAILURE;
772 std::array<SG::WriteHandle<xAOD::VertexContainer>, 4> VtxWriteHandles;
int ikey(0);
775 ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
784 if (pvContainer.
cptr()->
size()==0) {
786 return StatusCode::RECOVERABLE;
795 ATH_CHECK( refPvContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
802 ATH_CHECK( V0OutputContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
809 ATH_CHECK( disVtxOutputContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
812 std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
818 cascadeinfoContainer.erase(cascadeinfoContainer.begin()+
m_maxMainVCandidates, cascadeinfoContainer.end());
865 for(
auto cascade_info : cascadeinfoContainer) {
866 if(cascade_info==
nullptr) {
871 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->vertices();
872 if(cascadeVertices.size() != topoN)
ATH_MSG_ERROR(
"Incorrect number of vertices");
873 for(
size_t i=0;
i<topoN;
i++) {
874 if(cascadeVertices[
i]==
nullptr)
ATH_MSG_ERROR(
"Error null vertex");
877 cascade_info->setSVOwnership(
false);
878 const auto mainVertex = cascadeVertices[topoN-1];
879 const std::vector< std::vector<TLorentzVector> > &moms = cascade_info->getParticleMoms();
884 if(
m_jxDaug_num==4) jxVtx = FindVertex<4>(jxContainer.
ptr(), cascadeVertices[ijx]);
885 else if(
m_jxDaug_num==3) jxVtx = FindVertex<3>(jxContainer.
ptr(), cascadeVertices[ijx]);
886 else jxVtx = FindVertex<2>(jxContainer.
ptr(), cascadeVertices[ijx]);
903 PtErr_decor(*mainVertex) =
m_CascadeTools->pTError(moms[topoN-1],cascade_info->getCovariance()[topoN-1]);
905 chi2_decor(*mainVertex) = cascade_info->fitChi2();
906 ndof_decor(*mainVertex) = cascade_info->nDoF();
910 lxy_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
911 lxyErr_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
912 a0z_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
913 a0zErr_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
914 a0xy_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
915 a0xyErr_SV1_decor(*cascadeVertices[0]) =
m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
919 lxy_SV0_decor(*cascadeVertices[0]) =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
920 lxyErr_SV0_decor(*cascadeVertices[0]) =
m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
921 a0z_SV0_decor(*cascadeVertices[0]) =
m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1]);
922 a0zErr_SV0_decor(*cascadeVertices[0]) =
m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
923 a0xy_SV0_decor(*cascadeVertices[0]) =
m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1]);
924 a0xyErr_SV0_decor(*cascadeVertices[0]) =
m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
927 lxy_SV1_decor(*cascadeVertices[1]) =
m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
928 lxyErr_SV1_decor(*cascadeVertices[1]) =
m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
929 a0xy_SV1_decor(*cascadeVertices[1]) =
m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
930 a0xyErr_SV1_decor(*cascadeVertices[1]) =
m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
931 a0z_SV1_decor(*cascadeVertices[1]) =
m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
932 a0zErr_SV1_decor(*cascadeVertices[1]) =
m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
937 lxy_SV2_decor(*cascadeVertices[ijx]) =
m_CascadeTools->lxy(moms[ijx],cascadeVertices[ijx],mainVertex);
938 lxyErr_SV2_decor(*cascadeVertices[ijx]) =
m_CascadeTools->lxyError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
939 a0z_SV2_decor(*cascadeVertices[ijx]) =
m_CascadeTools->a0z(moms[ijx],cascadeVertices[ijx],mainVertex);
940 a0zErr_SV2_decor(*cascadeVertices[ijx]) =
m_CascadeTools->a0zError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
941 a0xy_SV2_decor(*cascadeVertices[ijx]) =
m_CascadeTools->a0xy(moms[ijx],cascadeVertices[ijx],mainVertex);
942 a0xyErr_SV2_decor(*cascadeVertices[ijx]) =
m_CascadeTools->a0xyError(moms[ijx],cascade_info->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
945 chi2_V2_decor(*cascadeVertices[ijx]) =
m_V0Tools->chisq(jxVtx);
946 ndof_V2_decor(*cascadeVertices[ijx]) =
m_V0Tools->ndof(jxVtx);
951 for(
size_t i=0;
i<topoN;
i++) {
952 VtxWriteHandles[
i].ptr()->push_back(cascadeVertices[
i]);
960 if( vertexLink1.
isValid() ) precedingVertexLinks.push_back( vertexLink1 );
965 if( vertexLink2.
isValid() ) precedingVertexLinks.push_back( vertexLink2 );
971 if( vertexLink3.
isValid() ) precedingVertexLinks.push_back( vertexLink3 );
973 CascadeLinksDecor(*mainVertex) = precedingVertexLinks;
978 for (
auto cascade_info : cascadeinfoContainer)
delete cascade_info;
980 return StatusCode::SUCCESS;
985 auto ctx = Gaudi::Hive::currentContext();
988 if(per == 0)
return pass;
990 double sig_d0 = sqrt((*per->covariance())(0,0));
991 if(std::abs(
d0/sig_d0) >
m_d0_cut) pass =
true;
995 if(per == 0)
return pass;
997 double sig_d0 = sqrt((*per->covariance())(0,0));
998 if(std::abs(
d0/sig_d0) >
m_d0_cut) pass =
true;
1007 std::vector<const xAOD::TrackParticle*> tracksV0;
1009 if(
std::find(tracksV0.cbegin(), tracksV0.cend(), track3) != tracksV0.cend())
return disVtx;
1011 std::vector<double> massesV0;
1016 TLorentzVector p4_v0,
tmp;
1022 std::unique_ptr<Trk::IVKalState> state =
m_iVertexFitter->makeState();
1025 std::vector<Trk::VertexID> vrtList;
1030 vrtList.push_back(vID);
1032 std::vector<const xAOD::TrackParticle*> tracksDis3{track3};
1035 else m_iVertexFitter->nextVertex(tracksDis3,massesDis3,vrtList,*state);
1037 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>(
m_iVertexFitter->fitCascade(*state) );
1038 if(cascade_info !=
nullptr) {
1041 const std::vector<xAOD::Vertex*>& disVertices = cascade_info->
vertices();
1042 double chi2NDF = cascade_info->
fitChi2()/cascade_info->
nDoF();
1050 chi2_decor(*disVertices[1]) = cascade_info->
fitChi2();
1051 ndof_decor(*disVertices[1]) = cascade_info->
nDoF();
1053 disVtx = disVertices[1];
1055 else delete disVertices[1];
1056 delete disVertices[0];
1064 std::vector<const xAOD::TrackParticle*> tracksJX;
1066 if (tracksJX.size() != massesJX.size()) {
1067 ATH_MSG_ERROR(
"Problems with JX input: number of tracks or track mass inputs is not correct!");
1073 std::vector<const xAOD::TrackParticle*> tracksV0;
1076 std::vector<const xAOD::TrackParticle*> tracksJpsi;
1077 tracksJpsi.push_back(tracksJX[0]);
1078 tracksJpsi.push_back(tracksJX[1]);
1079 std::vector<const xAOD::TrackParticle*> tracksX;
1083 std::vector<double> massesV0;
1088 TLorentzVector p4_moth,
tmp;
1095 p4_moth += V0_helper.
refTrk(
it,massesV0[
it]);
1122 std::vector<float> trk_px;
1123 std::vector<float> trk_py;
1124 std::vector<float> trk_pz;
1130 std::unique_ptr<Trk::IVKalState> state =
m_iVertexFitter->makeState();
1136 std::vector<Trk::VertexID> vrtList;
1145 vrtList.push_back(vID1);
1154 vrtList.push_back(vID2);
1156 std::vector<const xAOD::TrackParticle*>
tp;
tp.clear();
1157 std::vector<double> tp_masses; tp_masses.clear();
1172 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1179 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1185 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1191 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>(
m_iVertexFitter->fitCascade(*state) );
1193 if (fit_result !=
nullptr) {
1195 if(
v->nTrackParticles()==0) {
1196 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1197 v->setTrackParticleLinks(nullLinkVector);
1207 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1210 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1211 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1212 size_t iMoth = cascadeVertices.size()-1;
1213 double lxy_SV1 =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1215 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1216 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1217 if(V0==
LAMBDA) type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1218 else if(V0==
LAMBDABAR) type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1219 else if(V0==
KS) type_V1_decor(*cascadeVertices[0]) =
"Ks";
1220 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1221 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1222 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1223 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1224 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1225 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1226 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1227 if(trk_pxAcc.
isAvailable(*V0vtx)) trk_px = trk_pxAcc(*V0vtx);
1228 if(trk_pyAcc.
isAvailable(*V0vtx)) trk_py = trk_pyAcc(*V0vtx);
1229 if(trk_pzAcc.
isAvailable(*V0vtx)) trk_pz = trk_pzAcc(*V0vtx);
1230 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1231 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1232 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1234 result = fit_result.release();
1239 std::vector<double> massesJXExtra;
1240 for(
size_t i=0;
i<massesJX.size();
i++) massesJXExtra.push_back(massesJX[
i]);
1243 for(
auto tpIter=trackContainer->
cbegin(); tpIter!=trackContainer->
cend(); ++tpIter) {
1248 if(
std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend())
continue;
1249 if(
std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend())
continue;
1255 std::vector<const xAOD::TrackParticle*> tracksJXExtra;
1256 for(
size_t it=0;
it<tracksJX.size();
it++) tracksJXExtra.push_back(tracksJX[
it]);
1257 tracksJXExtra.push_back(tpExtra);
1260 std::unique_ptr<Trk::IVKalState> state =
m_iVertexFitter->makeState();
1266 std::vector<Trk::VertexID> vrtList;
1275 vrtList.push_back(vID1);
1279 vID2 =
m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,*state);
1280 vrtList.push_back(vID2);
1282 std::vector<const xAOD::TrackParticle*>
tp;
tp.clear();
1283 std::vector<double> tp_masses; tp_masses.clear();
1295 vID2 =
m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1299 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1305 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1311 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1317 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>(
m_iVertexFitter->fitCascade(*state) );
1319 if (fit_result !=
nullptr) {
1321 if(
v->nTrackParticles()==0) {
1322 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1323 v->setTrackParticleLinks(nullLinkVector);
1333 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1335 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1336 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1337 size_t iMoth = cascadeVertices.size()-1;
1338 double lxy_SV1 =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1340 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1341 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1342 if(V0==
LAMBDA) type_V1_decor(*cascadeVertices[0]) =
"Lambda";
1343 else if(V0==
LAMBDABAR) type_V1_decor(*cascadeVertices[0]) =
"Lambdabar";
1344 else if(V0==
KS) type_V1_decor(*cascadeVertices[0]) =
"Ks";
1345 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1346 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1347 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1348 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1349 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1350 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1351 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1352 if(trk_pxAcc.
isAvailable(*V0vtx)) trk_px = trk_pxAcc(*V0vtx);
1353 if(trk_pyAcc.
isAvailable(*V0vtx)) trk_py = trk_pyAcc(*V0vtx);
1354 if(trk_pzAcc.
isAvailable(*V0vtx)) trk_pz = trk_pzAcc(*V0vtx);
1355 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1356 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1357 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1359 result = fit_result.release();
1371 std::vector<const xAOD::TrackParticle*> tracksJX;
1373 if (tracksJX.size() != massesJX.size()) {
1374 ATH_MSG_ERROR(
"Problems with JX input: number of tracks or track mass inputs is not correct!");
1380 std::vector<const xAOD::TrackParticle*> tracksV0;
1384 std::vector<const xAOD::TrackParticle*> tracks3{disVtx->
trackParticle(0)};
1386 std::vector<const xAOD::TrackParticle*> tracksJpsi;
1387 tracksJpsi.push_back(tracksJX[0]);
1388 tracksJpsi.push_back(tracksJX[1]);
1389 std::vector<const xAOD::TrackParticle*> tracksX;
1393 std::vector<double> massesV0;
1400 std::vector<double> massesDisV = massesV0;
1401 massesDisV.push_back(massesDis3[0]);
1403 TLorentzVector p4_moth,
tmp;
1410 p4_moth += disV_helper.
refTrk(
it,massesDisV[
it]);
1414 std::vector<float> trk_px;
1415 std::vector<float> trk_py;
1416 std::vector<float> trk_pz;
1419 std::unique_ptr<Trk::IVKalState> state =
m_iVertexFitter->makeState();
1425 std::vector<Trk::VertexID> vrtList;
1426 std::vector<Trk::VertexID> vrtList2;
1435 vrtList.push_back(vID1);
1441 vID2 =
m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state);
1443 vrtList2.push_back(vID2);
1452 vrtList2.push_back(vID3);
1454 std::vector<const xAOD::TrackParticle*>
tp;
tp.clear();
1455 std::vector<double> tp_masses; tp_masses.clear();
1467 vID3 =
m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state);
1470 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1477 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1483 std::vector<Trk::VertexID> cnstV; cnstV.clear();
1489 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>(
m_iVertexFitter->fitCascade(*state) );
1491 if (fit_result !=
nullptr) {
1493 if(
v->nTrackParticles()==0) {
1494 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1495 v->setTrackParticleLinks(nullLinkVector);
1505 double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
1508 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
1509 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
1510 size_t iMoth = cascadeVertices.size()-1;
1511 double lxy_SV1_sub =
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
1512 double lxy_SV1 =
m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
1544 chi2_V1_decor(*cascadeVertices[1]) = ChiSquared.
isAvailable(*disVtx) ? ChiSquared(*disVtx) : 999999;
1545 ndof_V1_decor(*cascadeVertices[1]) =
nDoF.isAvailable(*disVtx) ?
nDoF(*disVtx) : 1;
1546 chi2_V0_decor(*cascadeVertices[0]) = V0vtx->
chiSquared();
1547 ndof_V0_decor(*cascadeVertices[0]) = V0vtx->
numberDoF();
1548 if(V0==
LAMBDA) type_V0_decor(*cascadeVertices[0]) =
"Lambda";
1549 else if(V0==
LAMBDABAR) type_V0_decor(*cascadeVertices[0]) =
"Lambdabar";
1550 else if(V0==
KS) type_V0_decor(*cascadeVertices[0]) =
"Ks";
1551 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.
isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1552 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.
isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1553 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1554 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.
isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1555 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.
isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1556 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.
isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1557 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1558 if(trk_pxAcc.
isAvailable(*V0vtx)) trk_px = trk_pxAcc(*V0vtx);
1559 if(trk_pyAcc.
isAvailable(*V0vtx)) trk_py = trk_pyAcc(*V0vtx);
1560 if(trk_pzAcc.
isAvailable(*V0vtx)) trk_pz = trk_pzAcc(*V0vtx);
1561 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1562 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1563 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1565 result = fit_result.release();
1572 template<
size_t NTracks>
1575 assert(v1->nTrackParticles() == NTracks);
1576 std::array<const xAOD::TrackParticle*, NTracks> a1;
1577 std::array<const xAOD::TrackParticle*, NTracks> a2;
1578 for(
size_t i=0;
i<NTracks;
i++){
1579 a1[
i] = v1->trackParticle(
i);
1580 a2[
i] =
v->trackParticle(
i);
1582 std::sort(a1.begin(), a1.end());
1583 std::sort(a2.begin(), a2.end());
1584 if(a1 == a2)
return v1;