ATLAS Offline Software
Loading...
Searching...
No Matches
DerivationFramework::JpsiXPlusDisplaced Class Reference

#include <JpsiXPlusDisplaced.h>

Inheritance diagram for DerivationFramework::JpsiXPlusDisplaced:

Classes

struct  XiCandidate
struct  MesonCandidate
class  MesonCandidateVector

Public Types

enum  V0Enum { UNKNOWN =0 , LAMBDA =1 , LAMBDABAR =2 , KS =3 }

Public Member Functions

 JpsiXPlusDisplaced (const std::string &type, const std::string &name, const IInterface *parent)
virtual ~JpsiXPlusDisplaced ()=default
virtual StatusCode initialize () override
StatusCode performSearch (std::vector< std::pair< Trk::VxCascadeInfo *, Trk::VxCascadeInfo * > > &cascadeinfoContainer, const std::vector< std::pair< const xAOD::Vertex *, V0Enum > > &selectedV0Candidates, const std::vector< const xAOD::TrackParticle * > &tracksDisplaced, const EventContext &ctx) const
virtual StatusCode addBranches (const EventContext &ctx) const override

Private Member Functions

bool d0Pass (const EventContext &ctx, const xAOD::TrackParticle *track, const xAOD::Vertex *PV) const
XiCandidate getXiCandidate (const xAOD::Vertex *V0vtx, const V0Enum V0, const xAOD::TrackParticle *track3) const
std::unique_ptr< xAOD::VertexfitTracks (const xAOD::TrackParticle *track1, const xAOD::TrackParticle *track2, const xAOD::TrackParticle *track3=nullptr) const
MesonCandidate getDpmCandidate (const xAOD::Vertex *JXvtx, const xAOD::TrackParticle *extraTrk1, const xAOD::TrackParticle *extraTrk2, const xAOD::TrackParticle *extraTrk3) const
MesonCandidate getD0Candidate (const xAOD::Vertex *JXvtx, const xAOD::TrackParticle *extraTrk1, const xAOD::TrackParticle *extraTrk2) const
std::vector< std::pair< Trk::VxCascadeInfo *, Trk::VxCascadeInfo * > > fitMainVtx (const xAOD::Vertex *JXvtx, const std::vector< double > &massesJX, const xAOD::Vertex *V0vtx, const V0Enum V0, const xAOD::TrackParticleContainer *trackContainer, const std::vector< const xAOD::TrackParticleContainer * > &trackCols, const xAOD::VertexContainer *defaultPVContainer, const xAOD::VertexContainer *pvContainer) const
std::vector< std::pair< Trk::VxCascadeInfo *, Trk::VxCascadeInfo * > > fitMainVtx (const xAOD::Vertex *JXvtx, const std::vector< double > &massesJX, const XiCandidate &disVtx, const xAOD::TrackParticleContainer *trackContainer, const std::vector< const xAOD::TrackParticleContainer * > &trackCols, const xAOD::VertexContainer *defaultPVContainer, const xAOD::VertexContainer *pvContainer) const
void fitV0Container (const EventContext &ctx, xAOD::VertexContainer *V0ContainerNew, const std::vector< const xAOD::TrackParticle * > &selectedTracks, const std::vector< const xAOD::TrackParticleContainer * > &trackCols) const
template<size_t NTracks>
const xAOD::VertexFindVertex (const xAOD::VertexContainer *cont, const xAOD::Vertex *v) const

Private Attributes

SG::ReadHandleKey< xAOD::VertexContainerm_vertexJXContainerKey
SG::ReadHandleKey< xAOD::VertexContainerm_vertexV0ContainerKey
std::vector< std::string > m_vertexJXHypoNames
SG::WriteHandleKeyArray< xAOD::VertexContainerm_cascadeOutputKeys
SG::WriteHandleKeyArray< xAOD::VertexContainerm_cascadeOutputKeys_mvc
SG::WriteHandleKey< xAOD::VertexContainerm_v0VtxOutputKey
SG::ReadHandleKey< xAOD::TrackParticleContainerm_TrkParticleCollection
SG::ReadHandleKey< xAOD::VertexContainerm_VxPrimaryCandidateName
SG::ReadHandleKey< xAOD::VertexContainerm_pvContainerName
SG::WriteHandleKey< xAOD::VertexContainerm_refPVContainerName
SG::ReadHandleKey< xAOD::EventInfom_eventInfo_key
SG::ReadHandleKeyArray< xAOD::TrackParticleContainerm_RelinkContainers
std::string m_hypoName
bool m_useImprovedMass {}
double m_jxMassLower {}
double m_jxMassUpper {}
double m_jpsiMassLower {}
double m_jpsiMassUpper {}
double m_diTrackMassLower {}
double m_diTrackMassUpper {}
std::string m_V0Hypothesis {}
double m_LambdaMassLower {}
double m_LambdaMassUpper {}
double m_KsMassLower {}
double m_KsMassUpper {}
double m_lxyV0_cut {}
double m_minMass_gamma {}
double m_chi2cut_gamma {}
double m_DisplacedMassLower {}
double m_DisplacedMassUpper {}
double m_lxyDisV_cut {}
double m_lxyDpm_cut {}
double m_lxyD0_cut {}
double m_MassLower {}
double m_MassUpper {}
double m_PostMassLower {}
double m_PostMassUpper {}
int m_jxDaug_num {}
double m_jxDaug1MassHypo {}
double m_jxDaug2MassHypo {}
double m_jxDaug3MassHypo {}
double m_jxDaug4MassHypo {}
bool m_jxPtOrdering {}
int m_disVDaug_num {}
double m_disVDaug3MassHypo {}
double m_disVDaug3MinPt {}
double m_extraTrk1MassHypo {}
double m_extraTrk1MinPt {}
double m_extraTrk2MassHypo {}
double m_extraTrk2MinPt {}
double m_extraTrk3MassHypo {}
double m_extraTrk3MinPt {}
double m_DpmMassLower {}
double m_DpmMassUpper {}
double m_D0MassLower {}
double m_D0MassUpper {}
size_t m_maxMesonCandidates {}
bool m_MesonPtOrdering {}
double m_massJX {}
double m_massJpsi {}
double m_massX {}
double m_massDisV {}
double m_massLd {}
double m_massKs {}
double m_massDpm {}
double m_massD0 {}
double m_massJXV0 {}
double m_massMainV {}
bool m_constrJX {}
bool m_constrJpsi {}
bool m_constrX {}
bool m_constrDisV {}
bool m_constrV0 {}
bool m_constrDpm {}
bool m_constrD0 {}
bool m_constrJXV0 {}
bool m_constrMainV {}
int m_cascadeFitWithPV {}
bool m_firstDecayAtPV {}
bool m_doPostMainVContrFit {}
bool m_JXSubVtx {}
bool m_JXV0SubVtx {}
double m_chi2cut_JX {}
double m_chi2cut_V0 {}
double m_chi2cut_DisV {}
double m_chi2cut_Dpm {}
double m_chi2cut_D0 {}
double m_chi2cut {}
bool m_useTRT {}
double m_ptTRT {}
double m_d0_cut {}
unsigned int m_maxJXCandidates {}
unsigned int m_maxV0Candidates {}
unsigned int m_maxDisVCandidates {}
unsigned int m_maxMainVCandidates {}
ServiceHandle< IPartPropSvc > m_partPropSvc {this, "PartPropSvc", "PartPropSvc"}
ToolHandle< Trk::TrkVKalVrtFitterm_iVertexFitter
ToolHandle< Trk::TrkV0VertexFitterm_iV0Fitter
ToolHandle< Trk::IVertexFitterm_iGammaFitter
PublicToolHandle< Analysis::PrimaryVertexRefitterm_pvRefitter
PublicToolHandle< Trk::V0Toolsm_V0Tools
ToolHandle< Reco::ITrackToVertexm_trackToVertexTool
ToolHandle< Trk::ITrackSelectorToolm_trkSelector
ToolHandle< Trk::ITrackSelectorToolm_v0TrkSelector
PublicToolHandle< DerivationFramework::CascadeToolsm_CascadeTools
ToolHandle< InDet::VertexPointEstimatorm_vertexEstimator
ToolHandle< Trk::IExtrapolatorm_extrapolator
bool m_refitPV {}
int m_PV_max {}
size_t m_PV_minNTracks {}
int m_DoVertexType {}
double m_mass_e {}
double m_mass_mu {}
double m_mass_pion {}
double m_mass_proton {}
double m_mass_Lambda {}
double m_mass_Ks {}
double m_mass_Xi {}
double m_mass_phi {}
double m_mass_B0 {}
double m_mass_Dpm {}
double m_mass_D0 {}
double m_mass_BCPLUS {}
double m_mass_Lambdab {}
std::vector< double > m_massesV0_ppi
std::vector< double > m_massesV0_pip
std::vector< double > m_massesV0_pipi

Detailed Description

Definition at line 41 of file JpsiXPlusDisplaced.h.

Member Enumeration Documentation

◆ V0Enum

Constructor & Destructor Documentation

◆ JpsiXPlusDisplaced()

DerivationFramework::JpsiXPlusDisplaced::JpsiXPlusDisplaced ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 56 of file JpsiXPlusDisplaced.cxx.

56 : base_class(type,name,parent),
57 m_vertexJXContainerKey("InputJXVertices"),
59 m_cascadeOutputKeys({"JpsiXPlusDisVtx1_sub", "JpsiXPlusDisVtx1", "JpsiXPlusDisVtx2", "JpsiXPlusDisVtx3"}),
60 m_cascadeOutputKeys_mvc({"JpsiXPlusDisVtx1_sub_mvc", "JpsiXPlusDisVtx1_mvc", "JpsiXPlusDisVtx2_mvc", "JpsiXPlusDisVtx3_mvc"}),
62 m_TrkParticleCollection("InDetTrackParticles"),
63 m_VxPrimaryCandidateName("PrimaryVertices"),
64 m_pvContainerName("PrimaryVertices"),
65 m_refPVContainerName("RefittedPrimaryVertices"),
66 m_eventInfo_key("EventInfo"),
67 m_RelinkContainers({"InDetTrackParticles","InDetLargeD0TrackParticles"}),
68 m_useImprovedMass(false),
69 m_jxMassLower(0.0),
70 m_jxMassUpper(10000.0),
71 m_jpsiMassLower(0.0),
72 m_jpsiMassUpper(10000.0),
75 m_V0Hypothesis("Lambda"),
77 m_LambdaMassUpper(10000.0),
78 m_KsMassLower(0.0),
79 m_KsMassUpper(10000.0),
80 m_lxyV0_cut(-999.0),
81 m_minMass_gamma(-1.0),
82 m_chi2cut_gamma(-1.0),
84 m_DisplacedMassUpper(10000.0),
85 m_lxyDisV_cut(-999.0),
86 m_lxyDpm_cut(-999.0),
87 m_lxyD0_cut(-999.0),
88 m_MassLower(0.0),
89 m_MassUpper(31000.0),
90 m_PostMassLower(0.0),
91 m_PostMassUpper(31000.0),
92 m_jxDaug_num(4),
97 m_jxPtOrdering(false),
100 m_disVDaug3MinPt(480),
102 m_extraTrk1MinPt(480),
104 m_extraTrk2MinPt(480),
106 m_extraTrk3MinPt(480),
107 m_DpmMassLower(0.0),
108 m_DpmMassUpper(10000.0),
109 m_D0MassLower(0.0),
110 m_D0MassUpper(10000.0),
112 m_MesonPtOrdering(true),
113 m_massJX(-1),
114 m_massJpsi(-1),
115 m_massX(-1),
116 m_massDisV(-1),
117 m_massLd(-1),
118 m_massKs(-1),
119 m_massDpm(-1),
120 m_massD0(-1),
121 m_massJXV0(-1),
122 m_massMainV(-1),
123 m_constrJX(false),
124 m_constrJpsi(false),
125 m_constrX(false),
126 m_constrDisV(false),
127 m_constrV0(false),
128 m_constrDpm(false),
129 m_constrD0(false),
130 m_constrJXV0(false),
131 m_constrMainV(false),
133 m_firstDecayAtPV(false),
135 m_JXSubVtx(false),
136 m_JXV0SubVtx(false),
137 m_chi2cut_JX(-1.0),
138 m_chi2cut_V0(-1.0),
139 m_chi2cut_DisV(-1.0),
140 m_chi2cut_Dpm(-1.0),
141 m_chi2cut_D0(-1.0),
142 m_chi2cut(-1.0),
143 m_useTRT(false),
144 m_ptTRT(450),
145 m_d0_cut(2),
150 m_iVertexFitter("Trk::TrkVKalVrtFitter"),
151 m_iV0Fitter("Trk::V0VertexFitter"),
152 m_iGammaFitter("Trk::TrkVKalVrtFitter"),
153 m_pvRefitter("Analysis::PrimaryVertexRefitter"),
154 m_V0Tools("Trk::V0Tools"),
155 m_trackToVertexTool("Reco::TrackToVertex"),
156 m_trkSelector("InDet::TrackSelectorTool"),
157 m_v0TrkSelector("InDet::TrackSelectorTool"),
158 m_CascadeTools("DerivationFramework::CascadeTools"),
159 m_vertexEstimator("InDet::VertexPointEstimator"),
160 m_extrapolator("Trk::Extrapolator/AtlasExtrapolator")
161 {
162 declareProperty("JXVertices", m_vertexJXContainerKey);
163 declareProperty("V0Vertices", m_vertexV0ContainerKey);
164 declareProperty("JXVtxHypoNames", m_vertexJXHypoNames);
165 declareProperty("CascadeVertexCollections", m_cascadeOutputKeys); // size is 3 or 4 only
166 declareProperty("CascadeVertexCollectionsMVC",m_cascadeOutputKeys_mvc); // size is 3 or 4 only
167 declareProperty("OutputV0VtxCollection", m_v0VtxOutputKey);
168 declareProperty("TrackParticleCollection", m_TrkParticleCollection);
169 declareProperty("VxPrimaryCandidateName", m_VxPrimaryCandidateName);
170 declareProperty("PVContainerName", m_pvContainerName);
171 declareProperty("RefPVContainerName", m_refPVContainerName);
172 declareProperty("EventInfoKey", m_eventInfo_key);
173 declareProperty("RelinkTracks", m_RelinkContainers);
174 declareProperty("UseImprovedMass", m_useImprovedMass);
175 declareProperty("JXMassLowerCut", m_jxMassLower); // only effective when m_jxDaug_num>2
176 declareProperty("JXMassUpperCut", m_jxMassUpper); // only effective when m_jxDaug_num>2
177 declareProperty("JpsiMassLowerCut", m_jpsiMassLower);
178 declareProperty("JpsiMassUpperCut", m_jpsiMassUpper);
179 declareProperty("DiTrackMassLower", m_diTrackMassLower); // only effective when m_jxDaug_num=4
180 declareProperty("DiTrackMassUpper", m_diTrackMassUpper); // only effective when m_jxDaug_num=4
181 declareProperty("V0Hypothesis", m_V0Hypothesis); // "Ks" or "Lambda"
182 declareProperty("LambdaMassLowerCut", m_LambdaMassLower);
183 declareProperty("LambdaMassUpperCut", m_LambdaMassUpper);
184 declareProperty("KsMassLowerCut", m_KsMassLower);
185 declareProperty("KsMassUpperCut", m_KsMassUpper);
186 declareProperty("LxyV0Cut", m_lxyV0_cut);
187 declareProperty("MassCutGamma", m_minMass_gamma);
188 declareProperty("Chi2CutGamma", m_chi2cut_gamma);
189 declareProperty("DisplacedMassLowerCut", m_DisplacedMassLower); // only effective when m_disVDaug_num=3
190 declareProperty("DisplacedMassUpperCut", m_DisplacedMassUpper); // only effective when m_disVDaug_num=3
191 declareProperty("LxyDisVtxCut", m_lxyDisV_cut); // only effective when m_disVDaug_num=3
192 declareProperty("LxyDpmCut", m_lxyDpm_cut); // only effective for D+/-
193 declareProperty("LxyD0Cut", m_lxyD0_cut); // only effective for D0
194 declareProperty("MassLowerCut", m_MassLower);
195 declareProperty("MassUpperCut", m_MassUpper);
196 declareProperty("PostMassLowerCut", m_PostMassLower); // only effective when m_doPostMainVContrFit=true
197 declareProperty("PostMassUpperCut", m_PostMassUpper); // only effective when m_doPostMainVContrFit=true
198 declareProperty("HypothesisName", m_hypoName = "TQ");
199 declareProperty("NumberOfJXDaughters", m_jxDaug_num); // 2, or 3, or 4 only
200 declareProperty("JXDaug1MassHypo", m_jxDaug1MassHypo);
201 declareProperty("JXDaug2MassHypo", m_jxDaug2MassHypo);
202 declareProperty("JXDaug3MassHypo", m_jxDaug3MassHypo);
203 declareProperty("JXDaug4MassHypo", m_jxDaug4MassHypo);
204 declareProperty("JXPtOrdering", m_jxPtOrdering);
205 declareProperty("NumberOfDisVDaughters", m_disVDaug_num); // 2 or 3 only
206 declareProperty("DisVDaug3MassHypo", m_disVDaug3MassHypo); // only effective when m_disVDaug_num=3
207 declareProperty("DisVDaug3MinPt", m_disVDaug3MinPt); // only effective when m_disVDaug_num=3
208 declareProperty("ExtraTrack1MassHypo", m_extraTrk1MassHypo); // for decays like B- -> J/psi Lambda pbar, the extra track is pbar (for m_disVDaug_num=2 only now)
209 declareProperty("ExtraTrack1MinPt", m_extraTrk1MinPt); // only effective if m_extraTrk1MassHypo>0
210 declareProperty("ExtraTrack2MassHypo", m_extraTrk2MassHypo); // for decays like Xi_bc^0 -> Jpsi Lambda D0(->Kpi) (for m_disVDaug_num=2 only now)
211 declareProperty("ExtraTrack2MinPt", m_extraTrk2MinPt); // only effective if m_extraTrk2MassHypo>0
212 declareProperty("ExtraTrack3MassHypo", m_extraTrk3MassHypo); // for decays like Bc+ -> Jpsi D+ Ks (for m_disVDaug_num=2 only now)
213 declareProperty("ExtraTrack3MinPt", m_extraTrk3MinPt); // only effective if m_extraTrk3MassHypo>0
214 declareProperty("DpmMassLowerCut", m_DpmMassLower); // only for D+/-
215 declareProperty("DpmMassUpperCut", m_DpmMassUpper); // only for D+/-
216 declareProperty("D0MassLowerCut", m_D0MassLower); // only for D0
217 declareProperty("D0MassUpperCut", m_D0MassUpper); // only for D0
218 declareProperty("MaxMesonCandidates", m_maxMesonCandidates); // only for 2/3 extra tracks
219 declareProperty("MesonPtOrdering", m_MesonPtOrdering); // only for 2/3 extra tracks
220 declareProperty("JXMass", m_massJX); // only effective when m_jxDaug_num>2
221 declareProperty("JpsiMass", m_massJpsi);
222 declareProperty("XMass", m_massX); // only effective when m_jxDaug_num=4
223 declareProperty("DisVtxMass", m_massDisV); // only effective when m_disVDaug_num=3
224 declareProperty("LambdaMass", m_massLd);
225 declareProperty("KsMass", m_massKs);
226 declareProperty("DpmMass", m_massDpm);
227 declareProperty("D0Mass", m_massD0);
228 declareProperty("JXV0Mass", m_massJXV0);
229 declareProperty("MainVtxMass", m_massMainV);
230 declareProperty("ApplyJXMassConstraint", m_constrJX); // only effective when m_jxDaug_num>2
231 declareProperty("ApplyJpsiMassConstraint", m_constrJpsi);
232 declareProperty("ApplyXMassConstraint", m_constrX); // only effective when m_jxDaug_num=4
233 declareProperty("ApplyDisVMassConstraint", m_constrDisV); // only effective when m_disVDaug_num=3
234 declareProperty("ApplyV0MassConstraint", m_constrV0);
235 declareProperty("ApplyDpmMassConstraint", m_constrDpm); // only for D+/-
236 declareProperty("ApplyD0MassConstraint", m_constrD0); // only for D0
237 declareProperty("ApplyJXV0MassConstraint", m_constrJXV0);
238 declareProperty("ApplyMainVMassConstraint", m_constrMainV);
239 declareProperty("DoCascadeFitWithPV", m_cascadeFitWithPV);
240 declareProperty("FirstDecayAtPV", m_firstDecayAtPV);
241 declareProperty("DoPostMainVContrFit", m_doPostMainVContrFit); // only effective when m_constrMainV=false
242 declareProperty("HasJXSubVertex", m_JXSubVtx);
243 declareProperty("HasJXV0SubVertex", m_JXV0SubVtx);
244 declareProperty("Chi2CutJX", m_chi2cut_JX);
245 declareProperty("Chi2CutV0", m_chi2cut_V0);
246 declareProperty("Chi2CutDisV", m_chi2cut_DisV); // only effective when m_disVDaug_num=3
247 declareProperty("Chi2CutDpm", m_chi2cut_Dpm); // only for D+/-
248 declareProperty("Chi2CutD0", m_chi2cut_D0); // only for D0
249 declareProperty("Chi2Cut", m_chi2cut);
250 declareProperty("UseTRT", m_useTRT);
251 declareProperty("PtTRT", m_ptTRT);
252 declareProperty("Trackd0Cut", m_d0_cut);
253 declareProperty("MaxJXCandidates", m_maxJXCandidates);
254 declareProperty("MaxV0Candidates", m_maxV0Candidates);
255 declareProperty("MaxDisVCandidates", m_maxDisVCandidates); // only effective when m_disVDaug_num=3
256 declareProperty("MaxMainVCandidates", m_maxMainVCandidates);
257 declareProperty("RefitPV", m_refitPV = true);
258 declareProperty("MaxnPV", m_PV_max = 1000);
259 declareProperty("MinNTracksInPV", m_PV_minNTracks = 0);
260 declareProperty("DoVertexType", m_DoVertexType = 7);
261 declareProperty("TrkVertexFitterTool", m_iVertexFitter);
262 declareProperty("V0VertexFitterTool", m_iV0Fitter);
263 declareProperty("GammaFitterTool", m_iGammaFitter);
264 declareProperty("PVRefitter", m_pvRefitter);
265 declareProperty("V0Tools", m_V0Tools);
266 declareProperty("TrackToVertexTool", m_trackToVertexTool);
267 declareProperty("TrackSelectorTool", m_trkSelector);
268 declareProperty("V0TrackSelectorTool", m_v0TrkSelector);
269 declareProperty("CascadeTools", m_CascadeTools);
270 declareProperty("VertexPointEstimator", m_vertexEstimator);
271 declareProperty("Extrapolator", m_extrapolator);
272 }
ToolHandle< Trk::ITrackSelectorTool > m_trkSelector
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo_key
ToolHandle< Trk::TrkV0VertexFitter > m_iV0Fitter
SG::WriteHandleKeyArray< xAOD::VertexContainer > m_cascadeOutputKeys
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_TrkParticleCollection
ToolHandle< Trk::TrkVKalVrtFitter > m_iVertexFitter
ToolHandle< Trk::IVertexFitter > m_iGammaFitter
PublicToolHandle< DerivationFramework::CascadeTools > m_CascadeTools
std::vector< std::string > m_vertexJXHypoNames
SG::WriteHandleKeyArray< xAOD::VertexContainer > m_cascadeOutputKeys_mvc
SG::ReadHandleKeyArray< xAOD::TrackParticleContainer > m_RelinkContainers
SG::WriteHandleKey< xAOD::VertexContainer > m_refPVContainerName
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexV0ContainerKey
SG::WriteHandleKey< xAOD::VertexContainer > m_v0VtxOutputKey
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexJXContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_VxPrimaryCandidateName
ToolHandle< Trk::ITrackSelectorTool > m_v0TrkSelector
PublicToolHandle< Analysis::PrimaryVertexRefitter > m_pvRefitter
SG::ReadHandleKey< xAOD::VertexContainer > m_pvContainerName
ToolHandle< Reco::ITrackToVertex > m_trackToVertexTool
ToolHandle< Trk::IExtrapolator > m_extrapolator
ToolHandle< InDet::VertexPointEstimator > m_vertexEstimator
PublicToolHandle< Trk::V0Tools > m_V0Tools

◆ ~JpsiXPlusDisplaced()

virtual DerivationFramework::JpsiXPlusDisplaced::~JpsiXPlusDisplaced ( )
virtualdefault

Member Function Documentation

◆ addBranches()

StatusCode DerivationFramework::JpsiXPlusDisplaced::addBranches ( const EventContext & ctx) const
overridevirtual

Definition at line 549 of file JpsiXPlusDisplaced.cxx.

549 {
550 size_t topoN = (m_disVDaug_num==2 ? 3 : 4);
551 if(!m_JXSubVtx) topoN--;
552 if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0) { // special cases
553 if(m_JXV0SubVtx) topoN = 4;
554 else topoN = 3;
555 }
556 else if(m_extraTrk1MassHypo>0 && m_disVDaug_num==2) { // special cases
557 if(m_JXV0SubVtx || m_JXSubVtx) topoN = 3;
558 else topoN = 2;
559 }
560
561 if(m_cascadeOutputKeys.size() != topoN) {
562 ATH_MSG_FATAL("Incorrect number of output cascade vertices");
563 return StatusCode::FAILURE;
564 }
566 ATH_MSG_FATAL("Incorrect number of output (mvc) cascade vertices");
567 return StatusCode::FAILURE;
568 }
569
570 std::array<SG::WriteHandle<xAOD::VertexContainer>, 4> VtxWriteHandles; int ikey(0);
571 for(const SG::WriteHandleKey<xAOD::VertexContainer>& key : m_cascadeOutputKeys) {
572 VtxWriteHandles[ikey] = SG::WriteHandle<xAOD::VertexContainer>(key, ctx);
573 ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
574 ikey++;
575 }
576 std::array<SG::WriteHandle<xAOD::VertexContainer>, 4> VtxWriteHandles_mvc; int ikey_mvc(0);
578 for(const SG::WriteHandleKey<xAOD::VertexContainer>& key_mvc : m_cascadeOutputKeys_mvc) {
579 VtxWriteHandles_mvc[ikey_mvc] = SG::WriteHandle<xAOD::VertexContainer>(key_mvc, ctx);
580 ATH_CHECK( VtxWriteHandles_mvc[ikey_mvc].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
581 ikey_mvc++;
582 }
583 }
584
585 //----------------------------------------------------
586 // retrieve primary vertices
587 //----------------------------------------------------
588 const xAOD::Vertex* primaryVertex(nullptr);
589 SG::ReadHandle<xAOD::VertexContainer> defaultPVContainer(m_VxPrimaryCandidateName, ctx);
590 ATH_CHECK( defaultPVContainer.isValid() );
591 if (defaultPVContainer.cptr()->size()==0) {
592 ATH_MSG_WARNING("You have no primary vertices: " << defaultPVContainer.cptr()->size());
593 return StatusCode::RECOVERABLE;
594 }
595 else primaryVertex = (*defaultPVContainer.cptr())[0];
596
597 //----------------------------------------------------
598 // Record refitted primary vertices
599 //----------------------------------------------------
600 SG::WriteHandle<xAOD::VertexContainer> refPvContainer;
601 if(m_refitPV) {
602 refPvContainer = SG::WriteHandle<xAOD::VertexContainer>(m_refPVContainerName, ctx);
603 ATH_CHECK( refPvContainer.record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
604 }
605
606 // Get TrackParticle container (standard + LRT)
607 SG::ReadHandle<xAOD::TrackParticleContainer> trackContainer(m_TrkParticleCollection, ctx);
608 ATH_CHECK( trackContainer.isValid() );
609
610 // Get all track containers when m_RelinkContainers is not empty
611 std::vector<const xAOD::TrackParticleContainer*> trackCols;
612 for(const SG::ReadHandleKey<xAOD::TrackParticleContainer>& key : m_RelinkContainers){
613 SG::ReadHandle<xAOD::TrackParticleContainer> handle(key, ctx);
614 ATH_CHECK( handle.isValid() );
615 trackCols.push_back(handle.cptr());
616 }
617
618 // output V0 vertices
619 SG::WriteHandle<xAOD::VertexContainer> V0OutputContainer;
620 if(m_vertexV0ContainerKey.key()=="" && m_v0VtxOutputKey.key()!="") {
621 V0OutputContainer = SG::WriteHandle<xAOD::VertexContainer>(m_v0VtxOutputKey, ctx);
622 ATH_CHECK( V0OutputContainer.record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
623 }
624
625 // Get Jpsi+X container
626 // Note: If the event does not contain a JX candidate, it is skipped and the V0 container will not be constructed if not previously available in StoreGate
627 SG::ReadHandle<xAOD::VertexContainer> jxContainer(m_vertexJXContainerKey, ctx);
628 ATH_CHECK( jxContainer.isValid() );
629 if(jxContainer->size()==0) return StatusCode::SUCCESS;
630
631 // Select the displaced tracks
632 std::vector<const xAOD::TrackParticle*> tracksDisplaced;
633 if(m_v0VtxOutputKey.key()!="" || m_disVDaug_num==3) {
634 for(const xAOD::TrackParticle* TP : *trackContainer.cptr()) {
635 // V0 track selection (https://gitlab.cern.ch/atlas/athena/-/blob/main/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetConversionTrackSelectorTool.cxx)
636 if(m_v0TrkSelector->decision(*TP, primaryVertex)) {
637 uint8_t temp(0);
638 uint8_t nclus(0);
639 if(TP->summaryValue(temp, xAOD::numberOfPixelHits)) nclus += temp;
640 if(TP->summaryValue(temp, xAOD::numberOfSCTHits) ) nclus += temp;
641 if(!m_useTRT && nclus == 0) continue;
642
643 bool trk_cut = false;
644 if(nclus != 0) trk_cut = true;
645 if(nclus == 0 && TP->pt()>=m_ptTRT) trk_cut = true;
646 if(!trk_cut) continue;
647
648 // track is used if std::abs(d0/sig_d0) > d0_cut for PV
649 if(!d0Pass(ctx,TP,primaryVertex)) continue;
650
651 tracksDisplaced.push_back(TP);
652 }
653 }
654 }
655
656 SG::AuxElement::Accessor<std::string> mAcc_type("Type_V0Vtx");
657 SG::AuxElement::Accessor<int> mAcc_gfit("gamma_fit");
658 SG::AuxElement::Accessor<float> mAcc_gmass("gamma_mass");
659 SG::AuxElement::Accessor<float> mAcc_gchisq("gamma_chisq");
660 SG::AuxElement::Accessor<int> mAcc_gndof("gamma_ndof");
661
662 std::vector<std::pair<const xAOD::Vertex*,V0Enum> > selectedV0Candidates;
663
664 SG::ReadHandle<xAOD::VertexContainer> V0Container;
665 if(m_vertexV0ContainerKey.key() != "") {
666 V0Container = SG::ReadHandle<xAOD::VertexContainer>(m_vertexV0ContainerKey, ctx);
667 ATH_CHECK( V0Container.isValid() );
668
669 for(const xAOD::Vertex* vtx : *V0Container.cptr()) {
670 std::string type_V0Vtx;
671 if(mAcc_type.isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
672
673 V0Enum opt(UNKNOWN); double massV0(0);
674 if(type_V0Vtx == "Lambda") {
675 opt = LAMBDA;
676 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_ppi);
677 if(massV0<m_LambdaMassLower || massV0>m_LambdaMassUpper) continue;
678 }
679 else if(type_V0Vtx == "Lambdabar") {
680 opt = LAMBDABAR;
681 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pip);
682 if(massV0<m_LambdaMassLower || massV0>m_LambdaMassUpper) continue;
683 }
684 else if(type_V0Vtx == "Ks") {
685 opt = KS;
686 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pipi);
687 if(massV0<m_KsMassLower || massV0>m_KsMassUpper) continue;
688 }
689
690 if(opt==UNKNOWN) continue;
691 if((opt==LAMBDA || opt==LAMBDABAR) && m_V0Hypothesis == "Ks") continue;
692 if(opt==KS && m_V0Hypothesis == "Lambda") continue;
693
694 int gamma_fit = mAcc_gfit.isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
695 double gamma_mass = mAcc_gmass.isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
696 double gamma_chisq = mAcc_gchisq.isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
697 double gamma_ndof = mAcc_gndof.isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
698 if(gamma_fit==1 && gamma_mass<m_minMass_gamma && gamma_chisq/gamma_ndof<m_chi2cut_gamma) continue;
699
700 selectedV0Candidates.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,opt});
701 }
702 }
703 else {
704 // fit V0 vertices
705 fitV0Container(ctx, V0OutputContainer.ptr(), tracksDisplaced, trackCols);
706
707 for(const xAOD::Vertex* vtx : *V0OutputContainer.cptr()) {
708 std::string type_V0Vtx;
709 if(mAcc_type.isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
710
711 V0Enum opt(UNKNOWN); double massV0(0);
712 if(type_V0Vtx == "Lambda") {
713 opt = LAMBDA;
714 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_ppi);
715 if(massV0<m_LambdaMassLower || massV0>m_LambdaMassUpper) continue;
716 }
717 else if(type_V0Vtx == "Lambdabar") {
718 opt = LAMBDABAR;
719 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pip);
720 if(massV0<m_LambdaMassLower || massV0>m_LambdaMassUpper) continue;
721 }
722 else if(type_V0Vtx == "Ks") {
723 opt = KS;
724 massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pipi);
725 if(massV0<m_KsMassLower || massV0>m_KsMassUpper) continue;
726 }
727
728 if(opt==UNKNOWN) continue;
729 if((opt==LAMBDA || opt==LAMBDABAR) && m_V0Hypothesis == "Ks") continue;
730 if(opt==KS && m_V0Hypothesis == "Lambda") continue;
731
732 int gamma_fit = mAcc_gfit.isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
733 double gamma_mass = mAcc_gmass.isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
734 double gamma_chisq = mAcc_gchisq.isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
735 double gamma_ndof = mAcc_gndof.isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
736 if(gamma_fit==1 && gamma_mass<m_minMass_gamma && gamma_chisq/gamma_ndof<m_chi2cut_gamma) continue;
737
738 selectedV0Candidates.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,opt});
739 }
740 }
741
742 // sort and chop the V0 candidates
743 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(); } );
744 if(m_maxV0Candidates>0 && selectedV0Candidates.size()>m_maxV0Candidates) {
745 selectedV0Candidates.erase(selectedV0Candidates.begin()+m_maxV0Candidates, selectedV0Candidates.end());
746 }
747 if(selectedV0Candidates.size()==0) return StatusCode::SUCCESS;
748
749 std::vector<std::pair<Trk::VxCascadeInfo*, Trk::VxCascadeInfo*> > cascadeinfoContainer;
750 ATH_CHECK( performSearch(cascadeinfoContainer, selectedV0Candidates, tracksDisplaced, ctx) );
751
752 // sort and chop the main candidates
753 std::sort( cascadeinfoContainer.begin(), cascadeinfoContainer.end(), [](std::pair<Trk::VxCascadeInfo*, Trk::VxCascadeInfo*> a, std::pair<Trk::VxCascadeInfo*, Trk::VxCascadeInfo*> b) { return a.first->fitChi2()/a.first->nDoF() < b.first->fitChi2()/b.first->nDoF(); } );
754 if(m_maxMainVCandidates>0 && cascadeinfoContainer.size()>m_maxMainVCandidates) {
755 for(auto it=cascadeinfoContainer.begin()+m_maxMainVCandidates; it!=cascadeinfoContainer.end(); it++) {
756 if(it->first) delete it->first;
757 if(it->second) delete it->second;
758 }
759 cascadeinfoContainer.erase(cascadeinfoContainer.begin()+m_maxMainVCandidates, cascadeinfoContainer.end());
760 }
761 if(cascadeinfoContainer.size()==0) return StatusCode::SUCCESS;
762
763 SG::ReadHandle<xAOD::EventInfo> evt(m_eventInfo_key, ctx);
764 ATH_CHECK( evt.isValid() );
765 BPhysPVCascadeTools helper(&(*m_CascadeTools), evt.cptr());
766 helper.SetMinNTracksInPV(m_PV_minNTracks);
767
768 // Decorators for the cascade vertices
769 SG::AuxElement::Decorator<VertexLinkVector> CascadeLinksDecor("CascadeVertexLinks");
770 SG::AuxElement::Decorator<VertexLinkVector> PrecedingLinksDecor("PrecedingVertexLinks");
771 SG::AuxElement::Decorator<float> chi2_decor("ChiSquared");
772 SG::AuxElement::Decorator<int> ndof_decor("nDoF");
773 SG::AuxElement::Decorator<float> Pt_decor("Pt");
774 SG::AuxElement::Decorator<float> PtErr_decor("PtErr");
775
776 SG::AuxElement::Decorator<float> lxy_SV0_decor("lxy_SV0");
777 SG::AuxElement::Decorator<float> lxyErr_SV0_decor("lxyErr_SV0");
778 SG::AuxElement::Decorator<float> a0xy_SV0_decor("a0xy_SV0");
779 SG::AuxElement::Decorator<float> a0xyErr_SV0_decor("a0xyErr_SV0");
780 SG::AuxElement::Decorator<float> a0z_SV0_decor("a0z_SV0");
781 SG::AuxElement::Decorator<float> a0zErr_SV0_decor("a0zErr_SV0");
782
783 SG::AuxElement::Decorator<float> lxy_SV1_decor("lxy_SV1");
784 SG::AuxElement::Decorator<float> lxyErr_SV1_decor("lxyErr_SV1");
785 SG::AuxElement::Decorator<float> a0xy_SV1_decor("a0xy_SV1");
786 SG::AuxElement::Decorator<float> a0xyErr_SV1_decor("a0xyErr_SV1");
787 SG::AuxElement::Decorator<float> a0z_SV1_decor("a0z_SV1");
788 SG::AuxElement::Decorator<float> a0zErr_SV1_decor("a0zErr_SV1");
789
790 SG::AuxElement::Decorator<float> lxy_SV2_decor("lxy_SV2");
791 SG::AuxElement::Decorator<float> lxyErr_SV2_decor("lxyErr_SV2");
792 SG::AuxElement::Decorator<float> a0xy_SV2_decor("a0xy_SV2");
793 SG::AuxElement::Decorator<float> a0xyErr_SV2_decor("a0xyErr_SV2");
794 SG::AuxElement::Decorator<float> a0z_SV2_decor("a0z_SV2");
795 SG::AuxElement::Decorator<float> a0zErr_SV2_decor("a0zErr_SV2");
796
797 SG::AuxElement::Decorator<float> chi2_V2_decor("ChiSquared_V2");
798 SG::AuxElement::Decorator<int> ndof_V2_decor("nDoF_V2");
799
800 for(auto cascade_info_pair : cascadeinfoContainer) {
801 if(cascade_info_pair.first==nullptr) {
802 ATH_MSG_ERROR("CascadeInfo is null");
803 continue;
804 }
805
806 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info_pair.first->vertices();
807 if(cascadeVertices.size() != topoN) ATH_MSG_ERROR("Incorrect number of vertices");
808 for(size_t i=0; i<topoN; i++) {
809 if(cascadeVertices[i]==nullptr) ATH_MSG_ERROR("Error null vertex");
810 }
811
812 cascade_info_pair.first->setSVOwnership(false); // Prevent Container from deleting vertices
813 const auto mainVertex = cascadeVertices[topoN-1]; // this is the mother vertex
814 const std::vector< std::vector<TLorentzVector> > &moms = cascade_info_pair.first->getParticleMoms();
815
816 // Identify the input JX
817 int ijx = m_JXSubVtx ? topoN-2 : topoN-1;
819 if(m_JXV0SubVtx) ijx = 1;
820 else ijx = topoN-1;
821 }
822 else if(m_extraTrk1MassHypo>0 && m_disVDaug_num==2) {
823 if(m_JXV0SubVtx || m_JXSubVtx) ijx = 1;
824 else ijx = topoN-1;
825 }
826 const xAOD::Vertex* jxVtx(nullptr);
827 if(m_jxDaug_num==4) jxVtx = FindVertex<4>(jxContainer.ptr(), cascadeVertices[ijx]);
828 else if(m_jxDaug_num==3) jxVtx = FindVertex<3>(jxContainer.ptr(), cascadeVertices[ijx]);
829 else jxVtx = FindVertex<2>(jxContainer.ptr(), cascadeVertices[ijx]);
830
831 xAOD::BPhysHypoHelper vtx(m_hypoName, mainVertex);
832
833 // Get refitted track momenta from all vertices, charged tracks only
834 BPhysPVCascadeTools::SetVectorInfo(vtx, cascade_info_pair.first);
835 vtx.setPass(true);
836
837 //
838 // Decorate main vertex
839 //
840 // mass, mass error
841 // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/VxCascadeInfo.h
842 BPHYS_CHECK( vtx.setMass(m_CascadeTools->invariantMass(moms[topoN-1])) );
843 BPHYS_CHECK( vtx.setMassErr(m_CascadeTools->invariantMassError(moms[topoN-1],cascade_info_pair.first->getCovariance()[topoN-1])) );
844 // pt and pT error (the default pt of mainVertex is != the pt of the full cascade fit!)
845 Pt_decor(*mainVertex) = m_CascadeTools->pT(moms[topoN-1]);
846 PtErr_decor(*mainVertex) = m_CascadeTools->pTError(moms[topoN-1],cascade_info_pair.first->getCovariance()[topoN-1]);
847 // chi2 and ndof (the default chi2 of mainVertex is != the chi2 of the full cascade fit!)
848 chi2_decor(*mainVertex) = cascade_info_pair.first->fitChi2();
849 ndof_decor(*mainVertex) = cascade_info_pair.first->nDoF();
850
851 if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0) { // special cases
852 if(m_JXV0SubVtx) {
853 lxy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
854 lxyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
855 a0z_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1]);
856 a0zErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
857 a0xy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1]);
858 a0xyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
859 lxy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
860 lxyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
861 a0z_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
862 a0zErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
863 a0xy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
864 a0xyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
865 lxy_SV2_decor(*cascadeVertices[2]) = m_CascadeTools->lxy(moms[2],cascadeVertices[2],mainVertex);
866 lxyErr_SV2_decor(*cascadeVertices[2]) = m_CascadeTools->lxyError(moms[2],cascade_info_pair.first->getCovariance()[2],cascadeVertices[2],mainVertex);
867 a0z_SV2_decor(*cascadeVertices[2]) = m_CascadeTools->a0z(moms[2],cascadeVertices[2],mainVertex);
868 a0zErr_SV2_decor(*cascadeVertices[2]) = m_CascadeTools->a0zError(moms[2],cascade_info_pair.first->getCovariance()[2],cascadeVertices[2],mainVertex);
869 a0xy_SV2_decor(*cascadeVertices[2]) = m_CascadeTools->a0xy(moms[2],cascadeVertices[2],mainVertex);
870 a0xyErr_SV2_decor(*cascadeVertices[2]) = m_CascadeTools->a0xyError(moms[2],cascade_info_pair.first->getCovariance()[2],cascadeVertices[2],mainVertex);
871 }
872 else {
873 lxy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
874 lxyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
875 a0z_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
876 a0zErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
877 a0xy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
878 a0xyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
879 lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
880 lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
881 a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
882 a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
883 a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
884 a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
885 }
886 }
887 else if(m_extraTrk1MassHypo>0 && m_disVDaug_num==2) { // special cases
888 if(m_JXV0SubVtx) {
889 lxy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
890 lxyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
891 a0z_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1]);
892 a0zErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
893 a0xy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1]);
894 a0xyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
895 lxy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
896 lxyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
897 a0z_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
898 a0zErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
899 a0xy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
900 a0xyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
901 }
902 else {
903 lxy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
904 lxyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
905 a0z_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
906 a0zErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
907 a0xy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
908 a0xyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
909 if(m_JXSubVtx) {
910 lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
911 lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
912 a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
913 a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
914 a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
915 a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
916 }
917 }
918 }
919 else { // other normal cases
920 if(m_disVDaug_num==2) {
921 lxy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
922 lxyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
923 a0z_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
924 a0zErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
925 a0xy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
926 a0xyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],mainVertex);
927 }
928 else {
929 lxy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
930 lxyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
931 a0z_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1]);
932 a0zErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
933 a0xy_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1]);
934 a0xyErr_SV0_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info_pair.first->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
935 lxy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
936 lxyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
937 a0xy_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
938 a0xyErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
939 a0z_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
940 a0zErr_SV1_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info_pair.first->getCovariance()[1],cascadeVertices[1],mainVertex);
941 }
942
943 if(m_JXSubVtx) {
944 lxy_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->lxy(moms[ijx],cascadeVertices[ijx],mainVertex);
945 lxyErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->lxyError(moms[ijx],cascade_info_pair.first->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
946 a0z_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0z(moms[ijx],cascadeVertices[ijx],mainVertex);
947 a0zErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0zError(moms[ijx],cascade_info_pair.first->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
948 a0xy_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0xy(moms[ijx],cascadeVertices[ijx],mainVertex);
949 a0xyErr_SV2_decor(*cascadeVertices[ijx]) = m_CascadeTools->a0xyError(moms[ijx],cascade_info_pair.first->getCovariance()[ijx],cascadeVertices[ijx],mainVertex);
950 }
951 }
952
953 chi2_V2_decor(*cascadeVertices[ijx]) = m_V0Tools->chisq(jxVtx);
954 ndof_V2_decor(*cascadeVertices[ijx]) = m_V0Tools->ndof(jxVtx);
955
956 if(m_cascadeFitWithPV==0) {
957 ATH_CHECK(helper.FillCandwithRefittedVertices(m_refitPV, defaultPVContainer.cptr(), m_refitPV ? refPvContainer.ptr() : 0, &(*m_pvRefitter), m_PV_max, m_DoVertexType, cascade_info_pair.first, topoN-1, m_massMainV, vtx));
958 }
959
960 for(size_t i=0; i<topoN; i++) {
961 VtxWriteHandles[i].ptr()->push_back(cascadeVertices[i]);
962 }
963
964 // Set links to cascade vertices
965 VertexLinkVector cascadeVertexLinks;
966 VertexLink vertexLink1;
967 vertexLink1.setElement(cascadeVertices[0]);
968 vertexLink1.setStorableObject(*VtxWriteHandles[0].ptr());
969 if( vertexLink1.isValid() ) cascadeVertexLinks.push_back( vertexLink1 );
970 if(topoN>=3) {
971 VertexLink vertexLink2;
972 vertexLink2.setElement(cascadeVertices[1]);
973 vertexLink2.setStorableObject(*VtxWriteHandles[1].ptr());
974 if( vertexLink2.isValid() ) cascadeVertexLinks.push_back( vertexLink2 );
975 }
976 if(topoN==4) {
977 VertexLink vertexLink3;
978 vertexLink3.setElement(cascadeVertices[2]);
979 vertexLink3.setStorableObject(*VtxWriteHandles[2].ptr());
980 if( vertexLink3.isValid() ) cascadeVertexLinks.push_back( vertexLink3 );
981 }
982 CascadeLinksDecor(*mainVertex) = cascadeVertexLinks;
983
984 // process the posterior cascade with mass constraint for the main vertex
985 if(cascade_info_pair.second) {
986 const std::vector<xAOD::Vertex*> &cascadeVertices_mvc = cascade_info_pair.second->vertices();
987 if(cascadeVertices_mvc.size() != topoN) ATH_MSG_ERROR("Incorrect number of vertices (mvc)");
988 for(size_t i=0; i<topoN; i++) {
989 if(cascadeVertices_mvc[i]==nullptr) ATH_MSG_ERROR("Error null vertex (mvc)");
990 }
991 cascade_info_pair.second->setSVOwnership(false);
992 const auto mainVertex_mvc = cascadeVertices_mvc[topoN-1];
993 const std::vector< std::vector<TLorentzVector> > &moms_mvc = cascade_info_pair.second->getParticleMoms();
994 // Identify the input JX
995 int ijx_mvc = m_JXSubVtx ? topoN-2 : topoN-1;
997 if(m_JXV0SubVtx) ijx_mvc = 1;
998 else ijx_mvc = topoN-1;
999 }
1000 else if(m_extraTrk1MassHypo>0 && m_disVDaug_num==2) {
1001 if(m_JXV0SubVtx || m_JXSubVtx) ijx_mvc = 1;
1002 else ijx_mvc = topoN-1;
1003 }
1004 const xAOD::Vertex* jxVtx_mvc(nullptr);
1005 if(m_jxDaug_num==4) jxVtx_mvc = FindVertex<4>(jxContainer.ptr(), cascadeVertices_mvc[ijx_mvc]);
1006 else if(m_jxDaug_num==3) jxVtx_mvc = FindVertex<3>(jxContainer.ptr(), cascadeVertices_mvc[ijx_mvc]);
1007 else jxVtx_mvc = FindVertex<2>(jxContainer.ptr(), cascadeVertices_mvc[ijx_mvc]);
1008
1009 xAOD::BPhysHypoHelper vtx_mvc(m_hypoName, mainVertex_mvc);
1010 BPhysPVCascadeTools::SetVectorInfo(vtx_mvc, cascade_info_pair.second);
1011 vtx_mvc.setPass(true);
1012
1013 BPHYS_CHECK( vtx_mvc.setMass(m_CascadeTools->invariantMass(moms_mvc[topoN-1])) );
1014 BPHYS_CHECK( vtx_mvc.setMassErr(m_CascadeTools->invariantMassError(moms_mvc[topoN-1],cascade_info_pair.second->getCovariance()[topoN-1])) );
1015 Pt_decor(*mainVertex_mvc) = m_CascadeTools->pT(moms_mvc[topoN-1]);
1016 PtErr_decor(*mainVertex_mvc) = m_CascadeTools->pTError(moms_mvc[topoN-1],cascade_info_pair.second->getCovariance()[topoN-1]);
1017 chi2_decor(*mainVertex_mvc) = cascade_info_pair.second->fitChi2();
1018 ndof_decor(*mainVertex_mvc) = cascade_info_pair.second->nDoF();
1019
1020 if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0) { // special cases
1021 if(m_JXV0SubVtx) {
1022 lxy_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxy(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1023 lxyErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1024 a0z_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0z(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1025 a0zErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0zError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1026 a0xy_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xy(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1027 a0xyErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1028 lxy_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1029 lxyErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1030 a0z_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0z(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1031 a0zErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0zError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1032 a0xy_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1033 a0xyErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1034 lxy_SV2_decor(*cascadeVertices_mvc[2]) = m_CascadeTools->lxy(moms_mvc[2],cascadeVertices_mvc[2],mainVertex_mvc);
1035 lxyErr_SV2_decor(*cascadeVertices_mvc[2]) = m_CascadeTools->lxyError(moms_mvc[2],cascade_info_pair.second->getCovariance()[2],cascadeVertices_mvc[2],mainVertex_mvc);
1036 a0z_SV2_decor(*cascadeVertices_mvc[2]) = m_CascadeTools->a0z(moms_mvc[2],cascadeVertices_mvc[2],mainVertex_mvc);
1037 a0zErr_SV2_decor(*cascadeVertices_mvc[2]) = m_CascadeTools->a0zError(moms_mvc[2],cascade_info_pair.second->getCovariance()[2],cascadeVertices_mvc[2],mainVertex_mvc);
1038 a0xy_SV2_decor(*cascadeVertices_mvc[2]) = m_CascadeTools->a0xy(moms_mvc[2],cascadeVertices_mvc[2],mainVertex_mvc);
1039 a0xyErr_SV2_decor(*cascadeVertices_mvc[2]) = m_CascadeTools->a0xyError(moms_mvc[2],cascade_info_pair.second->getCovariance()[2],cascadeVertices_mvc[2],mainVertex_mvc);
1040 }
1041 else {
1042 lxy_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxy(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1043 lxyErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1044 a0z_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0z(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1045 a0zErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0zError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1046 a0xy_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xy(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1047 a0xyErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1048 lxy_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1049 lxyErr_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1050 a0z_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0z(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1051 a0zErr_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0zError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1052 a0xy_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1053 a0xyErr_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1054 }
1055 }
1056 else if(m_extraTrk1MassHypo>0 && m_disVDaug_num==2) { // special cases
1057 if(m_JXV0SubVtx) {
1058 lxy_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxy(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1059 lxyErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1060 a0z_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0z(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1061 a0zErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0zError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1062 a0xy_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xy(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1063 a0xyErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1064 lxy_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1065 lxyErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1066 a0z_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0z(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1067 a0zErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0zError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1068 a0xy_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1069 a0xyErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1070 }
1071 else {
1072 lxy_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxy(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1073 lxyErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1074 a0z_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0z(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1075 a0zErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0zError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1076 a0xy_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xy(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1077 a0xyErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1078 if(m_JXSubVtx) {
1079 lxy_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1080 lxyErr_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1081 a0z_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0z(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1082 a0zErr_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0zError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1083 a0xy_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1084 a0xyErr_SV2_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1085 }
1086 }
1087 }
1088 else { // other normal cases
1089 if(m_disVDaug_num==2) {
1090 lxy_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxy(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1091 lxyErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1092 a0z_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0z(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1093 a0zErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0zError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1094 a0xy_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xy(moms_mvc[0],cascadeVertices_mvc[0],mainVertex_mvc);
1095 a0xyErr_SV1_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],mainVertex_mvc);
1096 }
1097 else {
1098 lxy_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxy(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1099 lxyErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->lxyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1100 a0z_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0z(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1101 a0zErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0zError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1102 a0xy_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xy(moms_mvc[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1103 a0xyErr_SV0_decor(*cascadeVertices_mvc[0]) = m_CascadeTools->a0xyError(moms_mvc[0],cascade_info_pair.second->getCovariance()[0],cascadeVertices_mvc[0],cascadeVertices_mvc[1]);
1104 lxy_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1105 lxyErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->lxyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1106 a0xy_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0z(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1107 a0xyErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0zError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1108 a0z_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xy(moms_mvc[1],cascadeVertices_mvc[1],mainVertex_mvc);
1109 a0zErr_SV1_decor(*cascadeVertices_mvc[1]) = m_CascadeTools->a0xyError(moms_mvc[1],cascade_info_pair.second->getCovariance()[1],cascadeVertices_mvc[1],mainVertex_mvc);
1110 }
1111 if(m_JXSubVtx) {
1112 lxy_SV2_decor(*cascadeVertices_mvc[ijx_mvc]) = m_CascadeTools->lxy(moms_mvc[ijx_mvc],cascadeVertices_mvc[ijx_mvc],mainVertex_mvc);
1113 lxyErr_SV2_decor(*cascadeVertices_mvc[ijx_mvc]) = m_CascadeTools->lxyError(moms_mvc[ijx_mvc],cascade_info_pair.second->getCovariance()[ijx_mvc],cascadeVertices_mvc[ijx_mvc],mainVertex_mvc);
1114 a0z_SV2_decor(*cascadeVertices_mvc[ijx_mvc]) = m_CascadeTools->a0z(moms_mvc[ijx_mvc],cascadeVertices_mvc[ijx_mvc],mainVertex_mvc);
1115 a0zErr_SV2_decor(*cascadeVertices_mvc[ijx_mvc]) = m_CascadeTools->a0zError(moms_mvc[ijx_mvc],cascade_info_pair.second->getCovariance()[ijx_mvc],cascadeVertices_mvc[ijx_mvc],mainVertex_mvc);
1116 a0xy_SV2_decor(*cascadeVertices_mvc[ijx_mvc]) = m_CascadeTools->a0xy(moms_mvc[ijx_mvc],cascadeVertices_mvc[ijx_mvc],mainVertex_mvc);
1117 a0xyErr_SV2_decor(*cascadeVertices_mvc[ijx_mvc]) = m_CascadeTools->a0xyError(moms_mvc[ijx_mvc],cascade_info_pair.second->getCovariance()[ijx_mvc],cascadeVertices_mvc[ijx_mvc],mainVertex_mvc);
1118 }
1119 }
1120 chi2_V2_decor(*cascadeVertices_mvc[ijx_mvc]) = m_V0Tools->chisq(jxVtx_mvc);
1121 ndof_V2_decor(*cascadeVertices_mvc[ijx_mvc]) = m_V0Tools->ndof(jxVtx_mvc);
1122
1123 if(m_cascadeFitWithPV==0) {
1124 ATH_CHECK(helper.FillCandwithRefittedVertices(m_refitPV, defaultPVContainer.cptr(), m_refitPV ? refPvContainer.ptr() : 0, &(*m_pvRefitter), m_PV_max, m_DoVertexType, cascade_info_pair.second, topoN-1, m_massMainV, vtx_mvc));
1125 }
1126
1127 for(size_t i=0; i<topoN; i++) {
1128 VtxWriteHandles_mvc[i].ptr()->push_back(cascadeVertices_mvc[i]);
1129 }
1130
1131 VertexLinkVector cascadeVertexLinks_mvc;
1132 VertexLink vertexLink1_mvc;
1133 vertexLink1_mvc.setElement(cascadeVertices_mvc[0]);
1134 vertexLink1_mvc.setStorableObject(*VtxWriteHandles_mvc[0].ptr());
1135 if( vertexLink1_mvc.isValid() ) cascadeVertexLinks_mvc.push_back( vertexLink1_mvc );
1136 if(topoN>=3) {
1137 VertexLink vertexLink2_mvc;
1138 vertexLink2_mvc.setElement(cascadeVertices_mvc[1]);
1139 vertexLink2_mvc.setStorableObject(*VtxWriteHandles_mvc[1].ptr());
1140 if( vertexLink2_mvc.isValid() ) cascadeVertexLinks_mvc.push_back( vertexLink2_mvc );
1141 }
1142 if(topoN==4) {
1143 VertexLink vertexLink3_mvc;
1144 vertexLink3_mvc.setElement(cascadeVertices_mvc[2]);
1145 vertexLink3_mvc.setStorableObject(*VtxWriteHandles_mvc[2].ptr());
1146 if( vertexLink3_mvc.isValid() ) cascadeVertexLinks_mvc.push_back( vertexLink3_mvc );
1147 }
1148 CascadeLinksDecor(*mainVertex_mvc) = cascadeVertexLinks_mvc;
1149
1150 VertexLinkVector precedingVertexLinks_mvc;
1151 VertexLink vertexLink_mvc;
1152 vertexLink_mvc.setElement(cascadeVertices[topoN-1]);
1153 vertexLink_mvc.setStorableObject(*VtxWriteHandles[topoN-1].ptr());
1154 if( vertexLink_mvc.isValid() ) precedingVertexLinks_mvc.push_back( vertexLink_mvc );
1155 PrecedingLinksDecor(*mainVertex_mvc) = precedingVertexLinks_mvc;
1156 } // cascade_info_pair.second!=0
1157 } // loop over cascadeinfoContainer
1158
1159 // Deleting cascadeinfo since this won't be stored.
1160 for (auto cascade_info_pair : cascadeinfoContainer) {
1161 if(cascade_info_pair.first) delete cascade_info_pair.first;
1162 if(cascade_info_pair.second) delete cascade_info_pair.second;
1163 }
1164
1165 return StatusCode::SUCCESS;
1166 }
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define BPHYS_CHECK(EXP)
Useful CHECK macro.
static Double_t a
V0Container
static void SetVectorInfo(xAOD::BPhysHelper &, const Trk::VxCascadeInfo *)
const xAOD::Vertex * FindVertex(const xAOD::VertexContainer *cont, const xAOD::Vertex *v) const
void fitV0Container(const EventContext &ctx, xAOD::VertexContainer *V0ContainerNew, const std::vector< const xAOD::TrackParticle * > &selectedTracks, const std::vector< const xAOD::TrackParticleContainer * > &trackCols) const
bool d0Pass(const EventContext &ctx, const xAOD::TrackParticle *track, const xAOD::Vertex *PV) const
StatusCode performSearch(std::vector< std::pair< Trk::VxCascadeInfo *, Trk::VxCascadeInfo * > > &cascadeinfoContainer, const std::vector< std::pair< const xAOD::Vertex *, V0Enum > > &selectedV0Candidates, const std::vector< const xAOD::TrackParticle * > &tracksDisplaced, const EventContext &ctx) const
const_pointer_type cptr() const
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
virtual void handle(const Incident &inc)
Handle end of run incidents to save the metadata at that point.
ElementLink< xAOD::VertexContainer > VertexLink
std::vector< VertexLink > VertexLinkVector
void * ptr(T *p)
Definition SGImplSvc.cxx:74
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].

◆ d0Pass()

bool DerivationFramework::JpsiXPlusDisplaced::d0Pass ( const EventContext & ctx,
const xAOD::TrackParticle * track,
const xAOD::Vertex * PV ) const
private

Definition at line 1168 of file JpsiXPlusDisplaced.cxx.

1168 {
1169 bool pass = false;
1170 std::unique_ptr<Trk::Perigee> per = m_trackToVertexTool->perigeeAtVertex(ctx, *track, PV->position());
1171 if(!per) return pass;
1172 double d0 = per->parameters()[Trk::d0];
1173 double sig_d0 = sqrt((*per->covariance())(0,0));
1174 if(std::abs(d0/sig_d0) > m_d0_cut) pass = true;
1175 return pass;
1176 }
const Amg::Vector3D & position() const
Returns the 3-pos.
@ d0
Definition ParamDefs.h:63

◆ FindVertex()

template<size_t NTracks>
const xAOD::Vertex * DerivationFramework::JpsiXPlusDisplaced::FindVertex ( const xAOD::VertexContainer * cont,
const xAOD::Vertex * v ) const
private

Definition at line 2823 of file JpsiXPlusDisplaced.cxx.

2823 {
2824 for (const xAOD::Vertex* v1 : *cont) {
2825 assert(v1->nTrackParticles() == NTracks);
2826 std::array<const xAOD::TrackParticle*, NTracks> a1;
2827 std::array<const xAOD::TrackParticle*, NTracks> a2;
2828 for(size_t i=0; i<NTracks; i++){
2829 a1[i] = v1->trackParticle(i);
2830 a2[i] = v->trackParticle(i);
2831 }
2832 std::sort(a1.begin(), a1.end());
2833 std::sort(a2.begin(), a2.end());
2834 if(a1 == a2) return v1;
2835 }
2836 return nullptr;
2837 }

◆ fitMainVtx() [1/2]

std::vector< std::pair< Trk::VxCascadeInfo *, Trk::VxCascadeInfo * > > DerivationFramework::JpsiXPlusDisplaced::fitMainVtx ( const xAOD::Vertex * JXvtx,
const std::vector< double > & massesJX,
const xAOD::Vertex * V0vtx,
const V0Enum V0,
const xAOD::TrackParticleContainer * trackContainer,
const std::vector< const xAOD::TrackParticleContainer * > & trackCols,
const xAOD::VertexContainer * defaultPVContainer,
const xAOD::VertexContainer * pvContainer ) const
private

Definition at line 1314 of file JpsiXPlusDisplaced.cxx.

1314 {
1315 std::vector<std::pair<Trk::VxCascadeInfo*,Trk::VxCascadeInfo*> > result;
1316
1317 std::vector<const xAOD::TrackParticle*> tracksJX;
1318 tracksJX.reserve(JXvtx->nTrackParticles());
1319 for(size_t i=0; i<JXvtx->nTrackParticles(); i++) tracksJX.push_back(JXvtx->trackParticle(i));
1320 if (tracksJX.size() != massesJX.size()) {
1321 ATH_MSG_ERROR("Problems with JX input: number of tracks or track mass inputs is not correct!");
1322 return result;
1323 }
1324 // Check identical tracks in input
1325 if(std::find(tracksJX.cbegin(), tracksJX.cend(), V0vtx->trackParticle(0)) != tracksJX.cend()) return result;
1326 if(std::find(tracksJX.cbegin(), tracksJX.cend(), V0vtx->trackParticle(1)) != tracksJX.cend()) return result;
1327 std::vector<const xAOD::TrackParticle*> tracksV0;
1328 tracksV0.reserve(V0vtx->nTrackParticles());
1329 for(size_t j=0; j<V0vtx->nTrackParticles(); j++) tracksV0.push_back(V0vtx->trackParticle(j));
1330
1331 std::vector<const xAOD::TrackParticle*> tracksJpsi{tracksJX[0], tracksJX[1]};
1332 std::vector<const xAOD::TrackParticle*> tracksX;
1333 if(m_jxDaug_num>=3) tracksX.push_back(tracksJX[2]);
1334 if(m_jxDaug_num==4) tracksX.push_back(tracksJX[3]);
1335
1336 std::vector<double> massesV0;
1337 if(V0==LAMBDA) {
1338 massesV0 = m_massesV0_ppi;
1339 }
1340 else if(V0==LAMBDABAR) {
1341 massesV0 = m_massesV0_pip;
1342 }
1343 else if(V0==KS) {
1344 massesV0 = m_massesV0_pipi;
1345 }
1346
1347 TLorentzVector p4_moth, p4_v0, tmp;
1348 for(size_t it=0; it<JXvtx->nTrackParticles(); it++) {
1349 tmp.SetPtEtaPhiM(JXvtx->trackParticle(it)->pt(), JXvtx->trackParticle(it)->eta(), JXvtx->trackParticle(it)->phi(), massesJX[it]);
1350 p4_moth += tmp;
1351 }
1352 xAOD::BPhysHelper V0_helper(V0vtx);
1353 for(int it=0; it<V0_helper.nRefTrks(); it++) {
1354 p4_moth += V0_helper.refTrk(it,massesV0[it]);
1355 p4_v0 += V0_helper.refTrk(it,massesV0[it]);
1356 }
1357
1363 xAOD::BPhysHelper JX_helper(JXvtx);
1364 const xAOD::Vertex* origPv_xAOD = (m_cascadeFitWithPV>=1 && m_cascadeFitWithPV<=4) ? JX_helper.origPv(pvtype) : nullptr;
1365 const xAOD::Vertex* pv_xAOD = (m_cascadeFitWithPV>=1 && m_cascadeFitWithPV<=4) ? JX_helper.pv(pvtype) : nullptr;
1366 std::unique_ptr<Trk::RecVertex> pv_AOD;
1367 if(pv_xAOD) pv_AOD = std::make_unique<Trk::RecVertex>(pv_xAOD->position(),pv_xAOD->covariancePosition(),pv_xAOD->numberDoF(),pv_xAOD->chiSquared());
1368
1369 SG::AuxElement::Decorator<float> chi2_V1_decor("ChiSquared_V1");
1370 SG::AuxElement::Decorator<int> ndof_V1_decor("nDoF_V1");
1371 SG::AuxElement::Decorator<std::string> type_V1_decor("Type_V1");
1372
1373 SG::AuxElement::Accessor<int> mAcc_gfit("gamma_fit");
1374 SG::AuxElement::Accessor<float> mAcc_gmass("gamma_mass");
1375 SG::AuxElement::Accessor<float> mAcc_gmasserr("gamma_massError");
1376 SG::AuxElement::Accessor<float> mAcc_gchisq("gamma_chisq");
1377 SG::AuxElement::Accessor<int> mAcc_gndof("gamma_ndof");
1378 SG::AuxElement::Accessor<float> mAcc_gprob("gamma_probability");
1379
1380 SG::AuxElement::Decorator<int> mDec_gfit("gamma_fit");
1381 SG::AuxElement::Decorator<float> mDec_gmass("gamma_mass");
1382 SG::AuxElement::Decorator<float> mDec_gmasserr("gamma_massError");
1383 SG::AuxElement::Decorator<float> mDec_gchisq("gamma_chisq");
1384 SG::AuxElement::Decorator<int> mDec_gndof("gamma_ndof");
1385 SG::AuxElement::Decorator<float> mDec_gprob("gamma_probability");
1386 SG::AuxElement::Decorator< std::vector<float> > trk_pxDeco("TrackPx_V0nc");
1387 SG::AuxElement::Decorator< std::vector<float> > trk_pyDeco("TrackPy_V0nc");
1388 SG::AuxElement::Decorator< std::vector<float> > trk_pzDeco("TrackPz_V0nc");
1389
1390 std::vector<float> trk_px;
1391 std::vector<float> trk_py;
1392 std::vector<float> trk_pz;
1393
1394 if(m_extraTrk1MassHypo<=0) {
1395 double main_mass = p4_moth.M();
1396 if(m_useImprovedMass) {
1397 if(m_jxDaug_num==2 && m_massJpsi>0) main_mass += - (p4_moth - p4_v0).M() + m_massJpsi;
1398 else if(m_jxDaug_num>=3 && m_massJX>0) main_mass += - (p4_moth - p4_v0).M() + m_massJX;
1399 if((V0==LAMBDA || V0==LAMBDABAR) && m_massLd>0) main_mass += - p4_v0.M() + m_massLd;
1400 else if(V0==KS && m_massKs>0) main_mass += - p4_v0.M() + m_massKs;
1401 }
1402 if (main_mass < m_MassLower || main_mass > m_MassUpper) return result;
1403
1404 // Apply the user's settings to the fitter
1405 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1406 // Robustness: http://cdsweb.cern.ch/record/685551
1407 int robustness = 0;
1408 m_iVertexFitter->setRobustness(robustness, *state);
1409 // Build up the topology
1410 // Vertex list
1411 std::vector<Trk::VertexID> vrtList;
1412 // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/IVertexCascadeFitter.h
1413 // V0 vertex
1414 Trk::VertexID vID1;
1415 if (m_constrV0) {
1416 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,V0==KS?m_massKs:m_massLd);
1417 } else {
1418 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1419 }
1420 vrtList.push_back(vID1);
1421 Trk::VertexID vID2;
1422 if(m_JXSubVtx) {
1423 // JX vertex
1424 if (m_constrJX && m_jxDaug_num>2) {
1425 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state,m_massJX);
1426 } else {
1427 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
1428 }
1429 vrtList.push_back(vID2);
1430 // Mother vertex including JX and V0
1431 std::vector<const xAOD::TrackParticle*> tp;
1432 std::vector<double> tp_masses;
1433 if(m_constrMainV) {
1434 m_iVertexFitter->nextVertex(tp,tp_masses,vrtList,*state,m_massMainV);
1435 } else {
1436 m_iVertexFitter->nextVertex(tp,tp_masses,vrtList,*state);
1437 }
1438 }
1439 else { // m_JXSubVtx=false
1440 // Mother vertex including JX and V0
1441 if(m_constrMainV) {
1442 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
1443 } else {
1444 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1445 }
1446 if (m_constrJX && m_jxDaug_num>2) {
1447 std::vector<Trk::VertexID> cnstV;
1448 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1449 ATH_MSG_WARNING("addMassConstraint for JX failed");
1450 }
1451 }
1452 }
1453 if (m_constrJpsi) {
1454 std::vector<Trk::VertexID> cnstV;
1455 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1456 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
1457 }
1458 }
1459 if (m_constrX && m_jxDaug_num==4) {
1460 std::vector<Trk::VertexID> cnstV;
1461 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1462 ATH_MSG_WARNING("addMassConstraint for X failed");
1463 }
1464 }
1465 // Do the work
1466 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state, pv_AOD.get(), pv_AOD.get() && m_firstDecayAtPV ? true : false) );
1467
1468 if (fit_result) {
1469 for(auto& v : fit_result->vertices()) {
1470 if(v->nTrackParticles()==0) {
1471 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1472 v->setTrackParticleLinks(nullLinkVector);
1473 }
1474 }
1475 // reset links to original tracks
1476 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1477
1478 // necessary to prevent memory leak
1479 fit_result->setSVOwnership(true);
1480
1481 // Chi2/DOF cut
1482 double chi2DOF = fit_result->fitChi2()/fit_result->nDoF();
1483 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1484
1485 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->getParticleMoms();
1486 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->vertices();
1487 size_t iMoth = cascadeVertices.size()-1;
1488 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1489 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut) {
1490 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->chiSquared();
1491 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->numberDoF();
1492 if(V0==LAMBDA) {
1493 type_V1_decor(*cascadeVertices[0]) = "Lambda";
1494 }
1495 else if(V0==LAMBDABAR) {
1496 type_V1_decor(*cascadeVertices[0]) = "Lambdabar";
1497 }
1498 else if(V0==KS) {
1499 type_V1_decor(*cascadeVertices[0]) = "Ks";
1500 }
1501 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1502 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1503 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1504 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1505 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1506 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1507 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1508 trk_px.reserve(V0_helper.nRefTrks());
1509 trk_py.reserve(V0_helper.nRefTrks());
1510 trk_pz.reserve(V0_helper.nRefTrks());
1511 for(auto&& vec3 : V0_helper.refTrks()) {
1512 trk_px.push_back( vec3.Px() );
1513 trk_py.push_back( vec3.Py() );
1514 trk_pz.push_back( vec3.Pz() );
1515 }
1516 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1517 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1518 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1519
1520 result.push_back( std::make_pair(fit_result.release(),nullptr) );
1521 }
1522 }
1523 } // for m_extraTrk1MassHypo<=0
1524 else if(m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo<=0) {
1525 std::vector<double> massesExtra{m_extraTrk1MassHypo};
1526 std::vector<double> massesJXExtra = massesJX; massesJXExtra.push_back(m_extraTrk1MassHypo);
1527
1528 for(const xAOD::TrackParticle* tpExtra : *trackContainer) {
1529 if( tpExtra->pt()<m_extraTrk1MinPt ) continue;
1530 if( !m_trkSelector->decision(*tpExtra, nullptr) ) continue;
1531 // Check identical tracks in input
1532 if(std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend()) continue;
1533 if(std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend()) continue;
1534
1535 TLorentzVector tmp;
1536 tmp.SetPtEtaPhiM(tpExtra->pt(),tpExtra->eta(),tpExtra->phi(),m_extraTrk1MassHypo);
1537 double main_mass = (p4_moth+tmp).M();
1538 if(m_useImprovedMass) {
1539 if(m_jxDaug_num==2 && m_massJpsi>0) main_mass += - (p4_moth - p4_v0).M() + m_massJpsi;
1540 else if(m_jxDaug_num>=3 && m_massJX>0) main_mass += - (p4_moth - p4_v0).M() + m_massJX;
1541 if((V0==LAMBDA || V0==LAMBDABAR) && m_massLd>0) main_mass += - p4_v0.M() + m_massLd;
1542 else if(V0==KS && m_massKs>0) main_mass += - p4_v0.M() + m_massKs;
1543 }
1544 if(main_mass < m_MassLower || main_mass > m_MassUpper) continue;
1545
1546 std::vector<const xAOD::TrackParticle*> tracksExtra{tpExtra};
1547 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX; tracksJXExtra.push_back(tpExtra);
1548
1549 // Apply the user's settings to the fitter
1550 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1551 // Robustness: http://cdsweb.cern.ch/record/685551
1552 int robustness = 0;
1553 m_iVertexFitter->setRobustness(robustness, *state);
1554 // Build up the topology
1555 // Vertex list
1556 std::vector<Trk::VertexID> vrtList;
1557 std::vector<Trk::VertexID> vrtList2;
1558 Trk::VertexID vID2;
1559 if(m_JXV0SubVtx) {
1560 // V0 vertex
1561 Trk::VertexID vID1;
1562 if (m_constrV0) {
1563 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,V0==KS?m_massKs:m_massLd);
1564 } else {
1565 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1566 }
1567 vrtList.push_back(vID1);
1568 // JX+V0 vertex
1569 if(m_constrJXV0) {
1570 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massJXV0);
1571 } else {
1572 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1573 }
1574 vrtList2.push_back(vID2);
1575 // Main vertex
1576 if(m_constrMainV) {
1577 m_iVertexFitter->nextVertex(tracksExtra,massesExtra,vrtList2,*state,m_massMainV);
1578 } else {
1579 m_iVertexFitter->nextVertex(tracksExtra,massesExtra,vrtList2,*state);
1580 }
1581 }
1582 else { // m_JXV0SubVtx==false
1583 // V0 vertex
1584 Trk::VertexID vID1;
1585 if (m_constrV0) {
1586 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,V0==KS?m_massKs:m_massLd);
1587 } else {
1588 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1589 }
1590 vrtList.push_back(vID1);
1591 if(m_JXSubVtx) {
1592 // JX vertex
1593 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
1594 vrtList.push_back(vID2);
1595 // Mother vertex
1596 if(m_constrMainV) {
1597 m_iVertexFitter->nextVertex(tracksExtra,massesExtra,vrtList,*state,m_massMainV);
1598 } else {
1599 m_iVertexFitter->nextVertex(tracksExtra,massesExtra,vrtList,*state);
1600 }
1601 }
1602 else { // m_JXSubVtx=false
1603 // Mother vertex includes one subvertex (V0) and JX tracks + extra track
1604 if(m_constrMainV) {
1605 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state,m_massMainV);
1606 } else {
1607 vID2 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList,*state);
1608 }
1609 }
1610 }
1611 if (m_constrJX && m_jxDaug_num>2) {
1612 std::vector<Trk::VertexID> cnstV;
1613 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1614 ATH_MSG_WARNING("addMassConstraint for JX failed");
1615 }
1616 }
1617 if (m_constrJpsi) {
1618 std::vector<Trk::VertexID> cnstV;
1619 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1620 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
1621 }
1622 }
1623 if (m_constrX && m_jxDaug_num==4) {
1624 std::vector<Trk::VertexID> cnstV;
1625 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1626 ATH_MSG_WARNING("addMassConstraint for X failed");
1627 }
1628 }
1629 // Do the work
1630 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state, pv_AOD.get(), pv_AOD.get() && m_firstDecayAtPV ? true : false) );
1631
1632 if (fit_result) {
1633 for(auto& v : fit_result->vertices()) {
1634 if(v->nTrackParticles()==0) {
1635 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1636 v->setTrackParticleLinks(nullLinkVector);
1637 }
1638 }
1639 // reset links to original tracks
1640 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1641
1642 // necessary to prevent memory leak
1643 fit_result->setSVOwnership(true);
1644
1645 // Chi2/DOF cut
1646 double chi2DOF = fit_result->fitChi2()/fit_result->nDoF();
1647 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1648 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->getParticleMoms();
1649 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->vertices();
1650 size_t iMoth = cascadeVertices.size()-1;
1651 double lxy_SV1(0);
1652 if(m_JXV0SubVtx) {
1653 lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
1654 }
1655 else {
1656 lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1657 }
1658 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut) {
1659 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->chiSquared();
1660 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->numberDoF();
1661 if(V0==LAMBDA) {
1662 type_V1_decor(*cascadeVertices[0]) = "Lambda";
1663 }
1664 else if(V0==LAMBDABAR) {
1665 type_V1_decor(*cascadeVertices[0]) = "Lambdabar";
1666 }
1667 else if(V0==KS) {
1668 type_V1_decor(*cascadeVertices[0]) = "Ks";
1669 }
1670 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1671 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1672 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1673 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1674 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1675 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1676 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1677 trk_px.reserve(V0_helper.nRefTrks());
1678 trk_py.reserve(V0_helper.nRefTrks());
1679 trk_pz.reserve(V0_helper.nRefTrks());
1680 for(auto&& vec3 : V0_helper.refTrks()) {
1681 trk_px.push_back( vec3.Px() );
1682 trk_py.push_back( vec3.Py() );
1683 trk_pz.push_back( vec3.Pz() );
1684 }
1685 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1686 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1687 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1688
1689 result.push_back( std::make_pair(fit_result.release(),nullptr) );
1690 }
1691 }
1692 } // loop over trackContainer
1693 } // for m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo<=0
1695 std::vector<const xAOD::TrackParticle*> tracksPlus;
1696 std::vector<const xAOD::TrackParticle*> tracksMinus;
1697 for(const xAOD::TrackParticle* tpExtra : *trackContainer) {
1698 if( tpExtra->pt() < std::fmin(m_extraTrk1MinPt,m_extraTrk2MinPt) ) continue;
1699 if( !m_trkSelector->decision(*tpExtra, nullptr) ) continue;
1700 // Check identical tracks in input
1701 if(std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend()) continue;
1702 if(std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend()) continue;
1703 if(tpExtra->charge()>0) {
1704 tracksPlus.push_back(tpExtra);
1705 }
1706 else {
1707 tracksMinus.push_back(tpExtra);
1708 }
1709 }
1710
1712 TLorentzVector p4_ExtraTrk1, p4_ExtraTrk2;
1713 for(const xAOD::TrackParticle* tp1 : tracksPlus) {
1714 for(const xAOD::TrackParticle* tp2 : tracksMinus) {
1715 if((tp1->pt()>m_extraTrk1MinPt && tp2->pt()>m_extraTrk2MinPt) ||
1716 (tp1->pt()>m_extraTrk2MinPt && tp2->pt()>m_extraTrk1MinPt)) {
1717 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1718 p4_ExtraTrk2.SetPtEtaPhiM(tp2->pt(), tp2->eta(), tp2->phi(), m_extraTrk2MassHypo);
1719 double main_mass = (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2).M();
1720 if(m_useImprovedMass) {
1721 if(m_jxDaug_num==2 && m_massJpsi>0) main_mass += - (p4_moth - p4_v0).M() + m_massJpsi;
1722 else if(m_jxDaug_num>=3 && m_massJX>0) main_mass += - (p4_moth - p4_v0).M() + m_massJX;
1723 if((V0==LAMBDA || V0==LAMBDABAR) && m_massLd>0) main_mass += - p4_v0.M() + m_massLd;
1724 else if(V0==KS && m_massKs>0) main_mass += - p4_v0.M() + m_massKs;
1725 if(m_massD0>0) main_mass += - (p4_ExtraTrk1+p4_ExtraTrk2).M() + m_massD0;
1726 }
1727 if(main_mass < m_MassLower || main_mass > m_MassUpper) continue;
1728 auto D0 = getD0Candidate(JXvtx,tp1,tp2);
1729 if(D0.extraTrack1) D0Candidates.push_back(D0);
1730 }
1731 }
1732 }
1733
1734 std::vector<double> massesExtra{m_extraTrk1MassHypo,m_extraTrk2MassHypo};
1735
1736 for(auto&& D0 : D0Candidates.vector()) {
1737 std::vector<const xAOD::TrackParticle*> tracksExtra{D0.extraTrack1,D0.extraTrack2};
1738
1739 // Apply the user's settings to the fitter
1740 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1741 // Robustness: http://cdsweb.cern.ch/record/685551
1742 int robustness = 0;
1743 m_iVertexFitter->setRobustness(robustness, *state);
1744 // Build up the topology
1745 // Vertex list
1746 std::vector<Trk::VertexID> vrtList;
1747 // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/IVertexCascadeFitter.h
1748 // V0 vertex
1749 Trk::VertexID vID1;
1750 if (m_constrV0) {
1751 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,V0==KS?m_massKs:m_massLd);
1752 } else {
1753 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1754 }
1755 vrtList.push_back(vID1);
1756 // D0 vertex
1757 Trk::VertexID vID2;
1758 if (m_constrD0) {
1759 vID2 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state,m_massD0);
1760 } else {
1761 vID2 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state);
1762 }
1763 vrtList.push_back(vID2);
1764 // Mother vertex includes one subvertex (V0) and JX tracks + extra track
1765 Trk::VertexID vID3;
1766 if(m_constrMainV) {
1767 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
1768 } else {
1769 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1770 }
1771 if (m_constrJX && m_jxDaug_num>2) {
1772 std::vector<Trk::VertexID> cnstV;
1773 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1774 ATH_MSG_WARNING("addMassConstraint for JX failed");
1775 }
1776 }
1777 if (m_constrJpsi) {
1778 std::vector<Trk::VertexID> cnstV;
1779 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1780 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
1781 }
1782 }
1783 if (m_constrX && m_jxDaug_num==4) {
1784 std::vector<Trk::VertexID> cnstV;
1785 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1786 ATH_MSG_WARNING("addMassConstraint for X failed");
1787 }
1788 }
1789 // Do the work
1790 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state, pv_AOD.get(), pv_AOD.get() && m_firstDecayAtPV ? true : false) );
1791
1792 if (fit_result) {
1793 for(auto& v : fit_result->vertices()) {
1794 if(v->nTrackParticles()==0) {
1795 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1796 v->setTrackParticleLinks(nullLinkVector);
1797 }
1798 }
1799 // reset links to original tracks
1800 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
1801
1802 // necessary to prevent memory leak
1803 fit_result->setSVOwnership(true);
1804
1805 // Chi2/DOF cut
1806 double chi2DOF = fit_result->fitChi2()/fit_result->nDoF();
1807 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1808 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->getParticleMoms();
1809 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->vertices();
1810 size_t iMoth = cascadeVertices.size()-1;
1811 double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1812 double lxy_SV2 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
1813 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut && lxy_SV2>m_lxyD0_cut) {
1814 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->chiSquared();
1815 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->numberDoF();
1816 if(V0==LAMBDA) {
1817 type_V1_decor(*cascadeVertices[0]) = "Lambda";
1818 }
1819 else if(V0==LAMBDABAR) {
1820 type_V1_decor(*cascadeVertices[0]) = "Lambdabar";
1821 }
1822 else if(V0==KS) {
1823 type_V1_decor(*cascadeVertices[0]) = "Ks";
1824 }
1825 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
1826 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
1827 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
1828 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
1829 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
1830 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
1831 trk_px.clear(); trk_py.clear(); trk_pz.clear();
1832 trk_px.reserve(V0_helper.nRefTrks());
1833 trk_py.reserve(V0_helper.nRefTrks());
1834 trk_pz.reserve(V0_helper.nRefTrks());
1835 for(auto&& vec3 : V0_helper.refTrks()) {
1836 trk_px.push_back( vec3.Px() );
1837 trk_py.push_back( vec3.Py() );
1838 trk_pz.push_back( vec3.Pz() );
1839 }
1840 trk_pxDeco(*cascadeVertices[0]) = trk_px;
1841 trk_pyDeco(*cascadeVertices[0]) = trk_py;
1842 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1843
1844 result.push_back( std::make_pair(fit_result.release(),nullptr) );
1845 }
1846 }
1847 } // loop over D0Candidates
1848 } // for m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo<=0
1850 std::vector<const xAOD::TrackParticle*> tracksPlus;
1851 std::vector<const xAOD::TrackParticle*> tracksMinus;
1852 double minTrkPt = std::fmin(std::fmin(m_extraTrk1MinPt,m_extraTrk2MinPt),m_extraTrk3MinPt);
1853 for(const xAOD::TrackParticle* tpExtra : *trackContainer) {
1854 if( tpExtra->pt() < minTrkPt ) continue;
1855 if( !m_trkSelector->decision(*tpExtra, nullptr) ) continue;
1856 // Check identical tracks in input
1857 if(std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend()) continue;
1858 if(std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend()) continue;
1859 if(tpExtra->charge()>0) {
1860 tracksPlus.push_back(tpExtra);
1861 }
1862 else {
1863 tracksMinus.push_back(tpExtra);
1864 }
1865 }
1866
1868 TLorentzVector p4_ExtraTrk1, p4_ExtraTrk2, p4_ExtraTrk3;
1869 // +,-,- combination (D- -> K+ pi- pi-)
1870 for(const xAOD::TrackParticle* tp1 : tracksPlus) {
1871 if( tp1->pt() < m_extraTrk1MinPt ) continue;
1872 for(auto tp2Itr=tracksMinus.cbegin(); tp2Itr!=tracksMinus.cend(); ++tp2Itr) {
1873 const xAOD::TrackParticle* tp2 = *tp2Itr;
1874 for(auto tp3Itr=tp2Itr+1; tp3Itr!=tracksMinus.cend(); ++tp3Itr) {
1875 const xAOD::TrackParticle* tp3 = *tp3Itr;
1876 if((tp2->pt()>m_extraTrk2MinPt && tp3->pt()>m_extraTrk3MinPt) ||
1877 (tp2->pt()>m_extraTrk3MinPt && tp3->pt()>m_extraTrk2MinPt)) {
1878 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1879 p4_ExtraTrk2.SetPtEtaPhiM(tp2->pt(), tp2->eta(), tp2->phi(), m_extraTrk2MassHypo);
1880 p4_ExtraTrk3.SetPtEtaPhiM(tp3->pt(), tp3->eta(), tp3->phi(), m_extraTrk3MassHypo);
1881 double main_mass = (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M();
1882 if(m_useImprovedMass) {
1883 if(m_jxDaug_num==2 && m_massJpsi>0) main_mass += - (p4_moth - p4_v0).M() + m_massJpsi;
1884 else if(m_jxDaug_num>=3 && m_massJX>0) main_mass += - (p4_moth - p4_v0).M() + m_massJX;
1885 if((V0==LAMBDA || V0==LAMBDABAR) && m_massLd>0) main_mass += - p4_v0.M() + m_massLd;
1886 else if(V0==KS && m_massKs>0) main_mass += - p4_v0.M() + m_massKs;
1887 if(m_massDpm>0) main_mass += - (p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() + m_massDpm;
1888 }
1889 if(main_mass < m_MassLower || main_mass > m_MassUpper) continue;
1890 auto Dpm = getDpmCandidate(JXvtx,tp1,tp2,tp3);
1891 if(Dpm.extraTrack1) DpmCandidates.push_back(Dpm);
1892 }
1893 }
1894 }
1895 }
1896 // -,+,+ combination (D+ -> K- pi+ pi+)
1897 for(const xAOD::TrackParticle* tp1 : tracksMinus) {
1898 if( tp1->pt() < m_extraTrk1MinPt ) continue;
1899 for(auto tp2Itr=tracksPlus.cbegin(); tp2Itr!=tracksPlus.cend(); ++tp2Itr) {
1900 const xAOD::TrackParticle* tp2 = *tp2Itr;
1901 for(auto tp3Itr=tp2Itr+1; tp3Itr!=tracksPlus.cend(); ++tp3Itr) {
1902 const xAOD::TrackParticle* tp3 = *tp3Itr;
1903 if((tp2->pt()>m_extraTrk2MinPt && tp3->pt()>m_extraTrk3MinPt) ||
1904 (tp2->pt()>m_extraTrk3MinPt && tp3->pt()>m_extraTrk2MinPt)) {
1905 p4_ExtraTrk1.SetPtEtaPhiM(tp1->pt(), tp1->eta(), tp1->phi(), m_extraTrk1MassHypo);
1906 p4_ExtraTrk2.SetPtEtaPhiM(tp2->pt(), tp2->eta(), tp2->phi(), m_extraTrk2MassHypo);
1907 p4_ExtraTrk3.SetPtEtaPhiM(tp3->pt(), tp3->eta(), tp3->phi(), m_extraTrk3MassHypo);
1908 double main_mass = (p4_moth+p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M();
1909 if(m_useImprovedMass) {
1910 if(m_jxDaug_num==2 && m_massJpsi>0) main_mass += - (p4_moth - p4_v0).M() + m_massJpsi;
1911 else if(m_jxDaug_num>=3 && m_massJX>0) main_mass += - (p4_moth - p4_v0).M() + m_massJX;
1912 if((V0==LAMBDA || V0==LAMBDABAR) && m_massLd>0) main_mass += - p4_v0.M() + m_massLd;
1913 else if(V0==KS && m_massKs>0) main_mass += - p4_v0.M() + m_massKs;
1914 if(m_massDpm>0) main_mass += - (p4_ExtraTrk1+p4_ExtraTrk2+p4_ExtraTrk3).M() + m_massDpm;
1915 }
1916 if(main_mass < m_MassLower || main_mass > m_MassUpper) continue;
1917 auto Dpm = getDpmCandidate(JXvtx,tp1,tp2,tp3);
1918 if(Dpm.extraTrack1) DpmCandidates.push_back(Dpm);
1919 }
1920 }
1921 }
1922 }
1923
1924 std::vector<double> massesExtra{m_extraTrk1MassHypo,m_extraTrk2MassHypo,m_extraTrk3MassHypo};
1925
1926 for(auto&& Dpm : DpmCandidates.vector()) {
1927 std::vector<const xAOD::TrackParticle*> tracksExtra{Dpm.extraTrack1,Dpm.extraTrack2,Dpm.extraTrack3};
1928
1929 // Apply the user's settings to the fitter
1930 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1931 // Robustness: http://cdsweb.cern.ch/record/685551
1932 int robustness = 0;
1933 m_iVertexFitter->setRobustness(robustness, *state);
1934 // Build up the topology
1935 // Vertex list
1936 std::vector<Trk::VertexID> vrtList;
1937 std::vector<Trk::VertexID> vrtList2;
1938 // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/IVertexCascadeFitter.h
1939 if(m_JXV0SubVtx) {
1940 // V0 vertex
1941 Trk::VertexID vID1;
1942 if (m_constrV0) {
1943 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,V0==KS?m_massKs:m_massLd);
1944 } else {
1945 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1946 }
1947 vrtList.push_back(vID1);
1948 // JX+V0 vertex
1949 Trk::VertexID vID2;
1950 if(m_constrJXV0) {
1951 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massJXV0);
1952 } else {
1953 vID2 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1954 }
1955 vrtList2.push_back(vID2);
1956 Trk::VertexID vID3;
1957 if (m_constrDpm) {
1958 vID3 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state,m_massDpm);
1959 } else {
1960 vID3 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state);
1961 }
1962 vrtList2.push_back(vID3);
1963 // Mother vertex includes two subvertices: V0, Dpm and JX tracks
1964 std::vector<const xAOD::TrackParticle*> tp;
1965 std::vector<double> tp_masses;
1966 if(m_constrMainV) {
1967 m_iVertexFitter->nextVertex(tp,tp_masses,vrtList2,*state,m_massMainV);
1968 } else {
1969 m_iVertexFitter->nextVertex(tp,tp_masses,vrtList2,*state);
1970 }
1971 if (m_constrJX && m_jxDaug_num>2) {
1972 std::vector<Trk::VertexID> cnstV;
1973 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1974 ATH_MSG_WARNING("addMassConstraint for JX failed");
1975 }
1976 }
1977 if (m_constrJpsi) {
1978 std::vector<Trk::VertexID> cnstV;
1979 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1980 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
1981 }
1982 }
1983 if (m_constrX && m_jxDaug_num==4) {
1984 std::vector<Trk::VertexID> cnstV;
1985 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1986 ATH_MSG_WARNING("addMassConstraint for X failed");
1987 }
1988 }
1989 }
1990 else { // m_JXV0SubVtx==false
1991 // V0 vertex
1992 Trk::VertexID vID1;
1993 if (m_constrV0) {
1994 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,V0==KS?m_massKs:m_massLd);
1995 } else {
1996 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1997 }
1998 vrtList.push_back(vID1);
1999 // Dpm vertex
2000 Trk::VertexID vID2;
2001 if (m_constrDpm) {
2002 vID2 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state,m_massDpm);
2003 } else {
2004 vID2 = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state);
2005 }
2006 vrtList.push_back(vID2);
2007 // Mother vertex includes two subvertices: V0, Dpm and JX tracks
2008 Trk::VertexID vID3;
2009 if(m_constrMainV) {
2010 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
2011 } else {
2012 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
2013 }
2014 if (m_constrJX && m_jxDaug_num>2) {
2015 std::vector<Trk::VertexID> cnstV;
2016 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
2017 ATH_MSG_WARNING("addMassConstraint for JX failed");
2018 }
2019 }
2020 if (m_constrJpsi) {
2021 std::vector<Trk::VertexID> cnstV;
2022 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
2023 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
2024 }
2025 }
2026 if (m_constrX && m_jxDaug_num==4) {
2027 std::vector<Trk::VertexID> cnstV;
2028 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
2029 ATH_MSG_WARNING("addMassConstraint for X failed");
2030 }
2031 }
2032 }
2033 // Do the work
2034 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state, pv_AOD.get(), pv_AOD.get() && m_firstDecayAtPV ? true : false) );
2035
2036 if (fit_result) {
2037 for(auto& v : fit_result->vertices()) {
2038 if(v->nTrackParticles()==0) {
2039 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
2040 v->setTrackParticleLinks(nullLinkVector);
2041 }
2042 }
2043 // reset links to original tracks
2044 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
2045
2046 // necessary to prevent memory leak
2047 fit_result->setSVOwnership(true);
2048
2049 // Chi2/DOF cut
2050 double chi2DOF = fit_result->fitChi2()/fit_result->nDoF();
2051 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
2052 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->getParticleMoms();
2053 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->vertices();
2054 size_t iMoth = cascadeVertices.size()-1;
2055 double lxy_SV1(0), lxy_SV2(0);
2056 if(m_JXV0SubVtx) {
2057 lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
2058 lxy_SV2 = m_CascadeTools->lxy(moms[2],cascadeVertices[2],cascadeVertices[iMoth]);
2059 }
2060 else {
2061 lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
2062 lxy_SV2 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
2063 }
2064 if(chi2CutPassed && lxy_SV1>m_lxyV0_cut && lxy_SV2>m_lxyDpm_cut) {
2065 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->chiSquared();
2066 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->numberDoF();
2067 if(V0==LAMBDA) {
2068 type_V1_decor(*cascadeVertices[0]) = "Lambda";
2069 }
2070 else if(V0==LAMBDABAR) {
2071 type_V1_decor(*cascadeVertices[0]) = "Lambdabar";
2072 }
2073 else if(V0==KS) {
2074 type_V1_decor(*cascadeVertices[0]) = "Ks";
2075 }
2076 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
2077 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
2078 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
2079 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
2080 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
2081 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
2082 trk_px.clear(); trk_py.clear(); trk_pz.clear();
2083 trk_px.reserve(V0_helper.nRefTrks());
2084 trk_py.reserve(V0_helper.nRefTrks());
2085 trk_pz.reserve(V0_helper.nRefTrks());
2086 for(auto&& vec3 : V0_helper.refTrks()) {
2087 trk_px.push_back( vec3.Px() );
2088 trk_py.push_back( vec3.Py() );
2089 trk_pz.push_back( vec3.Pz() );
2090 }
2091 trk_pxDeco(*cascadeVertices[0]) = trk_px;
2092 trk_pyDeco(*cascadeVertices[0]) = trk_py;
2093 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
2094
2095 // refit with main vertex mass constraint if required
2097 TLorentzVector totalMom;
2098 for(size_t it=0; it<moms[iMoth].size(); it++) totalMom += moms[iMoth][it];
2099 double mainV_mass = totalMom.M();
2100 if(mainV_mass>m_PostMassLower && mainV_mass<m_PostMassUpper) {
2101 std::unique_ptr<Trk::IVKalState> state_mvc = m_iVertexFitter->makeState();
2102 int robustness_mvc = 0;
2103 m_iVertexFitter->setRobustness(robustness_mvc, *state_mvc);
2104 std::vector<Trk::VertexID> vrtList_mvc;
2105 std::vector<Trk::VertexID> vrtList2_mvc;
2106 if(m_JXV0SubVtx) {
2107 Trk::VertexID vID1_mvc; // V0 vertex
2108 if (m_constrV0) {
2109 vID1_mvc = m_iVertexFitter->startVertex(tracksV0,massesV0,*state_mvc,V0==KS?m_massKs:m_massLd);
2110 } else {
2111 vID1_mvc = m_iVertexFitter->startVertex(tracksV0,massesV0,*state_mvc);
2112 }
2113 vrtList_mvc.push_back(vID1_mvc);
2114 Trk::VertexID vID2_mvc; // JX+V0 vertex
2115 if(m_constrJXV0) {
2116 vID2_mvc = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList_mvc,*state_mvc,m_massJXV0);
2117 } else {
2118 vID2_mvc = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList_mvc,*state_mvc);
2119 }
2120 vrtList2_mvc.push_back(vID2_mvc);
2121 Trk::VertexID vID3_mvc; // Dpm vertex
2122 if (m_constrDpm) {
2123 vID3_mvc = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state_mvc,m_massDpm);
2124 } else {
2125 vID3_mvc = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state_mvc);
2126 }
2127 vrtList2_mvc.push_back(vID3_mvc);
2128 std::vector<const xAOD::TrackParticle*> tp;
2129 std::vector<double> tp_masses;
2130 m_iVertexFitter->nextVertex(tp,tp_masses,vrtList2_mvc,*state_mvc,m_massMainV); // Mother vertex
2131 if (m_constrJX && m_jxDaug_num>2) {
2132 std::vector<Trk::VertexID> cnstV_mvc;
2133 if ( !m_iVertexFitter->addMassConstraint(vID2_mvc,tracksJX,cnstV_mvc,*state_mvc,m_massJX).isSuccess() ) {
2134 ATH_MSG_WARNING("addMassConstraint for JX failed");
2135 }
2136 }
2137 if (m_constrJpsi) {
2138 std::vector<Trk::VertexID> cnstV_mvc;
2139 if ( !m_iVertexFitter->addMassConstraint(vID2_mvc,tracksJpsi,cnstV_mvc,*state_mvc,m_massJpsi).isSuccess() ) {
2140 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
2141 }
2142 }
2143 if (m_constrX && m_jxDaug_num==4) {
2144 std::vector<Trk::VertexID> cnstV_mvc;
2145 if ( !m_iVertexFitter->addMassConstraint(vID2_mvc,tracksX,cnstV_mvc,*state_mvc,m_massX).isSuccess() ) {
2146 ATH_MSG_WARNING("addMassConstraint for X failed");
2147 }
2148 }
2149 }
2150 else {
2151 Trk::VertexID vID1_mvc; // V0 vertex
2152 if (m_constrV0) {
2153 vID1_mvc = m_iVertexFitter->startVertex(tracksV0,massesV0,*state_mvc,V0==KS?m_massKs:m_massLd);
2154 } else {
2155 vID1_mvc = m_iVertexFitter->startVertex(tracksV0,massesV0,*state_mvc);
2156 }
2157 vrtList_mvc.push_back(vID1_mvc);
2158 Trk::VertexID vID2_mvc; // Dpm vertex
2159 if (m_constrDpm) {
2160 vID2_mvc = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state_mvc,m_massDpm);
2161 } else {
2162 vID2_mvc = m_iVertexFitter->nextVertex(tracksExtra,massesExtra,*state_mvc);
2163 }
2164 vrtList_mvc.push_back(vID2_mvc);
2165 Trk::VertexID vID3_mvc = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList_mvc,*state_mvc,m_massMainV); // Mother vertex
2166 if (m_constrJX && m_jxDaug_num>2) {
2167 std::vector<Trk::VertexID> cnstV_mvc;
2168 if ( !m_iVertexFitter->addMassConstraint(vID3_mvc,tracksJX,cnstV_mvc,*state_mvc,m_massJX).isSuccess() ) {
2169 ATH_MSG_WARNING("addMassConstraint for JX failed");
2170 }
2171 }
2172 if (m_constrJpsi) {
2173 std::vector<Trk::VertexID> cnstV_mvc;
2174 if ( !m_iVertexFitter->addMassConstraint(vID3_mvc,tracksJpsi,cnstV_mvc,*state_mvc,m_massJpsi).isSuccess() ) {
2175 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
2176 }
2177 }
2178 if (m_constrX && m_jxDaug_num==4) {
2179 std::vector<Trk::VertexID> cnstV_mvc;
2180 if ( !m_iVertexFitter->addMassConstraint(vID3_mvc,tracksX,cnstV_mvc,*state_mvc,m_massX).isSuccess() ) {
2181 ATH_MSG_WARNING("addMassConstraint for X failed");
2182 }
2183 }
2184 }
2185 // Do the work
2186 std::unique_ptr<Trk::VxCascadeInfo> fit_result_mvc = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state_mvc, pv_AOD.get(), pv_AOD.get() && m_firstDecayAtPV ? true : false) );
2187
2188 if (fit_result_mvc) {
2189 for(auto& v : fit_result_mvc->vertices()) {
2190 if(v->nTrackParticles()==0) {
2191 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
2192 v->setTrackParticleLinks(nullLinkVector);
2193 }
2194 }
2195 BPhysPVCascadeTools::PrepareVertexLinks(fit_result_mvc.get(), trackCols);
2196 fit_result_mvc->setSVOwnership(true);
2197 chi2_V1_decor(*cascadeVertices[0]) = V0vtx->chiSquared();
2198 ndof_V1_decor(*cascadeVertices[0]) = V0vtx->numberDoF();
2199 if(V0==LAMBDA) {
2200 type_V1_decor(*cascadeVertices[0]) = "Lambda";
2201 }
2202 else if(V0==LAMBDABAR) {
2203 type_V1_decor(*cascadeVertices[0]) = "Lambdabar";
2204 }
2205 else if(V0==KS) {
2206 type_V1_decor(*cascadeVertices[0]) = "Ks";
2207 }
2208 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*V0vtx) ? mAcc_gfit(*V0vtx) : 0;
2209 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*V0vtx) ? mAcc_gmass(*V0vtx) : -1;
2210 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*V0vtx) ? mAcc_gmasserr(*V0vtx) : -1;
2211 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*V0vtx) ? mAcc_gchisq(*V0vtx) : 999999;
2212 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*V0vtx) ? mAcc_gndof(*V0vtx) : 0;
2213 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*V0vtx) ? mAcc_gprob(*V0vtx) : -1;
2214 trk_px.clear(); trk_py.clear(); trk_pz.clear();
2215 trk_px.reserve(V0_helper.nRefTrks());
2216 trk_py.reserve(V0_helper.nRefTrks());
2217 trk_pz.reserve(V0_helper.nRefTrks());
2218 for(auto&& vec3 : V0_helper.refTrks()) {
2219 trk_px.push_back( vec3.Px() );
2220 trk_py.push_back( vec3.Py() );
2221 trk_pz.push_back( vec3.Pz() );
2222 }
2223 trk_pxDeco(*cascadeVertices[0]) = trk_px;
2224 trk_pyDeco(*cascadeVertices[0]) = trk_py;
2225 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
2226
2227 result.push_back( std::make_pair(fit_result.release(),fit_result_mvc.release()) );
2228 }
2229 else result.push_back( std::make_pair(fit_result.release(),nullptr) );
2230 }
2231 else result.push_back( std::make_pair(fit_result.release(),nullptr) );
2232 }
2233 else result.push_back( std::make_pair(fit_result.release(),nullptr) );
2234 }
2235 }
2236 } // loop over DpmCandidates
2237 } // for m_extraTrk1MassHypo>0 && m_extraTrk2MassHypo>0 && m_extraTrk3MassHypo>0
2238
2239 if(pv_xAOD) {
2240 for(auto cascade_info_pair : result) {
2241 if(cascade_info_pair.first && cascade_info_pair.first->getParticleMoms().size()>0) {
2242 size_t index = cascade_info_pair.first->getParticleMoms().size() - 1;
2243 const std::vector<TLorentzVector> &mom = cascade_info_pair.first->getParticleMoms()[index];
2244 const Amg::MatrixX &cov = cascade_info_pair.first->getCovariance()[index];
2245 const xAOD::Vertex* mainVertex = cascade_info_pair.first->vertices()[index];
2246 xAOD::BPhysHypoHelper vtx(m_hypoName, mainVertex);
2247 bool isInDefaultPVCont = false;
2248 for(const xAOD::Vertex* pvVtx : *defaultPVContainer) {
2249 if(pv_xAOD == pvVtx) { isInDefaultPVCont = true; break; }
2250 }
2251 if(isInDefaultPVCont) vtx.setPv( pv_xAOD, defaultPVContainer, pvtype );
2252 else vtx.setPv( pv_xAOD, pvContainer, pvtype );
2253 if(origPv_xAOD) vtx.setOrigPv( origPv_xAOD, defaultPVContainer, pvtype );
2254 vtx.setLxy ( m_CascadeTools->lxy (mom, vtx.vtx(), pv_xAOD), pvtype );
2255 vtx.setLxyErr ( m_CascadeTools->lxyError (mom, cov, vtx.vtx(), pv_xAOD), pvtype );
2256 vtx.setA0 ( m_CascadeTools->a0 (mom, vtx.vtx(), pv_xAOD), pvtype );
2257 vtx.setA0Err ( m_CascadeTools->a0Error (mom, cov, vtx.vtx(), pv_xAOD), pvtype );
2258 vtx.setA0xy ( m_CascadeTools->a0xy (mom, vtx.vtx(), pv_xAOD), pvtype );
2259 vtx.setA0xyErr( m_CascadeTools->a0xyError(mom, cov, vtx.vtx(), pv_xAOD), pvtype );
2260 vtx.setZ0 ( m_CascadeTools->a0z (mom, vtx.vtx(), pv_xAOD), pvtype );
2261 vtx.setZ0Err ( m_CascadeTools->a0zError (mom, cov, vtx.vtx(), pv_xAOD), pvtype );
2262 vtx.setRefitPVStatus( 0, pvtype );
2263 // Proper decay times
2264 vtx.setTau( m_CascadeTools->tau(mom, vtx.vtx(), pv_xAOD), pvtype, xAOD::BPhysHypoHelper::TAU_INV_MASS );
2265 vtx.setTauErr( m_CascadeTools->tauError(mom, cov, vtx.vtx(), pv_xAOD), pvtype, xAOD::BPhysHypoHelper::TAU_INV_MASS );
2266 vtx.setTau( m_CascadeTools->tau(mom, vtx.vtx(), pv_xAOD, m_massMainV), pvtype, xAOD::BPhysHypoHelper::TAU_CONST_MASS );
2267 vtx.setTauErr( m_CascadeTools->tauError(mom, cov, vtx.vtx(), pv_xAOD, m_massMainV), pvtype, xAOD::BPhysHypoHelper::TAU_CONST_MASS );
2268
2269 if(cascade_info_pair.second && cascade_info_pair.second->getParticleMoms().size()>0) {
2270 index = cascade_info_pair.second->getParticleMoms().size() - 1;
2271 const std::vector<TLorentzVector> &mom_mvc = cascade_info_pair.second->getParticleMoms()[index];
2272 const Amg::MatrixX &cov_mvc = cascade_info_pair.second->getCovariance()[index];
2273 const xAOD::Vertex* mainVertex_mvc = cascade_info_pair.second->vertices()[index];
2274 xAOD::BPhysHypoHelper vtx_mvc(m_hypoName, mainVertex_mvc);
2275 if(isInDefaultPVCont) vtx_mvc.setPv( pv_xAOD, defaultPVContainer, pvtype );
2276 else vtx_mvc.setPv( pv_xAOD, pvContainer, pvtype );
2277 if(origPv_xAOD) vtx.setOrigPv( origPv_xAOD, defaultPVContainer, pvtype );
2278 vtx_mvc.setLxy ( m_CascadeTools->lxy (mom_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype );
2279 vtx_mvc.setLxyErr ( m_CascadeTools->lxyError (mom_mvc, cov_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype );
2280 vtx_mvc.setA0 ( m_CascadeTools->a0 (mom_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype );
2281 vtx_mvc.setA0Err ( m_CascadeTools->a0Error (mom_mvc, cov_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype );
2282 vtx_mvc.setA0xy ( m_CascadeTools->a0xy (mom_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype );
2283 vtx_mvc.setA0xyErr( m_CascadeTools->a0xyError(mom_mvc, cov_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype );
2284 vtx_mvc.setZ0 ( m_CascadeTools->a0z (mom_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype );
2285 vtx_mvc.setZ0Err ( m_CascadeTools->a0zError (mom_mvc, cov_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype );
2286 vtx_mvc.setRefitPVStatus( 0, pvtype );
2287 // Proper decay times
2288 vtx_mvc.setTau( m_CascadeTools->tau(mom_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype, xAOD::BPhysHypoHelper::TAU_INV_MASS );
2289 vtx_mvc.setTauErr( m_CascadeTools->tauError(mom_mvc, cov_mvc, vtx_mvc.vtx(), pv_xAOD), pvtype, xAOD::BPhysHypoHelper::TAU_INV_MASS );
2290 vtx_mvc.setTau( m_CascadeTools->tau(mom_mvc, vtx_mvc.vtx(), pv_xAOD, m_massMainV), pvtype, xAOD::BPhysHypoHelper::TAU_CONST_MASS );
2291 vtx_mvc.setTauErr( m_CascadeTools->tauError(mom_mvc, cov_mvc, vtx_mvc.vtx(), pv_xAOD, m_massMainV), pvtype, xAOD::BPhysHypoHelper::TAU_CONST_MASS );
2292 }
2293 }
2294 }
2295 }
2296
2297 return result;
2298 }
static const int D0
Definition AtlasPID.h:119
static void PrepareVertexLinks(Trk::VxCascadeInfo *result, const xAOD::TrackParticleContainer *importedTrackCollection)
MesonCandidate getD0Candidate(const xAOD::Vertex *JXvtx, const xAOD::TrackParticle *extraTrk1, const xAOD::TrackParticle *extraTrk2) const
MesonCandidate getDpmCandidate(const xAOD::Vertex *JXvtx, const xAOD::TrackParticle *extraTrk1, const xAOD::TrackParticle *extraTrk2, const xAOD::TrackParticle *extraTrk3) const
pv_type
: Enum type of the PV
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .).
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
float numberDoF() const
Returns the number of degrees of freedom of the vertex fit as float.
float chiSquared() const
Returns the of the vertex fit as float.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
str index
Definition DeMoScan.py:362
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)

◆ fitMainVtx() [2/2]

std::vector< std::pair< Trk::VxCascadeInfo *, Trk::VxCascadeInfo * > > DerivationFramework::JpsiXPlusDisplaced::fitMainVtx ( const xAOD::Vertex * JXvtx,
const std::vector< double > & massesJX,
const XiCandidate & disVtx,
const xAOD::TrackParticleContainer * trackContainer,
const std::vector< const xAOD::TrackParticleContainer * > & trackCols,
const xAOD::VertexContainer * defaultPVContainer,
const xAOD::VertexContainer * pvContainer ) const
private

Definition at line 2300 of file JpsiXPlusDisplaced.cxx.

2300 {
2301 std::vector<std::pair<Trk::VxCascadeInfo*,Trk::VxCascadeInfo*> > result;
2302
2303 std::vector<const xAOD::TrackParticle*> tracksJX;
2304 tracksJX.reserve(JXvtx->nTrackParticles());
2305 for(size_t i=0; i<JXvtx->nTrackParticles(); i++) tracksJX.push_back(JXvtx->trackParticle(i));
2306 if (tracksJX.size() != massesJX.size()) {
2307 ATH_MSG_ERROR("Problems with JX input: number of tracks or track mass inputs is not correct!");
2308 return result;
2309 }
2310 // Check identical tracks in input
2311 if(std::find(tracksJX.cbegin(), tracksJX.cend(), disVtx.V0vtx->trackParticle(0)) != tracksJX.cend()) return result;
2312 if(std::find(tracksJX.cbegin(), tracksJX.cend(), disVtx.V0vtx->trackParticle(1)) != tracksJX.cend()) return result;
2313 std::vector<const xAOD::TrackParticle*> tracksV0;
2314 tracksV0.reserve(disVtx.V0vtx->nTrackParticles());
2315 for(size_t j=0; j<disVtx.V0vtx->nTrackParticles(); j++) tracksV0.push_back(disVtx.V0vtx->trackParticle(j));
2316
2317 if(std::find(tracksJX.cbegin(), tracksJX.cend(), disVtx.track) != tracksJX.cend()) return result;
2318 std::vector<const xAOD::TrackParticle*> tracks3{disVtx.track};
2319 std::vector<double> massesDis3{m_disVDaug3MassHypo};
2320
2321 std::vector<const xAOD::TrackParticle*> tracksJpsi{tracksJX[0], tracksJX[1]};
2322 std::vector<const xAOD::TrackParticle*> tracksX;
2323 if(m_jxDaug_num>=3) tracksX.push_back(tracksJX[2]);
2324 if(m_jxDaug_num==4) tracksX.push_back(tracksJX[3]);
2325
2326 std::vector<double> massesV0;
2327 if(disVtx.V0type==LAMBDA) {
2328 massesV0 = m_massesV0_ppi;
2329 }
2330 else if(disVtx.V0type==LAMBDABAR) {
2331 massesV0 = m_massesV0_pip;
2332 }
2333 else if(disVtx.V0type==KS) {
2334 massesV0 = m_massesV0_pipi;
2335 }
2336
2337 std::vector<double> massesDisV = massesV0; massesDisV.push_back(m_disVDaug3MassHypo);
2338
2339 TLorentzVector p4_moth, p4_disV, tmp;
2340 for(size_t it=0; it<JXvtx->nTrackParticles(); it++) {
2341 tmp.SetPtEtaPhiM(JXvtx->trackParticle(it)->pt(), JXvtx->trackParticle(it)->eta(), JXvtx->trackParticle(it)->phi(), massesJX[it]);
2342 p4_moth += tmp;
2343 }
2344 p4_disV += disVtx.p4_V0track1; p4_disV += disVtx.p4_V0track2; p4_disV += disVtx.p4_disVtrack;
2345 p4_moth += p4_disV;
2346
2352 xAOD::BPhysHelper JX_helper(JXvtx);
2353 const xAOD::Vertex* origPv_xAOD = (m_cascadeFitWithPV>=1 && m_cascadeFitWithPV<=4) ? JX_helper.origPv(pvtype) : nullptr;
2354 const xAOD::Vertex* pv_xAOD = (m_cascadeFitWithPV>=1 && m_cascadeFitWithPV<=4) ? JX_helper.pv(pvtype) : nullptr;
2355 std::unique_ptr<Trk::RecVertex> pv_AOD;
2356 if(pv_xAOD) pv_AOD = std::make_unique<Trk::RecVertex>(pv_xAOD->position(),pv_xAOD->covariancePosition(),pv_xAOD->numberDoF(),pv_xAOD->chiSquared());
2357
2358 SG::AuxElement::Decorator<float> chi2_V0_decor("ChiSquared_V0");
2359 SG::AuxElement::Decorator<int> ndof_V0_decor("nDoF_V0");
2360 SG::AuxElement::Decorator<std::string> type_V0_decor("Type_V0");
2361
2362 SG::AuxElement::Accessor<int> mAcc_gfit("gamma_fit");
2363 SG::AuxElement::Accessor<float> mAcc_gmass("gamma_mass");
2364 SG::AuxElement::Accessor<float> mAcc_gmasserr("gamma_massError");
2365 SG::AuxElement::Accessor<float> mAcc_gchisq("gamma_chisq");
2366 SG::AuxElement::Accessor<int> mAcc_gndof("gamma_ndof");
2367 SG::AuxElement::Accessor<float> mAcc_gprob("gamma_probability");
2368
2369 SG::AuxElement::Decorator<int> mDec_gfit("gamma_fit");
2370 SG::AuxElement::Decorator<float> mDec_gmass("gamma_mass");
2371 SG::AuxElement::Decorator<float> mDec_gmasserr("gamma_massError");
2372 SG::AuxElement::Decorator<float> mDec_gchisq("gamma_chisq");
2373 SG::AuxElement::Decorator<int> mDec_gndof("gamma_ndof");
2374 SG::AuxElement::Decorator<float> mDec_gprob("gamma_probability");
2375 SG::AuxElement::Decorator< std::vector<float> > trk_pxDeco("TrackPx_V0nc");
2376 SG::AuxElement::Decorator< std::vector<float> > trk_pyDeco("TrackPy_V0nc");
2377 SG::AuxElement::Decorator< std::vector<float> > trk_pzDeco("TrackPz_V0nc");
2378 SG::AuxElement::Decorator<float> trk_px_deco("TrackPx_DisVnc");
2379 SG::AuxElement::Decorator<float> trk_py_deco("TrackPy_DisVnc");
2380 SG::AuxElement::Decorator<float> trk_pz_deco("TrackPz_DisVnc");
2381
2382 std::vector<float> trk_px;
2383 std::vector<float> trk_py;
2384 std::vector<float> trk_pz;
2385
2386 if(m_extraTrk1MassHypo<=0) {
2387 double main_mass = p4_moth.M();
2388 if(m_useImprovedMass) {
2389 if(m_jxDaug_num==2 && m_massJpsi>0) main_mass += - (p4_moth - p4_disV).M() + m_massJpsi;
2390 else if(m_jxDaug_num>=3 && m_massJX>0) main_mass += - (p4_moth - p4_disV).M() + m_massJX;
2391 if(m_massDisV>0) main_mass += - p4_disV.M() + m_massDisV;
2392 }
2393 if (main_mass < m_MassLower || main_mass > m_MassUpper) return result;
2394
2395 // Apply the user's settings to the fitter
2396 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
2397 // Robustness: http://cdsweb.cern.ch/record/685551
2398 int robustness = 0;
2399 m_iVertexFitter->setRobustness(robustness, *state);
2400 // Build up the topology
2401 // Vertex list
2402 std::vector<Trk::VertexID> vrtList;
2403 std::vector<Trk::VertexID> vrtList2;
2404 // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/IVertexCascadeFitter.h
2405 // V0 vertex
2406 Trk::VertexID vID1;
2407 if (m_constrV0) {
2408 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,disVtx.V0type==KS?m_massKs:m_massLd);
2409 } else {
2410 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
2411 }
2412 vrtList.push_back(vID1);
2413 // Displaced vertex
2414 Trk::VertexID vID2;
2415 if (m_constrDisV) {
2416 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state,m_massDisV);
2417 } else {
2418 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state);
2419 }
2420 vrtList2.push_back(vID2);
2421 Trk::VertexID vID3;
2422 if(m_JXSubVtx) {
2423 // JX vertex
2424 if (m_constrJX && m_jxDaug_num>2) {
2425 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state,m_massJX);
2426 } else {
2427 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
2428 }
2429 vrtList2.push_back(vID3);
2430 // Mother vertex includes two subvertices: DisV and JX
2431 std::vector<const xAOD::TrackParticle*> tp;
2432 std::vector<double> tp_masses;
2433 if(m_constrMainV) {
2434 m_iVertexFitter->nextVertex(tp,tp_masses,vrtList2,*state,m_massMainV);
2435 } else {
2436 m_iVertexFitter->nextVertex(tp,tp_masses,vrtList2,*state);
2437 }
2438 }
2439 else { // m_JXSubVtx=false
2440 // Mother vertex includes just one subvertex (DisV) and JX tracks
2441 if(m_constrMainV) {
2442 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state,m_massMainV);
2443 } else {
2444 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state);
2445 }
2446 if (m_constrJX && m_jxDaug_num>2) {
2447 std::vector<Trk::VertexID> cnstV;
2448 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
2449 ATH_MSG_WARNING("addMassConstraint for JX failed");
2450 }
2451 }
2452 }
2453 if (m_constrJpsi) {
2454 std::vector<Trk::VertexID> cnstV;
2455 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
2456 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
2457 }
2458 }
2459 if (m_constrX && m_jxDaug_num==4) {
2460 std::vector<Trk::VertexID> cnstV;
2461 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
2462 ATH_MSG_WARNING("addMassConstraint for X failed");
2463 }
2464 }
2465 // Do the work
2466 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state, pv_AOD.get(), pv_AOD.get() && m_firstDecayAtPV ? true : false) );
2467
2468 if (fit_result) {
2469 for(auto& v : fit_result->vertices()) {
2470 if(v->nTrackParticles()==0) {
2471 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
2472 v->setTrackParticleLinks(nullLinkVector);
2473 }
2474 }
2475 // reset links to original tracks
2476 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
2477
2478 // necessary to prevent memory leak
2479 fit_result->setSVOwnership(true);
2480
2481 // Chi2/DOF cut
2482 double chi2DOF = fit_result->fitChi2()/fit_result->nDoF();
2483 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
2484
2485 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->getParticleMoms();
2486 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->vertices();
2487 size_t iMoth = cascadeVertices.size()-1;
2488 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
2489 double lxy_SV1 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
2490
2491 if(chi2CutPassed && lxy_SV1>m_lxyDisV_cut && lxy_SV1_sub>m_lxyV0_cut) {
2492 chi2_V0_decor(*cascadeVertices[0]) = disVtx.V0vtx->chiSquared();
2493 ndof_V0_decor(*cascadeVertices[0]) = disVtx.V0vtx->numberDoF();
2494 if(disVtx.V0type==LAMBDA) {
2495 type_V0_decor(*cascadeVertices[0]) = "Lambda";
2496 }
2497 else if(disVtx.V0type==LAMBDABAR) {
2498 type_V0_decor(*cascadeVertices[0]) = "Lambdabar";
2499 }
2500 else if(disVtx.V0type==KS) {
2501 type_V0_decor(*cascadeVertices[0]) = "Ks";
2502 }
2503 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*disVtx.V0vtx) ? mAcc_gfit(*disVtx.V0vtx) : 0;
2504 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*disVtx.V0vtx) ? mAcc_gmass(*disVtx.V0vtx) : -1;
2505 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*disVtx.V0vtx) ? mAcc_gmasserr(*disVtx.V0vtx) : -1;
2506 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*disVtx.V0vtx) ? mAcc_gchisq(*disVtx.V0vtx) : 999999;
2507 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*disVtx.V0vtx) ? mAcc_gndof(*disVtx.V0vtx) : 0;
2508 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*disVtx.V0vtx) ? mAcc_gprob(*disVtx.V0vtx) : -1;
2509 trk_px.clear(); trk_py.clear(); trk_pz.clear();
2510 trk_px.push_back( disVtx.p4_V0track1.Px() ); trk_px.push_back( disVtx.p4_V0track2.Px() );
2511 trk_py.push_back( disVtx.p4_V0track1.Py() ); trk_py.push_back( disVtx.p4_V0track2.Py() );
2512 trk_pz.push_back( disVtx.p4_V0track1.Pz() ); trk_pz.push_back( disVtx.p4_V0track2.Pz() );
2513 trk_pxDeco(*cascadeVertices[0]) = trk_px;
2514 trk_pyDeco(*cascadeVertices[0]) = trk_py;
2515 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
2516 trk_px_deco(*cascadeVertices[1]) = disVtx.p4_disVtrack.Px();
2517 trk_py_deco(*cascadeVertices[1]) = disVtx.p4_disVtrack.Py();
2518 trk_pz_deco(*cascadeVertices[1]) = disVtx.p4_disVtrack.Pz();
2519
2520 result.push_back( std::make_pair(fit_result.release(),nullptr) );
2521 }
2522 }
2523 } // m_extraTrk1MassHypo<=0
2524 else { // m_extraTrk1MassHypo>0
2525 std::vector<double> massesExtra{m_extraTrk1MassHypo};
2526 std::vector<double> massesJXExtra = massesJX; massesJXExtra.push_back(m_extraTrk1MassHypo);
2527
2528 for(const xAOD::TrackParticle* tpExtra : *trackContainer) {
2529 if ( tpExtra->pt()<m_extraTrk1MinPt ) continue;
2530 if ( !m_trkSelector->decision(*tpExtra, nullptr) ) continue;
2531 // Check identical tracks in input
2532 if(std::find(tracksJX.cbegin(),tracksJX.cend(),tpExtra) != tracksJX.cend()) continue;
2533 if(std::find(tracksV0.cbegin(),tracksV0.cend(),tpExtra) != tracksV0.cend()) continue;
2534 if(tpExtra == disVtx.track) continue;
2535
2536 TLorentzVector tmp;
2537 tmp.SetPtEtaPhiM(tpExtra->pt(),tpExtra->eta(),tpExtra->phi(),m_extraTrk1MassHypo);
2538 double main_mass = (p4_moth+tmp).M();
2539 if(m_useImprovedMass) {
2540 if(m_jxDaug_num==2 && m_massJpsi>0) main_mass += - (p4_moth - p4_disV).M() + m_massJpsi;
2541 else if(m_jxDaug_num>=3 && m_massJX>0) main_mass += - (p4_moth - p4_disV).M() + m_massJX;
2542 if(m_massDisV>0) main_mass += - p4_disV.M() + m_massDisV;
2543 }
2544 if (main_mass < m_MassLower || main_mass > m_MassUpper) continue;
2545
2546 std::vector<const xAOD::TrackParticle*> tracksExtra{tpExtra};
2547 std::vector<const xAOD::TrackParticle*> tracksJXExtra = tracksJX; tracksJXExtra.push_back(tpExtra);
2548
2549 // Apply the user's settings to the fitter
2550 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
2551 // Robustness: http://cdsweb.cern.ch/record/685551
2552 int robustness = 0;
2553 m_iVertexFitter->setRobustness(robustness, *state);
2554 // Build up the topology
2555 // Vertex list
2556 std::vector<Trk::VertexID> vrtList;
2557 std::vector<Trk::VertexID> vrtList2;
2558 // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/IVertexCascadeFitter.h
2559 // V0 vertex
2560 Trk::VertexID vID1;
2561 if (m_constrV0) {
2562 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state,disVtx.V0type==KS?m_massKs:m_massLd);
2563 } else {
2564 vID1 = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
2565 }
2566 vrtList.push_back(vID1);
2567 // Displaced vertex
2568 Trk::VertexID vID2;
2569 if (m_constrDisV) {
2570 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state,m_massDisV);
2571 } else {
2572 vID2 = m_iVertexFitter->nextVertex(tracks3,massesDis3,vrtList,*state);
2573 }
2574 vrtList2.push_back(vID2);
2575 Trk::VertexID vID3;
2576 if(m_JXSubVtx) {
2577 // JXExtra vertex
2578 vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
2579 vrtList2.push_back(vID3);
2580 // Mother vertex
2581 if(m_constrMainV) {
2582 m_iVertexFitter->nextVertex(tracksExtra,massesExtra,vrtList2,*state,m_massMainV);
2583 } else {
2584 m_iVertexFitter->nextVertex(tracksExtra,massesExtra,vrtList2,*state);
2585 }
2586 }
2587 else { // m_JXSubVtx=false
2588 // Mother vertex includes just one subvertex (DisV) and JX tracks + extra track
2589 if(m_constrMainV) {
2590 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList2,*state,m_massMainV);
2591 } else {
2592 vID3 = m_iVertexFitter->nextVertex(tracksJXExtra,massesJXExtra,vrtList2,*state);
2593 }
2594 }
2595 if (m_constrJX && m_jxDaug_num>2) {
2596 std::vector<Trk::VertexID> cnstV;
2597 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
2598 ATH_MSG_WARNING("addMassConstraint for JX failed");
2599 }
2600 }
2601 if (m_constrJpsi) {
2602 std::vector<Trk::VertexID> cnstV;
2603 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
2604 ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
2605 }
2606 }
2607 if (m_constrX && m_jxDaug_num==4) {
2608 std::vector<Trk::VertexID> cnstV;
2609 if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
2610 ATH_MSG_WARNING("addMassConstraint for X failed");
2611 }
2612 }
2613 // Do the work
2614 std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state, pv_AOD.get(), pv_AOD.get() && m_firstDecayAtPV ? true : false) );
2615
2616 if (fit_result) {
2617 for(auto& v : fit_result->vertices()) {
2618 if(v->nTrackParticles()==0) {
2619 std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
2620 v->setTrackParticleLinks(nullLinkVector);
2621 }
2622 }
2623 // reset links to original tracks
2624 BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
2625
2626 // necessary to prevent memory leak
2627 fit_result->setSVOwnership(true);
2628
2629 // Chi2/DOF cut
2630 double chi2DOF = fit_result->fitChi2()/fit_result->nDoF();
2631 bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
2632
2633 const std::vector<std::vector<TLorentzVector> > &moms = fit_result->getParticleMoms();
2634 const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->vertices();
2635 size_t iMoth = cascadeVertices.size()-1;
2636 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
2637 double lxy_SV1 = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
2638
2639 if(chi2CutPassed && lxy_SV1>m_lxyDisV_cut && lxy_SV1_sub>m_lxyV0_cut) {
2640 chi2_V0_decor(*cascadeVertices[0]) = disVtx.V0vtx->chiSquared();
2641 ndof_V0_decor(*cascadeVertices[0]) = disVtx.V0vtx->numberDoF();
2642 if(disVtx.V0type==LAMBDA) {
2643 type_V0_decor(*cascadeVertices[0]) = "Lambda";
2644 }
2645 else if(disVtx.V0type==LAMBDABAR) {
2646 type_V0_decor(*cascadeVertices[0]) = "Lambdabar";
2647 }
2648 else if(disVtx.V0type==KS) {
2649 type_V0_decor(*cascadeVertices[0]) = "Ks";
2650 }
2651 mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*disVtx.V0vtx) ? mAcc_gfit(*disVtx.V0vtx) : 0;
2652 mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*disVtx.V0vtx) ? mAcc_gmass(*disVtx.V0vtx) : -1;
2653 mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*disVtx.V0vtx) ? mAcc_gmasserr(*disVtx.V0vtx) : -1;
2654 mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*disVtx.V0vtx) ? mAcc_gchisq(*disVtx.V0vtx) : 999999;
2655 mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*disVtx.V0vtx) ? mAcc_gndof(*disVtx.V0vtx) : 0;
2656 mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*disVtx.V0vtx) ? mAcc_gprob(*disVtx.V0vtx) : -1;
2657 trk_px.clear(); trk_py.clear(); trk_pz.clear();
2658 trk_px.push_back( disVtx.p4_V0track1.Px() ); trk_px.push_back( disVtx.p4_V0track2.Px() );
2659 trk_py.push_back( disVtx.p4_V0track1.Py() ); trk_py.push_back( disVtx.p4_V0track2.Py() );
2660 trk_pz.push_back( disVtx.p4_V0track1.Pz() ); trk_pz.push_back( disVtx.p4_V0track2.Pz() );
2661 trk_pxDeco(*cascadeVertices[0]) = trk_px;
2662 trk_pyDeco(*cascadeVertices[0]) = trk_py;
2663 trk_pzDeco(*cascadeVertices[0]) = trk_pz;
2664 trk_px_deco(*cascadeVertices[1]) = disVtx.p4_disVtrack.Px();
2665 trk_py_deco(*cascadeVertices[1]) = disVtx.p4_disVtrack.Py();
2666 trk_pz_deco(*cascadeVertices[1]) = disVtx.p4_disVtrack.Pz();
2667
2668 result.push_back( std::make_pair(fit_result.release(),nullptr) );
2669 }
2670 }
2671 } // loop over trackContainer
2672 } // m_extraTrk1MassHypo>0
2673
2674 if(pv_xAOD) {
2675 for(auto cascade_info_pair : result) {
2676 if(cascade_info_pair.first && cascade_info_pair.first->getParticleMoms().size()>0) {
2677 size_t index = cascade_info_pair.first->getParticleMoms().size() - 1;
2678 const std::vector<TLorentzVector> &mom = cascade_info_pair.first->getParticleMoms()[index];
2679 const Amg::MatrixX &cov = cascade_info_pair.first->getCovariance()[index];
2680 const xAOD::Vertex* mainVertex = cascade_info_pair.first->vertices()[index];
2681 xAOD::BPhysHypoHelper vtx(m_hypoName, mainVertex);
2682 bool isInDefaultPVCont = false;
2683 for(const xAOD::Vertex* pvVtx : *defaultPVContainer) {
2684 if(pv_xAOD == pvVtx) { isInDefaultPVCont = true; break; }
2685 }
2686 if(isInDefaultPVCont) vtx.setPv( pv_xAOD, defaultPVContainer, pvtype );
2687 else vtx.setPv( pv_xAOD, pvContainer, pvtype );
2688 if(origPv_xAOD) vtx.setOrigPv( origPv_xAOD, defaultPVContainer, pvtype );
2689 vtx.setLxy ( m_CascadeTools->lxy (mom, vtx.vtx(), pv_xAOD), pvtype );
2690 vtx.setLxyErr ( m_CascadeTools->lxyError (mom, cov, vtx.vtx(), pv_xAOD), pvtype );
2691 vtx.setA0 ( m_CascadeTools->a0 (mom, vtx.vtx(), pv_xAOD), pvtype );
2692 vtx.setA0Err ( m_CascadeTools->a0Error (mom, cov, vtx.vtx(), pv_xAOD), pvtype );
2693 vtx.setA0xy ( m_CascadeTools->a0xy (mom, vtx.vtx(), pv_xAOD), pvtype );
2694 vtx.setA0xyErr( m_CascadeTools->a0xyError(mom, cov, vtx.vtx(), pv_xAOD), pvtype );
2695 vtx.setZ0 ( m_CascadeTools->a0z (mom, vtx.vtx(), pv_xAOD), pvtype );
2696 vtx.setZ0Err ( m_CascadeTools->a0zError (mom, cov, vtx.vtx(), pv_xAOD), pvtype );
2697 vtx.setRefitPVStatus( 0, pvtype );
2698 // Proper decay times
2699 vtx.setTau( m_CascadeTools->tau(mom, vtx.vtx(), pv_xAOD), pvtype, xAOD::BPhysHypoHelper::TAU_INV_MASS );
2700 vtx.setTauErr( m_CascadeTools->tauError(mom, cov, vtx.vtx(), pv_xAOD), pvtype, xAOD::BPhysHypoHelper::TAU_INV_MASS );
2701 vtx.setTau( m_CascadeTools->tau(mom, vtx.vtx(), pv_xAOD, m_massMainV), pvtype, xAOD::BPhysHypoHelper::TAU_CONST_MASS );
2702 vtx.setTauErr( m_CascadeTools->tauError(mom, cov, vtx.vtx(), pv_xAOD, m_massMainV), pvtype, xAOD::BPhysHypoHelper::TAU_CONST_MASS );
2703 }
2704 }
2705 }
2706
2707 return result;
2708 }

◆ fitTracks()

std::unique_ptr< xAOD::Vertex > DerivationFramework::JpsiXPlusDisplaced::fitTracks ( const xAOD::TrackParticle * track1,
const xAOD::TrackParticle * track2,
const xAOD::TrackParticle * track3 = nullptr ) const
private

Definition at line 1228 of file JpsiXPlusDisplaced.cxx.

1228 {
1229 // Starting point
1230 const Trk::Perigee& aPerigee1 = track1->perigeeParameters();
1231 const Trk::Perigee& aPerigee2 = track2->perigeeParameters();
1232 int sflag(0), errorcode(0);
1233 Amg::Vector3D startingPoint = m_vertexEstimator->getCirclesIntersectionPoint(&aPerigee1,&aPerigee2,sflag,errorcode);
1234 if(errorcode) startingPoint(0) = startingPoint(1) = startingPoint(2) = 0.0;
1235 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1236 // do the fit
1237 if(track3) {
1238 std::unique_ptr<xAOD::Vertex> fittedVertex( m_iVertexFitter->fit(std::vector<const xAOD::TrackParticle*>{track1,track2,track3}, startingPoint, *state) );
1239 return fittedVertex;
1240 }
1241 else {
1242 std::unique_ptr<xAOD::Vertex> fittedVertex( m_iVertexFitter->fit(std::vector<const xAOD::TrackParticle*>{track1,track2}, startingPoint, *state) );
1243 return fittedVertex;
1244 }
1245 }
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
Eigen::Matrix< double, 3, 1 > Vector3D
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee

◆ fitV0Container()

void DerivationFramework::JpsiXPlusDisplaced::fitV0Container ( const EventContext & ctx,
xAOD::VertexContainer * V0ContainerNew,
const std::vector< const xAOD::TrackParticle * > & selectedTracks,
const std::vector< const xAOD::TrackParticleContainer * > & trackCols ) const
private

Definition at line 2710 of file JpsiXPlusDisplaced.cxx.

2710 {
2711
2712 SG::AuxElement::Decorator<std::string> mDec_type("Type_V0Vtx");
2713 SG::AuxElement::Decorator<int> mDec_gfit("gamma_fit");
2714 SG::AuxElement::Decorator<float> mDec_gmass("gamma_mass");
2715 SG::AuxElement::Decorator<float> mDec_gmasserr("gamma_massError");
2716 SG::AuxElement::Decorator<float> mDec_gchisq("gamma_chisq");
2717 SG::AuxElement::Decorator<int> mDec_gndof("gamma_ndof");
2718 SG::AuxElement::Decorator<float> mDec_gprob("gamma_probability");
2719
2720 std::vector<const xAOD::TrackParticle*> posTracks;
2721 std::vector<const xAOD::TrackParticle*> negTracks;
2722 for(const xAOD::TrackParticle* TP : selectedTracks) {
2723 if(TP->charge()>0) posTracks.push_back(TP);
2724 else negTracks.push_back(TP);
2725 }
2726
2727 for(const xAOD::TrackParticle* TP1 : posTracks) {
2728 const Trk::Perigee& aPerigee1 = TP1->perigeeParameters();
2729 for(const xAOD::TrackParticle* TP2 : negTracks) {
2730 const Trk::Perigee& aPerigee2 = TP2->perigeeParameters();
2731 int sflag(0), errorcode(0);
2732 Amg::Vector3D startingPoint = m_vertexEstimator->getCirclesIntersectionPoint(&aPerigee1,&aPerigee2,sflag,errorcode);
2733 if (errorcode != 0) {startingPoint(0) = 0.0; startingPoint(1) = 0.0; startingPoint(2) = 0.0;}
2734
2735 if (errorcode == 0 || errorcode == 5 || errorcode == 6 || errorcode == 8) {
2736 Trk::PerigeeSurface perigeeSurface(startingPoint);
2737 const Trk::TrackParameters* extrapolatedPerigee1 = m_extrapolator->extrapolate(ctx,TP1->perigeeParameters(), perigeeSurface).release();
2738 const Trk::TrackParameters* extrapolatedPerigee2 = m_extrapolator->extrapolate(ctx,TP2->perigeeParameters(), perigeeSurface).release();
2739 std::vector<std::unique_ptr<const Trk::TrackParameters> > cleanup;
2740 if(!extrapolatedPerigee1) extrapolatedPerigee1 = &TP1->perigeeParameters();
2741 else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee1));
2742 if(!extrapolatedPerigee2) extrapolatedPerigee2 = &TP2->perigeeParameters();
2743 else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee2));
2744 if(extrapolatedPerigee1 && extrapolatedPerigee2) {
2745 bool pass = false;
2746 TLorentzVector v1; TLorentzVector v2;
2747 if(!pass) {
2748 v1.SetXYZM(extrapolatedPerigee1->momentum().x(),extrapolatedPerigee1->momentum().y(),extrapolatedPerigee1->momentum().z(),m_mass_proton);
2749 v2.SetXYZM(extrapolatedPerigee2->momentum().x(),extrapolatedPerigee2->momentum().y(),extrapolatedPerigee2->momentum().z(),m_mass_pion);
2750 if((v1+v2).M()>1030.0 && (v1+v2).M()<1200.0) pass = true;
2751 }
2752 if(!pass) {
2753 v1.SetXYZM(extrapolatedPerigee1->momentum().x(),extrapolatedPerigee1->momentum().y(),extrapolatedPerigee1->momentum().z(),m_mass_pion);
2754 v2.SetXYZM(extrapolatedPerigee2->momentum().x(),extrapolatedPerigee2->momentum().y(),extrapolatedPerigee2->momentum().z(),m_mass_proton);
2755 if((v1+v2).M()>1030.0 && (v1+v2).M()<1200.0) pass = true;
2756 }
2757 if(!pass) {
2758 v1.SetXYZM(extrapolatedPerigee1->momentum().x(),extrapolatedPerigee1->momentum().y(),extrapolatedPerigee1->momentum().z(),m_mass_pion);
2759 v2.SetXYZM(extrapolatedPerigee2->momentum().x(),extrapolatedPerigee2->momentum().y(),extrapolatedPerigee2->momentum().z(),m_mass_pion);
2760 if((v1+v2).M()>430.0 && (v1+v2).M()<565.0) pass = true;
2761 }
2762 if(pass) {
2763 std::vector<const xAOD::TrackParticle*> tracksV0;
2764 tracksV0.push_back(TP1); tracksV0.push_back(TP2);
2765 std::unique_ptr<xAOD::Vertex> V0vtx = m_iV0Fitter->fit(ctx, tracksV0, startingPoint);
2766 if(V0vtx && V0vtx->chiSquared()>=0) {
2767 double chi2DOF = V0vtx->chiSquared()/V0vtx->numberDoF();
2768 if(chi2DOF>m_chi2cut_V0) continue;
2769
2770 double massSig_V0_Lambda1 = std::abs(m_V0Tools->invariantMass(V0vtx.get(), m_massesV0_ppi)-m_mass_Lambda)/m_V0Tools->invariantMassError(V0vtx.get(), m_massesV0_ppi);
2771 double massSig_V0_Lambda2 = std::abs(m_V0Tools->invariantMass(V0vtx.get(), m_massesV0_pip)-m_mass_Lambda)/m_V0Tools->invariantMassError(V0vtx.get(), m_massesV0_pip);
2772 double massSig_V0_Ks = std::abs(m_V0Tools->invariantMass(V0vtx.get(), m_massesV0_pipi)-m_mass_Ks)/m_V0Tools->invariantMassError(V0vtx.get(), m_massesV0_pipi);
2773 if(massSig_V0_Lambda1<=massSig_V0_Lambda2 && massSig_V0_Lambda1<=massSig_V0_Ks) {
2774 mDec_type(*V0vtx.get()) = "Lambda";
2775 }
2776 else if(massSig_V0_Lambda2<=massSig_V0_Lambda1 && massSig_V0_Lambda2<=massSig_V0_Ks) {
2777 mDec_type(*V0vtx.get()) = "Lambdabar";
2778 }
2779 else if(massSig_V0_Ks<=massSig_V0_Lambda1 && massSig_V0_Ks<=massSig_V0_Lambda2) {
2780 mDec_type(*V0vtx.get()) = "Ks";
2781 }
2782
2783 int gamma_fit = 0; int gamma_ndof = 0; double gamma_chisq = 999999.;
2784 double gamma_prob = -1., gamma_mass = -1., gamma_massErr = -1.;
2785 std::unique_ptr<xAOD::Vertex> gammaVtx = m_iGammaFitter->fit(ctx, tracksV0, m_V0Tools->vtx(V0vtx.get()));
2786 if (gammaVtx) {
2787 gamma_fit = 1;
2788 gamma_mass = m_V0Tools->invariantMass(gammaVtx.get(),m_mass_e,m_mass_e);
2789 gamma_massErr = m_V0Tools->invariantMassError(gammaVtx.get(),m_mass_e,m_mass_e);
2790 gamma_chisq = m_V0Tools->chisq(gammaVtx.get());
2791 gamma_ndof = m_V0Tools->ndof(gammaVtx.get());
2792 gamma_prob = m_V0Tools->vertexProbability(gammaVtx.get());
2793 }
2794 mDec_gfit(*V0vtx.get()) = gamma_fit;
2795 mDec_gmass(*V0vtx.get()) = gamma_mass;
2796 mDec_gmasserr(*V0vtx.get()) = gamma_massErr;
2797 mDec_gchisq(*V0vtx.get()) = gamma_chisq;
2798 mDec_gndof(*V0vtx.get()) = gamma_ndof;
2799 mDec_gprob(*V0vtx.get()) = gamma_prob;
2800
2801 xAOD::BPhysHelper V0_helper(V0vtx.get());
2802 V0_helper.setRefTrks(); // AOD only method
2803
2804 if(not trackCols.empty()){
2805 try {
2806 JpsiUpsilonCommon::RelinkVertexTracks(trackCols, V0vtx.get());
2807 } catch (std::runtime_error const& e) {
2808 ATH_MSG_ERROR(e.what());
2809 return;
2810 }
2811 }
2812
2813 V0ContainerNew->push_back(std::move(V0vtx));
2814 }
2815 }
2816 }
2817 }
2818 }
2819 }
2820 }
value_type push_back(value_type pElem)
Add an element to the end of the collection.
static void RelinkVertexTracks(std::span< const xAOD::TrackParticleContainer *const > trkcols, xAOD::Vertex *vtx)
const Amg::Vector3D & momentum() const
Access method for the momentum.
ParametersBase< TrackParametersDim, Charged > TrackParameters

◆ getD0Candidate()

JpsiXPlusDisplaced::MesonCandidate DerivationFramework::JpsiXPlusDisplaced::getD0Candidate ( const xAOD::Vertex * JXvtx,
const xAOD::TrackParticle * extraTrk1,
const xAOD::TrackParticle * extraTrk2 ) const
private

Definition at line 1283 of file JpsiXPlusDisplaced.cxx.

1283 {
1285
1286 TLorentzVector tmp1, tmp2;
1287 tmp1.SetPtEtaPhiM(extraTrk1->pt(),extraTrk1->eta(),extraTrk1->phi(),m_extraTrk1MassHypo);
1288 tmp2.SetPtEtaPhiM(extraTrk2->pt(),extraTrk2->eta(),extraTrk2->phi(),m_extraTrk2MassHypo);
1289 if((tmp1+tmp2).M() < m_D0MassLower || (tmp1+tmp2).M() > m_D0MassUpper) return D0;
1290
1291 std::unique_ptr<xAOD::Vertex> vtx = fitTracks(extraTrk1, extraTrk2);
1292 if(vtx) {
1293 double chi2NDF = vtx->chiSquared()/vtx->numberDoF();
1294 if(m_chi2cut_D0<=0.0 || chi2NDF < m_chi2cut_D0) {
1295 double lxyD0 = m_V0Tools->lxy(vtx.get(),JXvtx);
1296 if(lxyD0>m_lxyD0_cut) {
1297 D0.extraTrack1 = extraTrk1; D0.extraTrack2 = extraTrk2;
1298 D0.chi2NDF = chi2NDF;
1299 TVector3 tot_pt; TVector3 tmp;
1300 for(size_t i=0; i<vtx->vxTrackAtVertex().size(); ++i) {
1301 const Trk::TrackParameters* aPerigee = vtx->vxTrackAtVertex()[i].perigeeAtVertex();
1302 if(aPerigee) {
1303 tmp.SetXYZ(aPerigee->momentum()[Trk::px],aPerigee->momentum()[Trk::py],aPerigee->momentum()[Trk::pz]);
1304 tot_pt += tmp;
1305 }
1306 }
1307 D0.pt = tot_pt.Pt();
1308 }
1309 }
1310 }
1311 return D0;
1312 }
size_t size() const
Number of registered mappings.
std::unique_ptr< xAOD::Vertex > fitTracks(const xAOD::TrackParticle *track1, const xAOD::TrackParticle *track2, const xAOD::TrackParticle *track3=nullptr) const
@ pz
global momentum (cartesian)
Definition ParamDefs.h:61
@ px
Definition ParamDefs.h:59
@ py
Definition ParamDefs.h:60

◆ getDpmCandidate()

JpsiXPlusDisplaced::MesonCandidate DerivationFramework::JpsiXPlusDisplaced::getDpmCandidate ( const xAOD::Vertex * JXvtx,
const xAOD::TrackParticle * extraTrk1,
const xAOD::TrackParticle * extraTrk2,
const xAOD::TrackParticle * extraTrk3 ) const
private

Definition at line 1247 of file JpsiXPlusDisplaced.cxx.

1247 {
1248 MesonCandidate Dpm;
1249 // Check overlap
1250 std::vector<const xAOD::TrackParticle*> tracksJX;
1251 tracksJX.reserve(JXvtx->nTrackParticles());
1252 for(size_t i=0; i<JXvtx->nTrackParticles(); i++) tracksJX.push_back(JXvtx->trackParticle(i));
1253
1254 TLorentzVector tmp1, tmp2, tmp3;
1255 tmp1.SetPtEtaPhiM(extraTrk1->pt(),extraTrk1->eta(),extraTrk1->phi(),m_extraTrk1MassHypo);
1256 tmp2.SetPtEtaPhiM(extraTrk2->pt(),extraTrk2->eta(),extraTrk2->phi(),m_extraTrk2MassHypo);
1257 tmp3.SetPtEtaPhiM(extraTrk3->pt(),extraTrk3->eta(),extraTrk3->phi(),m_extraTrk3MassHypo);
1258 if((tmp1+tmp2+tmp3).M() < m_DpmMassLower || (tmp1+tmp2+tmp3).M() > m_DpmMassUpper) return Dpm;
1259
1260 std::unique_ptr<xAOD::Vertex> vtx = fitTracks(extraTrk1, extraTrk2, extraTrk3);
1261 if(vtx) {
1262 double chi2NDF = vtx->chiSquared()/vtx->numberDoF();
1263 if(m_chi2cut_Dpm<=0.0 || chi2NDF < m_chi2cut_Dpm) {
1264 double lxyDpm = m_V0Tools->lxy(vtx.get(),JXvtx);
1265 if(lxyDpm>m_lxyDpm_cut) {
1266 Dpm.extraTrack1 = extraTrk1; Dpm.extraTrack2 = extraTrk2; Dpm.extraTrack3 = extraTrk3;
1267 Dpm.chi2NDF = chi2NDF;
1268 TVector3 tot_pt; TVector3 tmp;
1269 for(size_t i=0; i<vtx->vxTrackAtVertex().size(); ++i) {
1270 const Trk::TrackParameters* aPerigee = vtx->vxTrackAtVertex()[i].perigeeAtVertex();
1271 if(aPerigee) {
1272 tmp.SetXYZ(aPerigee->momentum()[Trk::px],aPerigee->momentum()[Trk::py],aPerigee->momentum()[Trk::pz]);
1273 tot_pt += tmp;
1274 }
1275 }
1276 Dpm.pt = tot_pt.Pt();
1277 }
1278 }
1279 }
1280 return Dpm;
1281 }

◆ getXiCandidate()

JpsiXPlusDisplaced::XiCandidate DerivationFramework::JpsiXPlusDisplaced::getXiCandidate ( const xAOD::Vertex * V0vtx,
const V0Enum V0,
const xAOD::TrackParticle * track3 ) const
private

Definition at line 1178 of file JpsiXPlusDisplaced.cxx.

1178 {
1179 XiCandidate disVtx;
1180
1181 std::vector<const xAOD::TrackParticle*> tracksV0;
1182 tracksV0.reserve(V0vtx->nTrackParticles());
1183 for(size_t i=0; i<V0vtx->nTrackParticles(); i++) tracksV0.push_back(V0vtx->trackParticle(i));
1184 std::vector<double> massesV0;
1185 if(V0==LAMBDA) massesV0 = m_massesV0_ppi;
1186 else if(V0==LAMBDABAR) massesV0 = m_massesV0_pip;
1187 else if(V0==KS) massesV0 = m_massesV0_pipi;
1188
1189 std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
1190 int robustness = 0;
1191 m_iVertexFitter->setRobustness(robustness, *state);
1192 std::vector<Trk::VertexID> vrtList;
1193 // V0 vertex
1194 Trk::VertexID vID = m_iVertexFitter->startVertex(tracksV0,massesV0,*state);
1195 vrtList.push_back(vID);
1196 // Mother vertex
1197 std::vector<const xAOD::TrackParticle*> tracksDis3{track3};
1198 std::vector<double> massesDis3{m_disVDaug3MassHypo};
1199 m_iVertexFitter->nextVertex(tracksDis3,massesDis3,vrtList,*state);
1200 // Do the work
1201 std::unique_ptr<Trk::VxCascadeInfo> cascade_info = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1202 if(cascade_info) {
1203 cascade_info->setSVOwnership(true);
1204 double chi2NDF = cascade_info->fitChi2()/cascade_info->nDoF();
1205 if(m_chi2cut_DisV<=0 || chi2NDF < m_chi2cut_DisV) {
1206 const std::vector<std::vector<TLorentzVector> > &moms = cascade_info->getParticleMoms();
1207 const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->vertices();
1208 double lxy_SV1_sub = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
1209 if(lxy_SV1_sub > 0.2) {
1210 TLorentzVector totalMom;
1211 for(size_t it=0; it<moms[1].size(); it++) totalMom += moms[1][it];
1212 double disV_mass = totalMom.M();
1213 if(m_useImprovedMass) {
1214 if((V0==LAMBDA || V0==LAMBDABAR) && m_massLd>0) disV_mass += - moms[1][1].M() + m_massLd;
1215 else if(V0==KS && m_massKs>0) disV_mass += - moms[1][1].M() + m_massKs;
1216 }
1217 if(disV_mass>m_DisplacedMassLower && disV_mass<m_DisplacedMassUpper) {
1218 disVtx.track = track3; disVtx.V0vtx = V0vtx; disVtx.V0type = V0;
1219 disVtx.chi2NDF = chi2NDF; disVtx.p4_V0track1 = moms[0][0];
1220 disVtx.p4_V0track2 = moms[0][1]; disVtx.p4_disVtrack = moms[1][0];
1221 }
1222 }
1223 }
1224 }
1225 return disVtx;
1226 }

◆ initialize()

StatusCode DerivationFramework::JpsiXPlusDisplaced::initialize ( )
overridevirtual

Definition at line 274 of file JpsiXPlusDisplaced.cxx.

274 {
275 if(m_V0Hypothesis != "Ks" && m_V0Hypothesis != "Lambda"
276 && m_V0Hypothesis != "Lambda/Ks"&& m_V0Hypothesis != "Ks/Lambda") {
277 ATH_MSG_FATAL("Incorrect V0 container hypothesis - not recognized");
278 return StatusCode::FAILURE;
279 }
280
282 ATH_MSG_FATAL("Incorrect number of JX or DisVtx daughters");
283 return StatusCode::FAILURE;
284 }
285
286 if(m_vertexV0ContainerKey.key()=="" && m_v0VtxOutputKey.key()=="") {
287 ATH_MSG_FATAL("Input and output V0 container names can not be both empty");
288 return StatusCode::FAILURE;
289 }
290
291 // retrieving vertex Fitter
292 ATH_CHECK( m_iVertexFitter.retrieve() );
293
294 // retrieving V0 vertex Fitter
295 ATH_CHECK( m_iV0Fitter.retrieve() );
296
297 // retrieving photon conversion vertex Fitter
298 ATH_CHECK( m_iGammaFitter.retrieve() );
299
300 // retrieving primary vertex refitter
301 ATH_CHECK( m_pvRefitter.retrieve() );
302
303 // retrieving the V0 tool
304 ATH_CHECK( m_V0Tools.retrieve() );
305
306 // retrieving the TrackToVertex extrapolator tool
307 ATH_CHECK( m_trackToVertexTool.retrieve() );
308
309 // retrieving the track selector tool
310 ATH_CHECK( m_trkSelector.retrieve() );
311
312 // retrieving the V0 track selector tool
313 ATH_CHECK( m_v0TrkSelector.retrieve() );
314
315 // retrieving the Cascade tools
316 ATH_CHECK( m_CascadeTools.retrieve() );
317
318 // retrieving the vertex point estimator
319 ATH_CHECK( m_vertexEstimator.retrieve() );
320
321 // retrieving the extrapolator
322 ATH_CHECK( m_extrapolator.retrieve() );
323
324 ATH_CHECK( m_vertexJXContainerKey.initialize() );
326 ATH_CHECK( m_VxPrimaryCandidateName.initialize() );
327 ATH_CHECK( m_pvContainerName.initialize() );
328 ATH_CHECK( m_refPVContainerName.initialize() );
329 ATH_CHECK( m_TrkParticleCollection.initialize() );
330 ATH_CHECK( m_cascadeOutputKeys.initialize() );
331 ATH_CHECK( m_cascadeOutputKeys_mvc.initialize() );
332 ATH_CHECK( m_eventInfo_key.initialize() );
333 ATH_CHECK( m_RelinkContainers.initialize() );
335
336 ATH_CHECK( m_partPropSvc.retrieve() );
337 auto pdt = m_partPropSvc->PDT();
338
339 // https://gitlab.cern.ch/atlas/athena/-/blob/main/Generators/TruthUtils/TruthUtils/AtlasPID.h
353
354 m_massesV0_ppi.push_back(m_mass_proton);
355 m_massesV0_ppi.push_back(m_mass_pion);
356 m_massesV0_pip.push_back(m_mass_pion);
357 m_massesV0_pip.push_back(m_mass_proton);
358 m_massesV0_pipi.push_back(m_mass_pion);
359 m_massesV0_pipi.push_back(m_mass_pion);
360
361 // retrieve particle masses
365 if(m_constrV0) {
368 }
374
380
381 return StatusCode::SUCCESS;
382 }
static double getParticleMass(const HepPDT::ParticleDataTable *pdt, int pdg)
ServiceHandle< IPartPropSvc > m_partPropSvc
static const int PSI2S
static const int MUON
static const int DPLUS
static const int BCPLUS
static const int ELECTRON
static const int K0S
static const int LAMBDAB0
static const int PIPLUS
static const int JPSI
static const int B0
static const int LAMBDA0
static const int D0
static const int PROTON

◆ performSearch()

StatusCode DerivationFramework::JpsiXPlusDisplaced::performSearch ( std::vector< std::pair< Trk::VxCascadeInfo *, Trk::VxCascadeInfo * > > & cascadeinfoContainer,
const std::vector< std::pair< const xAOD::Vertex *, V0Enum > > & selectedV0Candidates,
const std::vector< const xAOD::TrackParticle * > & tracksDisplaced,
const EventContext & ctx ) const

Definition at line 384 of file JpsiXPlusDisplaced.cxx.

384 {
385 ATH_MSG_DEBUG( "JpsiXPlusDisplaced::performSearch" );
386 if(selectedV0Candidates.size()==0) return StatusCode::SUCCESS;
387
388 // Get TrackParticle container (standard + LRT)
389 SG::ReadHandle<xAOD::TrackParticleContainer> trackContainer(m_TrkParticleCollection, ctx);
390 ATH_CHECK( trackContainer.isValid() );
391
392 // Get all track containers when m_RelinkContainers is not empty
393 std::vector<const xAOD::TrackParticleContainer*> trackCols;
394 for(const SG::ReadHandleKey<xAOD::TrackParticleContainer>& key : m_RelinkContainers){
395 SG::ReadHandle<xAOD::TrackParticleContainer> handle(key, ctx);
396 ATH_CHECK( handle.isValid() );
397 trackCols.push_back(handle.cptr());
398 }
399
400 // Get default PV container
401 SG::ReadHandle<xAOD::VertexContainer> defaultPVContainer(m_VxPrimaryCandidateName, ctx);
402 ATH_CHECK( defaultPVContainer.isValid() );
403
404 // Get PV container
405 SG::ReadHandle<xAOD::VertexContainer> pvContainer(m_pvContainerName,ctx);
406 ATH_CHECK( pvContainer.isValid() );
407
408 // Get Jpsi+X container
409 SG::ReadHandle<xAOD::VertexContainer> jxContainer(m_vertexJXContainerKey, ctx);
410 ATH_CHECK( jxContainer.isValid() );
411
412 std::vector<double> massesJX{m_jxDaug1MassHypo, m_jxDaug2MassHypo};
413 if(m_jxDaug_num>=3) massesJX.push_back(m_jxDaug3MassHypo);
414 if(m_jxDaug_num==4) massesJX.push_back(m_jxDaug4MassHypo);
415
416 // Make the displaced candidates if needed
417 std::vector<XiCandidate> disVtxContainer;
418 if(m_disVDaug_num==3) {
419 for(size_t it=0; it<selectedV0Candidates.size(); ++it) {
420 std::pair<const xAOD::Vertex*,V0Enum> elem = selectedV0Candidates[it];
421 std::vector<const xAOD::TrackParticle*> tracksV0;
422 tracksV0.reserve(elem.first->nTrackParticles());
423 for(size_t i=0; i<elem.first->nTrackParticles(); i++) tracksV0.push_back(elem.first->trackParticle(i));
424 std::vector<double> massesV0;
425 if(elem.second==LAMBDA) massesV0 = m_massesV0_ppi;
426 else if(elem.second==LAMBDABAR) massesV0 = m_massesV0_pip;
427 else if(elem.second==KS) massesV0 = m_massesV0_pipi;
428 xAOD::BPhysHelper V0_helper(elem.first); TLorentzVector p4_v0;
429 for(int i=0; i<V0_helper.nRefTrks(); i++) p4_v0 += V0_helper.refTrk(i,massesV0[i]);
430 for(const xAOD::TrackParticle* TP : tracksDisplaced) {
431 if(TP->pt() < m_disVDaug3MinPt) continue;
432 // Check overlap
433 if(std::find(tracksV0.cbegin(), tracksV0.cend(), TP) != tracksV0.cend()) continue;
434 TLorentzVector tmp;
435 tmp.SetPtEtaPhiM(TP->pt(),TP->eta(),TP->phi(),m_disVDaug3MassHypo);
436 double disV_mass = (p4_v0+tmp).M();
438 if((elem.second==LAMBDA || elem.second==LAMBDABAR) && m_massLd>0) disV_mass += - p4_v0.M() + m_massLd;
439 else if(elem.second==KS && m_massKs>0) disV_mass += - p4_v0.M() + m_massKs;
440 }
441 // A rough mass window cut, as V0 and track3 are not from a common vertex
442 if(disV_mass > m_DisplacedMassLower-500. && disV_mass < m_DisplacedMassUpper+500.) {
443 auto disVtx = getXiCandidate(elem.first,elem.second,TP);
444 if(disVtx.V0vtx && disVtx.track) disVtxContainer.push_back(disVtx);
445 }
446 }
447 }
448
449 std::sort( disVtxContainer.begin(), disVtxContainer.end(), [](const XiCandidate& a, const XiCandidate& b) { return a.chi2NDF < b.chi2NDF; } );
450 if(m_maxDisVCandidates>0 && disVtxContainer.size()>m_maxDisVCandidates) {
451 disVtxContainer.erase(disVtxContainer.begin()+m_maxDisVCandidates, disVtxContainer.end());
452 }
453 if(disVtxContainer.size()==0) return StatusCode::SUCCESS;
454 } // m_disVDaug_num==3
455
456 // Select the JX candidates before calling cascade fit
457 std::vector<const xAOD::Vertex*> selectedJXCandidates;
458 for(const xAOD::Vertex* vtx : *jxContainer.cptr()) {
459 // Check the passed flag first
460 bool passed = false;
461 for(const std::string& name : m_vertexJXHypoNames) {
462 SG::AuxElement::Accessor<Char_t> flagAcc("passed_"+name);
463 if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
464 passed = true;
465 }
466 }
467 if(m_vertexJXHypoNames.size() && !passed) continue;
468
469 // Add loose cut on Jpsi mass from e.g. JX -> Jpsi pi+ pi-
470 TLorentzVector p4_mu1, p4_mu2;
471 p4_mu1.SetPtEtaPhiM(vtx->trackParticle(0)->pt(),vtx->trackParticle(0)->eta(),vtx->trackParticle(0)->phi(), m_jxDaug1MassHypo);
472 p4_mu2.SetPtEtaPhiM(vtx->trackParticle(1)->pt(),vtx->trackParticle(1)->eta(),vtx->trackParticle(1)->phi(), m_jxDaug2MassHypo);
473 double mass_jpsi = (p4_mu1 + p4_mu2).M();
474 if (mass_jpsi < m_jpsiMassLower || mass_jpsi > m_jpsiMassUpper) continue;
475
476 TLorentzVector p4_trk1, p4_trk2;
477 if(m_jxDaug_num>=3) p4_trk1.SetPtEtaPhiM(vtx->trackParticle(2)->pt(),vtx->trackParticle(2)->eta(),vtx->trackParticle(2)->phi(), m_jxDaug3MassHypo);
478 if(m_jxDaug_num==4) p4_trk2.SetPtEtaPhiM(vtx->trackParticle(3)->pt(),vtx->trackParticle(3)->eta(),vtx->trackParticle(3)->phi(), m_jxDaug4MassHypo);
479
480 if(m_jxDaug_num==3) {
481 double mass_jx = (p4_mu1 + p4_mu2 + p4_trk1).M();
482 if(m_useImprovedMass && m_massJpsi>0) mass_jx += - (p4_mu1 + p4_mu2).M() + m_massJpsi;
483 if(mass_jx < m_jxMassLower || mass_jx > m_jxMassUpper) continue;
484 }
485 else if(m_jxDaug_num==4) {
486 double mass_jx = (p4_mu1 + p4_mu2 + p4_trk1 + p4_trk2).M();
487 if(m_useImprovedMass && m_massJpsi>0) mass_jx += - (p4_mu1 + p4_mu2).M() + m_massJpsi;
488 if(mass_jx < m_jxMassLower || mass_jx > m_jxMassUpper) continue;
489
491 double mass_diTrk = (p4_trk1 + p4_trk2).M();
492 if(mass_diTrk < m_diTrackMassLower || mass_diTrk > m_diTrackMassUpper) continue;
493 }
494 }
495
496 double chi2DOF = vtx->chiSquared()/vtx->numberDoF();
497 if(m_chi2cut_JX>0 && chi2DOF>m_chi2cut_JX) continue;
498
499 selectedJXCandidates.push_back(vtx);
500 }
501 if(selectedJXCandidates.size()==0) return StatusCode::SUCCESS;
502
503 if(m_jxPtOrdering) {
504 std::sort( selectedJXCandidates.begin(), selectedJXCandidates.end(), [massesJX](const xAOD::Vertex* a, const xAOD::Vertex* b) {
505 TLorentzVector p4_a, p4_b, tmp;
506 for(size_t it=0; it<a->nTrackParticles(); it++) {
507 tmp.SetPtEtaPhiM(a->trackParticle(it)->pt(), a->trackParticle(it)->eta(), a->trackParticle(it)->phi(), massesJX[it]);
508 p4_a += tmp;
509 }
510 for(size_t it=0; it<b->nTrackParticles(); it++) {
511 tmp.SetPtEtaPhiM(b->trackParticle(it)->pt(), b->trackParticle(it)->eta(), b->trackParticle(it)->phi(), massesJX[it]);
512 p4_b += tmp;
513 }
514 return p4_a.Pt() > p4_b.Pt();
515 } );
516 }
517 else {
518 std::sort( selectedJXCandidates.begin(), selectedJXCandidates.end(), [](const xAOD::Vertex* a, const xAOD::Vertex* b) { return a->chiSquared()/a->numberDoF() < b->chiSquared()/b->numberDoF(); } );
519 }
520 if(m_maxJXCandidates>0 && selectedJXCandidates.size()>m_maxJXCandidates) {
521 selectedJXCandidates.erase(selectedJXCandidates.begin()+m_maxJXCandidates, selectedJXCandidates.end());
522 }
523
524 // Select JX+DisV candidates
525 // Iterate over JX vertices
526 for(const xAOD::Vertex* jxVtx : selectedJXCandidates) {
527 // Iterate over displaced vertices
528 if(m_disVDaug_num==2) {
529 for(auto&& V0Candidate : selectedV0Candidates) {
530 std::vector<std::pair<Trk::VxCascadeInfo*, Trk::VxCascadeInfo*> > result = fitMainVtx(jxVtx, massesJX, V0Candidate.first, V0Candidate.second, trackContainer.cptr(), trackCols, defaultPVContainer.cptr(), pvContainer.cptr());
531 for(auto cascade_info_pair : result) {
532 if(cascade_info_pair.first) cascadeinfoContainer.push_back(cascade_info_pair);
533 }
534 }
535 } // m_disVDaug_num==2
536 else if(m_disVDaug_num==3) {
537 for(auto&& disVtx : disVtxContainer) {
538 std::vector<std::pair<Trk::VxCascadeInfo*, Trk::VxCascadeInfo*> > result = fitMainVtx(jxVtx, massesJX, disVtx, trackContainer.cptr(), trackCols, defaultPVContainer.cptr(), pvContainer.cptr());
539 for(auto cascade_info_pair : result) {
540 if(cascade_info_pair.first) cascadeinfoContainer.push_back(cascade_info_pair);
541 }
542 }
543 } // m_disVDaug_num==3
544 } // Iterate over JX vertices
545
546 return StatusCode::SUCCESS;
547 }
#define ATH_MSG_DEBUG(x)
bool passed(DecisionID id, const DecisionIDContainer &)
checks if required decision ID is in the set of IDs in the container
XiCandidate getXiCandidate(const xAOD::Vertex *V0vtx, const V0Enum V0, const xAOD::TrackParticle *track3) const
std::vector< std::pair< Trk::VxCascadeInfo *, Trk::VxCascadeInfo * > > fitMainVtx(const xAOD::Vertex *JXvtx, const std::vector< double > &massesJX, const xAOD::Vertex *V0vtx, const V0Enum V0, const xAOD::TrackParticleContainer *trackContainer, const std::vector< const xAOD::TrackParticleContainer * > &trackCols, const xAOD::VertexContainer *defaultPVContainer, const xAOD::VertexContainer *pvContainer) const

Member Data Documentation

◆ m_cascadeFitWithPV

int DerivationFramework::JpsiXPlusDisplaced::m_cascadeFitWithPV {}
private

Definition at line 163 of file JpsiXPlusDisplaced.h.

163{};

◆ m_cascadeOutputKeys

SG::WriteHandleKeyArray<xAOD::VertexContainer> DerivationFramework::JpsiXPlusDisplaced::m_cascadeOutputKeys
private

Definition at line 88 of file JpsiXPlusDisplaced.h.

◆ m_cascadeOutputKeys_mvc

SG::WriteHandleKeyArray<xAOD::VertexContainer> DerivationFramework::JpsiXPlusDisplaced::m_cascadeOutputKeys_mvc
private

Definition at line 89 of file JpsiXPlusDisplaced.h.

◆ m_CascadeTools

PublicToolHandle< DerivationFramework::CascadeTools > DerivationFramework::JpsiXPlusDisplaced::m_CascadeTools
private

Definition at line 192 of file JpsiXPlusDisplaced.h.

◆ m_chi2cut

double DerivationFramework::JpsiXPlusDisplaced::m_chi2cut {}
private

Definition at line 173 of file JpsiXPlusDisplaced.h.

173{};

◆ m_chi2cut_D0

double DerivationFramework::JpsiXPlusDisplaced::m_chi2cut_D0 {}
private

Definition at line 172 of file JpsiXPlusDisplaced.h.

172{};

◆ m_chi2cut_DisV

double DerivationFramework::JpsiXPlusDisplaced::m_chi2cut_DisV {}
private

Definition at line 170 of file JpsiXPlusDisplaced.h.

170{};

◆ m_chi2cut_Dpm

double DerivationFramework::JpsiXPlusDisplaced::m_chi2cut_Dpm {}
private

Definition at line 171 of file JpsiXPlusDisplaced.h.

171{};

◆ m_chi2cut_gamma

double DerivationFramework::JpsiXPlusDisplaced::m_chi2cut_gamma {}
private

Definition at line 113 of file JpsiXPlusDisplaced.h.

113{};

◆ m_chi2cut_JX

double DerivationFramework::JpsiXPlusDisplaced::m_chi2cut_JX {}
private

Definition at line 168 of file JpsiXPlusDisplaced.h.

168{};

◆ m_chi2cut_V0

double DerivationFramework::JpsiXPlusDisplaced::m_chi2cut_V0 {}
private

Definition at line 169 of file JpsiXPlusDisplaced.h.

169{};

◆ m_constrD0

bool DerivationFramework::JpsiXPlusDisplaced::m_constrD0 {}
private

Definition at line 160 of file JpsiXPlusDisplaced.h.

160{};

◆ m_constrDisV

bool DerivationFramework::JpsiXPlusDisplaced::m_constrDisV {}
private

Definition at line 157 of file JpsiXPlusDisplaced.h.

157{};

◆ m_constrDpm

bool DerivationFramework::JpsiXPlusDisplaced::m_constrDpm {}
private

Definition at line 159 of file JpsiXPlusDisplaced.h.

159{};

◆ m_constrJpsi

bool DerivationFramework::JpsiXPlusDisplaced::m_constrJpsi {}
private

Definition at line 155 of file JpsiXPlusDisplaced.h.

155{};

◆ m_constrJX

bool DerivationFramework::JpsiXPlusDisplaced::m_constrJX {}
private

Definition at line 154 of file JpsiXPlusDisplaced.h.

154{};

◆ m_constrJXV0

bool DerivationFramework::JpsiXPlusDisplaced::m_constrJXV0 {}
private

Definition at line 161 of file JpsiXPlusDisplaced.h.

161{};

◆ m_constrMainV

bool DerivationFramework::JpsiXPlusDisplaced::m_constrMainV {}
private

Definition at line 162 of file JpsiXPlusDisplaced.h.

162{};

◆ m_constrV0

bool DerivationFramework::JpsiXPlusDisplaced::m_constrV0 {}
private

Definition at line 158 of file JpsiXPlusDisplaced.h.

158{};

◆ m_constrX

bool DerivationFramework::JpsiXPlusDisplaced::m_constrX {}
private

Definition at line 156 of file JpsiXPlusDisplaced.h.

156{};

◆ m_d0_cut

double DerivationFramework::JpsiXPlusDisplaced::m_d0_cut {}
private

Definition at line 176 of file JpsiXPlusDisplaced.h.

176{};

◆ m_D0MassLower

double DerivationFramework::JpsiXPlusDisplaced::m_D0MassLower {}
private

Definition at line 140 of file JpsiXPlusDisplaced.h.

140{};

◆ m_D0MassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_D0MassUpper {}
private

Definition at line 141 of file JpsiXPlusDisplaced.h.

141{};

◆ m_DisplacedMassLower

double DerivationFramework::JpsiXPlusDisplaced::m_DisplacedMassLower {}
private

Definition at line 114 of file JpsiXPlusDisplaced.h.

114{};

◆ m_DisplacedMassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_DisplacedMassUpper {}
private

Definition at line 115 of file JpsiXPlusDisplaced.h.

115{};

◆ m_disVDaug3MassHypo

double DerivationFramework::JpsiXPlusDisplaced::m_disVDaug3MassHypo {}
private

Definition at line 130 of file JpsiXPlusDisplaced.h.

130{}; // mass hypothesis of 3rd daughter from displaced vertex

◆ m_disVDaug3MinPt

double DerivationFramework::JpsiXPlusDisplaced::m_disVDaug3MinPt {}
private

Definition at line 131 of file JpsiXPlusDisplaced.h.

131{};

◆ m_disVDaug_num

int DerivationFramework::JpsiXPlusDisplaced::m_disVDaug_num {}
private

Definition at line 129 of file JpsiXPlusDisplaced.h.

129{};

◆ m_diTrackMassLower

double DerivationFramework::JpsiXPlusDisplaced::m_diTrackMassLower {}
private

Definition at line 104 of file JpsiXPlusDisplaced.h.

104{};

◆ m_diTrackMassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_diTrackMassUpper {}
private

Definition at line 105 of file JpsiXPlusDisplaced.h.

105{};

◆ m_doPostMainVContrFit

bool DerivationFramework::JpsiXPlusDisplaced::m_doPostMainVContrFit {}
private

Definition at line 165 of file JpsiXPlusDisplaced.h.

165{};

◆ m_DoVertexType

int DerivationFramework::JpsiXPlusDisplaced::m_DoVertexType {}
private

Definition at line 199 of file JpsiXPlusDisplaced.h.

199{};

◆ m_DpmMassLower

double DerivationFramework::JpsiXPlusDisplaced::m_DpmMassLower {}
private

Definition at line 138 of file JpsiXPlusDisplaced.h.

138{};

◆ m_DpmMassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_DpmMassUpper {}
private

Definition at line 139 of file JpsiXPlusDisplaced.h.

139{};

◆ m_eventInfo_key

SG::ReadHandleKey<xAOD::EventInfo> DerivationFramework::JpsiXPlusDisplaced::m_eventInfo_key
private

Definition at line 95 of file JpsiXPlusDisplaced.h.

◆ m_extrapolator

ToolHandle< Trk::IExtrapolator > DerivationFramework::JpsiXPlusDisplaced::m_extrapolator
private

Definition at line 194 of file JpsiXPlusDisplaced.h.

◆ m_extraTrk1MassHypo

double DerivationFramework::JpsiXPlusDisplaced::m_extraTrk1MassHypo {}
private

Definition at line 132 of file JpsiXPlusDisplaced.h.

132{};

◆ m_extraTrk1MinPt

double DerivationFramework::JpsiXPlusDisplaced::m_extraTrk1MinPt {}
private

Definition at line 133 of file JpsiXPlusDisplaced.h.

133{};

◆ m_extraTrk2MassHypo

double DerivationFramework::JpsiXPlusDisplaced::m_extraTrk2MassHypo {}
private

Definition at line 134 of file JpsiXPlusDisplaced.h.

134{};

◆ m_extraTrk2MinPt

double DerivationFramework::JpsiXPlusDisplaced::m_extraTrk2MinPt {}
private

Definition at line 135 of file JpsiXPlusDisplaced.h.

135{};

◆ m_extraTrk3MassHypo

double DerivationFramework::JpsiXPlusDisplaced::m_extraTrk3MassHypo {}
private

Definition at line 136 of file JpsiXPlusDisplaced.h.

136{};

◆ m_extraTrk3MinPt

double DerivationFramework::JpsiXPlusDisplaced::m_extraTrk3MinPt {}
private

Definition at line 137 of file JpsiXPlusDisplaced.h.

137{};

◆ m_firstDecayAtPV

bool DerivationFramework::JpsiXPlusDisplaced::m_firstDecayAtPV {}
private

Definition at line 164 of file JpsiXPlusDisplaced.h.

164{};

◆ m_hypoName

std::string DerivationFramework::JpsiXPlusDisplaced::m_hypoName
private

Definition at line 97 of file JpsiXPlusDisplaced.h.

◆ m_iGammaFitter

ToolHandle< Trk::IVertexFitter > DerivationFramework::JpsiXPlusDisplaced::m_iGammaFitter
private

Definition at line 186 of file JpsiXPlusDisplaced.h.

◆ m_iV0Fitter

ToolHandle< Trk::TrkV0VertexFitter > DerivationFramework::JpsiXPlusDisplaced::m_iV0Fitter
private

Definition at line 185 of file JpsiXPlusDisplaced.h.

◆ m_iVertexFitter

ToolHandle< Trk::TrkVKalVrtFitter > DerivationFramework::JpsiXPlusDisplaced::m_iVertexFitter
private

Definition at line 184 of file JpsiXPlusDisplaced.h.

◆ m_jpsiMassLower

double DerivationFramework::JpsiXPlusDisplaced::m_jpsiMassLower {}
private

Definition at line 102 of file JpsiXPlusDisplaced.h.

102{};

◆ m_jpsiMassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_jpsiMassUpper {}
private

Definition at line 103 of file JpsiXPlusDisplaced.h.

103{};

◆ m_jxDaug1MassHypo

double DerivationFramework::JpsiXPlusDisplaced::m_jxDaug1MassHypo {}
private

Definition at line 124 of file JpsiXPlusDisplaced.h.

124{}; // mass hypothesis of 1st daughter from vertex JX

◆ m_jxDaug2MassHypo

double DerivationFramework::JpsiXPlusDisplaced::m_jxDaug2MassHypo {}
private

Definition at line 125 of file JpsiXPlusDisplaced.h.

125{}; // mass hypothesis of 2nd daughter from vertex JX

◆ m_jxDaug3MassHypo

double DerivationFramework::JpsiXPlusDisplaced::m_jxDaug3MassHypo {}
private

Definition at line 126 of file JpsiXPlusDisplaced.h.

126{}; // mass hypothesis of 3rd daughter from vertex JX

◆ m_jxDaug4MassHypo

double DerivationFramework::JpsiXPlusDisplaced::m_jxDaug4MassHypo {}
private

Definition at line 127 of file JpsiXPlusDisplaced.h.

127{}; // mass hypothesis of 4th daughter from vertex JX

◆ m_jxDaug_num

int DerivationFramework::JpsiXPlusDisplaced::m_jxDaug_num {}
private

Definition at line 123 of file JpsiXPlusDisplaced.h.

123{};

◆ m_jxMassLower

double DerivationFramework::JpsiXPlusDisplaced::m_jxMassLower {}
private

Definition at line 100 of file JpsiXPlusDisplaced.h.

100{};

◆ m_jxMassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_jxMassUpper {}
private

Definition at line 101 of file JpsiXPlusDisplaced.h.

101{};

◆ m_jxPtOrdering

bool DerivationFramework::JpsiXPlusDisplaced::m_jxPtOrdering {}
private

Definition at line 128 of file JpsiXPlusDisplaced.h.

128{};

◆ m_JXSubVtx

bool DerivationFramework::JpsiXPlusDisplaced::m_JXSubVtx {}
private

Definition at line 166 of file JpsiXPlusDisplaced.h.

166{};

◆ m_JXV0SubVtx

bool DerivationFramework::JpsiXPlusDisplaced::m_JXV0SubVtx {}
private

Definition at line 167 of file JpsiXPlusDisplaced.h.

167{};

◆ m_KsMassLower

double DerivationFramework::JpsiXPlusDisplaced::m_KsMassLower {}
private

Definition at line 109 of file JpsiXPlusDisplaced.h.

109{};

◆ m_KsMassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_KsMassUpper {}
private

Definition at line 110 of file JpsiXPlusDisplaced.h.

110{};

◆ m_LambdaMassLower

double DerivationFramework::JpsiXPlusDisplaced::m_LambdaMassLower {}
private

Definition at line 107 of file JpsiXPlusDisplaced.h.

107{};

◆ m_LambdaMassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_LambdaMassUpper {}
private

Definition at line 108 of file JpsiXPlusDisplaced.h.

108{};

◆ m_lxyD0_cut

double DerivationFramework::JpsiXPlusDisplaced::m_lxyD0_cut {}
private

Definition at line 118 of file JpsiXPlusDisplaced.h.

118{};

◆ m_lxyDisV_cut

double DerivationFramework::JpsiXPlusDisplaced::m_lxyDisV_cut {}
private

Definition at line 116 of file JpsiXPlusDisplaced.h.

116{};

◆ m_lxyDpm_cut

double DerivationFramework::JpsiXPlusDisplaced::m_lxyDpm_cut {}
private

Definition at line 117 of file JpsiXPlusDisplaced.h.

117{};

◆ m_lxyV0_cut

double DerivationFramework::JpsiXPlusDisplaced::m_lxyV0_cut {}
private

Definition at line 111 of file JpsiXPlusDisplaced.h.

111{};

◆ m_mass_B0

double DerivationFramework::JpsiXPlusDisplaced::m_mass_B0 {}
private

Definition at line 209 of file JpsiXPlusDisplaced.h.

209{};

◆ m_mass_BCPLUS

double DerivationFramework::JpsiXPlusDisplaced::m_mass_BCPLUS {}
private

Definition at line 212 of file JpsiXPlusDisplaced.h.

212{};

◆ m_mass_D0

double DerivationFramework::JpsiXPlusDisplaced::m_mass_D0 {}
private

Definition at line 211 of file JpsiXPlusDisplaced.h.

211{};

◆ m_mass_Dpm

double DerivationFramework::JpsiXPlusDisplaced::m_mass_Dpm {}
private

Definition at line 210 of file JpsiXPlusDisplaced.h.

210{};

◆ m_mass_e

double DerivationFramework::JpsiXPlusDisplaced::m_mass_e {}
private

Definition at line 201 of file JpsiXPlusDisplaced.h.

201{};

◆ m_mass_Ks

double DerivationFramework::JpsiXPlusDisplaced::m_mass_Ks {}
private

Definition at line 206 of file JpsiXPlusDisplaced.h.

206{};

◆ m_mass_Lambda

double DerivationFramework::JpsiXPlusDisplaced::m_mass_Lambda {}
private

Definition at line 205 of file JpsiXPlusDisplaced.h.

205{};

◆ m_mass_Lambdab

double DerivationFramework::JpsiXPlusDisplaced::m_mass_Lambdab {}
private

Definition at line 213 of file JpsiXPlusDisplaced.h.

213{};

◆ m_mass_mu

double DerivationFramework::JpsiXPlusDisplaced::m_mass_mu {}
private

Definition at line 202 of file JpsiXPlusDisplaced.h.

202{};

◆ m_mass_phi

double DerivationFramework::JpsiXPlusDisplaced::m_mass_phi {}
private

Definition at line 208 of file JpsiXPlusDisplaced.h.

208{};

◆ m_mass_pion

double DerivationFramework::JpsiXPlusDisplaced::m_mass_pion {}
private

Definition at line 203 of file JpsiXPlusDisplaced.h.

203{};

◆ m_mass_proton

double DerivationFramework::JpsiXPlusDisplaced::m_mass_proton {}
private

Definition at line 204 of file JpsiXPlusDisplaced.h.

204{};

◆ m_mass_Xi

double DerivationFramework::JpsiXPlusDisplaced::m_mass_Xi {}
private

Definition at line 207 of file JpsiXPlusDisplaced.h.

207{};

◆ m_massD0

double DerivationFramework::JpsiXPlusDisplaced::m_massD0 {}
private

Definition at line 151 of file JpsiXPlusDisplaced.h.

151{};

◆ m_massDisV

double DerivationFramework::JpsiXPlusDisplaced::m_massDisV {}
private

Definition at line 147 of file JpsiXPlusDisplaced.h.

147{};

◆ m_massDpm

double DerivationFramework::JpsiXPlusDisplaced::m_massDpm {}
private

Definition at line 150 of file JpsiXPlusDisplaced.h.

150{};

◆ m_massesV0_pip

std::vector<double> DerivationFramework::JpsiXPlusDisplaced::m_massesV0_pip
private

Definition at line 216 of file JpsiXPlusDisplaced.h.

◆ m_massesV0_pipi

std::vector<double> DerivationFramework::JpsiXPlusDisplaced::m_massesV0_pipi
private

Definition at line 217 of file JpsiXPlusDisplaced.h.

◆ m_massesV0_ppi

std::vector<double> DerivationFramework::JpsiXPlusDisplaced::m_massesV0_ppi
private

Definition at line 215 of file JpsiXPlusDisplaced.h.

◆ m_massJpsi

double DerivationFramework::JpsiXPlusDisplaced::m_massJpsi {}
private

Definition at line 145 of file JpsiXPlusDisplaced.h.

145{};

◆ m_massJX

double DerivationFramework::JpsiXPlusDisplaced::m_massJX {}
private

Definition at line 144 of file JpsiXPlusDisplaced.h.

144{};

◆ m_massJXV0

double DerivationFramework::JpsiXPlusDisplaced::m_massJXV0 {}
private

Definition at line 152 of file JpsiXPlusDisplaced.h.

152{};

◆ m_massKs

double DerivationFramework::JpsiXPlusDisplaced::m_massKs {}
private

Definition at line 149 of file JpsiXPlusDisplaced.h.

149{};

◆ m_massLd

double DerivationFramework::JpsiXPlusDisplaced::m_massLd {}
private

Definition at line 148 of file JpsiXPlusDisplaced.h.

148{};

◆ m_MassLower

double DerivationFramework::JpsiXPlusDisplaced::m_MassLower {}
private

Definition at line 119 of file JpsiXPlusDisplaced.h.

119{};

◆ m_massMainV

double DerivationFramework::JpsiXPlusDisplaced::m_massMainV {}
private

Definition at line 153 of file JpsiXPlusDisplaced.h.

153{};

◆ m_MassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_MassUpper {}
private

Definition at line 120 of file JpsiXPlusDisplaced.h.

120{};

◆ m_massX

double DerivationFramework::JpsiXPlusDisplaced::m_massX {}
private

Definition at line 146 of file JpsiXPlusDisplaced.h.

146{};

◆ m_maxDisVCandidates

unsigned int DerivationFramework::JpsiXPlusDisplaced::m_maxDisVCandidates {}
private

Definition at line 179 of file JpsiXPlusDisplaced.h.

179{};

◆ m_maxJXCandidates

unsigned int DerivationFramework::JpsiXPlusDisplaced::m_maxJXCandidates {}
private

Definition at line 177 of file JpsiXPlusDisplaced.h.

177{};

◆ m_maxMainVCandidates

unsigned int DerivationFramework::JpsiXPlusDisplaced::m_maxMainVCandidates {}
private

Definition at line 180 of file JpsiXPlusDisplaced.h.

180{};

◆ m_maxMesonCandidates

size_t DerivationFramework::JpsiXPlusDisplaced::m_maxMesonCandidates {}
private

Definition at line 142 of file JpsiXPlusDisplaced.h.

142{};

◆ m_maxV0Candidates

unsigned int DerivationFramework::JpsiXPlusDisplaced::m_maxV0Candidates {}
private

Definition at line 178 of file JpsiXPlusDisplaced.h.

178{};

◆ m_MesonPtOrdering

bool DerivationFramework::JpsiXPlusDisplaced::m_MesonPtOrdering {}
private

Definition at line 143 of file JpsiXPlusDisplaced.h.

143{};

◆ m_minMass_gamma

double DerivationFramework::JpsiXPlusDisplaced::m_minMass_gamma {}
private

Definition at line 112 of file JpsiXPlusDisplaced.h.

112{};

◆ m_partPropSvc

ServiceHandle<IPartPropSvc> DerivationFramework::JpsiXPlusDisplaced::m_partPropSvc {this, "PartPropSvc", "PartPropSvc"}
private

Definition at line 182 of file JpsiXPlusDisplaced.h.

182{this, "PartPropSvc", "PartPropSvc"};

◆ m_PostMassLower

double DerivationFramework::JpsiXPlusDisplaced::m_PostMassLower {}
private

Definition at line 121 of file JpsiXPlusDisplaced.h.

121{};

◆ m_PostMassUpper

double DerivationFramework::JpsiXPlusDisplaced::m_PostMassUpper {}
private

Definition at line 122 of file JpsiXPlusDisplaced.h.

122{};

◆ m_ptTRT

double DerivationFramework::JpsiXPlusDisplaced::m_ptTRT {}
private

Definition at line 175 of file JpsiXPlusDisplaced.h.

175{};

◆ m_PV_max

int DerivationFramework::JpsiXPlusDisplaced::m_PV_max {}
private

Definition at line 197 of file JpsiXPlusDisplaced.h.

197{};

◆ m_PV_minNTracks

size_t DerivationFramework::JpsiXPlusDisplaced::m_PV_minNTracks {}
private

Definition at line 198 of file JpsiXPlusDisplaced.h.

198{};

◆ m_pvContainerName

SG::ReadHandleKey<xAOD::VertexContainer> DerivationFramework::JpsiXPlusDisplaced::m_pvContainerName
private

Definition at line 93 of file JpsiXPlusDisplaced.h.

◆ m_pvRefitter

PublicToolHandle< Analysis::PrimaryVertexRefitter > DerivationFramework::JpsiXPlusDisplaced::m_pvRefitter
private

Definition at line 187 of file JpsiXPlusDisplaced.h.

◆ m_refitPV

bool DerivationFramework::JpsiXPlusDisplaced::m_refitPV {}
private

Definition at line 196 of file JpsiXPlusDisplaced.h.

196{};

◆ m_refPVContainerName

SG::WriteHandleKey<xAOD::VertexContainer> DerivationFramework::JpsiXPlusDisplaced::m_refPVContainerName
private

Definition at line 94 of file JpsiXPlusDisplaced.h.

◆ m_RelinkContainers

SG::ReadHandleKeyArray<xAOD::TrackParticleContainer> DerivationFramework::JpsiXPlusDisplaced::m_RelinkContainers
private

Definition at line 96 of file JpsiXPlusDisplaced.h.

◆ m_trackToVertexTool

ToolHandle< Reco::ITrackToVertex > DerivationFramework::JpsiXPlusDisplaced::m_trackToVertexTool
private

Definition at line 189 of file JpsiXPlusDisplaced.h.

◆ m_TrkParticleCollection

SG::ReadHandleKey<xAOD::TrackParticleContainer> DerivationFramework::JpsiXPlusDisplaced::m_TrkParticleCollection
private

Definition at line 91 of file JpsiXPlusDisplaced.h.

◆ m_trkSelector

ToolHandle< Trk::ITrackSelectorTool > DerivationFramework::JpsiXPlusDisplaced::m_trkSelector
private

Definition at line 190 of file JpsiXPlusDisplaced.h.

◆ m_useImprovedMass

bool DerivationFramework::JpsiXPlusDisplaced::m_useImprovedMass {}
private

Definition at line 99 of file JpsiXPlusDisplaced.h.

99{};

◆ m_useTRT

bool DerivationFramework::JpsiXPlusDisplaced::m_useTRT {}
private

Definition at line 174 of file JpsiXPlusDisplaced.h.

174{};

◆ m_V0Hypothesis

std::string DerivationFramework::JpsiXPlusDisplaced::m_V0Hypothesis {}
private

Definition at line 106 of file JpsiXPlusDisplaced.h.

106{};

◆ m_V0Tools

PublicToolHandle< Trk::V0Tools > DerivationFramework::JpsiXPlusDisplaced::m_V0Tools
private

Definition at line 188 of file JpsiXPlusDisplaced.h.

◆ m_v0TrkSelector

ToolHandle< Trk::ITrackSelectorTool > DerivationFramework::JpsiXPlusDisplaced::m_v0TrkSelector
private

Definition at line 191 of file JpsiXPlusDisplaced.h.

◆ m_v0VtxOutputKey

SG::WriteHandleKey<xAOD::VertexContainer> DerivationFramework::JpsiXPlusDisplaced::m_v0VtxOutputKey
private

Definition at line 90 of file JpsiXPlusDisplaced.h.

◆ m_vertexEstimator

ToolHandle< InDet::VertexPointEstimator > DerivationFramework::JpsiXPlusDisplaced::m_vertexEstimator
private

Definition at line 193 of file JpsiXPlusDisplaced.h.

◆ m_vertexJXContainerKey

SG::ReadHandleKey<xAOD::VertexContainer> DerivationFramework::JpsiXPlusDisplaced::m_vertexJXContainerKey
private

Definition at line 85 of file JpsiXPlusDisplaced.h.

◆ m_vertexJXHypoNames

std::vector<std::string> DerivationFramework::JpsiXPlusDisplaced::m_vertexJXHypoNames
private

Definition at line 87 of file JpsiXPlusDisplaced.h.

◆ m_vertexV0ContainerKey

SG::ReadHandleKey<xAOD::VertexContainer> DerivationFramework::JpsiXPlusDisplaced::m_vertexV0ContainerKey
private

Definition at line 86 of file JpsiXPlusDisplaced.h.

◆ m_VxPrimaryCandidateName

SG::ReadHandleKey<xAOD::VertexContainer> DerivationFramework::JpsiXPlusDisplaced::m_VxPrimaryCandidateName
private

Definition at line 92 of file JpsiXPlusDisplaced.h.


The documentation for this class was generated from the following files: