ATLAS Offline Software
JpsiXPlus2V0.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  Contact: Xin Chen <xin.chen@cern.ch>
4 */
10 #include "GaudiKernel/IPartPropSvc.h"
16 #include "HepPDT/ParticleDataTable.hh"
17 #include "VxVertex/RecVertex.h"
19 #include <algorithm>
20 #include <functional>
21 
22 namespace DerivationFramework {
24  typedef std::vector<VertexLink> VertexLinkVector;
25 
26  JpsiXPlus2V0::JpsiXPlus2V0(const std::string& type, const std::string& name, const IInterface* parent) : AthAlgTool(type,name,parent),
27  m_vertexJXContainerKey("InputJXVertices"),
28  m_vertexV0ContainerKeys{"InputV0Containers"},
29  m_cascadeOutputKeys({"JpsiXPlus2V0_SubVtx1", "JpsiXPlus2V0_SubVtx2", "JpsiXPlus2V0_SubVtx3", "JpsiXPlus2V0_MainVtx"}),
30  m_refitV0(false),
31  m_constrV0(true),
32  m_v0VtxOutputKeys(this,"OutoutV0VtxCollections",{}),
33  m_TrkParticleCollection("InDetTrackParticles"),
34  m_VxPrimaryCandidateName("PrimaryVertices"),
35  m_eventInfo_key("EventInfo"),
36  m_jxMassLower(0.0),
37  m_jxMassUpper(30000.0),
38  m_jpsiMassLower(0.0),
39  m_jpsiMassUpper(20000.0),
40  m_diTrackMassLower(-1.0),
41  m_diTrackMassUpper(-1.0),
42  m_V01Hypothesis("Ks"),
43  m_V01MassLower(0.0),
44  m_V01MassUpper(20000.0),
45  m_lxyV01_cut(-999.0),
46  m_V02Hypothesis("Lambda"),
47  m_V02MassLower(0.0),
48  m_V02MassUpper(20000.0),
49  m_lxyV02_cut(-999.0),
50  m_doV0Enum(false),
51  m_decorV0P(false),
52  m_minMass_gamma(-1.0),
53  m_chi2cut_gamma(-1.0),
54  m_MassLower(0.0),
55  m_MassUpper(41000.0),
56  m_jxDaug_num(4),
57  m_jxDaug1MassHypo(-1),
58  m_jxDaug2MassHypo(-1),
59  m_jxDaug3MassHypo(-1),
60  m_jxDaug4MassHypo(-1),
61  m_massJX(-1),
62  m_massJpsi(-1),
63  m_massX(-1),
64  m_massJXV02(-1),
65  m_massMainV(-1),
66  m_constrJX(false),
67  m_constrJpsi(false),
68  m_constrX(false),
69  m_constrV01(false),
70  m_constrV02(false),
71  m_constrJXV02(false),
72  m_constrMainV(false),
73  m_JXSubVtx(true),
74  m_JXV02SubVtx(false),
75  m_chi2cut_JX(-1.0),
76  m_chi2cut_V0(-1.0),
77  m_chi2cut(-1.0),
78  m_maxJXCandidates(0),
79  m_maxV0Candidates(0),
80  m_maxMainVCandidates(0),
81  m_iVertexFitter("Trk::TrkVKalVrtFitter"),
82  m_iV0Fitter("Trk::V0VertexFitter"),
83  m_iGammaFitter("Trk::TrkVKalVrtFitter"),
84  m_pvRefitter("Analysis::PrimaryVertexRefitter", this),
85  m_V0Tools("Trk::V0Tools"),
86  m_CascadeTools("DerivationFramework::CascadeTools")
87  {
88  declareProperty("JXVertices", m_vertexJXContainerKey);
89  declareProperty("V0Containers", m_vertexV0ContainerKeys);
90  declareProperty("JXVtxHypoNames", m_vertexJXHypoNames);
91  declareProperty("V0VtxHypoNames", m_vertexV0HypoNames);
92  declareProperty("CascadeVertexCollections", m_cascadeOutputKeys); // size is 3 or 4 only
93  declareProperty("RefitV0", m_refitV0);
94  declareProperty("ApplyV0MassConstraint", m_constrV0); // only effective when m_refitV0 = true
95  declareProperty("OutoutV0VtxCollections", m_v0VtxOutputKeys);
96  declareProperty("TrackParticleCollection", m_TrkParticleCollection);
97  declareProperty("VxPrimaryCandidateName", m_VxPrimaryCandidateName);
98  declareProperty("RefPVContainerName", m_refPVContainerName = "RefittedPrimaryVertices");
99  declareProperty("JXMassLowerCut", m_jxMassLower); // only effective when m_jxDaug_num>2
100  declareProperty("JXMassUpperCut", m_jxMassUpper); // only effective when m_jxDaug_num>2
101  declareProperty("JpsiMassLowerCut", m_jpsiMassLower);
102  declareProperty("JpsiMassUpperCut", m_jpsiMassUpper);
103  declareProperty("DiTrackMassLower", m_diTrackMassLower); // only effective when m_jxDaug_num=4
104  declareProperty("DiTrackMassUpper", m_diTrackMassUpper); // only effective when m_jxDaug_num=4
105  declareProperty("V01Hypothesis", m_V01Hypothesis); // "Ks" or "Lambda"
106  declareProperty("V01MassLowerCut", m_V01MassLower);
107  declareProperty("V01MassUpperCut", m_V01MassUpper);
108  declareProperty("LxyV01Cut", m_lxyV01_cut);
109  declareProperty("V02Hypothesis", m_V02Hypothesis); // "Ks" or "Lambda"
110  declareProperty("V02MassLowerCut", m_V02MassLower);
111  declareProperty("V02MassUpperCut", m_V02MassUpper);
112  declareProperty("LxyV02Cut", m_lxyV02_cut);
113  declareProperty("DoV0Enumeration", m_doV0Enum);
114  declareProperty("DecorateV0Momentum", m_decorV0P); // only effective when m_refitV0=true and m_constrV0=true
115  declareProperty("MassCutGamma", m_minMass_gamma);
116  declareProperty("Chi2CutGamma", m_chi2cut_gamma);
117  declareProperty("MassLowerCut", m_MassLower);
118  declareProperty("MassUpperCut", m_MassUpper);
119  declareProperty("HypothesisName", m_hypoName = "TQ");
120  declareProperty("NumberOfJXDaughters", m_jxDaug_num); // 2, or 3, or 4 only
121  declareProperty("JXDaug1MassHypo", m_jxDaug1MassHypo);
122  declareProperty("JXDaug2MassHypo", m_jxDaug2MassHypo);
123  declareProperty("JXDaug3MassHypo", m_jxDaug3MassHypo);
124  declareProperty("JXDaug4MassHypo", m_jxDaug4MassHypo);
125  declareProperty("JXMass", m_massJX); // only effective when m_jxDaug_num>2
126  declareProperty("JpsiMass", m_massJpsi);
127  declareProperty("XMass", m_massX); // only effective when m_jxDaug_num=4
128  declareProperty("JXV02VtxMass", m_massJXV02); // mass of JX + 2nd V0
129  declareProperty("MainVtxMass", m_massMainV);
130  declareProperty("ApplyJXMassConstraint", m_constrJX);
131  declareProperty("ApplyJpsiMassConstraint", m_constrJpsi); // only effective when m_jxDaug_num>2
132  declareProperty("ApplyXMassConstraint", m_constrX); // only effective when m_jxDaug_num=4
133  declareProperty("ApplyV01MassConstraint", m_constrV01); // first V0
134  declareProperty("ApplyV02MassConstraint", m_constrV02); // second V0
135  declareProperty("ApplyJXV02MassConstraint", m_constrJXV02); // constrain JX + 2nd V0
136  declareProperty("ApplyMainVMassConstraint", m_constrMainV);
137  declareProperty("HasJXSubVertex", m_JXSubVtx);
138  declareProperty("HasJXV02SubVertex", m_JXV02SubVtx); // only effective when m_JXSubVtx=true
139  declareProperty("Chi2CutJX", m_chi2cut_JX);
140  declareProperty("Chi2CutV0", m_chi2cut_V0);
141  declareProperty("Chi2Cut", m_chi2cut);
142  declareProperty("MaxJXCandidates", m_maxJXCandidates);
143  declareProperty("MaxV0Candidates", m_maxV0Candidates);
144  declareProperty("MaxMainVCandidates", m_maxMainVCandidates);
145  declareProperty("RefitPV", m_refitPV = true);
146  declareProperty("MaxnPV", m_PV_max = 1000);
147  declareProperty("MinNTracksInPV", m_PV_minNTracks = 0);
148  declareProperty("DoVertexType", m_DoVertexType = 7);
149  declareProperty("TrkVertexFitterTool", m_iVertexFitter);
150  declareProperty("V0VertexFitterTool", m_iV0Fitter);
151  declareProperty("GammaFitterTool", m_iGammaFitter);
152  declareProperty("PVRefitter", m_pvRefitter);
153  declareProperty("V0Tools", m_V0Tools);
154  declareProperty("CascadeTools", m_CascadeTools);
155  }
156 
158  if((m_V01Hypothesis != "Ks" && m_V01Hypothesis != "Lambda") || (m_V02Hypothesis != "Ks" && m_V02Hypothesis != "Lambda")) {
159  ATH_MSG_FATAL("Incorrect V0 container hypothesis - not recognized");
160  return StatusCode::FAILURE;
161  }
162 
163  if( (m_V01Hypothesis == m_V02Hypothesis && (m_v0VtxOutputKeys.size() != 0 && m_v0VtxOutputKeys.size() != 1)) ||
164  (m_V01Hypothesis != m_V02Hypothesis && (m_v0VtxOutputKeys.size() != 0 && m_v0VtxOutputKeys.size() != 2)) ) {
165  ATH_MSG_FATAL("V0OutputKeys size is not correct!");
166  }
167 
168  if(m_jxDaug_num<2 || m_jxDaug_num>4) {
169  ATH_MSG_FATAL("Incorrect number of JX daughters");
170  return StatusCode::FAILURE;
171  }
172 
173  if(m_vertexV0ContainerKeys.size()>10) {
174  ATH_MSG_FATAL("Number of input V0 containers is too large");
175  return StatusCode::FAILURE;
176  }
177 
178  // retrieving vertex Fitter
179  ATH_CHECK( m_iVertexFitter.retrieve() );
180 
181  // retrieving V0 vertex Fitter
182  ATH_CHECK( m_iV0Fitter.retrieve() );
183 
184  // retrieving photon conversion vertex Fitter
185  ATH_CHECK( m_iGammaFitter.retrieve() );
186 
187  // retrieving primary vertex refitter
188  ATH_CHECK( m_pvRefitter.retrieve() );
189 
190  // retrieving the V0 tool
191  ATH_CHECK( m_V0Tools.retrieve() );
192 
193  // retrieving the Cascade tools
194  ATH_CHECK( m_CascadeTools.retrieve() );
195 
196  ATH_CHECK( m_vertexJXContainerKey.initialize() );
197  ATH_CHECK( m_vertexV0ContainerKeys.initialize() );
198  ATH_CHECK( m_VxPrimaryCandidateName.initialize() );
200  ATH_CHECK( m_refPVContainerName.initialize() );
201  ATH_CHECK( m_cascadeOutputKeys.initialize() );
203  ATH_CHECK( m_v0VtxOutputKeys.initialize() );
204 
205  IPartPropSvc* partPropSvc = nullptr;
206  ATH_CHECK( service("PartPropSvc", partPropSvc, true) );
207  auto pdt = partPropSvc->PDT();
208 
209  // https://gitlab.cern.ch/atlas/athena/-/blob/main/Generators/TruthUtils/TruthUtils/AtlasPID.h
210  m_mass_e = BPhysPVCascadeTools::getParticleMass(pdt, MC::ELECTRON);
218 
219  // retrieve particle masses
224 
229 
230  return StatusCode::SUCCESS;
231  }
232 
233  StatusCode JpsiXPlus2V0::performSearch(std::vector<Trk::VxCascadeInfo*> *cascadeinfoContainer, std::vector<xAOD::VertexContainer*> V0OutputContainers) const {
234  ATH_MSG_DEBUG( "JpsiXPlus2V0::performSearch" );
235  assert(cascadeinfoContainer!=nullptr);
236 
237  // Get TrackParticle container
239  ATH_CHECK( trackContainer.isValid() );
240 
241  // Get the PrimaryVertices container
243  ATH_CHECK( pvContainer.isValid() );
244  if (pvContainer.cptr()->size()==0) {
245  ATH_MSG_WARNING("You have no primary vertices: " << pvContainer.cptr()->size());
246  return StatusCode::RECOVERABLE;
247  }
248 
249  std::vector<double> massesJX;
250  massesJX.push_back(m_jxDaug1MassHypo);
251  massesJX.push_back(m_jxDaug2MassHypo);
252  if(m_jxDaug_num>=3) massesJX.push_back(m_jxDaug3MassHypo);
253  if(m_jxDaug_num==4) massesJX.push_back(m_jxDaug4MassHypo);
254  std::vector<double> massesV0_ppi;
255  massesV0_ppi.push_back(m_mass_proton);
256  massesV0_ppi.push_back(m_mass_pion);
257  std::vector<double> massesV0_pip;
258  massesV0_pip.push_back(m_mass_pion);
259  massesV0_pip.push_back(m_mass_proton);
260  std::vector<double> massesV0_pipi;
261  massesV0_pipi.push_back(m_mass_pion);
262  massesV0_pipi.push_back(m_mass_pion);
263 
264  // Get Jpsi+X container
266  ATH_CHECK( jxContainer.isValid() );
267 
268  // Get V0 containers
269  std::vector<const xAOD::VertexContainer*> V0Containers;
270  std::array<SG::ReadHandle<xAOD::VertexContainer>, 10> V0Handles; int ikey(0);
272  V0Handles[ikey] = SG::ReadHandle<xAOD::VertexContainer>(key);
273  ATH_CHECK( V0Handles[ikey].isValid() );
274  V0Containers.push_back(V0Handles[ikey].cptr());
275  ikey++;
276  }
277 
278  // Accessors of V0 with photon conversion info and no-mass-constraint track momenta
279  SG::AuxElement::Accessor<std::string> mAcc_type("Type_V0Vtx");
280  SG::AuxElement::Accessor<int> mAcc_gfit("gamma_fit");
281  SG::AuxElement::Accessor<float> mAcc_gmass("gamma_mass");
282  SG::AuxElement::Accessor<float> mAcc_gmasserr("gamma_massError");
283  SG::AuxElement::Accessor<float> mAcc_gchisq("gamma_chisq");
284  SG::AuxElement::Accessor<int> mAcc_gndof("gamma_ndof");
285  SG::AuxElement::Accessor<float> mAcc_gprob("gamma_probability");
286  SG::AuxElement::Accessor< std::vector<float> > trk_pxAcc("TrackPx_V0nc");
287  SG::AuxElement::Accessor< std::vector<float> > trk_pyAcc("TrackPy_V0nc");
288  SG::AuxElement::Accessor< std::vector<float> > trk_pzAcc("TrackPz_V0nc");
289  // Decorators of V0 vertices
290  SG::AuxElement::Decorator<std::string> mDec_type("Type_V0Vtx");
291  SG::AuxElement::Decorator<int> mDec_gfit("gamma_fit");
292  SG::AuxElement::Decorator<float> mDec_gmass("gamma_mass");
293  SG::AuxElement::Decorator<float> mDec_gmasserr("gamma_massError");
294  SG::AuxElement::Decorator<float> mDec_gchisq("gamma_chisq");
295  SG::AuxElement::Decorator<int> mDec_gndof("gamma_ndof");
296  SG::AuxElement::Decorator<float> mDec_gprob("gamma_probability");
297  SG::AuxElement::Decorator< std::vector<float> > trk_pxDeco("TrackPx_V0nc");
298  SG::AuxElement::Decorator< std::vector<float> > trk_pyDeco("TrackPy_V0nc");
299  SG::AuxElement::Decorator< std::vector<float> > trk_pzDeco("TrackPz_V0nc");
300 
301  std::vector<float> trk_px;
302  std::vector<float> trk_py;
303  std::vector<float> trk_pz;
304  std::vector<const xAOD::TrackParticle*> tracksV0;
305 
306  // Select the V0 candidates before calling cascade fit
307  std::vector<std::pair<const xAOD::Vertex*,V0Enum> > selectedV0Candidates_EXISTING;
308  std::vector<std::pair<xAOD::Vertex*,V0Enum> > selectedV0Candidates_CREATED;
309  for(size_t ic=0; ic<V0Containers.size(); ic++) {
310  const xAOD::VertexContainer* V0Container = V0Containers[ic];
311  for(auto vxcItr=V0Container->begin(); vxcItr!=V0Container->end(); ++vxcItr) {
312  const xAOD::Vertex* vtx = *vxcItr;
313  // Check the passed flags first
314  bool passed = false;
315  for(auto name : m_vertexV0HypoNames) {
316  SG::AuxElement::Accessor<Char_t> flagAcc("passed_"+name);
317  if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
318  passed = true;
319  }
320  }
321  if(m_vertexV0HypoNames.size() && !passed) continue;
322 
323  V0Enum opt(UNKNOWN); double massV0(0);
324  if(m_doV0Enum) {
325  // determine V0 candidate track masses
326  double massSig_V0_Lambda1 = std::abs(m_V0Tools->invariantMass(vtx, massesV0_ppi)-m_mass_Lambda)/m_V0Tools->invariantMassError(vtx, massesV0_ppi);
327  double massSig_V0_Lambda2 = std::abs(m_V0Tools->invariantMass(vtx, massesV0_pip)-m_mass_Lambda)/m_V0Tools->invariantMassError(vtx, massesV0_pip);
328  double massSig_V0_Ks = std::abs(m_V0Tools->invariantMass(vtx, massesV0_pipi)-m_mass_Ks)/m_V0Tools->invariantMassError(vtx, massesV0_pipi);
329  if(massSig_V0_Lambda1<=massSig_V0_Lambda2 && massSig_V0_Lambda1<=massSig_V0_Ks) {
330  opt = LAMBDA;
331  massV0 = m_V0Tools->invariantMass(vtx, massesV0_ppi);
332  }
333  else if(massSig_V0_Lambda2<=massSig_V0_Lambda1 && massSig_V0_Lambda2<=massSig_V0_Ks) {
334  opt = LAMBDABAR;
335  massV0 = m_V0Tools->invariantMass(vtx, massesV0_pip);
336  }
337  else if(massSig_V0_Ks<=massSig_V0_Lambda1 && massSig_V0_Ks<=massSig_V0_Lambda2) {
338  opt = KS;
339  massV0 = m_V0Tools->invariantMass(vtx, massesV0_pipi);
340  }
341 
342  if(opt==LAMBDA || opt==LAMBDABAR) {
343  if(m_V01Hypothesis == "Lambda" && m_V02Hypothesis == "Lambda") {
344  if((massV0<m_V01MassLower || massV0>m_V01MassUpper) && (massV0<m_V02MassLower || massV0>m_V02MassUpper)) continue;
345  }
346  else if(m_V01Hypothesis == "Lambda") {
347  if(massV0<m_V01MassLower || massV0>m_V01MassUpper) continue;
348  }
349  else if(m_V02Hypothesis == "Lambda") {
350  if(massV0<m_V02MassLower || massV0>m_V02MassUpper) continue;
351  }
352  else continue;
353  }
354  else if(opt==KS) {
355  if(m_V01Hypothesis == "Ks" && m_V02Hypothesis == "Ks") {
356  if((massV0<m_V01MassLower || massV0>m_V01MassUpper) && (massV0<m_V02MassLower || massV0>m_V02MassUpper)) continue;
357  }
358  else if(m_V01Hypothesis == "Ks") {
359  if(massV0<m_V01MassLower || massV0>m_V01MassUpper) continue;
360  }
361  else if(m_V02Hypothesis == "Ks") {
362  if(massV0<m_V02MassLower || massV0>m_V02MassUpper) continue;
363  }
364  else continue;
365  }
366  }
367  else {
368  std::string type_V0Vtx;
369  if(mAcc_type.isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
370  if(type_V0Vtx == "Lambda") opt = LAMBDA;
371  else if(type_V0Vtx == "Lambdabar") opt = LAMBDABAR;
372  else if(type_V0Vtx == "Ks") opt = KS;
373  else opt = UNKNOWN;
374  }
375 
376  if(opt==UNKNOWN) continue;
378  if((opt==LAMBDA || opt==LAMBDABAR) && m_V01Hypothesis != "Lambda") continue;
379  if(opt==KS && m_V01Hypothesis != "Ks") continue;
380  }
381 
382  tracksV0.clear();
383  for(size_t i=0; i<vtx->nTrackParticles(); i++) tracksV0.push_back(vtx->trackParticle(i));
384  Amg::Vector3D vtxPos = m_V0Tools->vtx(vtx);
385 
386  int gamma_fit = 0; int gamma_ndof = 0;
387  double gamma_chisq = 999999., gamma_prob = -1., gamma_mass = -1., gamma_massErr = -1.;
388  if(mAcc_gfit.isAvailable(*vtx)) {
389  gamma_fit = mAcc_gfit.isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
390  gamma_mass = mAcc_gmass.isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
391  gamma_massErr = mAcc_gmasserr.isAvailable(*vtx) ? mAcc_gmasserr(*vtx) : -1;
392  gamma_chisq = mAcc_gchisq.isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
393  gamma_ndof = mAcc_gndof.isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
394  gamma_prob = mAcc_gprob.isAvailable(*vtx) ? mAcc_gprob(*vtx) : -1;
395  }
396  else {
397  std::unique_ptr<xAOD::Vertex> gammaVtx = std::unique_ptr<xAOD::Vertex>( m_iGammaFitter->fit(tracksV0, vtxPos) );
398  if (gammaVtx) {
399  gamma_fit = 1;
400  gamma_mass = m_V0Tools->invariantMass(gammaVtx.get(),m_mass_e,m_mass_e);
401  gamma_massErr = m_V0Tools->invariantMassError(gammaVtx.get(),m_mass_e,m_mass_e);
402  gamma_chisq = m_V0Tools->chisq(gammaVtx.get());
403  gamma_ndof = m_V0Tools->ndof(gammaVtx.get());
404  gamma_prob = m_V0Tools->vertexProbability(gammaVtx.get());
405  }
406  }
407  if(gamma_fit==1 && gamma_mass<m_minMass_gamma && gamma_chisq/gamma_ndof<m_chi2cut_gamma) continue;
408 
409  // store track momenta at vertex before refit
410  trk_px.clear(); trk_py.clear(); trk_pz.clear();
411  for(size_t i=0; i<vtx->vxTrackAtVertex().size(); ++i) {
412  const Trk::TrackParameters* aPerigee = vtx->vxTrackAtVertex()[i].perigeeAtVertex();
413  if(aPerigee) {
414  trk_px.push_back( aPerigee->momentum()[Trk::px] );
415  trk_py.push_back( aPerigee->momentum()[Trk::py] );
416  trk_pz.push_back( aPerigee->momentum()[Trk::pz] );
417  }
418  }
419 
420  if(m_refitV0) {
421  std::unique_ptr<xAOD::Vertex> V0vtx;
422  if(m_constrV0) {
423  std::vector<double> massesV0;
424  if(opt == LAMBDA) massesV0 = massesV0_ppi;
425  else if(opt == LAMBDABAR) massesV0 = massesV0_pip;
426  else if(opt == KS) massesV0 = massesV0_pipi;
427  // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkV0Fitter/TrkV0Fitter/TrkV0VertexFitter.h
428  V0vtx = std::unique_ptr<xAOD::Vertex>( m_iV0Fitter->fit(tracksV0, massesV0, opt==KS ? m_mass_Ks : m_mass_Lambda, 0, vtxPos) );
429  }
430  else {
431  V0vtx = std::unique_ptr<xAOD::Vertex>( m_iV0Fitter->fit(tracksV0, vtxPos) );
432  }
433  if(V0vtx && V0vtx->chiSquared()>=0) {
434  double chi2DOF = V0vtx->chiSquared()/V0vtx->numberDoF();
435  if(m_chi2cut_V0>0 && chi2DOF>m_chi2cut_V0) continue;
436 
437  xAOD::BPhysHelper V0_helper(V0vtx.get());
438  V0_helper.setRefTrks(); // AOD only method
439 
440  V0vtx->clearTracks();
442  newLink1.setElement(tracksV0[0]);
443  newLink1.setStorableObject(*trackContainer.cptr());
445  newLink2.setElement(tracksV0[1]);
446  newLink2.setStorableObject(*trackContainer.cptr());
447  V0vtx->addTrackAtVertex(newLink1);
448  V0vtx->addTrackAtVertex(newLink2);
449 
450  mDec_gfit(*V0vtx.get()) = gamma_fit;
451  mDec_gmass(*V0vtx.get()) = gamma_mass;
452  mDec_gmasserr(*V0vtx.get()) = gamma_massErr;
453  mDec_gchisq(*V0vtx.get()) = gamma_chisq;
454  mDec_gndof(*V0vtx.get()) = gamma_ndof;
455  mDec_gprob(*V0vtx.get()) = gamma_prob;
456  if(opt==LAMBDA) mDec_type(*V0vtx.get()) = "Lambda";
457  else if(opt==LAMBDABAR) mDec_type(*V0vtx.get()) = "Lambdabar";
458  else if(opt==KS) mDec_type(*V0vtx.get()) = "Ks";
459  if(m_constrV0 && m_decorV0P) {
460  trk_pxDeco(*V0vtx.get()) = trk_px;
461  trk_pyDeco(*V0vtx.get()) = trk_py;
462  trk_pzDeco(*V0vtx.get()) = trk_pz;
463  }
464  selectedV0Candidates_CREATED.push_back(std::pair<xAOD::Vertex*,V0Enum>{V0vtx.release(),opt});
465  }
466  } // refitV0
467  else { // no V0 refit
468  double chi2DOF = vtx->chiSquared()/vtx->numberDoF();
469  if(m_chi2cut_V0>0 && chi2DOF>m_chi2cut_V0) continue;
470  mDec_gfit(*vtx) = gamma_fit;
471  mDec_gmass(*vtx) = gamma_mass;
472  mDec_gmasserr(*vtx) = gamma_massErr;
473  mDec_gchisq(*vtx) = gamma_chisq;
474  mDec_gndof(*vtx) = gamma_ndof;
475  mDec_gprob(*vtx) = gamma_prob;
476  if(opt==LAMBDA) mDec_type(*vtx) = "Lambda";
477  else if(opt==LAMBDABAR) mDec_type(*vtx) = "Lambdabar";
478  else if(opt==KS) mDec_type(*vtx) = "Ks";
479  selectedV0Candidates_EXISTING.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,opt});
480  } // no V0 refit
481  } // V0 candidate
482  } // V0Container
483  if((m_refitV0 && selectedV0Candidates_CREATED.size()==0) || (!m_refitV0 && selectedV0Candidates_EXISTING.size()==0)) return StatusCode::SUCCESS;
484 
485  std::vector<std::pair<const xAOD::Vertex*,V0Enum> > selectedV01Candidates_EXISTING;
486  std::vector<std::pair<const xAOD::Vertex*,V0Enum> > selectedV02Candidates_EXISTING;
487  std::vector<std::pair<xAOD::Vertex*,V0Enum> > selectedV01Candidates_CREATED;
488  std::vector<std::pair<xAOD::Vertex*,V0Enum> > selectedV02Candidates_CREATED;
490  if(m_refitV0) {
491  for(size_t j=0; j<selectedV0Candidates_CREATED.size(); j++) {
492  std::pair<xAOD::Vertex*,V0Enum> candidate = selectedV0Candidates_CREATED[j];
493  if(candidate.second==LAMBDA || candidate.second==LAMBDABAR) {
494  if(m_V01Hypothesis == "Lambda") selectedV01Candidates_CREATED.push_back(candidate);
495  else if(m_V02Hypothesis == "Lambda") selectedV02Candidates_CREATED.push_back(candidate);
496  }
497  else if(candidate.second==KS) {
498  if(m_V01Hypothesis == "Ks") selectedV01Candidates_CREATED.push_back(candidate);
499  else if(m_V02Hypothesis == "Ks") selectedV02Candidates_CREATED.push_back(candidate);
500  }
501  }
502 
503  std::sort( selectedV01Candidates_CREATED.begin(), selectedV01Candidates_CREATED.end(), [](std::pair<xAOD::Vertex*,V0Enum> a, std::pair<xAOD::Vertex*,V0Enum> b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
504  if(m_maxV0Candidates>0 && selectedV01Candidates_CREATED.size()>m_maxV0Candidates) {
505  for(auto it=selectedV01Candidates_CREATED.begin()+m_maxV0Candidates; it!=selectedV01Candidates_CREATED.end(); it++) delete it->first;
506  selectedV01Candidates_CREATED.erase(selectedV01Candidates_CREATED.begin()+m_maxV0Candidates, selectedV01Candidates_CREATED.end());
507  }
508  std::sort( selectedV02Candidates_CREATED.begin(), selectedV02Candidates_CREATED.end(), [](std::pair<xAOD::Vertex*,V0Enum> a, std::pair<xAOD::Vertex*,V0Enum> b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
509  if(m_maxV0Candidates>0 && selectedV02Candidates_CREATED.size()>m_maxV0Candidates) {
510  for(auto it=selectedV02Candidates_CREATED.begin()+m_maxV0Candidates; it!=selectedV02Candidates_CREATED.end(); it++) delete it->first;
511  selectedV02Candidates_CREATED.erase(selectedV02Candidates_CREATED.begin()+m_maxV0Candidates, selectedV02Candidates_CREATED.end());
512  }
513 
514  if(V0OutputContainers.size()==2) {
515  for(auto v0VItr=selectedV01Candidates_CREATED.begin(); v0VItr!=selectedV01Candidates_CREATED.end(); ++v0VItr) V0OutputContainers[0]->push_back(v0VItr->first);
516  for(auto v0VItr=selectedV02Candidates_CREATED.begin(); v0VItr!=selectedV02Candidates_CREATED.end(); ++v0VItr) V0OutputContainers[1]->push_back(v0VItr->first);
517  }
518  }
519  else { // not refit V0
520  for(size_t j=0; j<selectedV0Candidates_EXISTING.size(); j++) {
521  std::pair<const xAOD::Vertex*,V0Enum> candidate = selectedV0Candidates_EXISTING[j];
522  if(candidate.second==LAMBDA || candidate.second==LAMBDABAR) {
523  if(m_V01Hypothesis == "Lambda") selectedV01Candidates_EXISTING.push_back(candidate);
524  else if(m_V02Hypothesis == "Lambda") selectedV02Candidates_EXISTING.push_back(candidate);
525  }
526  else if(candidate.second==KS) {
527  if(m_V01Hypothesis == "Ks") selectedV01Candidates_EXISTING.push_back(candidate);
528  else if(m_V02Hypothesis == "Ks") selectedV02Candidates_EXISTING.push_back(candidate);
529  }
530  }
531 
532  std::sort( selectedV01Candidates_EXISTING.begin(), selectedV01Candidates_EXISTING.end(), [](std::pair<const xAOD::Vertex*,V0Enum> a, std::pair<const xAOD::Vertex*,V0Enum> b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
533  if(m_maxV0Candidates>0 && selectedV01Candidates_EXISTING.size()>m_maxV0Candidates) {
534  selectedV01Candidates_EXISTING.erase(selectedV01Candidates_EXISTING.begin()+m_maxV0Candidates, selectedV01Candidates_EXISTING.end());
535  }
536  std::sort( selectedV02Candidates_EXISTING.begin(), selectedV02Candidates_EXISTING.end(), [](std::pair<const xAOD::Vertex*,V0Enum> a, std::pair<const xAOD::Vertex*,V0Enum> b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
537  if(m_maxV0Candidates>0 && selectedV02Candidates_EXISTING.size()>m_maxV0Candidates) {
538  selectedV02Candidates_EXISTING.erase(selectedV02Candidates_EXISTING.begin()+m_maxV0Candidates, selectedV02Candidates_EXISTING.end());
539  }
540  }
541  }
542  else { // m_V01Hypothesis == m_V02Hypothesis
543  if(m_refitV0) {
544  std::sort( selectedV0Candidates_CREATED.begin(), selectedV0Candidates_CREATED.end(), [](std::pair<xAOD::Vertex*,V0Enum> a, std::pair<xAOD::Vertex*,V0Enum> b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
545  if(m_maxV0Candidates>0 && selectedV0Candidates_CREATED.size()>m_maxV0Candidates) {
546  for(auto it=selectedV0Candidates_CREATED.begin()+m_maxV0Candidates; it!=selectedV0Candidates_CREATED.end(); it++) delete it->first;
547  selectedV0Candidates_CREATED.erase(selectedV0Candidates_CREATED.begin()+m_maxV0Candidates, selectedV0Candidates_CREATED.end());
548  }
549 
550  if(V0OutputContainers.size()==1) {
551  for(auto v0VItr=selectedV0Candidates_CREATED.begin(); v0VItr!=selectedV0Candidates_CREATED.end(); ++v0VItr) V0OutputContainers[0]->push_back(v0VItr->first);
552  }
553  }
554  else { // not refit V0
555  std::sort( selectedV0Candidates_EXISTING.begin(), selectedV0Candidates_EXISTING.end(), [](std::pair<const xAOD::Vertex*,V0Enum> a, std::pair<const xAOD::Vertex*,V0Enum> b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
556  if(m_maxV0Candidates>0 && selectedV0Candidates_EXISTING.size()>m_maxV0Candidates) {
557  selectedV0Candidates_EXISTING.erase(selectedV0Candidates_EXISTING.begin()+m_maxV0Candidates, selectedV0Candidates_EXISTING.end());
558  }
559  }
560  }
561 
562  // Select the JX candidates before calling cascade fit
563  std::vector<const xAOD::Vertex*> selectedJXCandidates;
564  for(auto vxcItr=jxContainer.ptr()->begin(); vxcItr!=jxContainer.ptr()->end(); ++vxcItr) {
565  // Check the passed flag first
566  const xAOD::Vertex* vtx = *vxcItr;
567  bool passed = false;
568  for(auto name : m_vertexJXHypoNames) {
569  SG::AuxElement::Accessor<Char_t> flagAcc("passed_"+name);
570  if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
571  passed = true;
572  }
573  }
574  if(m_vertexJXHypoNames.size() && !passed) continue;
575 
576  // Check Psi candidate invariant mass and skip if need be
577  if(m_jxDaug_num>2) {
578  double mass_jx = m_V0Tools->invariantMass(*vxcItr,massesJX);
579  if(mass_jx < m_jxMassLower || mass_jx > m_jxMassUpper) continue;
580  }
581 
582  // Add loose cut on Jpsi mass from e.g. JX -> Jpsi pi+ pi-
583  TLorentzVector p4_mu1, p4_mu2;
584  p4_mu1.SetPtEtaPhiM( vtx->trackParticle(0)->pt(),
585  vtx->trackParticle(0)->eta(),
586  vtx->trackParticle(0)->phi(), m_jxDaug1MassHypo);
587  p4_mu2.SetPtEtaPhiM( vtx->trackParticle(1)->pt(),
588  vtx->trackParticle(1)->eta(),
589  vtx->trackParticle(1)->phi(), m_jxDaug2MassHypo);
590  double mass_jpsi = (p4_mu1 + p4_mu2).M();
591  if (mass_jpsi < m_jpsiMassLower || mass_jpsi > m_jpsiMassUpper) continue;
592 
594  TLorentzVector p4_trk1, p4_trk2;
595  p4_trk1.SetPtEtaPhiM( vtx->trackParticle(2)->pt(),
596  vtx->trackParticle(2)->eta(),
597  vtx->trackParticle(2)->phi(), m_jxDaug3MassHypo);
598  p4_trk2.SetPtEtaPhiM( vtx->trackParticle(3)->pt(),
599  vtx->trackParticle(3)->eta(),
600  vtx->trackParticle(3)->phi(), m_jxDaug4MassHypo);
601  double mass_diTrk = (p4_trk1 + p4_trk2).M();
602  if (mass_diTrk < m_diTrackMassLower || mass_diTrk > m_diTrackMassUpper) continue;
603  }
604 
605  double chi2DOF = vtx->chiSquared()/vtx->numberDoF();
606  if(m_chi2cut_JX>0 && chi2DOF>m_chi2cut_JX) continue;
607 
608  selectedJXCandidates.push_back(vtx);
609  }
610 
611  if(selectedJXCandidates.size()==0) {
612  if(V0OutputContainers.size()==0) {
614  for(auto v0VItr=selectedV01Candidates_CREATED.begin(); v0VItr!=selectedV01Candidates_CREATED.end(); ++v0VItr) delete v0VItr->first;
615  for(auto v0VItr=selectedV02Candidates_CREATED.begin(); v0VItr!=selectedV02Candidates_CREATED.end(); ++v0VItr) delete v0VItr->first;
616  } else {
617  for(auto v0VItr=selectedV0Candidates_CREATED.begin(); v0VItr!=selectedV0Candidates_CREATED.end(); ++v0VItr) delete v0VItr->first;
618  }
619  }
620  return StatusCode::SUCCESS;
621  }
622 
623  std::sort( selectedJXCandidates.begin(), selectedJXCandidates.end(), [](const xAOD::Vertex* a, const xAOD::Vertex* b) { return a->chiSquared()/a->numberDoF() < b->chiSquared()/b->numberDoF(); } );
624  if(m_maxJXCandidates>0 && selectedJXCandidates.size()>m_maxJXCandidates) {
625  selectedJXCandidates.erase(selectedJXCandidates.begin()+m_maxJXCandidates, selectedJXCandidates.end());
626  }
627 
628  // Select JX+V0+V0 candidates
629  // Iterate over JX vertices
630  for(auto jxItr=selectedJXCandidates.cbegin(); jxItr!=selectedJXCandidates.cend(); ++jxItr) {
631  // Iterate over V0 vertices
633  if(m_refitV0) {
634  for(auto V0Itr1=selectedV0Candidates_CREATED.begin(); V0Itr1!=selectedV0Candidates_CREATED.end(); ++V0Itr1) {
635  for(auto V0Itr2=V0Itr1+1; V0Itr2!=selectedV0Candidates_CREATED.end(); ++V0Itr2) {
636  Trk::VxCascadeInfo* result = fitMainVtx(*jxItr, massesJX, V0Itr1->first, V0Itr1->second, V0Itr2->first, V0Itr2->second, trackContainer.ptr());
637  if(result) cascadeinfoContainer->push_back(result);
638  }
639  }
640  }
641  else { // not refit V0
642  for(auto V0Itr1=selectedV0Candidates_EXISTING.begin(); V0Itr1!=selectedV0Candidates_EXISTING.end(); ++V0Itr1) {
643  for(auto V0Itr2=V0Itr1+1; V0Itr2!=selectedV0Candidates_EXISTING.end(); ++V0Itr2) {
644  Trk::VxCascadeInfo* result = fitMainVtx(*jxItr, massesJX, V0Itr1->first, V0Itr1->second, V0Itr2->first, V0Itr2->second, trackContainer.ptr());
645  if(result) cascadeinfoContainer->push_back(result);
646  }
647  }
648  }
649  }
650  else { // m_V01Hypothesis != m_V02Hypothesis
651  if(m_refitV0) {
652  for(auto V0Itr1=selectedV01Candidates_CREATED.begin(); V0Itr1!=selectedV01Candidates_CREATED.end(); ++V0Itr1) {
653  for(auto V0Itr2=selectedV02Candidates_CREATED.begin(); V0Itr2!=selectedV02Candidates_CREATED.end(); ++V0Itr2) {
654  Trk::VxCascadeInfo* result = fitMainVtx(*jxItr, massesJX, V0Itr1->first, V0Itr1->second, V0Itr2->first, V0Itr2->second, trackContainer.ptr());
655  if(result) cascadeinfoContainer->push_back(result);
656  }
657  }
658  }
659  else { // not refit V0
660  for(auto V0Itr1=selectedV01Candidates_EXISTING.begin(); V0Itr1!=selectedV01Candidates_EXISTING.end(); ++V0Itr1) {
661  for(auto V0Itr2=selectedV02Candidates_EXISTING.begin(); V0Itr2!=selectedV02Candidates_EXISTING.end(); ++V0Itr2) {
662  Trk::VxCascadeInfo* result = fitMainVtx(*jxItr, massesJX, V0Itr1->first, V0Itr1->second, V0Itr2->first, V0Itr2->second, trackContainer.ptr());
663  if(result) cascadeinfoContainer->push_back(result);
664  }
665  }
666  }
667  }
668  } // jxItr
669 
670  // clean up transient objects
671  if(V0OutputContainers.size()==0) {
673  for(auto v0VItr=selectedV01Candidates_CREATED.begin(); v0VItr!=selectedV01Candidates_CREATED.end(); ++v0VItr) delete v0VItr->first;
674  for(auto v0VItr=selectedV02Candidates_CREATED.begin(); v0VItr!=selectedV02Candidates_CREATED.end(); ++v0VItr) delete v0VItr->first;
675  } else {
676  for(auto v0VItr=selectedV0Candidates_CREATED.begin(); v0VItr!=selectedV0Candidates_CREATED.end(); ++v0VItr) delete v0VItr->first;
677  }
678  }
679 
680  return StatusCode::SUCCESS;
681  }
682 
684  size_t topoN = 4;
685  if(!m_JXSubVtx) topoN--;
686 
687  if(m_cascadeOutputKeys.size() != topoN) {
688  ATH_MSG_FATAL("Incorrect number of output cascade vertices");
689  return StatusCode::FAILURE;
690  }
691 
692  std::array<SG::WriteHandle<xAOD::VertexContainer>, 4> VtxWriteHandles; int ikey(0);
694  VtxWriteHandles[ikey] = SG::WriteHandle<xAOD::VertexContainer>(key);
695  ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
696  ikey++;
697  }
698 
699  //----------------------------------------------------
700  // retrieve primary vertices
701  //----------------------------------------------------
703  ATH_CHECK( pvContainer.isValid() );
704  if (pvContainer.cptr()->size()==0) {
705  ATH_MSG_WARNING("You have no primary vertices: " << pvContainer.cptr()->size());
706  return StatusCode::RECOVERABLE;
707  }
708 
709  //----------------------------------------------------
710  // Record refitted primary vertices
711  //----------------------------------------------------
713  if(m_refitPV) {
715  ATH_CHECK( refPvContainer.record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
716  }
717 
718  // output V0 vertices
719  std::vector<xAOD::VertexContainer*> V0OutputContainers;
720  std::array<SG::WriteHandle<xAOD::VertexContainer>, 2> V0OutputHandles; ikey = 0;
722  V0OutputHandles[ikey] = SG::WriteHandle<xAOD::VertexContainer>(key);
723  ATH_CHECK( V0OutputHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
724  V0OutputContainers.push_back(V0OutputHandles[ikey].ptr());
725  ikey++;
726  }
727 
728  std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
729  ATH_CHECK(performSearch(&cascadeinfoContainer,V0OutputContainers));
730 
731  std::sort( cascadeinfoContainer.begin(), cascadeinfoContainer.end(), [](Trk::VxCascadeInfo* a, Trk::VxCascadeInfo* b) { return a->fitChi2()/a->nDoF() < b->fitChi2()/b->nDoF(); } );
732  if(m_maxMainVCandidates>0 && cascadeinfoContainer.size()>m_maxMainVCandidates) {
733  for(auto it=cascadeinfoContainer.begin()+m_maxMainVCandidates; it!=cascadeinfoContainer.end(); it++) delete *it;
734  cascadeinfoContainer.erase(cascadeinfoContainer.begin()+m_maxMainVCandidates, cascadeinfoContainer.end());
735  }
736 
738  ATH_CHECK( evt.isValid() );
740  helper.SetMinNTracksInPV(m_PV_minNTracks);
741 
742  // Decorators for the main vertex: chi2, ndf, pt and pt error, plus the V0 vertex variables
743  SG::AuxElement::Decorator<VertexLinkVector> CascadeLinksDecor("CascadeVertexLinks");
744  SG::AuxElement::Decorator<VertexLinkVector> JXLinksDecor("JXVertexLinks");
745  SG::AuxElement::Decorator<VertexLinkVector> V0LinksDecor("V0VertexLinks");
746  SG::AuxElement::Decorator<float> chi2_decor("ChiSquared");
747  SG::AuxElement::Decorator<int> ndof_decor("nDoF");
748  SG::AuxElement::Decorator<float> Pt_decor("Pt");
749  SG::AuxElement::Decorator<float> PtErr_decor("PtErr");
750 
751  SG::AuxElement::Decorator<float> lxy_SV1_decor("lxy_SV1");
752  SG::AuxElement::Decorator<float> lxyErr_SV1_decor("lxyErr_SV1");
753  SG::AuxElement::Decorator<float> a0xy_SV1_decor("a0xy_SV1");
754  SG::AuxElement::Decorator<float> a0xyErr_SV1_decor("a0xyErr_SV1");
755  SG::AuxElement::Decorator<float> a0z_SV1_decor("a0z_SV1");
756  SG::AuxElement::Decorator<float> a0zErr_SV1_decor("a0zErr_SV1");
757 
758  SG::AuxElement::Decorator<float> lxy_SV2_decor("lxy_SV2");
759  SG::AuxElement::Decorator<float> lxyErr_SV2_decor("lxyErr_SV2");
760  SG::AuxElement::Decorator<float> a0xy_SV2_decor("a0xy_SV2");
761  SG::AuxElement::Decorator<float> a0xyErr_SV2_decor("a0xyErr_SV2");
762  SG::AuxElement::Decorator<float> a0z_SV2_decor("a0z_SV2");
763  SG::AuxElement::Decorator<float> a0zErr_SV2_decor("a0zErr_SV2");
764 
765  SG::AuxElement::Decorator<float> lxy_SV3_decor("lxy_SV3");
766  SG::AuxElement::Decorator<float> lxyErr_SV3_decor("lxyErr_SV3");
767  SG::AuxElement::Decorator<float> a0xy_SV3_decor("a0xy_SV3");
768  SG::AuxElement::Decorator<float> a0xyErr_SV3_decor("a0xyErr_SV3");
769  SG::AuxElement::Decorator<float> a0z_SV3_decor("a0z_SV3");
770  SG::AuxElement::Decorator<float> a0zErr_SV3_decor("a0zErr_SV3");
771 
772  SG::AuxElement::Decorator<float> chi2_V3_decor("ChiSquared_V3");
773  SG::AuxElement::Decorator<int> ndof_V3_decor("nDoF_V3");
774 
775  // Get the input containers
777  ATH_CHECK( jxContainer.isValid() );
778 
779  for(auto cascade_info : cascadeinfoContainer) {
780  if(cascade_info==nullptr) ATH_MSG_ERROR("CascadeInfo is null");
781 
782  const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->vertices();
783  if(cascadeVertices.size() != topoN) ATH_MSG_ERROR("Incorrect number of vertices");
784  for(size_t i=0; i<topoN; i++) {
785  if(cascadeVertices[i]==nullptr) ATH_MSG_ERROR("Error null vertex");
786  }
787 
788  cascade_info->setSVOwnership(false); // Prevent Container from deleting vertices
789  const auto mainVertex = cascadeVertices[topoN-1]; // this is the mother vertex
790  const std::vector< std::vector<TLorentzVector> > &moms = cascade_info->getParticleMoms();
791 
792  // Identify the input JX
793  int ijx = !m_JXSubVtx ? topoN-1 : topoN-2;
794  const xAOD::Vertex* jxVtx(nullptr);
795  if(m_jxDaug_num==4) jxVtx = FindVertex<4>(jxContainer.ptr(), cascadeVertices[ijx]);
796  else if(m_jxDaug_num==3) jxVtx = FindVertex<3>(jxContainer.ptr(), cascadeVertices[ijx]);
797  else jxVtx = FindVertex<2>(jxContainer.ptr(), cascadeVertices[ijx]);
798 
799  xAOD::BPhysHypoHelper vtx(m_hypoName, mainVertex);
800 
801  // Get refitted track momenta from all vertices, charged tracks only
802  BPhysPVCascadeTools::SetVectorInfo(vtx, cascade_info);
803  vtx.setPass(true);
804 
805  //
806  // Decorate main vertex
807  //
808  // mass, mass error
809  // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/VxCascadeInfo.h
810  BPHYS_CHECK( vtx.setMass(m_CascadeTools->invariantMass(moms[topoN-1])) );
811  BPHYS_CHECK( vtx.setMassErr(m_CascadeTools->invariantMassError(moms[topoN-1],cascade_info->getCovariance()[topoN-1])) );
812  // pt and pT error (the default pt of mainVertex is != the pt of the full cascade fit!)
813  Pt_decor(*mainVertex) = m_CascadeTools->pT(moms[topoN-1]);
814  PtErr_decor(*mainVertex) = m_CascadeTools->pTError(moms[topoN-1],cascade_info->getCovariance()[topoN-1]);
815  // chi2 and ndof (the default chi2 of mainVertex is != the chi2 of the full cascade fit!)
816  chi2_decor(*mainVertex) = cascade_info->fitChi2();
817  ndof_decor(*mainVertex) = cascade_info->nDoF();
818 
819  // decorate the cascade vertices
820  lxy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
821  lxyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
822  a0z_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
823  a0zErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
824  a0xy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
825  a0xyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
826 
827  if(m_JXSubVtx && m_JXV02SubVtx) {
828  lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[2]);
829  lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
830  a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],cascadeVertices[2]);
831  a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
832  a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],cascadeVertices[2]);
833  a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
834  }
835  else {
836  lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
837  lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
838  a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
839  a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
840  a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
841  a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
842  }
843 
844  if(m_JXSubVtx) {
845  lxy_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->lxy(moms[2],cascadeVertices[2],mainVertex);
846  lxyErr_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->lxyError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
847  a0z_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->a0z(moms[2],cascadeVertices[2],mainVertex);
848  a0zErr_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->a0zError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
849  a0xy_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->a0xy(moms[2],cascadeVertices[2],mainVertex);
850  a0xyErr_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->a0xyError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
851  }
852 
853  chi2_V3_decor(*cascadeVertices[2]) = m_V0Tools->chisq(jxVtx);
854  ndof_V3_decor(*cascadeVertices[2]) = m_V0Tools->ndof(jxVtx);
855 
856  double Mass_Moth = m_CascadeTools->invariantMass(moms[topoN-1]);
857  ATH_CHECK(helper.FillCandwithRefittedVertices(m_refitPV, pvContainer.cptr(), m_refitPV ? refPvContainer.ptr() : 0, &(*m_pvRefitter), m_PV_max, m_DoVertexType, cascade_info, topoN-1, Mass_Moth, vtx));
858 
859  for(size_t i=0; i<topoN; i++) {
860  VtxWriteHandles[i].ptr()->push_back(cascadeVertices[i]);
861  }
862 
863  // Set links to cascade vertices
864  VertexLinkVector precedingVertexLinks;
865  VertexLink vertexLink1;
866  vertexLink1.setElement(cascadeVertices[0]);
867  vertexLink1.setStorableObject(*VtxWriteHandles[0].ptr());
868  if( vertexLink1.isValid() ) precedingVertexLinks.push_back( vertexLink1 );
869  VertexLink vertexLink2;
870  vertexLink2.setElement(cascadeVertices[1]);
871  vertexLink2.setStorableObject(*VtxWriteHandles[1].ptr());
872  if( vertexLink2.isValid() ) precedingVertexLinks.push_back( vertexLink2 );
873  if(topoN==4) {
874  VertexLink vertexLink3;
875  vertexLink3.setElement(cascadeVertices[2]);
876  vertexLink3.setStorableObject(*VtxWriteHandles[2].ptr());
877  if( vertexLink3.isValid() ) precedingVertexLinks.push_back( vertexLink3 );
878  }
879  CascadeLinksDecor(*mainVertex) = precedingVertexLinks;
880  } // loop over cascadeinfoContainer
881 
882  // Deleting cascadeinfo since this won't be stored.
883  // Vertices have been kept in m_cascadeOutputs and should be owned by their container
884  for (auto cascade_info : cascadeinfoContainer) delete cascade_info;
885 
886  return StatusCode::SUCCESS;
887  }
888 
889  Trk::VxCascadeInfo* JpsiXPlus2V0::fitMainVtx(const xAOD::Vertex* JXvtx, std::vector<double>& massesJX, const xAOD::Vertex* V01vtx, const V0Enum V01, const xAOD::Vertex* V02vtx, const V0Enum V02, const xAOD::TrackParticleContainer* trackContainer) const {
890  Trk::VxCascadeInfo* result(nullptr);
891 
892  std::vector<const xAOD::TrackParticle*> tracksJX;
893  for(size_t i=0; i<JXvtx->nTrackParticles(); i++) tracksJX.push_back(JXvtx->trackParticle(i));
894  if (tracksJX.size() != massesJX.size()) {
895  ATH_MSG_ERROR("Problems with JX input: number of tracks or track mass inputs is not correct!");
896  return result;
897  }
898 
899  // Check identical tracks in input
900  if(std::find(tracksJX.cbegin(), tracksJX.cend(), V01vtx->trackParticle(0)) != tracksJX.cend()) return result;
901  if(std::find(tracksJX.cbegin(), tracksJX.cend(), V01vtx->trackParticle(1)) != tracksJX.cend()) return result;
902  if(std::find(tracksJX.cbegin(), tracksJX.cend(), V02vtx->trackParticle(0)) != tracksJX.cend()) return result;
903  if(std::find(tracksJX.cbegin(), tracksJX.cend(), V02vtx->trackParticle(1)) != tracksJX.cend()) return result;
904 
905  std::vector<const xAOD::TrackParticle*> tracksV01;
906  for(size_t j=0; j<V01vtx->nTrackParticles(); j++) tracksV01.push_back(V01vtx->trackParticle(j));
907  if(std::find(tracksV01.cbegin(), tracksV01.cend(), V02vtx->trackParticle(0)) != tracksV01.cend()) return result;
908  if(std::find(tracksV01.cbegin(), tracksV01.cend(), V02vtx->trackParticle(1)) != tracksV01.cend()) return result;
909  std::vector<const xAOD::TrackParticle*> tracksV02;
910  for(size_t j=0; j<V02vtx->nTrackParticles(); j++) tracksV02.push_back(V02vtx->trackParticle(j));
911 
912  std::vector<double> massesV01;
913  if(V01==LAMBDA) massesV01 = std::vector<double>{m_mass_proton,m_mass_pion};
914  else if(V01==LAMBDABAR) massesV01 = std::vector<double>{m_mass_pion,m_mass_proton};
915  else if(V01==KS) massesV01 = std::vector<double>{m_mass_pion,m_mass_pion};
916  std::vector<double> massesV02;
917  if(V02==LAMBDA) massesV02 = std::vector<double>{m_mass_proton,m_mass_pion};
918  else if(V02==LAMBDABAR) massesV02 = std::vector<double>{m_mass_pion,m_mass_proton};
919  else if(V02==KS) massesV02 = std::vector<double>{m_mass_pion,m_mass_pion};
920 
921  TLorentzVector p4_moth, tmp;
922  for(size_t it=0; it<JXvtx->nTrackParticles(); it++) {
923  tmp.SetPtEtaPhiM(JXvtx->trackParticle(it)->pt(), JXvtx->trackParticle(it)->eta(), JXvtx->trackParticle(it)->phi(), massesJX[it]);
924  p4_moth += tmp;
925  }
926  xAOD::BPhysHelper V01_helper(V01vtx);
927  for(int it=0; it<V01_helper.nRefTrks(); it++) {
928  p4_moth += V01_helper.refTrk(it,massesV01[it]);
929  }
930  xAOD::BPhysHelper V02_helper(V02vtx);
931  for(int it=0; it<V02_helper.nRefTrks(); it++) {
932  p4_moth += V02_helper.refTrk(it,massesV02[it]);
933  }
934  if (p4_moth.M() < m_MassLower || p4_moth.M() > m_MassUpper) return result;
935 
936  std::vector<const xAOD::TrackParticle*> tracksJpsi;
937  tracksJpsi.push_back(tracksJX[0]);
938  tracksJpsi.push_back(tracksJX[1]);
939  std::vector<const xAOD::TrackParticle*> tracksX;
940  if(m_jxDaug_num>=3) tracksX.push_back(tracksJX[2]);
941  if(m_jxDaug_num==4) tracksX.push_back(tracksJX[3]);
942 
943  std::vector<float> trk_px;
944  std::vector<float> trk_py;
945  std::vector<float> trk_pz;
946 
947  // Apply the user's settings to the fitter
948  std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
949  // Robustness: http://cdsweb.cern.ch/record/685551
950  int robustness = 0;
951  m_iVertexFitter->setRobustness(robustness, *state);
952  // Build up the topology
953  // Vertex list
954  std::vector<Trk::VertexID> vrtList;
955  // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/IVertexCascadeFitter.h
956  // V01 vertex
957  Trk::VertexID vID1;
958  if (m_constrV01) {
959  vID1 = m_iVertexFitter->startVertex(tracksV01,massesV01,*state,m_V01Hypothesis=="Ks" ? m_mass_Ks : m_mass_Lambda);
960  } else {
961  vID1 = m_iVertexFitter->startVertex(tracksV01,massesV01,*state);
962  }
963  vrtList.push_back(vID1);
964  // V02 vertex
965  Trk::VertexID vID2;
966  if (m_constrV02) {
967  vID2 = m_iVertexFitter->nextVertex(tracksV02,massesV02,*state,m_V02Hypothesis=="Ks" ? m_mass_Ks : m_mass_Lambda);
968  } else {
969  vID2 = m_iVertexFitter->nextVertex(tracksV02,massesV02,*state);
970  }
971  vrtList.push_back(vID2);
972  Trk::VertexID vID3;
973  if(m_JXSubVtx) {
974  if(m_JXV02SubVtx) {
975  // JX+V02 vertex
976  std::vector<Trk::VertexID> vrtList1{vID1};
977  std::vector<Trk::VertexID> vrtList2{vID2};
978  if (m_constrJXV02) {
979  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state,m_massJXV02);
980  } else {
981  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state);
982  }
983  vrtList1.push_back(vID3);
984  // Mother vertex including JX and two V0's
985  std::vector<const xAOD::TrackParticle*> tp; tp.clear();
986  std::vector<double> tp_masses; tp_masses.clear();
987  if(m_constrMainV) {
988  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList1,*state,m_massMainV);
989  } else {
990  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList1,*state);
991  }
992  }
993  else { // no JXV02SubVtx
994  // JX vertex
995  if (m_constrJX && m_jxDaug_num>2) {
996  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state,m_massJX);
997  } else {
998  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
999  }
1000  vrtList.push_back(vID3);
1001  // Mother vertex including JX and two V0's
1002  std::vector<const xAOD::TrackParticle*> tp; tp.clear();
1003  std::vector<double> tp_masses; tp_masses.clear();
1004  if(m_constrMainV) {
1005  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList,*state,m_massMainV);
1006  } else {
1007  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList,*state);
1008  }
1009  }
1010  }
1011  else { // m_JXSubVtx=false
1012  // Mother vertex including JX and two V0's
1013  if(m_constrMainV) {
1014  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
1015  } else {
1016  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
1017  }
1018  if (m_constrJX && m_jxDaug_num>2) {
1019  std::vector<Trk::VertexID> cnstV; cnstV.clear();
1020  if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
1021  ATH_MSG_WARNING("addMassConstraint for JX failed");
1022  }
1023  }
1024  }
1025  if (m_constrJpsi) {
1026  std::vector<Trk::VertexID> cnstV; cnstV.clear();
1027  if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
1028  ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
1029  }
1030  }
1031  if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
1032  std::vector<Trk::VertexID> cnstV; cnstV.clear();
1033  if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
1034  ATH_MSG_WARNING("addMassConstraint for X failed");
1035  }
1036  }
1037  // Do the work
1038  std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
1039 
1040  if (fit_result != nullptr) {
1041  for(auto v : fit_result->vertices()) {
1042  if(v->nTrackParticles()==0) {
1043  std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
1044  v->setTrackParticleLinks(nullLinkVector);
1045  }
1046  }
1047  // reset links to original tracks
1048  BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackContainer);
1049 
1050  // necessary to prevent memory leak
1051  fit_result->setSVOwnership(true);
1052 
1053  // Chi2/DOF cut
1054  double chi2DOF = fit_result->fitChi2()/fit_result->nDoF();
1055  bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
1056 
1057  const std::vector<std::vector<TLorentzVector> > &moms = fit_result->getParticleMoms();
1058  const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->vertices();
1059  size_t iMoth = cascadeVertices.size()-1;
1060  double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
1061  double lxy_SV2 = (m_JXSubVtx && m_JXV02SubVtx) ? m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[2]) : m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[iMoth]);
1062  if(chi2CutPassed && lxy_SV1>m_lxyV01_cut && lxy_SV2>m_lxyV02_cut) {
1063  SG::AuxElement::Decorator<float> chi2_V1_decor("ChiSquared_V1");
1064  SG::AuxElement::Decorator<int> ndof_V1_decor("nDoF_V1");
1065  SG::AuxElement::Decorator<std::string> type_V1_decor("Type_V1");
1066  SG::AuxElement::Decorator<float> chi2_V2_decor("ChiSquared_V2");
1067  SG::AuxElement::Decorator<int> ndof_V2_decor("nDoF_V2");
1068  SG::AuxElement::Decorator<std::string> type_V2_decor("Type_V2");
1069 
1070  SG::AuxElement::Accessor<int> mAcc_gfit("gamma_fit");
1071  SG::AuxElement::Accessor<float> mAcc_gmass("gamma_mass");
1072  SG::AuxElement::Accessor<float> mAcc_gmasserr("gamma_massError");
1073  SG::AuxElement::Accessor<float> mAcc_gchisq("gamma_chisq");
1074  SG::AuxElement::Accessor<int> mAcc_gndof("gamma_ndof");
1075  SG::AuxElement::Accessor<float> mAcc_gprob("gamma_probability");
1076  SG::AuxElement::Accessor< std::vector<float> > trk_pxAcc("TrackPx_V0nc");
1077  SG::AuxElement::Accessor< std::vector<float> > trk_pyAcc("TrackPy_V0nc");
1078  SG::AuxElement::Accessor< std::vector<float> > trk_pzAcc("TrackPz_V0nc");
1079 
1080  SG::AuxElement::Decorator<int> mDec_gfit("gamma_fit");
1081  SG::AuxElement::Decorator<float> mDec_gmass("gamma_mass");
1082  SG::AuxElement::Decorator<float> mDec_gmasserr("gamma_massError");
1083  SG::AuxElement::Decorator<float> mDec_gchisq("gamma_chisq");
1084  SG::AuxElement::Decorator<int> mDec_gndof("gamma_ndof");
1085  SG::AuxElement::Decorator<float> mDec_gprob("gamma_probability");
1086  SG::AuxElement::Decorator< std::vector<float> > trk_pxDeco("TrackPx_V0nc");
1087  SG::AuxElement::Decorator< std::vector<float> > trk_pyDeco("TrackPy_V0nc");
1088  SG::AuxElement::Decorator< std::vector<float> > trk_pzDeco("TrackPz_V0nc");
1089 
1090  chi2_V1_decor(*cascadeVertices[0]) = V01vtx->chiSquared();
1091  ndof_V1_decor(*cascadeVertices[0]) = V01vtx->numberDoF();
1092  if(V01==LAMBDA) type_V1_decor(*cascadeVertices[0]) = "Lambda";
1093  else if(V01==LAMBDABAR) type_V1_decor(*cascadeVertices[0]) = "Lambdabar";
1094  else if(V01==KS) type_V1_decor(*cascadeVertices[0]) = "Ks";
1095  mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*V01vtx) ? mAcc_gfit(*V01vtx) : 0;
1096  mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*V01vtx) ? mAcc_gmass(*V01vtx) : -1;
1097  mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*V01vtx) ? mAcc_gmasserr(*V01vtx) : -1;
1098  mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*V01vtx) ? mAcc_gchisq(*V01vtx) : 999999;
1099  mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*V01vtx) ? mAcc_gndof(*V01vtx) : 0;
1100  mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*V01vtx) ? mAcc_gprob(*V01vtx) : -1;
1101  trk_px.clear(); trk_py.clear(); trk_pz.clear();
1102  if(trk_pxAcc.isAvailable(*V01vtx)) trk_px = trk_pxAcc(*V01vtx);
1103  if(trk_pyAcc.isAvailable(*V01vtx)) trk_py = trk_pyAcc(*V01vtx);
1104  if(trk_pzAcc.isAvailable(*V01vtx)) trk_pz = trk_pzAcc(*V01vtx);
1105  trk_pxDeco(*cascadeVertices[0]) = trk_px;
1106  trk_pyDeco(*cascadeVertices[0]) = trk_py;
1107  trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1108 
1109  chi2_V2_decor(*cascadeVertices[1]) = V02vtx->chiSquared();
1110  ndof_V2_decor(*cascadeVertices[1]) = V02vtx->numberDoF();
1111  if(V02==LAMBDA) type_V2_decor(*cascadeVertices[1]) = "Lambda";
1112  else if(V02==LAMBDABAR) type_V2_decor(*cascadeVertices[1]) = "Lambdabar";
1113  else if(V02==KS) type_V2_decor(*cascadeVertices[1]) = "Ks";
1114  mDec_gfit(*cascadeVertices[1]) = mAcc_gfit.isAvailable(*V02vtx) ? mAcc_gfit(*V02vtx) : 0;
1115  mDec_gmass(*cascadeVertices[1]) = mAcc_gmass.isAvailable(*V02vtx) ? mAcc_gmass(*V02vtx) : -1;
1116  mDec_gmasserr(*cascadeVertices[1]) = mAcc_gmasserr.isAvailable(*V02vtx) ? mAcc_gmasserr(*V02vtx) : -1;
1117  mDec_gchisq(*cascadeVertices[1]) = mAcc_gchisq.isAvailable(*V02vtx) ? mAcc_gchisq(*V02vtx) : 999999;
1118  mDec_gndof(*cascadeVertices[1]) = mAcc_gndof.isAvailable(*V02vtx) ? mAcc_gndof(*V02vtx) : 0;
1119  mDec_gprob(*cascadeVertices[1]) = mAcc_gprob.isAvailable(*V02vtx) ? mAcc_gprob(*V02vtx) : -1;
1120  trk_px.clear(); trk_py.clear(); trk_pz.clear();
1121  if(trk_pxAcc.isAvailable(*V02vtx)) trk_px = trk_pxAcc(*V02vtx);
1122  if(trk_pyAcc.isAvailable(*V02vtx)) trk_py = trk_pyAcc(*V02vtx);
1123  if(trk_pzAcc.isAvailable(*V02vtx)) trk_pz = trk_pzAcc(*V02vtx);
1124  trk_pxDeco(*cascadeVertices[1]) = trk_px;
1125  trk_pyDeco(*cascadeVertices[1]) = trk_py;
1126  trk_pzDeco(*cascadeVertices[1]) = trk_pz;
1127 
1128  result = fit_result.release();
1129  }
1130  }
1131 
1132  return result;
1133  }
1134 
1135  template<size_t NTracks>
1137  for (const xAOD::Vertex* v1 : *cont) {
1138  assert(v1->nTrackParticles() == NTracks);
1139  std::array<const xAOD::TrackParticle*, NTracks> a1;
1140  std::array<const xAOD::TrackParticle*, NTracks> a2;
1141  for(size_t i=0; i<NTracks; i++){
1142  a1[i] = v1->trackParticle(i);
1143  a2[i] = v->trackParticle(i);
1144  }
1145  std::sort(a1.begin(), a1.end());
1146  std::sort(a2.begin(), a2.end());
1147  if(a1 == a2) return v1;
1148  }
1149  return nullptr;
1150  }
1151 
1152  template<size_t NTracks>
1153  const xAOD::Vertex* JpsiXPlus2V0::FindVertex(std::vector<const xAOD::VertexContainer*> containers, const xAOD::Vertex* v) const {
1154  for (const xAOD::VertexContainer* cont : containers) {
1155  const xAOD::Vertex* vtx = FindVertex<NTracks>(cont, v);
1156  if(vtx) return vtx;
1157  }
1158  return nullptr;
1159  }
1160 }
xAOD::BPhysHypoHelper::setMass
bool setMass(const float val)
Set given invariant mass and its error.
Definition: BPhysHypoHelper.cxx:49
xAOD::TrackParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TrackParticle_v1.cxx:73
Trk::VxSecVertexInfo::setSVOwnership
void setSVOwnership(bool Ownership)
Definition: VxSecVertexInfo.h:118
RecVertex.h
DerivationFramework::JpsiXPlus2V0::V0Enum
V0Enum
Definition: JpsiXPlus2V0.h:40
DerivationFramework::JpsiXPlus2V0::UNKNOWN
@ UNKNOWN
Definition: JpsiXPlus2V0.h:40
Trk::py
@ py
Definition: ParamDefs.h:66
V0Tools.h
DerivationFramework::JpsiXPlus2V0::m_constrMainV
bool m_constrMainV
Definition: JpsiXPlus2V0.h:100
DerivationFramework::JpsiXPlus2V0::m_diTrackMassLower
double m_diTrackMassLower
Definition: JpsiXPlus2V0.h:68
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DerivationFramework::JpsiXPlus2V0::m_VxPrimaryCandidateName
SG::ReadHandleKey< xAOD::VertexContainer > m_VxPrimaryCandidateName
Definition: JpsiXPlus2V0.h:59
DerivationFramework::JpsiXPlus2V0::m_V02MassUpper
double m_V02MassUpper
Definition: JpsiXPlus2V0.h:76
DerivationFramework::JpsiXPlus2V0::m_constrJX
bool m_constrJX
Definition: JpsiXPlus2V0.h:94
get_generator_info.result
result
Definition: get_generator_info.py:21
xAOD::Vertex_v1::nTrackParticles
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
Definition: Vertex_v1.cxx:270
xAOD::BPhysHelper
Definition: BPhysHelper.h:71
Trk::VxCascadeInfo
Definition: VxCascadeInfo.h:75
DerivationFramework::JpsiXPlus2V0::m_cascadeOutputKeys
SG::WriteHandleKeyArray< xAOD::VertexContainer > m_cascadeOutputKeys
Definition: JpsiXPlus2V0.h:54
DerivationFramework::JpsiXPlus2V0::LAMBDA
@ LAMBDA
Definition: JpsiXPlus2V0.h:40
DerivationFramework::JpsiXPlus2V0::m_chi2cut_gamma
double m_chi2cut_gamma
Definition: JpsiXPlus2V0.h:81
DerivationFramework::JpsiXPlus2V0::m_refitPV
bool m_refitPV
Definition: JpsiXPlus2V0.h:117
DerivationFramework::JpsiXPlus2V0::m_constrV01
bool m_constrV01
Definition: JpsiXPlus2V0.h:97
xAOD::BPhysHelper::nRefTrks
int nRefTrks()
Returns number of stored refitted track momenta.
Definition: BPhysHelper.cxx:115
Trk::VertexID
int VertexID
Definition: IVertexCascadeFitter.h:23
TrigCompositeUtils::passed
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
Definition: TrigCompositeUtilsRoot.cxx:117
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
VertexPointEstimator.h
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
DerivationFramework::JpsiXPlus2V0::m_iV0Fitter
ToolHandle< Trk::TrkV0VertexFitter > m_iV0Fitter
Definition: JpsiXPlus2V0.h:111
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:66
DerivationFramework::JpsiXPlus2V0::m_mass_Bpm
double m_mass_Bpm
Definition: JpsiXPlus2V0.h:129
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
DerivationFramework::JpsiXPlus2V0::m_pvRefitter
ToolHandle< Analysis::PrimaryVertexRefitter > m_pvRefitter
Definition: JpsiXPlus2V0.h:113
xAOD::TrackParticle_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: TrackParticle_v1.cxx:77
DerivationFramework::JpsiXPlus2V0::m_MassUpper
double m_MassUpper
Definition: JpsiXPlus2V0.h:83
DerivationFramework::BPhysPVCascadeTools::getParticleMass
static double getParticleMass(const HepPDT::ParticleDataTable *pdt, int pdg)
Definition: BPhysPVCascadeTools.cxx:491
Trk::VxSecVertexInfo::vertices
const std::vector< xAOD::Vertex * > & vertices() const
Definition: VxSecVertexInfo.cxx:100
DerivationFramework::JpsiXPlus2V0::m_V01Hypothesis
std::string m_V01Hypothesis
Definition: JpsiXPlus2V0.h:70
skel.it
it
Definition: skel.GENtoEVGEN.py:423
DerivationFramework::JpsiXPlus2V0::m_TrkParticleCollection
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_TrkParticleCollection
Definition: JpsiXPlus2V0.h:58
DerivationFramework::JpsiXPlus2V0::m_chi2cut_V0
double m_chi2cut_V0
Definition: JpsiXPlus2V0.h:104
ParticleTest.tp
tp
Definition: ParticleTest.py:25
DerivationFramework::JpsiXPlus2V0::m_jpsiMassUpper
double m_jpsiMassUpper
Definition: JpsiXPlus2V0.h:67
DerivationFramework::JpsiXPlus2V0::m_doV0Enum
bool m_doV0Enum
Definition: JpsiXPlus2V0.h:78
DerivationFramework::JpsiXPlus2V0::m_PV_minNTracks
size_t m_PV_minNTracks
Definition: JpsiXPlus2V0.h:119
DerivationFramework::JpsiXPlus2V0::KS
@ KS
Definition: JpsiXPlus2V0.h:40
DerivationFramework::JpsiXPlus2V0::m_iVertexFitter
ToolHandle< Trk::TrkVKalVrtFitter > m_iVertexFitter
Definition: JpsiXPlus2V0.h:110
DerivationFramework::JpsiXPlus2V0::m_V02Hypothesis
std::string m_V02Hypothesis
Definition: JpsiXPlus2V0.h:74
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
DerivationFramework::JpsiXPlus2V0::m_PV_max
int m_PV_max
Definition: JpsiXPlus2V0.h:118
isValid
bool isValid(const T &p)
Definition: AtlasPID.h:214
SG::ReadHandleKey
Property holding a SG store/key/clid from which a ReadHandle is made.
Definition: StoreGate/StoreGate/ReadHandleKey.h:39
Trk::VxCascadeInfo::nDoF
int nDoF() const
Definition: VxCascadeInfo.h:133
DerivationFramework::JpsiXPlus2V0::m_chi2cut
double m_chi2cut
Definition: JpsiXPlus2V0.h:105
Trk::pz
@ pz
global momentum (cartesian)
Definition: ParamDefs.h:67
DerivationFramework::JpsiXPlus2V0::m_jxDaug2MassHypo
double m_jxDaug2MassHypo
Definition: JpsiXPlus2V0.h:86
DerivationFramework::JpsiXPlus2V0::m_jxDaug_num
int m_jxDaug_num
Definition: JpsiXPlus2V0.h:84
DerivationFramework::JpsiXPlus2V0::m_jxDaug3MassHypo
double m_jxDaug3MassHypo
Definition: JpsiXPlus2V0.h:87
DerivationFramework::JpsiXPlus2V0::m_mass_e
double m_mass_e
Definition: JpsiXPlus2V0.h:122
TrkVKalVrtFitter.h
DerivationFramework::JpsiXPlus2V0::m_lxyV02_cut
double m_lxyV02_cut
Definition: JpsiXPlus2V0.h:77
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:112
DerivationFramework::JpsiXPlus2V0::m_massX
double m_massX
Definition: JpsiXPlus2V0.h:91
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
DerivationFramework::JpsiXPlus2V0::m_iGammaFitter
ToolHandle< Trk::IVertexFitter > m_iGammaFitter
Definition: JpsiXPlus2V0.h:112
DerivationFramework::JpsiXPlus2V0::m_constrV02
bool m_constrV02
Definition: JpsiXPlus2V0.h:98
xAOD::Vertex_v1::addTrackAtVertex
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
Definition: Vertex_v1.cxx:314
V0Container
Definition: V0Container.h:22
xAOD::BPhysHypoHelper
Definition: BPhysHypoHelper.h:73
DerivationFramework::BPhysPVCascadeTools::SetVectorInfo
static void SetVectorInfo(xAOD::BPhysHelper &, const Trk::VxCascadeInfo *)
Definition: BPhysPVCascadeTools.cxx:424
BPHYS_CHECK
#define BPHYS_CHECK(EXP)
Useful CHECK macro.
Definition: BPhysHelper.h:738
DerivationFramework::JpsiXPlus2V0::m_refPVContainerName
SG::WriteHandleKey< xAOD::VertexContainer > m_refPVContainerName
Definition: JpsiXPlus2V0.h:60
JpsiXPlus2V0.h
DerivationFramework::JpsiXPlus2V0::m_v0VtxOutputKeys
SG::WriteHandleKeyArray< xAOD::VertexContainer > m_v0VtxOutputKeys
Definition: JpsiXPlus2V0.h:57
DerivationFramework::JpsiXPlus2V0::m_mass_mu
double m_mass_mu
Definition: JpsiXPlus2V0.h:123
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::WriteHandleKey
Property holding a SG store/key/clid from which a WriteHandle is made.
Definition: StoreGate/StoreGate/WriteHandleKey.h:40
DerivationFramework::JpsiXPlus2V0::m_mass_Ks
double m_mass_Ks
Definition: JpsiXPlus2V0.h:128
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:58
IsoCloseByCorrectionTest.containers
containers
Associate the close-by pflow objects and the calorimeter clusters.
Definition: IsoCloseByCorrectionTest.py:82
DerivationFramework::JpsiXPlus2V0::m_CascadeTools
ToolHandle< DerivationFramework::CascadeTools > m_CascadeTools
Definition: JpsiXPlus2V0.h:115
lumiFormat.i
int i
Definition: lumiFormat.py:92
DerivationFramework::JpsiXPlus2V0::m_minMass_gamma
double m_minMass_gamma
Definition: JpsiXPlus2V0.h:80
xAOD::BPhysHypoHelper::setPass
bool setPass(bool passVal)
get the pass flag for this hypothesis
Definition: BPhysHypoHelper.cxx:364
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
BPhysHypoHelper.h
: B-physcis xAOD helpers.
Trk::VxCascadeInfo::fitChi2
double fitChi2() const
Definition: VxCascadeInfo.h:134
DerivationFramework::JpsiXPlus2V0::m_JXSubVtx
bool m_JXSubVtx
Definition: JpsiXPlus2V0.h:101
DerivationFramework::JpsiXPlus2V0::m_massMainV
double m_massMainV
Definition: JpsiXPlus2V0.h:93
Trk::px
@ px
Definition: ParamDefs.h:65
test_pyathena.parent
parent
Definition: test_pyathena.py:15
DerivationFramework::BPhysPVCascadeTools::PrepareVertexLinks
static void PrepareVertexLinks(Trk::VxCascadeInfo *result, const xAOD::TrackParticleContainer *importedTrackCollection)
Definition: BPhysPVCascadeTools.cxx:204
DerivationFramework::JpsiXPlus2V0::m_constrX
bool m_constrX
Definition: JpsiXPlus2V0.h:96
MUON
xAOD::Muon MUON
D3PD INCLUDES.
Definition: TileCellFillerTool.h:37
DerivationFramework::JpsiXPlus2V0::m_constrJXV02
bool m_constrJXV02
Definition: JpsiXPlus2V0.h:99
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DerivationFramework::JpsiXPlus2V0::m_lxyV01_cut
double m_lxyV01_cut
Definition: JpsiXPlus2V0.h:73
DerivationFramework::JpsiXPlus2V0::m_V01MassUpper
double m_V01MassUpper
Definition: JpsiXPlus2V0.h:72
DerivationFramework::JpsiXPlus2V0::m_hypoName
std::string m_hypoName
Definition: JpsiXPlus2V0.h:62
DerivationFramework::JpsiXPlus2V0::JpsiXPlus2V0
JpsiXPlus2V0(const std::string &type, const std::string &name, const IInterface *parent)
Definition: JpsiXPlus2V0.cxx:26
DerivationFramework::JpsiXPlus2V0::LAMBDABAR
@ LAMBDABAR
Definition: JpsiXPlus2V0.h:40
xAOD::Vertex_v1::trackParticle
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
Definition: Vertex_v1.cxx:249
xAOD::Vertex_v1::clearTracks
void clearTracks()
Remove all tracks from the vertex.
Definition: Vertex_v1.cxx:331
Trk::ParametersBase
Definition: ParametersBase.h:55
DerivationFramework
THE reconstruction tool.
Definition: ParticleSortingAlg.h:24
DerivationFramework::JpsiXPlus2V0::m_massJXV02
double m_massJXV02
Definition: JpsiXPlus2V0.h:92
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DerivationFramework::VertexLink
ElementLink< xAOD::VertexContainer > VertexLink
Definition: Cascade3Plus1.cxx:23
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
BPhysPVCascadeTools.h
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
DerivationFramework::JpsiXPlus2V0::m_massJpsi
double m_massJpsi
Definition: JpsiXPlus2V0.h:90
grepfile.ic
int ic
Definition: grepfile.py:33
DerivationFramework::JpsiXPlus2V0::m_diTrackMassUpper
double m_diTrackMassUpper
Definition: JpsiXPlus2V0.h:69
DerivationFramework::JpsiXPlus2V0::m_vertexJXHypoNames
std::vector< std::string > m_vertexJXHypoNames
Definition: JpsiXPlus2V0.h:52
DerivationFramework::JpsiXPlus2V0::m_maxV0Candidates
unsigned int m_maxV0Candidates
Definition: JpsiXPlus2V0.h:107
DerivationFramework::JpsiXPlus2V0::m_vertexJXContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexJXContainerKey
Definition: JpsiXPlus2V0.h:50
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
pmontree.opt
opt
Definition: pmontree.py:16
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
DerivationFramework::JpsiXPlus2V0::fitMainVtx
Trk::VxCascadeInfo * fitMainVtx(const xAOD::Vertex *JXvtx, std::vector< double > &massesJX, const xAOD::Vertex *V01vtx, const V0Enum V01, const xAOD::Vertex *V02vtx, const V0Enum V02, const xAOD::TrackParticleContainer *trackContainer) const
Definition: JpsiXPlus2V0.cxx:889
DerivationFramework::BPhysPVCascadeTools
Definition: BPhysPVCascadeTools.h:34
DerivationFramework::JpsiXPlus2V0::initialize
virtual StatusCode initialize() override
Definition: JpsiXPlus2V0.cxx:157
CascadeTools.h
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::VxCascadeInfo::getParticleMoms
const std::vector< std::vector< TLorentzVector > > & getParticleMoms() const
Definition: VxCascadeInfo.h:131
DerivationFramework::JpsiXPlus2V0::m_DoVertexType
int m_DoVertexType
Definition: JpsiXPlus2V0.h:120
IVertexFitter.h
DerivationFramework::JpsiXPlus2V0::m_JXV02SubVtx
bool m_JXV02SubVtx
Definition: JpsiXPlus2V0.h:102
VxCascadeInfo.h
SG::ReadHandle::ptr
const_pointer_type ptr()
Dereference the pointer.
xAOD::Vertex_v1::numberDoF
float numberDoF() const
Returns the number of degrees of freedom of the vertex fit as float.
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
DerivationFramework::JpsiXPlus2V0::m_jxMassUpper
double m_jxMassUpper
Definition: JpsiXPlus2V0.h:65
python.PyAthena.v
v
Definition: PyAthena.py:157
DerivationFramework::JpsiXPlus2V0::FindVertex
const xAOD::Vertex * FindVertex(const xAOD::VertexContainer *cont, const xAOD::Vertex *v) const
Definition: JpsiXPlus2V0.cxx:1136
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
xAOD::BPhysHelper::setRefTrks
bool setRefTrks(std::vector< float > px, std::vector< float > py, std::vector< float > pz)
Sets refitted track momenta.
Definition: BPhysHelper.cxx:286
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
DerivationFramework::VertexLinkVector
std::vector< VertexLink > VertexLinkVector
Definition: Cascade3Plus1.cxx:24
a
TList * a
Definition: liststreamerinfos.cxx:10
xAOD::Vertex_v1::chiSquared
float chiSquared() const
Returns the of the vertex fit as float.
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
xAOD::BPhysHelper::refTrk
TVector3 refTrk(const size_t index)
Returns i-th refitted track 3-momentum.
Definition: BPhysHelper.cxx:126
DerivationFramework::JpsiXPlus2V0::m_maxJXCandidates
unsigned int m_maxJXCandidates
Definition: JpsiXPlus2V0.h:106
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DerivationFramework::JpsiXPlus2V0::m_vertexV0ContainerKeys
SG::ReadHandleKeyArray< xAOD::VertexContainer > m_vertexV0ContainerKeys
Definition: JpsiXPlus2V0.h:51
DerivationFramework::JpsiXPlus2V0::m_refitV0
bool m_refitV0
Definition: JpsiXPlus2V0.h:55
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DerivationFramework::JpsiXPlus2V0::m_mass_proton
double m_mass_proton
Definition: JpsiXPlus2V0.h:125
DerivationFramework::JpsiXPlus2V0::m_massJX
double m_massJX
Definition: JpsiXPlus2V0.h:89
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
DerivationFramework::JpsiXPlus2V0::m_constrV0
bool m_constrV0
Definition: JpsiXPlus2V0.h:56
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
xAOD::Vertex_v1::vxTrackAtVertex
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
Definition: Vertex_v1.cxx:181
AthAlgTool
Definition: AthAlgTool.h:26
DerivationFramework::JpsiXPlus2V0::m_jxDaug1MassHypo
double m_jxDaug1MassHypo
Definition: JpsiXPlus2V0.h:85
DerivationFramework::JpsiXPlus2V0::m_MassLower
double m_MassLower
Definition: JpsiXPlus2V0.h:82
DerivationFramework::JpsiXPlus2V0::performSearch
StatusCode performSearch(std::vector< Trk::VxCascadeInfo * > *cascadeinfoContainer, std::vector< xAOD::VertexContainer * > V0OutputContainers) const
Definition: JpsiXPlus2V0.cxx:233
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
DerivationFramework::JpsiXPlus2V0::m_vertexV0HypoNames
std::vector< std::string > m_vertexV0HypoNames
Definition: JpsiXPlus2V0.h:53
DerivationFramework::JpsiXPlus2V0::addBranches
virtual StatusCode addBranches() const override
Pass the thinning service
Definition: JpsiXPlus2V0.cxx:683
DerivationFramework::JpsiXPlus2V0::m_mass_Lambda_b
double m_mass_Lambda_b
Definition: JpsiXPlus2V0.h:127
DerivationFramework::JpsiXPlus2V0::m_eventInfo_key
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo_key
Definition: JpsiXPlus2V0.h:61
DerivationFramework::JpsiXPlus2V0::m_V0Tools
ToolHandle< Trk::V0Tools > m_V0Tools
Definition: JpsiXPlus2V0.h:114
DerivationFramework::JpsiXPlus2V0::m_constrJpsi
bool m_constrJpsi
Definition: JpsiXPlus2V0.h:95
DerivationFramework::JpsiXPlus2V0::m_maxMainVCandidates
unsigned int m_maxMainVCandidates
Definition: JpsiXPlus2V0.h:108
HepMCHelpers.h
xAOD::BPhysHypoHelper::setMassErr
bool setMassErr(const float val)
invariant mass error
Definition: BPhysHypoHelper.cxx:54
DerivationFramework::JpsiXPlus2V0::m_mass_Lambda
double m_mass_Lambda
Definition: JpsiXPlus2V0.h:126
DerivationFramework::JpsiXPlus2V0::m_mass_pion
double m_mass_pion
Definition: JpsiXPlus2V0.h:124
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
VertexAuxContainer.h
xAOD::TrackParticle_v1::phi
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
DerivationFramework::JpsiXPlus2V0::m_chi2cut_JX
double m_chi2cut_JX
Definition: JpsiXPlus2V0.h:103
DerivationFramework::JpsiXPlus2V0::m_jxDaug4MassHypo
double m_jxDaug4MassHypo
Definition: JpsiXPlus2V0.h:88
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
DerivationFramework::JpsiXPlus2V0::m_decorV0P
bool m_decorV0P
Definition: JpsiXPlus2V0.h:79