16 #include "HepPDT/ParticleDataTable.hh" 
   30     m_vertexJXContainerKey(
"InputJXVertices"),
 
   31     m_vertexV0ContainerKey{
""},
 
   32     m_cascadeOutputKeys({
"JpsiXPlus2V0_SubVtx1", 
"JpsiXPlus2V0_SubVtx2", 
"JpsiXPlus2V0_SubVtx3", 
"JpsiXPlus2V0_MainVtx"}),
 
   34     m_TrkParticleCollection(
"InDetTrackParticles"),
 
   35     m_VxPrimaryCandidateName(
"PrimaryVertices"),
 
   36     m_refPVContainerName(
"RefittedPrimaryVertices"),
 
   37     m_eventInfo_key(
"EventInfo"),
 
   38     m_RelinkContainers({
"InDetTrackParticles",
"InDetLargeD0TrackParticles"}),
 
   39     m_useImprovedMass(
false),
 
   41     m_jxMassUpper(30000.0),
 
   43     m_jpsiMassUpper(20000.0),
 
   44     m_diTrackMassLower(-1.0),
 
   45     m_diTrackMassUpper(-1.0),
 
   46     m_V01Hypothesis(
"Ks"),
 
   47     m_V02Hypothesis(
"Lambda"),
 
   48     m_LambdaMassLower(0.0),
 
   49     m_LambdaMassUpper(10000.0),
 
   51     m_KsMassUpper(10000.0),
 
   54     m_minMass_gamma(-1.0),
 
   55     m_chi2cut_gamma(-1.0),
 
   56     m_JXV02MassLower(0.0),
 
   57     m_JXV02MassUpper(30000.0),
 
   61     m_jxDaug1MassHypo(-1),
 
   62     m_jxDaug2MassHypo(-1),
 
   63     m_jxDaug3MassHypo(-1),
 
   64     m_jxDaug4MassHypo(-1),
 
   89     m_maxMainVCandidates(0),
 
   90     m_iVertexFitter(
"Trk::TrkVKalVrtFitter"),
 
   91     m_iV0Fitter(
"Trk::V0VertexFitter"),
 
   92     m_iGammaFitter(
"Trk::TrkVKalVrtFitter"),
 
   93     m_pvRefitter(
"Analysis::PrimaryVertexRefitter", 
this),
 
   94     m_V0Tools(
"Trk::V0Tools"),
 
   95     m_trackToVertexTool(
"Reco::TrackToVertex"),
 
   96     m_v0TrkSelector(
"InDet::TrackSelectorTool"),
 
   97     m_CascadeTools(
"DerivationFramework::CascadeTools"),
 
   98     m_vertexEstimator(
"InDet::VertexPointEstimator"),
 
   99     m_extrapolator(
"Trk::Extrapolator/AtlasExtrapolator")
 
  101     declareProperty(
"JXVertices",               m_vertexJXContainerKey);
 
  102     declareProperty(
"V0Vertices",               m_vertexV0ContainerKey);
 
  103     declareProperty(
"JXVtxHypoNames",           m_vertexJXHypoNames);
 
  104     declareProperty(
"CascadeVertexCollections", m_cascadeOutputKeys); 
 
  105     declareProperty(
"OutoutV0VtxCollection",    m_v0VtxOutputKey);
 
  106     declareProperty(
"TrackParticleCollection",  m_TrkParticleCollection);
 
  107     declareProperty(
"VxPrimaryCandidateName",   m_VxPrimaryCandidateName);
 
  108     declareProperty(
"RefPVContainerName",       m_refPVContainerName);
 
  109     declareProperty(
"EventInfoKey",             m_eventInfo_key);
 
  110     declareProperty(
"RelinkTracks",             m_RelinkContainers);
 
  111     declareProperty(
"UseImprovedMass",          m_useImprovedMass);
 
  112     declareProperty(
"JXMassLowerCut",           m_jxMassLower); 
 
  113     declareProperty(
"JXMassUpperCut",           m_jxMassUpper); 
 
  114     declareProperty(
"JpsiMassLowerCut",         m_jpsiMassLower);
 
  115     declareProperty(
"JpsiMassUpperCut",         m_jpsiMassUpper);
 
  116     declareProperty(
"DiTrackMassLower",         m_diTrackMassLower); 
 
  117     declareProperty(
"DiTrackMassUpper",         m_diTrackMassUpper); 
 
  118     declareProperty(
"V01Hypothesis",            m_V01Hypothesis); 
 
  119     declareProperty(
"V02Hypothesis",            m_V02Hypothesis); 
 
  120     declareProperty(
"LxyV01Cut",                m_lxyV01_cut);
 
  121     declareProperty(
"LxyV02Cut",                m_lxyV02_cut);
 
  122     declareProperty(
"LambdaMassLowerCut",       m_LambdaMassLower);
 
  123     declareProperty(
"LambdaMassUpperCut",       m_LambdaMassUpper);
 
  124     declareProperty(
"KsMassLowerCut",           m_KsMassLower);
 
  125     declareProperty(
"KsMassUpperCut",           m_KsMassUpper);
 
  126     declareProperty(
"MassCutGamma",             m_minMass_gamma);
 
  127     declareProperty(
"Chi2CutGamma",             m_chi2cut_gamma);
 
  128     declareProperty(
"JXV02MassLowerCut",        m_JXV02MassLower); 
 
  129     declareProperty(
"JXV02MassUpperCut",        m_JXV02MassUpper); 
 
  130     declareProperty(
"MassLowerCut",             m_MassLower);
 
  131     declareProperty(
"MassUpperCut",             m_MassUpper);
 
  132     declareProperty(
"HypothesisName",           m_hypoName = 
"TQ");
 
  133     declareProperty(
"NumberOfJXDaughters",      m_jxDaug_num); 
 
  134     declareProperty(
"JXDaug1MassHypo",          m_jxDaug1MassHypo);
 
  135     declareProperty(
"JXDaug2MassHypo",          m_jxDaug2MassHypo);
 
  136     declareProperty(
"JXDaug3MassHypo",          m_jxDaug3MassHypo);
 
  137     declareProperty(
"JXDaug4MassHypo",          m_jxDaug4MassHypo);
 
  138     declareProperty(
"JXMass",                   m_massJX); 
 
  139     declareProperty(
"JpsiMass",                 m_massJpsi);
 
  140     declareProperty(
"XMass",                    m_massX); 
 
  141     declareProperty(
"LambdaMass",               m_massLd);
 
  142     declareProperty(
"KsMass",                   m_massKs);
 
  143     declareProperty(
"JXV02VtxMass",             m_massJXV02); 
 
  144     declareProperty(
"MainVtxMass",              m_massMainV);
 
  145     declareProperty(
"ApplyJXMassConstraint",    m_constrJX); 
 
  146     declareProperty(
"ApplyJpsiMassConstraint",  m_constrJpsi);
 
  147     declareProperty(
"ApplyXMassConstraint",     m_constrX); 
 
  148     declareProperty(
"ApplyV01MassConstraint",   m_constrV01); 
 
  149     declareProperty(
"ApplyV02MassConstraint",   m_constrV02); 
 
  150     declareProperty(
"ApplyJXV02MassConstraint", m_constrJXV02); 
 
  151     declareProperty(
"ApplyMainVMassConstraint", m_constrMainV);
 
  152     declareProperty(
"HasJXSubVertex",           m_JXSubVtx);
 
  153     declareProperty(
"HasJXV02SubVertex",        m_JXV02SubVtx); 
 
  154     declareProperty(
"Chi2CutJX",                m_chi2cut_JX);
 
  155     declareProperty(
"Chi2CutV0",                m_chi2cut_V0);
 
  156     declareProperty(
"Chi2Cut",                  m_chi2cut);
 
  157     declareProperty(
"UseTRT",                   m_useTRT);
 
  158     declareProperty(
"PtTRT",                    m_ptTRT);
 
  159     declareProperty(
"Trackd0Cut",               m_d0_cut);
 
  160     declareProperty(
"MaxJXCandidates",          m_maxJXCandidates);
 
  161     declareProperty(
"MaxV0Candidates",          m_maxV0Candidates);
 
  162     declareProperty(
"MaxMainVCandidates",       m_maxMainVCandidates);
 
  163     declareProperty(
"RefitPV",                  m_refitPV         = 
true);
 
  164     declareProperty(
"MaxnPV",                   m_PV_max          = 1000);
 
  165     declareProperty(
"MinNTracksInPV",           m_PV_minNTracks   = 0);
 
  166     declareProperty(
"DoVertexType",             m_DoVertexType    = 7);
 
  167     declareProperty(
"TrkVertexFitterTool",      m_iVertexFitter);
 
  168     declareProperty(
"V0VertexFitterTool",       m_iV0Fitter);
 
  169     declareProperty(
"GammaFitterTool",          m_iGammaFitter);
 
  170     declareProperty(
"PVRefitter",               m_pvRefitter);
 
  171     declareProperty(
"V0Tools",                  m_V0Tools);
 
  172     declareProperty(
"TrackToVertexTool",        m_trackToVertexTool);
 
  173     declareProperty(
"V0TrackSelectorTool",      m_v0TrkSelector);
 
  174     declareProperty(
"CascadeTools",             m_CascadeTools);
 
  175     declareProperty(
"VertexPointEstimator",     m_vertexEstimator);
 
  176     declareProperty(
"Extrapolator",             m_extrapolator);
 
  182       ATH_MSG_FATAL(
"Incorrect V0 container hypothesis - not recognized");
 
  183       return StatusCode::FAILURE;
 
  186     if(m_jxDaug_num<2 || m_jxDaug_num>4) {
 
  188       return StatusCode::FAILURE;
 
  192       ATH_MSG_FATAL(
"Input and output V0 container names can not be both empty");
 
  193       return StatusCode::FAILURE;
 
  273     return StatusCode::SUCCESS;
 
  276   StatusCode JpsiXPlus2V0::performSearch(std::vector<Trk::VxCascadeInfo*>& cascadeinfoContainer, 
const std::vector<std::pair<const xAOD::Vertex*,V0Enum> >& selectedV0Candidates, 
const EventContext& ctx)
 const {
 
  278     if(selectedV0Candidates.size()==0) 
return StatusCode::SUCCESS;
 
  281     std::vector<const xAOD::TrackParticleContainer*> trackCols;
 
  285       trackCols.push_back(handle.
cptr());
 
  297     std::vector<const xAOD::Vertex*> selectedJXCandidates;
 
  298     for(
auto vxcItr=jxContainer.
ptr()->
begin(); vxcItr!=jxContainer.
ptr()->
end(); ++vxcItr) {
 
  311       TLorentzVector p4_mu1, p4_mu2;
 
  314       double mass_jpsi = (p4_mu1 + p4_mu2).M();
 
  315       if (mass_jpsi < m_jpsiMassLower || mass_jpsi > 
m_jpsiMassUpper) 
continue;
 
  317       TLorentzVector p4_trk1, p4_trk2;
 
  322     double mass_jx = (p4_mu1 + p4_mu2 + p4_trk1).M();
 
  324     if(mass_jx < m_jxMassLower || mass_jx > 
m_jxMassUpper) 
continue;
 
  327     double mass_jx = (p4_mu1 + p4_mu2 + p4_trk1 + p4_trk2).M();
 
  329     if(mass_jx < m_jxMassLower || mass_jx > 
m_jxMassUpper) 
continue;
 
  332       double mass_diTrk = (p4_trk1 + p4_trk2).M();
 
  340       selectedJXCandidates.push_back(vtx);
 
  342     if(selectedJXCandidates.size()==0) 
return StatusCode::SUCCESS;
 
  344     std::sort( selectedJXCandidates.begin(), selectedJXCandidates.end(), [](
const xAOD::Vertex* 
a, 
const xAOD::Vertex* 
b) { return a->chiSquared()/a->numberDoF() < b->chiSquared()/b->numberDoF(); } );
 
  346       selectedJXCandidates.erase(selectedJXCandidates.begin()+
m_maxJXCandidates, selectedJXCandidates.end());
 
  350     std::vector<const xAOD::TrackParticle*> tracksJX; tracksJX.reserve(
m_jxDaug_num);
 
  351     std::vector<const xAOD::TrackParticle*> tracksV01; tracksV01.reserve(2);
 
  352     for(
auto jxItr=selectedJXCandidates.cbegin(); jxItr!=selectedJXCandidates.cend(); ++jxItr) {
 
  354       for(
size_t i=0; 
i<(*jxItr)->nTrackParticles(); 
i++) tracksJX.push_back((*jxItr)->trackParticle(
i));
 
  355       for(
auto V0Itr1=selectedV0Candidates.cbegin(); V0Itr1!=selectedV0Candidates.cend(); ++V0Itr1) {
 
  356     if(
std::find(tracksJX.cbegin(), tracksJX.cend(), V0Itr1->first->trackParticle(0)) != tracksJX.cend()) 
continue;
 
  357     if(
std::find(tracksJX.cbegin(), tracksJX.cend(), V0Itr1->first->trackParticle(1)) != tracksJX.cend()) 
continue;
 
  359     for(
size_t j=0; j<V0Itr1->first->nTrackParticles(); j++) tracksV01.push_back(V0Itr1->first->trackParticle(j));
 
  360     for(
auto V0Itr2=V0Itr1+1; V0Itr2!=selectedV0Candidates.cend(); ++V0Itr2) {
 
  361       if(
std::find(tracksJX.cbegin(), tracksJX.cend(), V0Itr2->first->trackParticle(0)) != tracksJX.cend()) 
continue;
 
  362       if(
std::find(tracksJX.cbegin(), tracksJX.cend(), V0Itr2->first->trackParticle(1)) != tracksJX.cend()) 
continue;
 
  363       if(
std::find(tracksV01.cbegin(), tracksV01.cend(), V0Itr2->first->trackParticle(0)) != tracksV01.cend()) 
continue;
 
  364       if(
std::find(tracksV01.cbegin(), tracksV01.cend(), V0Itr2->first->trackParticle(1)) != tracksV01.cend()) 
continue;
 
  366       int numberOfVertices = 0;
 
  376           else numberOfVertices = -1;
 
  385           else numberOfVertices = -1;
 
  389         if(V0Itr1->second==
KS && (V0Itr2->second==
LAMBDA || V0Itr2->second==
LAMBDABAR)) numberOfVertices = 1;
 
  390         else if(V0Itr2->second==
KS && (V0Itr1->second==
LAMBDA || V0Itr1->second==
LAMBDABAR)) numberOfVertices = -1;
 
  393         if((V0Itr1->second==
LAMBDA || V0Itr1->second==
LAMBDABAR) && V0Itr2->second==
KS) numberOfVertices = 1;
 
  394         else if((V0Itr2->second==
LAMBDA || V0Itr2->second==
LAMBDABAR) && V0Itr1->second==
KS) numberOfVertices = -1;
 
  403       if(numberOfVertices==2) {
 
  405         if(result1) cascadeinfoContainer.push_back(result1);
 
  407         if(result2) cascadeinfoContainer.push_back(result2);
 
  409       else if(numberOfVertices==1) {
 
  413       else if(numberOfVertices==-1) {
 
  421     return StatusCode::SUCCESS;
 
  429       ATH_MSG_FATAL(
"Incorrect number of output cascade vertices");
 
  430       return StatusCode::FAILURE;
 
  433     std::array<SG::WriteHandle<xAOD::VertexContainer>, 4> VtxWriteHandles; 
int ikey(0);
 
  436       ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
 
  446     if (pvContainer.
cptr()->
size()==0) {
 
  448       return StatusCode::RECOVERABLE;
 
  450     else primaryVertex = (*pvContainer.
cptr())[0];
 
  458       ATH_CHECK( refPvContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
 
  466     std::vector<const xAOD::TrackParticleContainer*> trackCols;
 
  470       trackCols.push_back(handle.
cptr());
 
  477       ATH_CHECK( V0OutputContainer.
record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
 
  484     if(jxContainer->
size()==0) 
return StatusCode::SUCCESS;
 
  487     std::vector<const xAOD::TrackParticle*> tracksDisplaced;
 
  496       if(!
m_useTRT && nclus == 0) 
continue;
 
  498       bool trk_cut = 
false;
 
  499       if(nclus != 0) trk_cut = 
true;
 
  500       if(nclus == 0 && TP->pt()>=
m_ptTRT) trk_cut = 
true;
 
  501       if(!trk_cut) 
continue;
 
  504       if(!
d0Pass(TP,primaryVertex)) 
continue;
 
  506       tracksDisplaced.push_back(TP);
 
  517     std::vector<std::pair<const xAOD::Vertex*,V0Enum> > selectedV0Candidates;
 
  525     std::string type_V0Vtx;
 
  526     if(mAcc_type.
isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
 
  529     if(type_V0Vtx == 
"Lambda") {
 
  534     else if(type_V0Vtx == 
"Lambdabar") {
 
  539     else if(type_V0Vtx == 
"Ks") {
 
  551     int gamma_fit      = mAcc_gfit.
isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
 
  552     double gamma_mass  = mAcc_gmass.
isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
 
  553     double gamma_chisq = mAcc_gchisq.
isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
 
  554     double gamma_ndof  = mAcc_gndof.
isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
 
  557     selectedV0Candidates.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,
opt});
 
  565     std::string type_V0Vtx;
 
  566     if(mAcc_type.
isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
 
  569     if(type_V0Vtx == 
"Lambda") {
 
  574     else if(type_V0Vtx == 
"Lambdabar") {
 
  579     else if(type_V0Vtx == 
"Ks") {
 
  591     int gamma_fit      = mAcc_gfit.
isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
 
  592     double gamma_mass  = mAcc_gmass.
isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
 
  593     double gamma_chisq = mAcc_gchisq.
isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
 
  594     double gamma_ndof  = mAcc_gndof.
isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
 
  597     selectedV0Candidates.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,
opt});
 
  602     std::sort( selectedV0Candidates.begin(), selectedV0Candidates.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(); } );
 
  604       selectedV0Candidates.erase(selectedV0Candidates.begin()+
m_maxV0Candidates, selectedV0Candidates.end());
 
  606     if(selectedV0Candidates.size()==0) 
return StatusCode::SUCCESS;
 
  608     std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
 
  615       cascadeinfoContainer.erase(cascadeinfoContainer.begin()+
m_maxMainVCandidates, cascadeinfoContainer.end());
 
  654     for(
auto cascade_info : cascadeinfoContainer) {
 
  655       if(cascade_info==
nullptr) {
 
  660       const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->vertices();
 
  661       if(cascadeVertices.size() != topoN) 
ATH_MSG_ERROR(
"Incorrect number of vertices");
 
  662       for(
size_t i=0; 
i<topoN; 
i++) {
 
  663     if(cascadeVertices[
i]==
nullptr) 
ATH_MSG_ERROR(
"Error null vertex");
 
  666       cascade_info->setSVOwnership(
false); 
 
  667       const auto mainVertex = cascadeVertices[topoN-1]; 
 
  668       const std::vector< std::vector<TLorentzVector> > &moms = cascade_info->getParticleMoms();
 
  673       if(
m_jxDaug_num==4) jxVtx = FindVertex<4>(jxContainer.
ptr(), cascadeVertices[ijx]);
 
  674       else if(
m_jxDaug_num==3) jxVtx = FindVertex<3>(jxContainer.
ptr(), cascadeVertices[ijx]);
 
  675       else jxVtx = FindVertex<2>(jxContainer.
ptr(), cascadeVertices[ijx]);
 
  692       PtErr_decor(*mainVertex)    = 
m_CascadeTools->pTError(moms[topoN-1],cascade_info->getCovariance()[topoN-1]);
 
  694       chi2_decor(*mainVertex)     = cascade_info->fitChi2();
 
  695       ndof_decor(*mainVertex)     = cascade_info->nDoF();
 
  698       lxy_SV1_decor(*cascadeVertices[0])     = 
m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
 
  699       lxyErr_SV1_decor(*cascadeVertices[0])  = 
m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
 
  700       a0z_SV1_decor(*cascadeVertices[0])     = 
m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
 
  701       a0zErr_SV1_decor(*cascadeVertices[0])  = 
m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
 
  702       a0xy_SV1_decor(*cascadeVertices[0])    = 
m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
 
  703       a0xyErr_SV1_decor(*cascadeVertices[0]) = 
m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
 
  706     lxy_SV2_decor(*cascadeVertices[1])     = 
m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[2]);
 
  707     lxyErr_SV2_decor(*cascadeVertices[1])  = 
m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
 
  708     a0z_SV2_decor(*cascadeVertices[1])     = 
m_CascadeTools->a0z(moms[1],cascadeVertices[1],cascadeVertices[2]);
 
  709     a0zErr_SV2_decor(*cascadeVertices[1])  = 
m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
 
  710     a0xy_SV2_decor(*cascadeVertices[1])    = 
m_CascadeTools->a0xy(moms[1],cascadeVertices[1],cascadeVertices[2]);
 
  711     a0xyErr_SV2_decor(*cascadeVertices[1]) = 
m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
 
  714     lxy_SV2_decor(*cascadeVertices[1])     = 
m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
 
  715     lxyErr_SV2_decor(*cascadeVertices[1])  = 
m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
 
  716     a0z_SV2_decor(*cascadeVertices[1])     = 
m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
 
  717     a0zErr_SV2_decor(*cascadeVertices[1])  = 
m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
 
  718     a0xy_SV2_decor(*cascadeVertices[1])    = 
m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
 
  719     a0xyErr_SV2_decor(*cascadeVertices[1]) = 
m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
 
  723     lxy_SV3_decor(*cascadeVertices[2])     = 
m_CascadeTools->lxy(moms[2],cascadeVertices[2],mainVertex);
 
  724     lxyErr_SV3_decor(*cascadeVertices[2])  = 
m_CascadeTools->lxyError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
 
  725     a0z_SV3_decor(*cascadeVertices[2])     = 
m_CascadeTools->a0z(moms[2],cascadeVertices[2],mainVertex);
 
  726     a0zErr_SV3_decor(*cascadeVertices[2])  = 
m_CascadeTools->a0zError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
 
  727     a0xy_SV3_decor(*cascadeVertices[2])    = 
m_CascadeTools->a0xy(moms[2],cascadeVertices[2],mainVertex);
 
  728     a0xyErr_SV3_decor(*cascadeVertices[2]) = 
m_CascadeTools->a0xyError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
 
  731       chi2_V3_decor(*cascadeVertices[2])     = 
m_V0Tools->chisq(jxVtx);
 
  732       ndof_V3_decor(*cascadeVertices[2])     = 
m_V0Tools->ndof(jxVtx);
 
  737       for(
size_t i=0; 
i<topoN; 
i++) {
 
  738         VtxWriteHandles[
i].ptr()->push_back(cascadeVertices[
i]);
 
  746       if( vertexLink1.
isValid() ) cascadeVertexLinks.push_back( vertexLink1 );
 
  750       if( vertexLink2.
isValid() ) cascadeVertexLinks.push_back( vertexLink2 );
 
  755     if( vertexLink3.
isValid() ) cascadeVertexLinks.push_back( vertexLink3 );
 
  757       CascadeLinksDecor(*mainVertex) = cascadeVertexLinks;
 
  761     for (
auto cascade_info : cascadeinfoContainer) {
 
  762       if(cascade_info) 
delete cascade_info;
 
  765     return StatusCode::SUCCESS;
 
  770     const EventContext& ctx = Gaudi::Hive::currentContext();
 
  772     if(!per) 
return pass;
 
  774     double sig_d0 = sqrt((*per->covariance())(0,0));
 
  775     if(std::abs(
d0/sig_d0) > 
m_d0_cut) pass = 
true;
 
  782     std::vector<const xAOD::TrackParticle*> tracksJX;
 
  784     if (tracksJX.size() != massesJX.size()) {
 
  785       ATH_MSG_ERROR(
"Problems with JX input: number of tracks or track mass inputs is not correct!");
 
  788     std::vector<const xAOD::TrackParticle*> tracksV01;
 
  790     std::vector<const xAOD::TrackParticle*> tracksV02;
 
  793     std::vector<const xAOD::TrackParticle*> tracksJpsi{tracksJX[0], tracksJX[1]};
 
  794     std::vector<const xAOD::TrackParticle*> tracksX;
 
  798     std::vector<double> massesV01;
 
  802     std::vector<double> massesV02;
 
  807     TLorentzVector p4_moth, p4_JX, p4_v01, p4_v02, 
tmp;
 
  810       p4_moth += 
tmp; p4_JX += 
tmp;
 
  814       p4_moth += V01_helper.
refTrk(
it,massesV01[
it]);
 
  815       p4_v01 += V01_helper.
refTrk(
it,massesV01[
it]);
 
  819       p4_moth += V02_helper.
refTrk(
it,massesV02[
it]);
 
  820       p4_v02 += V02_helper.
refTrk(
it,massesV02[
it]);
 
  822     double main_mass = p4_moth.M();
 
  834       double JXV02_mass = (p4_JX+p4_v02).M();
 
  868     std::vector<float> trk_px;
 
  869     std::vector<float> trk_py;
 
  870     std::vector<float> trk_pz;
 
  879     std::vector<Trk::VertexID> vrtList;
 
  888     vrtList.push_back(vID1);
 
  896     vrtList.push_back(vID2);
 
  901     std::vector<Trk::VertexID> vrtList1{vID1};
 
  902     std::vector<Trk::VertexID> vrtList2{vID2};
 
  908     vrtList1.push_back(vID3);
 
  910       std::vector<Trk::VertexID> cnstV; cnstV.clear();
 
  916     std::vector<const xAOD::TrackParticle*> 
tp; 
tp.clear();
 
  917     std::vector<double> tp_masses; tp_masses.clear();
 
  931     vrtList.push_back(vID3);
 
  933     std::vector<const xAOD::TrackParticle*> 
tp; 
tp.clear();
 
  934     std::vector<double> tp_masses; tp_masses.clear();
 
  950     std::vector<Trk::VertexID> cnstV; cnstV.clear();
 
  958       std::vector<Trk::VertexID> cnstV; cnstV.clear();
 
  964       std::vector<Trk::VertexID> cnstV; cnstV.clear();
 
  970     std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( 
m_iVertexFitter->fitCascade(*state) );
 
  972     if (fit_result != 
nullptr) {
 
  974     if(
v->nTrackParticles()==0) {
 
  975       std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
 
  976       v->setTrackParticleLinks(nullLinkVector);
 
  986       double chi2DOF = fit_result->
fitChi2()/fit_result->
nDoF();
 
  989       const std::vector<std::vector<TLorentzVector> > &moms = fit_result->
getParticleMoms();
 
  990       const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->
vertices();
 
  991       size_t iMoth = cascadeVertices.size()-1;
 
  992       double lxy_SV1 = 
m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
 
  995     chi2_V1_decor(*cascadeVertices[0]) = V01vtx->
chiSquared();
 
  996     ndof_V1_decor(*cascadeVertices[0]) = V01vtx->
numberDoF();
 
  997     if(V01==
LAMBDA)         type_V1_decor(*cascadeVertices[0]) = 
"Lambda";
 
  998     else if(V01==
LAMBDABAR) type_V1_decor(*cascadeVertices[0]) = 
"Lambdabar";
 
  999     else if(V01==
KS)        type_V1_decor(*cascadeVertices[0]) = 
"Ks";
 
 1000     mDec_gfit(*cascadeVertices[0])     = mAcc_gfit.
isAvailable(*V01vtx) ? mAcc_gfit(*V01vtx) : 0;
 
 1001     mDec_gmass(*cascadeVertices[0])    = mAcc_gmass.
isAvailable(*V01vtx) ? mAcc_gmass(*V01vtx) : -1;
 
 1002     mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.
isAvailable(*V01vtx) ? mAcc_gmasserr(*V01vtx) : -1;
 
 1003     mDec_gchisq(*cascadeVertices[0])   = mAcc_gchisq.
isAvailable(*V01vtx) ? mAcc_gchisq(*V01vtx) : 999999;
 
 1004     mDec_gndof(*cascadeVertices[0])    = mAcc_gndof.
isAvailable(*V01vtx) ? mAcc_gndof(*V01vtx) : 0;
 
 1005     mDec_gprob(*cascadeVertices[0])    = mAcc_gprob.
isAvailable(*V01vtx) ? mAcc_gprob(*V01vtx) : -1;
 
 1006     trk_px.clear(); trk_py.clear(); trk_pz.clear();
 
 1008       trk_px.push_back( V01_helper.
refTrk(
it).Px() );
 
 1009       trk_py.push_back( V01_helper.
refTrk(
it).Py() );
 
 1010       trk_pz.push_back( V01_helper.
refTrk(
it).Pz() );
 
 1012     trk_pxDeco(*cascadeVertices[0]) = trk_px;
 
 1013     trk_pyDeco(*cascadeVertices[0]) = trk_py;
 
 1014     trk_pzDeco(*cascadeVertices[0]) = trk_pz;
 
 1016     chi2_V2_decor(*cascadeVertices[1]) = V02vtx->
chiSquared();
 
 1017     ndof_V2_decor(*cascadeVertices[1]) = V02vtx->
numberDoF();
 
 1018     if(V02==
LAMBDA)         type_V2_decor(*cascadeVertices[1]) = 
"Lambda";
 
 1019     else if(V02==
LAMBDABAR) type_V2_decor(*cascadeVertices[1]) = 
"Lambdabar";
 
 1020     else if(V02==
KS)        type_V2_decor(*cascadeVertices[1]) = 
"Ks";
 
 1021     mDec_gfit(*cascadeVertices[1])     = mAcc_gfit.
isAvailable(*V02vtx) ? mAcc_gfit(*V02vtx) : 0;
 
 1022     mDec_gmass(*cascadeVertices[1])    = mAcc_gmass.
isAvailable(*V02vtx) ? mAcc_gmass(*V02vtx) : -1;
 
 1023     mDec_gmasserr(*cascadeVertices[1]) = mAcc_gmasserr.
isAvailable(*V02vtx) ? mAcc_gmasserr(*V02vtx) : -1;
 
 1024     mDec_gchisq(*cascadeVertices[1])   = mAcc_gchisq.
isAvailable(*V02vtx) ? mAcc_gchisq(*V02vtx) : 999999;
 
 1025     mDec_gndof(*cascadeVertices[1])    = mAcc_gndof.
isAvailable(*V02vtx) ? mAcc_gndof(*V02vtx) : 0;
 
 1026     mDec_gprob(*cascadeVertices[1])    = mAcc_gprob.
isAvailable(*V02vtx) ? mAcc_gprob(*V02vtx) : -1;
 
 1027     trk_px.clear(); trk_py.clear(); trk_pz.clear();
 
 1029       trk_px.push_back( V02_helper.
refTrk(
it).Px() );
 
 1030       trk_py.push_back( V02_helper.
refTrk(
it).Py() );
 
 1031       trk_pz.push_back( V02_helper.
refTrk(
it).Pz() );
 
 1033     trk_pxDeco(*cascadeVertices[1]) = trk_px;
 
 1034     trk_pyDeco(*cascadeVertices[1]) = trk_py;
 
 1035     trk_pzDeco(*cascadeVertices[1]) = trk_pz;
 
 1037     result = fit_result.release();
 
 1045     const EventContext& ctx = Gaudi::Hive::currentContext();
 
 1055     std::vector<const xAOD::TrackParticle*> posTracks;
 
 1056     std::vector<const xAOD::TrackParticle*> negTracks;
 
 1058       if(TP->charge()>0) posTracks.push_back(TP);
 
 1059       else negTracks.push_back(TP);
 
 1063       const Trk::Perigee& aPerigee1 = TP1->perigeeParameters();
 
 1065     const Trk::Perigee& aPerigee2 = TP2->perigeeParameters();
 
 1066     int sflag(0), errorcode(0);
 
 1068     if (errorcode != 0) {startingPoint(0) = 0.0; startingPoint(1) = 0.0; startingPoint(2) = 0.0;}
 
 1070     if (errorcode == 0 || errorcode == 5 || errorcode == 6 || errorcode == 8) {
 
 1074       std::vector<std::unique_ptr<const Trk::TrackParameters> > cleanup;
 
 1075       if(!extrapolatedPerigee1) extrapolatedPerigee1 = &TP1->perigeeParameters();
 
 1076       else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee1));
 
 1077       if(!extrapolatedPerigee2) extrapolatedPerigee2 = &TP2->perigeeParameters();
 
 1078       else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee2));
 
 1079       if(extrapolatedPerigee1 && extrapolatedPerigee2) {
 
 1081         TLorentzVector v1; TLorentzVector 
v2;
 
 1085           if((v1+
v2).M()>1030.0 && (v1+
v2).M()<1200.0) pass = 
true;
 
 1090           if((v1+
v2).M()>1030.0 && (v1+
v2).M()<1200.0) pass = 
true;
 
 1095           if((v1+
v2).M()>430.0 && (v1+
v2).M()<565.0) pass = 
true;
 
 1098           std::vector<const xAOD::TrackParticle*> tracksV0;
 
 1099           tracksV0.push_back(TP1); tracksV0.push_back(TP2);
 
 1100           std::unique_ptr<xAOD::Vertex> V0vtx = std::unique_ptr<xAOD::Vertex>( 
m_iV0Fitter->fit(tracksV0, startingPoint) );
 
 1108         if(massSig_V0_Lambda1<=massSig_V0_Lambda2 && massSig_V0_Lambda1<=massSig_V0_Ks) {
 
 1109           mDec_type(*V0vtx.get()) = 
"Lambda";
 
 1111         else if(massSig_V0_Lambda2<=massSig_V0_Lambda1 && massSig_V0_Lambda2<=massSig_V0_Ks) {
 
 1112           mDec_type(*V0vtx.get()) = 
"Lambdabar";
 
 1114         else if(massSig_V0_Ks<=massSig_V0_Lambda1 && massSig_V0_Ks<=massSig_V0_Lambda2) {
 
 1115           mDec_type(*V0vtx.get()) = 
"Ks";
 
 1118         int gamma_fit = 0; 
int gamma_ndof = 0; 
double gamma_chisq = 999999.;
 
 1119         double gamma_prob = -1., gamma_mass = -1., gamma_massErr = -1.;
 
 1120         std::unique_ptr<xAOD::Vertex> gammaVtx = std::unique_ptr<xAOD::Vertex>( 
m_iGammaFitter->fit(tracksV0, 
m_V0Tools->vtx(V0vtx.get())) );
 
 1125           gamma_chisq   = 
m_V0Tools->chisq(gammaVtx.get());
 
 1126           gamma_ndof    = 
m_V0Tools->ndof(gammaVtx.get());
 
 1127           gamma_prob    = 
m_V0Tools->vertexProbability(gammaVtx.get());
 
 1129         mDec_gfit(*V0vtx.get())     = gamma_fit;
 
 1130         mDec_gmass(*V0vtx.get())    = gamma_mass;
 
 1131         mDec_gmasserr(*V0vtx.get()) = gamma_massErr;
 
 1132         mDec_gchisq(*V0vtx.get())   = gamma_chisq;
 
 1133         mDec_gndof(*V0vtx.get())    = gamma_ndof;
 
 1134         mDec_gprob(*V0vtx.get())    = gamma_prob;
 
 1139         if(not trackCols.empty()){
 
 1142           } 
catch (std::runtime_error 
const& 
e) {
 
 1148         V0ContainerNew->
push_back(std::move(V0vtx));
 
 1157   template<
size_t NTracks>
 
 1160       assert(v1->nTrackParticles() == NTracks);
 
 1161       std::array<const xAOD::TrackParticle*, NTracks> a1;
 
 1162       std::array<const xAOD::TrackParticle*, NTracks> a2;
 
 1163       for(
size_t i=0; 
i<NTracks; 
i++){
 
 1164     a1[
i] = v1->trackParticle(
i);
 
 1165     a2[
i] = 
v->trackParticle(
i);
 
 1167       std::sort(a1.begin(), a1.end());
 
 1168       std::sort(a2.begin(), a2.end());
 
 1169       if(a1 == a2) 
return v1;