Loading [MathJax]/jax/output/SVG/config.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
JpsiXPlus2V0.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3  Contact: Xin Chen <xin.chen@cern.ch>
4 */
16 #include "HepPDT/ParticleDataTable.hh"
17 #include "VxVertex/RecVertex.h"
20 #include <algorithm>
21 #include <functional>
22 
23 namespace DerivationFramework {
25  typedef std::vector<VertexLink> VertexLinkVector;
26 
28 
29  JpsiXPlus2V0::JpsiXPlus2V0(const std::string& type, const std::string& name, const IInterface* parent) : AthAlgTool(type,name,parent),
30  m_vertexJXContainerKey("InputJXVertices"),
31  m_vertexV0ContainerKey{""},
32  m_cascadeOutputKeys({"JpsiXPlus2V0_SubVtx1", "JpsiXPlus2V0_SubVtx2", "JpsiXPlus2V0_SubVtx3", "JpsiXPlus2V0_MainVtx"}),
33  m_v0VtxOutputKey(""),
34  m_TrkParticleCollection("InDetTrackParticles"),
35  m_VxPrimaryCandidateName("PrimaryVertices"),
36  m_refPVContainerName("RefittedPrimaryVertices"),
37  m_eventInfo_key("EventInfo"),
38  m_RelinkContainers({"InDetTrackParticles","InDetLargeD0TrackParticles"}),
39  m_useImprovedMass(false),
40  m_jxMassLower(0.0),
41  m_jxMassUpper(30000.0),
42  m_jpsiMassLower(0.0),
43  m_jpsiMassUpper(20000.0),
44  m_diTrackMassLower(-1.0),
45  m_diTrackMassUpper(-1.0),
46  m_V01Hypothesis("Ks"),
47  m_V02Hypothesis("Lambda"),
48  m_LambdaMassLower(0.0),
49  m_LambdaMassUpper(10000.0),
50  m_KsMassLower(0.0),
51  m_KsMassUpper(10000.0),
52  m_lxyV01_cut(-999.0),
53  m_lxyV02_cut(-999.0),
54  m_minMass_gamma(-1.0),
55  m_chi2cut_gamma(-1.0),
56  m_JXV02MassLower(0.0),
57  m_JXV02MassUpper(30000.0),
58  m_MassLower(0.0),
59  m_MassUpper(31000.0),
60  m_jxDaug_num(4),
61  m_jxDaug1MassHypo(-1),
62  m_jxDaug2MassHypo(-1),
63  m_jxDaug3MassHypo(-1),
64  m_jxDaug4MassHypo(-1),
65  m_massJX(-1),
66  m_massJpsi(-1),
67  m_massX(-1),
68  m_massLd(-1),
69  m_massKs(-1),
70  m_massJXV02(-1),
71  m_massMainV(-1),
72  m_constrJX(false),
73  m_constrJpsi(false),
74  m_constrX(false),
75  m_constrV01(false),
76  m_constrV02(false),
77  m_constrJXV02(false),
78  m_constrMainV(false),
79  m_JXSubVtx(false),
80  m_JXV02SubVtx(false),
81  m_chi2cut_JX(-1.0),
82  m_chi2cut_V0(-1.0),
83  m_chi2cut(-1.0),
84  m_useTRT(false),
85  m_ptTRT(450),
86  m_d0_cut(2),
87  m_maxJXCandidates(0),
88  m_maxV0Candidates(0),
89  m_maxMainVCandidates(0),
90  m_iVertexFitter("Trk::TrkVKalVrtFitter"),
91  m_iV0Fitter("Trk::V0VertexFitter"),
92  m_iGammaFitter("Trk::TrkVKalVrtFitter"),
93  m_pvRefitter("Analysis::PrimaryVertexRefitter", this),
94  m_V0Tools("Trk::V0Tools"),
95  m_trackToVertexTool("Reco::TrackToVertex"),
96  m_v0TrkSelector("InDet::TrackSelectorTool"),
97  m_CascadeTools("DerivationFramework::CascadeTools"),
98  m_vertexEstimator("InDet::VertexPointEstimator"),
99  m_extrapolator("Trk::Extrapolator/AtlasExtrapolator")
100  {
101  declareProperty("JXVertices", m_vertexJXContainerKey);
102  declareProperty("V0Vertices", m_vertexV0ContainerKey);
103  declareProperty("JXVtxHypoNames", m_vertexJXHypoNames);
104  declareProperty("CascadeVertexCollections", m_cascadeOutputKeys); // size is 3 or 4 only
105  declareProperty("OutoutV0VtxCollection", m_v0VtxOutputKey);
106  declareProperty("TrackParticleCollection", m_TrkParticleCollection);
107  declareProperty("VxPrimaryCandidateName", m_VxPrimaryCandidateName);
108  declareProperty("RefPVContainerName", m_refPVContainerName);
109  declareProperty("EventInfoKey", m_eventInfo_key);
110  declareProperty("RelinkTracks", m_RelinkContainers);
111  declareProperty("UseImprovedMass", m_useImprovedMass);
112  declareProperty("JXMassLowerCut", m_jxMassLower); // only effective when m_jxDaug_num>2
113  declareProperty("JXMassUpperCut", m_jxMassUpper); // only effective when m_jxDaug_num>2
114  declareProperty("JpsiMassLowerCut", m_jpsiMassLower);
115  declareProperty("JpsiMassUpperCut", m_jpsiMassUpper);
116  declareProperty("DiTrackMassLower", m_diTrackMassLower); // only effective when m_jxDaug_num=4
117  declareProperty("DiTrackMassUpper", m_diTrackMassUpper); // only effective when m_jxDaug_num=4
118  declareProperty("V01Hypothesis", m_V01Hypothesis); // "Ks", "Lambda" or "Lambda/Ks"
119  declareProperty("V02Hypothesis", m_V02Hypothesis); // "Ks", "Lambda" or "Lambda/Ks"
120  declareProperty("LxyV01Cut", m_lxyV01_cut);
121  declareProperty("LxyV02Cut", m_lxyV02_cut);
122  declareProperty("LambdaMassLowerCut", m_LambdaMassLower);
123  declareProperty("LambdaMassUpperCut", m_LambdaMassUpper);
124  declareProperty("KsMassLowerCut", m_KsMassLower);
125  declareProperty("KsMassUpperCut", m_KsMassUpper);
126  declareProperty("MassCutGamma", m_minMass_gamma);
127  declareProperty("Chi2CutGamma", m_chi2cut_gamma);
128  declareProperty("JXV02MassLowerCut", m_JXV02MassLower); // only effective when m_JXSubVtx=true & m_JXV02SubVtx=true
129  declareProperty("JXV02MassUpperCut", m_JXV02MassUpper); // only effective when m_JXSubVtx=true & m_JXV02SubVtx=true
130  declareProperty("MassLowerCut", m_MassLower);
131  declareProperty("MassUpperCut", m_MassUpper);
132  declareProperty("HypothesisName", m_hypoName = "TQ");
133  declareProperty("NumberOfJXDaughters", m_jxDaug_num); // 2, or 3, or 4 only
134  declareProperty("JXDaug1MassHypo", m_jxDaug1MassHypo);
135  declareProperty("JXDaug2MassHypo", m_jxDaug2MassHypo);
136  declareProperty("JXDaug3MassHypo", m_jxDaug3MassHypo);
137  declareProperty("JXDaug4MassHypo", m_jxDaug4MassHypo);
138  declareProperty("JXMass", m_massJX); // only effective when m_jxDaug_num>2
139  declareProperty("JpsiMass", m_massJpsi);
140  declareProperty("XMass", m_massX); // only effective when m_jxDaug_num=4
141  declareProperty("LambdaMass", m_massLd);
142  declareProperty("KsMass", m_massKs);
143  declareProperty("JXV02VtxMass", m_massJXV02); // mass of JX + 2nd V0
144  declareProperty("MainVtxMass", m_massMainV);
145  declareProperty("ApplyJXMassConstraint", m_constrJX); // only effective when m_jxDaug_num>2
146  declareProperty("ApplyJpsiMassConstraint", m_constrJpsi);
147  declareProperty("ApplyXMassConstraint", m_constrX); // only effective when m_jxDaug_num=4
148  declareProperty("ApplyV01MassConstraint", m_constrV01); // first V0
149  declareProperty("ApplyV02MassConstraint", m_constrV02); // second V0
150  declareProperty("ApplyJXV02MassConstraint", m_constrJXV02); // constrain JX + 2nd V0
151  declareProperty("ApplyMainVMassConstraint", m_constrMainV);
152  declareProperty("HasJXSubVertex", m_JXSubVtx);
153  declareProperty("HasJXV02SubVertex", m_JXV02SubVtx); // only effective when m_JXSubVtx=true
154  declareProperty("Chi2CutJX", m_chi2cut_JX);
155  declareProperty("Chi2CutV0", m_chi2cut_V0);
156  declareProperty("Chi2Cut", m_chi2cut);
157  declareProperty("UseTRT", m_useTRT);
158  declareProperty("PtTRT", m_ptTRT);
159  declareProperty("Trackd0Cut", m_d0_cut);
160  declareProperty("MaxJXCandidates", m_maxJXCandidates);
161  declareProperty("MaxV0Candidates", m_maxV0Candidates);
162  declareProperty("MaxMainVCandidates", m_maxMainVCandidates);
163  declareProperty("RefitPV", m_refitPV = true);
164  declareProperty("MaxnPV", m_PV_max = 1000);
165  declareProperty("MinNTracksInPV", m_PV_minNTracks = 0);
166  declareProperty("DoVertexType", m_DoVertexType = 7);
167  declareProperty("TrkVertexFitterTool", m_iVertexFitter);
168  declareProperty("V0VertexFitterTool", m_iV0Fitter);
169  declareProperty("GammaFitterTool", m_iGammaFitter);
170  declareProperty("PVRefitter", m_pvRefitter);
171  declareProperty("V0Tools", m_V0Tools);
172  declareProperty("TrackToVertexTool", m_trackToVertexTool);
173  declareProperty("V0TrackSelectorTool", m_v0TrkSelector);
174  declareProperty("CascadeTools", m_CascadeTools);
175  declareProperty("VertexPointEstimator", m_vertexEstimator);
176  declareProperty("Extrapolator", m_extrapolator);
177  }
178 
180  if((m_V01Hypothesis != "Ks" && m_V01Hypothesis != "Lambda" && m_V01Hypothesis != "Lambda/Ks" && m_V01Hypothesis != "Ks/Lambda") ||
181  (m_V02Hypothesis != "Ks" && m_V02Hypothesis != "Lambda" && m_V02Hypothesis != "Lambda/Ks" && m_V02Hypothesis != "Ks/Lambda")) {
182  ATH_MSG_FATAL("Incorrect V0 container hypothesis - not recognized");
183  return StatusCode::FAILURE;
184  }
185 
186  if(m_jxDaug_num<2 || m_jxDaug_num>4) {
187  ATH_MSG_FATAL("Incorrect number of JX daughters");
188  return StatusCode::FAILURE;
189  }
190 
191  if(m_vertexV0ContainerKey.key()=="" && m_v0VtxOutputKey.key()=="") {
192  ATH_MSG_FATAL("Input and output V0 container names can not be both empty");
193  return StatusCode::FAILURE;
194  }
195 
196  // retrieving vertex Fitter
197  ATH_CHECK( m_iVertexFitter.retrieve() );
198 
199  // retrieving V0 vertex Fitter
200  ATH_CHECK( m_iV0Fitter.retrieve() );
201 
202  // retrieving photon conversion vertex Fitter
203  ATH_CHECK( m_iGammaFitter.retrieve() );
204 
205  // retrieving primary vertex refitter
206  ATH_CHECK( m_pvRefitter.retrieve() );
207 
208  // retrieving the V0 tool
209  ATH_CHECK( m_V0Tools.retrieve() );
210 
211  // retrieving the TrackToVertex extrapolator tool
212  ATH_CHECK( m_trackToVertexTool.retrieve() );
213 
214  // retrieving the V0 track selector tool
215  ATH_CHECK( m_v0TrkSelector.retrieve() );
216 
217  // retrieving the Cascade tools
218  ATH_CHECK( m_CascadeTools.retrieve() );
219 
220  // retrieving the vertex point estimator
221  ATH_CHECK( m_vertexEstimator.retrieve() );
222 
223  // retrieving the extrapolator
224  ATH_CHECK( m_extrapolator.retrieve() );
225 
226  ATH_CHECK( m_vertexJXContainerKey.initialize() );
228  ATH_CHECK( m_VxPrimaryCandidateName.initialize() );
230  ATH_CHECK( m_refPVContainerName.initialize() );
231  ATH_CHECK( m_cascadeOutputKeys.initialize() );
233  ATH_CHECK( m_RelinkContainers.initialize() );
235 
236  ATH_CHECK( m_partPropSvc.retrieve() );
237  auto pdt = m_partPropSvc->PDT();
238 
239  // https://gitlab.cern.ch/atlas/athena/-/blob/main/Generators/TruthUtils/TruthUtils/AtlasPID.h
240  m_mass_e = BPhysPVCascadeTools::getParticleMass(pdt, MC::ELECTRON);
249 
250  m_massesV0_ppi.push_back(m_mass_proton);
251  m_massesV0_ppi.push_back(m_mass_pion);
252  m_massesV0_pip.push_back(m_mass_pion);
253  m_massesV0_pip.push_back(m_mass_proton);
254  m_massesV0_pipi.push_back(m_mass_pion);
255  m_massesV0_pipi.push_back(m_mass_pion);
256 
257  // retrieve particle masses
261  if(m_constrV01 || m_constrV02) {
263  if(m_massKs<0) m_massKs = m_mass_Ks;
264  }
267 
272 
273  return StatusCode::SUCCESS;
274  }
275 
276  StatusCode JpsiXPlus2V0::performSearch(std::vector<Trk::VxCascadeInfo*>& cascadeinfoContainer, const std::vector<std::pair<const xAOD::Vertex*,V0Enum> >& selectedV0Candidates) const {
277  ATH_MSG_DEBUG( "JpsiXPlus2V0::performSearch" );
278  if(selectedV0Candidates.size()==0) return StatusCode::SUCCESS;
279 
280  // Get all track containers when m_RelinkContainers is not empty
281  std::vector<const xAOD::TrackParticleContainer*> trackCols;
284  ATH_CHECK( handle.isValid() );
285  trackCols.push_back(handle.cptr());
286  }
287 
288  // Get Jpsi+X container
290  ATH_CHECK( jxContainer.isValid() );
291 
292  std::vector<double> massesJX{m_jxDaug1MassHypo, m_jxDaug2MassHypo};
293  if(m_jxDaug_num>=3) massesJX.push_back(m_jxDaug3MassHypo);
294  if(m_jxDaug_num==4) massesJX.push_back(m_jxDaug4MassHypo);
295 
296  // Select the JX candidates before calling cascade fit
297  std::vector<const xAOD::Vertex*> selectedJXCandidates;
298  for(auto vxcItr=jxContainer.ptr()->begin(); vxcItr!=jxContainer.ptr()->end(); ++vxcItr) {
299  // Check the passed flag first
300  const xAOD::Vertex* vtx = *vxcItr;
301  bool passed = false;
302  for(const std::string& name : m_vertexJXHypoNames) {
303  SG::AuxElement::Accessor<Char_t> flagAcc("passed_"+name);
304  if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
305  passed = true;
306  }
307  }
308  if(m_vertexJXHypoNames.size() && !passed) continue;
309 
310  // Add loose cut on Jpsi mass from e.g. JX -> Jpsi pi+ pi-
311  TLorentzVector p4_mu1, p4_mu2;
312  p4_mu1.SetPtEtaPhiM(vtx->trackParticle(0)->pt(),vtx->trackParticle(0)->eta(),vtx->trackParticle(0)->phi(), m_jxDaug1MassHypo);
313  p4_mu2.SetPtEtaPhiM(vtx->trackParticle(1)->pt(),vtx->trackParticle(1)->eta(),vtx->trackParticle(1)->phi(), m_jxDaug2MassHypo);
314  double mass_jpsi = (p4_mu1 + p4_mu2).M();
315  if (mass_jpsi < m_jpsiMassLower || mass_jpsi > m_jpsiMassUpper) continue;
316 
317  TLorentzVector p4_trk1, p4_trk2;
318  if(m_jxDaug_num>=3) p4_trk1.SetPtEtaPhiM(vtx->trackParticle(2)->pt(),vtx->trackParticle(2)->eta(),vtx->trackParticle(2)->phi(), m_jxDaug3MassHypo);
319  if(m_jxDaug_num==4) p4_trk2.SetPtEtaPhiM(vtx->trackParticle(3)->pt(),vtx->trackParticle(3)->eta(),vtx->trackParticle(3)->phi(), m_jxDaug4MassHypo);
320 
321  if(m_jxDaug_num==3) {
322  double mass_jx = (p4_mu1 + p4_mu2 + p4_trk1).M();
323  if(m_useImprovedMass && m_massJpsi>0) mass_jx += - (p4_mu1 + p4_mu2).M() + m_massJpsi;
324  if(mass_jx < m_jxMassLower || mass_jx > m_jxMassUpper) continue;
325  }
326  else if(m_jxDaug_num==4) {
327  double mass_jx = (p4_mu1 + p4_mu2 + p4_trk1 + p4_trk2).M();
328  if(m_useImprovedMass && m_massJpsi>0) mass_jx += - (p4_mu1 + p4_mu2).M() + m_massJpsi;
329  if(mass_jx < m_jxMassLower || mass_jx > m_jxMassUpper) continue;
330 
332  double mass_diTrk = (p4_trk1 + p4_trk2).M();
333  if(mass_diTrk < m_diTrackMassLower || mass_diTrk > m_diTrackMassUpper) continue;
334  }
335  }
336 
337  double chi2DOF = vtx->chiSquared()/vtx->numberDoF();
338  if(m_chi2cut_JX>0 && chi2DOF>m_chi2cut_JX) continue;
339 
340  selectedJXCandidates.push_back(vtx);
341  }
342  if(selectedJXCandidates.size()==0) return StatusCode::SUCCESS;
343 
344  std::sort( selectedJXCandidates.begin(), selectedJXCandidates.end(), [](const xAOD::Vertex* a, const xAOD::Vertex* b) { return a->chiSquared()/a->numberDoF() < b->chiSquared()/b->numberDoF(); } );
345  if(m_maxJXCandidates>0 && selectedJXCandidates.size()>m_maxJXCandidates) {
346  selectedJXCandidates.erase(selectedJXCandidates.begin()+m_maxJXCandidates, selectedJXCandidates.end());
347  }
348 
349  // Select JX+V0+V0 candidates
350  std::vector<const xAOD::TrackParticle*> tracksJX; tracksJX.reserve(m_jxDaug_num);
351  std::vector<const xAOD::TrackParticle*> tracksV01; tracksV01.reserve(2);
352  for(auto jxItr=selectedJXCandidates.cbegin(); jxItr!=selectedJXCandidates.cend(); ++jxItr) {
353  tracksJX.clear();
354  for(size_t i=0; i<(*jxItr)->nTrackParticles(); i++) tracksJX.push_back((*jxItr)->trackParticle(i));
355  for(auto V0Itr1=selectedV0Candidates.cbegin(); V0Itr1!=selectedV0Candidates.cend(); ++V0Itr1) {
356  if(std::find(tracksJX.cbegin(), tracksJX.cend(), V0Itr1->first->trackParticle(0)) != tracksJX.cend()) continue;
357  if(std::find(tracksJX.cbegin(), tracksJX.cend(), V0Itr1->first->trackParticle(1)) != tracksJX.cend()) continue;
358  tracksV01.clear();
359  for(size_t j=0; j<V0Itr1->first->nTrackParticles(); j++) tracksV01.push_back(V0Itr1->first->trackParticle(j));
360  for(auto V0Itr2=V0Itr1+1; V0Itr2!=selectedV0Candidates.cend(); ++V0Itr2) {
361  if(std::find(tracksJX.cbegin(), tracksJX.cend(), V0Itr2->first->trackParticle(0)) != tracksJX.cend()) continue;
362  if(std::find(tracksJX.cbegin(), tracksJX.cend(), V0Itr2->first->trackParticle(1)) != tracksJX.cend()) continue;
363  if(std::find(tracksV01.cbegin(), tracksV01.cend(), V0Itr2->first->trackParticle(0)) != tracksV01.cend()) continue;
364  if(std::find(tracksV01.cbegin(), tracksV01.cend(), V0Itr2->first->trackParticle(1)) != tracksV01.cend()) continue;
365 
366  int numberOfVertices = 0;
367  if((m_V01Hypothesis=="Lambda/Ks" || m_V01Hypothesis=="Ks/Lambda") && (m_V02Hypothesis=="Lambda/Ks" || m_V02Hypothesis=="Ks/Lambda")) {
368  numberOfVertices = m_JXSubVtx && m_JXV02SubVtx ? 2 : 1;
369  }
370  else if((m_V01Hypothesis == "Ks" || m_V01Hypothesis == "Lambda") && (m_V02Hypothesis=="Lambda/Ks" || m_V02Hypothesis=="Ks/Lambda")) {
371  if((m_V01Hypothesis == "Ks" && V0Itr1->second==KS) ||
372  (m_V01Hypothesis == "Lambda" && (V0Itr1->second==LAMBDA || V0Itr1->second==LAMBDABAR))) numberOfVertices = 1;
373  if((m_V01Hypothesis == "Ks" && V0Itr2->second==KS) ||
374  (m_V01Hypothesis == "Lambda" && (V0Itr2->second==LAMBDA || V0Itr2->second==LAMBDABAR))) {
375  if(numberOfVertices == 1) numberOfVertices = m_JXSubVtx && m_JXV02SubVtx ? 2 : 1;
376  else numberOfVertices = -1;
377  }
378  }
379  else if((m_V02Hypothesis == "Ks" || m_V02Hypothesis == "Lambda") && (m_V01Hypothesis=="Lambda/Ks" || m_V01Hypothesis=="Ks/Lambda")) {
380  if((m_V02Hypothesis == "Ks" && V0Itr2->second==KS) ||
381  (m_V02Hypothesis == "Lambda" && (V0Itr2->second==LAMBDA || V0Itr2->second==LAMBDABAR))) numberOfVertices = 1;
382  if((m_V02Hypothesis == "Ks" && V0Itr1->second==KS) ||
383  (m_V02Hypothesis == "Lambda" && (V0Itr1->second==LAMBDA || V0Itr1->second==LAMBDABAR))) {
384  if(numberOfVertices == 1) numberOfVertices = m_JXSubVtx && m_JXV02SubVtx ? 2 : 1;
385  else numberOfVertices = -1;
386  }
387  }
388  else if(m_V01Hypothesis == "Ks" && m_V02Hypothesis == "Lambda") {
389  if(V0Itr1->second==KS && (V0Itr2->second==LAMBDA || V0Itr2->second==LAMBDABAR)) numberOfVertices = 1;
390  else if(V0Itr2->second==KS && (V0Itr1->second==LAMBDA || V0Itr1->second==LAMBDABAR)) numberOfVertices = -1;
391  }
392  else if(m_V01Hypothesis == "Lambda" && m_V02Hypothesis == "Ks") {
393  if((V0Itr1->second==LAMBDA || V0Itr1->second==LAMBDABAR) && V0Itr2->second==KS) numberOfVertices = 1;
394  else if((V0Itr2->second==LAMBDA || V0Itr2->second==LAMBDABAR) && V0Itr1->second==KS) numberOfVertices = -1;
395  }
396  else if(m_V01Hypothesis == "Ks" && m_V02Hypothesis == "Ks") {
397  if(V0Itr1->second==KS && V0Itr2->second==KS) numberOfVertices = m_JXSubVtx && m_JXV02SubVtx ? 2 : 1;
398  }
399  else if(m_V01Hypothesis == "Lambda" && m_V02Hypothesis == "Lambda") {
400  if((V0Itr1->second==LAMBDA || V0Itr1->second==LAMBDABAR) && (V0Itr2->second==LAMBDA || V0Itr2->second==LAMBDABAR)) numberOfVertices = m_JXSubVtx && m_JXV02SubVtx ? 2 : 1;
401  }
402 
403  if(numberOfVertices==2) {
404  Trk::VxCascadeInfo* result1 = fitMainVtx(*jxItr, massesJX, V0Itr1->first, V0Itr1->second, V0Itr2->first, V0Itr2->second, trackCols);
405  if(result1) cascadeinfoContainer.push_back(result1);
406  Trk::VxCascadeInfo* result2 = fitMainVtx(*jxItr, massesJX, V0Itr2->first, V0Itr2->second, V0Itr1->first, V0Itr1->second, trackCols);
407  if(result2) cascadeinfoContainer.push_back(result2);
408  }
409  else if(numberOfVertices==1) {
410  Trk::VxCascadeInfo* result = fitMainVtx(*jxItr, massesJX, V0Itr1->first, V0Itr1->second, V0Itr2->first, V0Itr2->second, trackCols);
411  if(result) cascadeinfoContainer.push_back(result);
412  }
413  else if(numberOfVertices==-1) {
414  Trk::VxCascadeInfo* result = fitMainVtx(*jxItr, massesJX, V0Itr2->first, V0Itr2->second, V0Itr1->first, V0Itr1->second, trackCols);
415  if(result) cascadeinfoContainer.push_back(result);
416  }
417  }
418  }
419  }
420 
421  return StatusCode::SUCCESS;
422  }
423 
425  size_t topoN = 4;
426  if(!m_JXSubVtx) topoN--;
427 
428  if(m_cascadeOutputKeys.size() != topoN) {
429  ATH_MSG_FATAL("Incorrect number of output cascade vertices");
430  return StatusCode::FAILURE;
431  }
432 
433  std::array<SG::WriteHandle<xAOD::VertexContainer>, 4> VtxWriteHandles; int ikey(0);
435  VtxWriteHandles[ikey] = SG::WriteHandle<xAOD::VertexContainer>(key);
436  ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
437  ikey++;
438  }
439 
440  //----------------------------------------------------
441  // retrieve primary vertices
442  //----------------------------------------------------
443  const xAOD::Vertex* primaryVertex(nullptr);
445  ATH_CHECK( pvContainer.isValid() );
446  if (pvContainer.cptr()->size()==0) {
447  ATH_MSG_WARNING("You have no primary vertices: " << pvContainer.cptr()->size());
448  return StatusCode::RECOVERABLE;
449  }
450  else primaryVertex = (*pvContainer.cptr())[0];
451 
452  //----------------------------------------------------
453  // Record refitted primary vertices
454  //----------------------------------------------------
456  if(m_refitPV) {
458  ATH_CHECK( refPvContainer.record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
459  }
460 
461  // Get TrackParticle container (standard + LRT)
463  ATH_CHECK( trackContainer.isValid() );
464 
465  // Get all track containers when m_RelinkContainers is not empty
466  std::vector<const xAOD::TrackParticleContainer*> trackCols;
469  ATH_CHECK( handle.isValid() );
470  trackCols.push_back(handle.cptr());
471  }
472 
473  // output V0 vertices
474  SG::WriteHandle<xAOD::VertexContainer> V0OutputContainer;
475  if(m_vertexV0ContainerKey.key()=="" && m_v0VtxOutputKey.key()!="") {
477  ATH_CHECK( V0OutputContainer.record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
478  }
479 
480  // Get the input containers
481  // 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
483  ATH_CHECK( jxContainer.isValid() );
484  if(jxContainer->size()==0) return StatusCode::SUCCESS;
485 
486  // Select the displaced tracks
487  std::vector<const xAOD::TrackParticle*> tracksDisplaced;
488  if(m_v0VtxOutputKey.key()!="") {
489  for(const xAOD::TrackParticle* TP : *trackContainer.cptr()) {
490  // V0 track selection (https://gitlab.cern.ch/atlas/athena/-/blob/main/InnerDetector/InDetRecTools/InDetTrackSelectorTool/src/InDetConversionTrackSelectorTool.cxx)
491  if(m_v0TrkSelector->decision(*TP, primaryVertex)) {
492  uint8_t temp(0);
493  uint8_t nclus(0);
494  if(TP->summaryValue(temp, xAOD::numberOfPixelHits)) nclus += temp;
495  if(TP->summaryValue(temp, xAOD::numberOfSCTHits) ) nclus += temp;
496  if(!m_useTRT && nclus == 0) continue;
497 
498  bool trk_cut = false;
499  if(nclus != 0) trk_cut = true;
500  if(nclus == 0 && TP->pt()>=m_ptTRT) trk_cut = true;
501  if(!trk_cut) continue;
502 
503  // track is used if std::abs(d0/sig_d0) > d0_cut for PV
504  if(!d0Pass(TP,primaryVertex)) continue;
505 
506  tracksDisplaced.push_back(TP);
507  }
508  }
509  }
510 
511  SG::AuxElement::Accessor<std::string> mAcc_type("Type_V0Vtx");
512  SG::AuxElement::Accessor<int> mAcc_gfit("gamma_fit");
513  SG::AuxElement::Accessor<float> mAcc_gmass("gamma_mass");
514  SG::AuxElement::Accessor<float> mAcc_gchisq("gamma_chisq");
515  SG::AuxElement::Accessor<int> mAcc_gndof("gamma_ndof");
516 
517  std::vector<std::pair<const xAOD::Vertex*,V0Enum> > selectedV0Candidates;
518 
520  if(m_vertexV0ContainerKey.key() != "") {
522  ATH_CHECK( V0Container.isValid() );
523 
524  for(const xAOD::Vertex* vtx : *V0Container.cptr()) {
525  std::string type_V0Vtx;
526  if(mAcc_type.isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
527 
528  V0Enum opt(UNKNOWN); double massV0(0);
529  if(type_V0Vtx == "Lambda") {
530  opt = LAMBDA;
531  massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_ppi);
532  if(massV0<m_LambdaMassLower || massV0>m_LambdaMassUpper) continue;
533  }
534  else if(type_V0Vtx == "Lambdabar") {
535  opt = LAMBDABAR;
536  massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pip);
537  if(massV0<m_LambdaMassLower || massV0>m_LambdaMassUpper) continue;
538  }
539  else if(type_V0Vtx == "Ks") {
540  opt = KS;
541  massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pipi);
542  if(massV0<m_KsMassLower || massV0>m_KsMassUpper) continue;
543  }
544 
545  if(opt==UNKNOWN) continue;
547  if((opt==LAMBDA || opt==LAMBDABAR) && m_V01Hypothesis == "Ks") continue;
548  if(opt==KS && m_V01Hypothesis == "Lambda") continue;
549  }
550 
551  int gamma_fit = mAcc_gfit.isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
552  double gamma_mass = mAcc_gmass.isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
553  double gamma_chisq = mAcc_gchisq.isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
554  double gamma_ndof = mAcc_gndof.isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
555  if(gamma_fit==1 && gamma_mass<m_minMass_gamma && gamma_chisq/gamma_ndof<m_chi2cut_gamma) continue;
556 
557  selectedV0Candidates.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,opt});
558  }
559  }
560  else {
561  // fit V0 vertices
562  fitV0Container(V0OutputContainer.ptr(), tracksDisplaced, trackCols);
563 
564  for(const xAOD::Vertex* vtx : *V0OutputContainer.cptr()) {
565  std::string type_V0Vtx;
566  if(mAcc_type.isAvailable(*vtx)) type_V0Vtx = mAcc_type(*vtx);
567 
568  V0Enum opt(UNKNOWN); double massV0(0);
569  if(type_V0Vtx == "Lambda") {
570  opt = LAMBDA;
571  massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_ppi);
572  if(massV0<m_LambdaMassLower || massV0>m_LambdaMassUpper) continue;
573  }
574  else if(type_V0Vtx == "Lambdabar") {
575  opt = LAMBDABAR;
576  massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pip);
577  if(massV0<m_LambdaMassLower || massV0>m_LambdaMassUpper) continue;
578  }
579  else if(type_V0Vtx == "Ks") {
580  opt = KS;
581  massV0 = m_V0Tools->invariantMass(vtx, m_massesV0_pipi);
582  if(massV0<m_KsMassLower || massV0>m_KsMassUpper) continue;
583  }
584 
585  if(opt==UNKNOWN) continue;
587  if((opt==LAMBDA || opt==LAMBDABAR) && m_V01Hypothesis == "Ks") continue;
588  if(opt==KS && m_V01Hypothesis == "Lambda") continue;
589  }
590 
591  int gamma_fit = mAcc_gfit.isAvailable(*vtx) ? mAcc_gfit(*vtx) : 0;
592  double gamma_mass = mAcc_gmass.isAvailable(*vtx) ? mAcc_gmass(*vtx) : -1;
593  double gamma_chisq = mAcc_gchisq.isAvailable(*vtx) ? mAcc_gchisq(*vtx) : 999999;
594  double gamma_ndof = mAcc_gndof.isAvailable(*vtx) ? mAcc_gndof(*vtx) : 0;
595  if(gamma_fit==1 && gamma_mass<m_minMass_gamma && gamma_chisq/gamma_ndof<m_chi2cut_gamma) continue;
596 
597  selectedV0Candidates.push_back(std::pair<const xAOD::Vertex*,V0Enum>{vtx,opt});
598  }
599  }
600 
601  // sort and chop the V0 candidates
602  std::sort( selectedV0Candidates.begin(), selectedV0Candidates.end(), [](std::pair<const xAOD::Vertex*,V0Enum>& a, std::pair<const xAOD::Vertex*,V0Enum>& b) { return a.first->chiSquared()/a.first->numberDoF() < b.first->chiSquared()/b.first->numberDoF(); } );
603  if(m_maxV0Candidates>0 && selectedV0Candidates.size()>m_maxV0Candidates) {
604  selectedV0Candidates.erase(selectedV0Candidates.begin()+m_maxV0Candidates, selectedV0Candidates.end());
605  }
606  if(selectedV0Candidates.size()==0) return StatusCode::SUCCESS;
607 
608  std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
609  ATH_CHECK( performSearch(cascadeinfoContainer, selectedV0Candidates) );
610 
611  // sort and chop the main candidates
612  std::sort( cascadeinfoContainer.begin(), cascadeinfoContainer.end(), [](Trk::VxCascadeInfo* a, Trk::VxCascadeInfo* b) { return a->fitChi2()/a->nDoF() < b->fitChi2()/b->nDoF(); } );
613  if(m_maxMainVCandidates>0 && cascadeinfoContainer.size()>m_maxMainVCandidates) {
614  for(auto it=cascadeinfoContainer.begin()+m_maxMainVCandidates; it!=cascadeinfoContainer.end(); it++) delete *it;
615  cascadeinfoContainer.erase(cascadeinfoContainer.begin()+m_maxMainVCandidates, cascadeinfoContainer.end());
616  }
617 
619  ATH_CHECK( evt.isValid() );
621  helper.SetMinNTracksInPV(m_PV_minNTracks);
622 
623  // Decorators for the main vertex: chi2, ndf, pt and pt error, plus the V0 vertex variables
624  SG::AuxElement::Decorator<VertexLinkVector> CascadeLinksDecor("CascadeVertexLinks");
625  SG::AuxElement::Decorator<float> chi2_decor("ChiSquared");
626  SG::AuxElement::Decorator<int> ndof_decor("nDoF");
627  SG::AuxElement::Decorator<float> Pt_decor("Pt");
628  SG::AuxElement::Decorator<float> PtErr_decor("PtErr");
629 
630  SG::AuxElement::Decorator<float> lxy_SV1_decor("lxy_SV1");
631  SG::AuxElement::Decorator<float> lxyErr_SV1_decor("lxyErr_SV1");
632  SG::AuxElement::Decorator<float> a0xy_SV1_decor("a0xy_SV1");
633  SG::AuxElement::Decorator<float> a0xyErr_SV1_decor("a0xyErr_SV1");
634  SG::AuxElement::Decorator<float> a0z_SV1_decor("a0z_SV1");
635  SG::AuxElement::Decorator<float> a0zErr_SV1_decor("a0zErr_SV1");
636 
637  SG::AuxElement::Decorator<float> lxy_SV2_decor("lxy_SV2");
638  SG::AuxElement::Decorator<float> lxyErr_SV2_decor("lxyErr_SV2");
639  SG::AuxElement::Decorator<float> a0xy_SV2_decor("a0xy_SV2");
640  SG::AuxElement::Decorator<float> a0xyErr_SV2_decor("a0xyErr_SV2");
641  SG::AuxElement::Decorator<float> a0z_SV2_decor("a0z_SV2");
642  SG::AuxElement::Decorator<float> a0zErr_SV2_decor("a0zErr_SV2");
643 
644  SG::AuxElement::Decorator<float> lxy_SV3_decor("lxy_SV3");
645  SG::AuxElement::Decorator<float> lxyErr_SV3_decor("lxyErr_SV3");
646  SG::AuxElement::Decorator<float> a0xy_SV3_decor("a0xy_SV3");
647  SG::AuxElement::Decorator<float> a0xyErr_SV3_decor("a0xyErr_SV3");
648  SG::AuxElement::Decorator<float> a0z_SV3_decor("a0z_SV3");
649  SG::AuxElement::Decorator<float> a0zErr_SV3_decor("a0zErr_SV3");
650 
651  SG::AuxElement::Decorator<float> chi2_V3_decor("ChiSquared_V3");
652  SG::AuxElement::Decorator<int> ndof_V3_decor("nDoF_V3");
653 
654  for(auto cascade_info : cascadeinfoContainer) {
655  if(cascade_info==nullptr) {
656  ATH_MSG_ERROR("CascadeInfo is null");
657  continue;
658  }
659 
660  const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->vertices();
661  if(cascadeVertices.size() != topoN) ATH_MSG_ERROR("Incorrect number of vertices");
662  for(size_t i=0; i<topoN; i++) {
663  if(cascadeVertices[i]==nullptr) ATH_MSG_ERROR("Error null vertex");
664  }
665 
666  cascade_info->setSVOwnership(false); // Prevent Container from deleting vertices
667  const auto mainVertex = cascadeVertices[topoN-1]; // this is the mother vertex
668  const std::vector< std::vector<TLorentzVector> > &moms = cascade_info->getParticleMoms();
669 
670  // Identify the input JX
671  int ijx = m_JXSubVtx ? topoN-2 : topoN-1;
672  const xAOD::Vertex* jxVtx(nullptr);
673  if(m_jxDaug_num==4) jxVtx = FindVertex<4>(jxContainer.ptr(), cascadeVertices[ijx]);
674  else if(m_jxDaug_num==3) jxVtx = FindVertex<3>(jxContainer.ptr(), cascadeVertices[ijx]);
675  else jxVtx = FindVertex<2>(jxContainer.ptr(), cascadeVertices[ijx]);
676 
677  xAOD::BPhysHypoHelper vtx(m_hypoName, mainVertex);
678 
679  // Get refitted track momenta from all vertices, charged tracks only
680  BPhysPVCascadeTools::SetVectorInfo(vtx, cascade_info);
681  vtx.setPass(true);
682 
683  //
684  // Decorate main vertex
685  //
686  // mass, mass error
687  // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/VxCascadeInfo.h
688  BPHYS_CHECK( vtx.setMass(m_CascadeTools->invariantMass(moms[topoN-1])) );
689  BPHYS_CHECK( vtx.setMassErr(m_CascadeTools->invariantMassError(moms[topoN-1],cascade_info->getCovariance()[topoN-1])) );
690  // pt and pT error (the default pt of mainVertex is != the pt of the full cascade fit!)
691  Pt_decor(*mainVertex) = m_CascadeTools->pT(moms[topoN-1]);
692  PtErr_decor(*mainVertex) = m_CascadeTools->pTError(moms[topoN-1],cascade_info->getCovariance()[topoN-1]);
693  // chi2 and ndof (the default chi2 of mainVertex is != the chi2 of the full cascade fit!)
694  chi2_decor(*mainVertex) = cascade_info->fitChi2();
695  ndof_decor(*mainVertex) = cascade_info->nDoF();
696 
697  // decorate the cascade vertices
698  lxy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
699  lxyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
700  a0z_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
701  a0zErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
702  a0xy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
703  a0xyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
704 
705  if(m_JXSubVtx && m_JXV02SubVtx) {
706  lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],cascadeVertices[2]);
707  lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
708  a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],cascadeVertices[2]);
709  a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
710  a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],cascadeVertices[2]);
711  a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],cascadeVertices[2]);
712  }
713  else {
714  lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
715  lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
716  a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
717  a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
718  a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
719  a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
720  }
721 
722  if(m_JXSubVtx) {
723  lxy_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->lxy(moms[2],cascadeVertices[2],mainVertex);
724  lxyErr_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->lxyError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
725  a0z_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->a0z(moms[2],cascadeVertices[2],mainVertex);
726  a0zErr_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->a0zError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
727  a0xy_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->a0xy(moms[2],cascadeVertices[2],mainVertex);
728  a0xyErr_SV3_decor(*cascadeVertices[2]) = m_CascadeTools->a0xyError(moms[2],cascade_info->getCovariance()[2],cascadeVertices[2],mainVertex);
729  }
730 
731  chi2_V3_decor(*cascadeVertices[2]) = m_V0Tools->chisq(jxVtx);
732  ndof_V3_decor(*cascadeVertices[2]) = m_V0Tools->ndof(jxVtx);
733 
734  double Mass_Moth = m_CascadeTools->invariantMass(moms[topoN-1]);
735  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));
736 
737  for(size_t i=0; i<topoN; i++) {
738  VtxWriteHandles[i].ptr()->push_back(cascadeVertices[i]);
739  }
740 
741  // Set links to cascade vertices
742  VertexLinkVector cascadeVertexLinks;
743  VertexLink vertexLink1;
744  vertexLink1.setElement(cascadeVertices[0]);
745  vertexLink1.setStorableObject(*VtxWriteHandles[0].ptr());
746  if( vertexLink1.isValid() ) cascadeVertexLinks.push_back( vertexLink1 );
747  VertexLink vertexLink2;
748  vertexLink2.setElement(cascadeVertices[1]);
749  vertexLink2.setStorableObject(*VtxWriteHandles[1].ptr());
750  if( vertexLink2.isValid() ) cascadeVertexLinks.push_back( vertexLink2 );
751  if(topoN==4) {
752  VertexLink vertexLink3;
753  vertexLink3.setElement(cascadeVertices[2]);
754  vertexLink3.setStorableObject(*VtxWriteHandles[2].ptr());
755  if( vertexLink3.isValid() ) cascadeVertexLinks.push_back( vertexLink3 );
756  }
757  CascadeLinksDecor(*mainVertex) = cascadeVertexLinks;
758  } // loop over cascadeinfoContainer
759 
760  // Deleting cascadeinfo since this won't be stored.
761  for (auto cascade_info : cascadeinfoContainer) {
762  if(cascade_info) delete cascade_info;
763  }
764 
765  return StatusCode::SUCCESS;
766  }
767 
768  bool JpsiXPlus2V0::d0Pass(const xAOD::TrackParticle* track, const xAOD::Vertex* PV) const {
769  bool pass = false;
770  const EventContext& ctx = Gaudi::Hive::currentContext();
771  std::unique_ptr<Trk::Perigee> per = m_trackToVertexTool->perigeeAtVertex(ctx, *track, PV->position());
772  if(!per) return pass;
773  double d0 = per->parameters()[Trk::d0];
774  double sig_d0 = sqrt((*per->covariance())(0,0));
775  if(std::abs(d0/sig_d0) > m_d0_cut) pass = true;
776  return pass;
777  }
778 
779  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 std::vector<const xAOD::TrackParticleContainer*>& trackCols) const {
780  Trk::VxCascadeInfo* result(nullptr);
781 
782  std::vector<const xAOD::TrackParticle*> tracksJX;
783  for(size_t i=0; i<JXvtx->nTrackParticles(); i++) tracksJX.push_back(JXvtx->trackParticle(i));
784  if (tracksJX.size() != massesJX.size()) {
785  ATH_MSG_ERROR("Problems with JX input: number of tracks or track mass inputs is not correct!");
786  return result;
787  }
788  std::vector<const xAOD::TrackParticle*> tracksV01;
789  for(size_t j=0; j<V01vtx->nTrackParticles(); j++) tracksV01.push_back(V01vtx->trackParticle(j));
790  std::vector<const xAOD::TrackParticle*> tracksV02;
791  for(size_t j=0; j<V02vtx->nTrackParticles(); j++) tracksV02.push_back(V02vtx->trackParticle(j));
792 
793  std::vector<const xAOD::TrackParticle*> tracksJpsi{tracksJX[0], tracksJX[1]};
794  std::vector<const xAOD::TrackParticle*> tracksX;
795  if(m_jxDaug_num>=3) tracksX.push_back(tracksJX[2]);
796  if(m_jxDaug_num==4) tracksX.push_back(tracksJX[3]);
797 
798  std::vector<double> massesV01;
799  if(V01==LAMBDA) massesV01 = m_massesV0_ppi;
800  else if(V01==LAMBDABAR) massesV01 = m_massesV0_pip;
801  else if(V01==KS) massesV01 = m_massesV0_pipi;
802  std::vector<double> massesV02;
803  if(V02==LAMBDA) massesV02 = m_massesV0_ppi;
804  else if(V02==LAMBDABAR) massesV02 = m_massesV0_pip;
805  else if(V02==KS) massesV02 = m_massesV0_pipi;
806 
807  TLorentzVector p4_moth, p4_JX, p4_v01, p4_v02, tmp;
808  for(size_t it=0; it<JXvtx->nTrackParticles(); it++) {
809  tmp.SetPtEtaPhiM(JXvtx->trackParticle(it)->pt(), JXvtx->trackParticle(it)->eta(), JXvtx->trackParticle(it)->phi(), massesJX[it]);
810  p4_moth += tmp; p4_JX += tmp;
811  }
812  xAOD::BPhysHelper V01_helper(V01vtx);
813  for(int it=0; it<V01_helper.nRefTrks(); it++) {
814  p4_moth += V01_helper.refTrk(it,massesV01[it]);
815  p4_v01 += V01_helper.refTrk(it,massesV01[it]);
816  }
817  xAOD::BPhysHelper V02_helper(V02vtx);
818  for(int it=0; it<V02_helper.nRefTrks(); it++) {
819  p4_moth += V02_helper.refTrk(it,massesV02[it]);
820  p4_v02 += V02_helper.refTrk(it,massesV02[it]);
821  }
822  double main_mass = p4_moth.M();
823  if(m_useImprovedMass) {
824  if(m_jxDaug_num==2 && m_massJpsi>0) main_mass += - p4_JX.M() + m_massJpsi;
825  else if(m_jxDaug_num>=3 && m_massJX>0) main_mass += - p4_JX.M() + m_massJX;
826  if((V01==LAMBDA || V01==LAMBDABAR) && m_massLd>0) main_mass += - p4_v01.M() + m_massLd;
827  else if(V01==KS && m_massKs>0) main_mass += - p4_v01.M() + m_massKs;
828  if((V02==LAMBDA || V02==LAMBDABAR) && m_massLd>0) main_mass += - p4_v02.M() + m_massLd;
829  else if(V02==KS && m_massKs>0) main_mass += - p4_v02.M() + m_massKs;
830  }
831  if (main_mass < m_MassLower || main_mass > m_MassUpper) return result;
832 
833  if(m_JXSubVtx && m_JXV02SubVtx) {
834  double JXV02_mass = (p4_JX+p4_v02).M();
835  if(m_useImprovedMass) {
836  if(m_jxDaug_num==2 && m_massJpsi>0) JXV02_mass += - p4_JX.M() + m_massJpsi;
837  else if(m_jxDaug_num>=3 && m_massJX>0) JXV02_mass += - p4_JX.M() + m_massJX;
838  if((V02==LAMBDA || V02==LAMBDABAR) && m_massLd>0) JXV02_mass += - p4_v02.M() + m_massLd;
839  else if(V02==KS && m_massKs>0) JXV02_mass += - p4_v02.M() + m_massKs;
840  }
841  if (JXV02_mass < m_JXV02MassLower || JXV02_mass > m_JXV02MassUpper) return result;
842  }
843 
844  SG::AuxElement::Decorator<float> chi2_V1_decor("ChiSquared_V1");
845  SG::AuxElement::Decorator<int> ndof_V1_decor("nDoF_V1");
846  SG::AuxElement::Decorator<std::string> type_V1_decor("Type_V1");
847  SG::AuxElement::Decorator<float> chi2_V2_decor("ChiSquared_V2");
848  SG::AuxElement::Decorator<int> ndof_V2_decor("nDoF_V2");
849  SG::AuxElement::Decorator<std::string> type_V2_decor("Type_V2");
850 
851  SG::AuxElement::Accessor<int> mAcc_gfit("gamma_fit");
852  SG::AuxElement::Accessor<float> mAcc_gmass("gamma_mass");
853  SG::AuxElement::Accessor<float> mAcc_gmasserr("gamma_massError");
854  SG::AuxElement::Accessor<float> mAcc_gchisq("gamma_chisq");
855  SG::AuxElement::Accessor<int> mAcc_gndof("gamma_ndof");
856  SG::AuxElement::Accessor<float> mAcc_gprob("gamma_probability");
857 
858  SG::AuxElement::Decorator<int> mDec_gfit("gamma_fit");
859  SG::AuxElement::Decorator<float> mDec_gmass("gamma_mass");
860  SG::AuxElement::Decorator<float> mDec_gmasserr("gamma_massError");
861  SG::AuxElement::Decorator<float> mDec_gchisq("gamma_chisq");
862  SG::AuxElement::Decorator<int> mDec_gndof("gamma_ndof");
863  SG::AuxElement::Decorator<float> mDec_gprob("gamma_probability");
864  SG::AuxElement::Decorator< std::vector<float> > trk_pxDeco("TrackPx_V0nc");
865  SG::AuxElement::Decorator< std::vector<float> > trk_pyDeco("TrackPy_V0nc");
866  SG::AuxElement::Decorator< std::vector<float> > trk_pzDeco("TrackPz_V0nc");
867 
868  std::vector<float> trk_px;
869  std::vector<float> trk_py;
870  std::vector<float> trk_pz;
871 
872  // Apply the user's settings to the fitter
873  std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
874  // Robustness: http://cdsweb.cern.ch/record/685551
875  int robustness = 0;
876  m_iVertexFitter->setRobustness(robustness, *state);
877  // Build up the topology
878  // Vertex list
879  std::vector<Trk::VertexID> vrtList;
880  // https://gitlab.cern.ch/atlas/athena/-/blob/main/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/IVertexCascadeFitter.h
881  // V01 vertex
882  Trk::VertexID vID1;
883  if (m_constrV01) {
884  vID1 = m_iVertexFitter->startVertex(tracksV01,massesV01,*state,V01==KS?m_massKs:m_massLd);
885  } else {
886  vID1 = m_iVertexFitter->startVertex(tracksV01,massesV01,*state);
887  }
888  vrtList.push_back(vID1);
889  // V02 vertex
890  Trk::VertexID vID2;
891  if (m_constrV02) {
892  vID2 = m_iVertexFitter->nextVertex(tracksV02,massesV02,*state,V02==KS?m_massKs:m_massLd);
893  } else {
894  vID2 = m_iVertexFitter->nextVertex(tracksV02,massesV02,*state);
895  }
896  vrtList.push_back(vID2);
897  Trk::VertexID vID3;
898  if(m_JXSubVtx) {
899  if(m_JXV02SubVtx) { // for e.g. Lambda_b -> Jpsi + Lambda
900  // JX+V02 vertex
901  std::vector<Trk::VertexID> vrtList1{vID1};
902  std::vector<Trk::VertexID> vrtList2{vID2};
903  if (m_constrJXV02) {
904  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state,m_massJXV02);
905  } else {
906  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList2,*state);
907  }
908  vrtList1.push_back(vID3);
909  if (m_constrJX && m_jxDaug_num>2) {
910  std::vector<Trk::VertexID> cnstV; cnstV.clear();
911  if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
912  ATH_MSG_WARNING("addMassConstraint for JX failed");
913  }
914  }
915  // Mother vertex including JX and two V0's
916  std::vector<const xAOD::TrackParticle*> tp; tp.clear();
917  std::vector<double> tp_masses; tp_masses.clear();
918  if(m_constrMainV) {
919  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList1,*state,m_massMainV);
920  } else {
921  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList1,*state);
922  }
923  }
924  else { // no JXV02SubVtx
925  // JX vertex
926  if (m_constrJX && m_jxDaug_num>2) {
927  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state,m_massJX);
928  } else {
929  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,*state);
930  }
931  vrtList.push_back(vID3);
932  // Mother vertex including JX and two V0's
933  std::vector<const xAOD::TrackParticle*> tp; tp.clear();
934  std::vector<double> tp_masses; tp_masses.clear();
935  if(m_constrMainV) {
936  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList,*state,m_massMainV);
937  } else {
938  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList,*state);
939  }
940  }
941  }
942  else { // m_JXSubVtx=false
943  // Mother vertex including JX and two V0's
944  if(m_constrMainV) {
945  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state,m_massMainV);
946  } else {
947  vID3 = m_iVertexFitter->nextVertex(tracksJX,massesJX,vrtList,*state);
948  }
949  if (m_constrJX && m_jxDaug_num>2) {
950  std::vector<Trk::VertexID> cnstV; cnstV.clear();
951  if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJX,cnstV,*state,m_massJX).isSuccess() ) {
952  ATH_MSG_WARNING("addMassConstraint for JX failed");
953  }
954  }
955  }
956 
957  if (m_constrJpsi) {
958  std::vector<Trk::VertexID> cnstV; cnstV.clear();
959  if ( !m_iVertexFitter->addMassConstraint(vID3,tracksJpsi,cnstV,*state,m_massJpsi).isSuccess() ) {
960  ATH_MSG_WARNING("addMassConstraint for Jpsi failed");
961  }
962  }
963  if (m_constrX && m_jxDaug_num==4 && m_massX>0) {
964  std::vector<Trk::VertexID> cnstV; cnstV.clear();
965  if ( !m_iVertexFitter->addMassConstraint(vID3,tracksX,cnstV,*state,m_massX).isSuccess() ) {
966  ATH_MSG_WARNING("addMassConstraint for X failed");
967  }
968  }
969  // Do the work
970  std::unique_ptr<Trk::VxCascadeInfo> fit_result = std::unique_ptr<Trk::VxCascadeInfo>( m_iVertexFitter->fitCascade(*state) );
971 
972  if (fit_result != nullptr) {
973  for(auto v : fit_result->vertices()) {
974  if(v->nTrackParticles()==0) {
975  std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
976  v->setTrackParticleLinks(nullLinkVector);
977  }
978  }
979  // reset links to original tracks
980  BPhysPVCascadeTools::PrepareVertexLinks(fit_result.get(), trackCols);
981 
982  // necessary to prevent memory leak
983  fit_result->setSVOwnership(true);
984 
985  // Chi2/DOF cut
986  double chi2DOF = fit_result->fitChi2()/fit_result->nDoF();
987  bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
988 
989  const std::vector<std::vector<TLorentzVector> > &moms = fit_result->getParticleMoms();
990  const std::vector<xAOD::Vertex*> &cascadeVertices = fit_result->vertices();
991  size_t iMoth = cascadeVertices.size()-1;
992  double lxy_SV1 = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[iMoth]);
993  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]);
994  if(chi2CutPassed && lxy_SV1>m_lxyV01_cut && lxy_SV2>m_lxyV02_cut) {
995  chi2_V1_decor(*cascadeVertices[0]) = V01vtx->chiSquared();
996  ndof_V1_decor(*cascadeVertices[0]) = V01vtx->numberDoF();
997  if(V01==LAMBDA) type_V1_decor(*cascadeVertices[0]) = "Lambda";
998  else if(V01==LAMBDABAR) type_V1_decor(*cascadeVertices[0]) = "Lambdabar";
999  else if(V01==KS) type_V1_decor(*cascadeVertices[0]) = "Ks";
1000  mDec_gfit(*cascadeVertices[0]) = mAcc_gfit.isAvailable(*V01vtx) ? mAcc_gfit(*V01vtx) : 0;
1001  mDec_gmass(*cascadeVertices[0]) = mAcc_gmass.isAvailable(*V01vtx) ? mAcc_gmass(*V01vtx) : -1;
1002  mDec_gmasserr(*cascadeVertices[0]) = mAcc_gmasserr.isAvailable(*V01vtx) ? mAcc_gmasserr(*V01vtx) : -1;
1003  mDec_gchisq(*cascadeVertices[0]) = mAcc_gchisq.isAvailable(*V01vtx) ? mAcc_gchisq(*V01vtx) : 999999;
1004  mDec_gndof(*cascadeVertices[0]) = mAcc_gndof.isAvailable(*V01vtx) ? mAcc_gndof(*V01vtx) : 0;
1005  mDec_gprob(*cascadeVertices[0]) = mAcc_gprob.isAvailable(*V01vtx) ? mAcc_gprob(*V01vtx) : -1;
1006  trk_px.clear(); trk_py.clear(); trk_pz.clear();
1007  for(int it=0; it<V01_helper.nRefTrks(); it++) {
1008  trk_px.push_back( V01_helper.refTrk(it).Px() );
1009  trk_py.push_back( V01_helper.refTrk(it).Py() );
1010  trk_pz.push_back( V01_helper.refTrk(it).Pz() );
1011  }
1012  trk_pxDeco(*cascadeVertices[0]) = trk_px;
1013  trk_pyDeco(*cascadeVertices[0]) = trk_py;
1014  trk_pzDeco(*cascadeVertices[0]) = trk_pz;
1015 
1016  chi2_V2_decor(*cascadeVertices[1]) = V02vtx->chiSquared();
1017  ndof_V2_decor(*cascadeVertices[1]) = V02vtx->numberDoF();
1018  if(V02==LAMBDA) type_V2_decor(*cascadeVertices[1]) = "Lambda";
1019  else if(V02==LAMBDABAR) type_V2_decor(*cascadeVertices[1]) = "Lambdabar";
1020  else if(V02==KS) type_V2_decor(*cascadeVertices[1]) = "Ks";
1021  mDec_gfit(*cascadeVertices[1]) = mAcc_gfit.isAvailable(*V02vtx) ? mAcc_gfit(*V02vtx) : 0;
1022  mDec_gmass(*cascadeVertices[1]) = mAcc_gmass.isAvailable(*V02vtx) ? mAcc_gmass(*V02vtx) : -1;
1023  mDec_gmasserr(*cascadeVertices[1]) = mAcc_gmasserr.isAvailable(*V02vtx) ? mAcc_gmasserr(*V02vtx) : -1;
1024  mDec_gchisq(*cascadeVertices[1]) = mAcc_gchisq.isAvailable(*V02vtx) ? mAcc_gchisq(*V02vtx) : 999999;
1025  mDec_gndof(*cascadeVertices[1]) = mAcc_gndof.isAvailable(*V02vtx) ? mAcc_gndof(*V02vtx) : 0;
1026  mDec_gprob(*cascadeVertices[1]) = mAcc_gprob.isAvailable(*V02vtx) ? mAcc_gprob(*V02vtx) : -1;
1027  trk_px.clear(); trk_py.clear(); trk_pz.clear();
1028  for(int it=0; it<V02_helper.nRefTrks(); it++) {
1029  trk_px.push_back( V02_helper.refTrk(it).Px() );
1030  trk_py.push_back( V02_helper.refTrk(it).Py() );
1031  trk_pz.push_back( V02_helper.refTrk(it).Pz() );
1032  }
1033  trk_pxDeco(*cascadeVertices[1]) = trk_px;
1034  trk_pyDeco(*cascadeVertices[1]) = trk_py;
1035  trk_pzDeco(*cascadeVertices[1]) = trk_pz;
1036 
1037  result = fit_result.release();
1038  }
1039  }
1040 
1041  return result;
1042  }
1043 
1044  void JpsiXPlus2V0::fitV0Container(xAOD::VertexContainer* V0ContainerNew, const std::vector<const xAOD::TrackParticle*>& selectedTracks, const std::vector<const xAOD::TrackParticleContainer*>& trackCols) const {
1045  const EventContext& ctx = Gaudi::Hive::currentContext();
1046 
1047  SG::AuxElement::Decorator<std::string> mDec_type("Type_V0Vtx");
1048  SG::AuxElement::Decorator<int> mDec_gfit("gamma_fit");
1049  SG::AuxElement::Decorator<float> mDec_gmass("gamma_mass");
1050  SG::AuxElement::Decorator<float> mDec_gmasserr("gamma_massError");
1051  SG::AuxElement::Decorator<float> mDec_gchisq("gamma_chisq");
1052  SG::AuxElement::Decorator<int> mDec_gndof("gamma_ndof");
1053  SG::AuxElement::Decorator<float> mDec_gprob("gamma_probability");
1054 
1055  std::vector<const xAOD::TrackParticle*> posTracks;
1056  std::vector<const xAOD::TrackParticle*> negTracks;
1057  for(const xAOD::TrackParticle* TP : selectedTracks) {
1058  if(TP->charge()>0) posTracks.push_back(TP);
1059  else negTracks.push_back(TP);
1060  }
1061 
1062  for(const xAOD::TrackParticle* TP1 : posTracks) {
1063  const Trk::Perigee& aPerigee1 = TP1->perigeeParameters();
1064  for(const xAOD::TrackParticle* TP2 : negTracks) {
1065  const Trk::Perigee& aPerigee2 = TP2->perigeeParameters();
1066  int sflag(0), errorcode(0);
1067  Amg::Vector3D startingPoint = m_vertexEstimator->getCirclesIntersectionPoint(&aPerigee1,&aPerigee2,sflag,errorcode);
1068  if (errorcode != 0) {startingPoint(0) = 0.0; startingPoint(1) = 0.0; startingPoint(2) = 0.0;}
1069 
1070  if (errorcode == 0 || errorcode == 5 || errorcode == 6 || errorcode == 8) {
1071  Trk::PerigeeSurface perigeeSurface(startingPoint);
1072  const Trk::TrackParameters* extrapolatedPerigee1 = m_extrapolator->extrapolate(ctx,TP1->perigeeParameters(), perigeeSurface).release();
1073  const Trk::TrackParameters* extrapolatedPerigee2 = m_extrapolator->extrapolate(ctx,TP2->perigeeParameters(), perigeeSurface).release();
1074  std::vector<std::unique_ptr<const Trk::TrackParameters> > cleanup;
1075  if(!extrapolatedPerigee1) extrapolatedPerigee1 = &TP1->perigeeParameters();
1076  else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee1));
1077  if(!extrapolatedPerigee2) extrapolatedPerigee2 = &TP2->perigeeParameters();
1078  else cleanup.push_back(std::unique_ptr<const Trk::TrackParameters>(extrapolatedPerigee2));
1079  if(extrapolatedPerigee1 && extrapolatedPerigee2) {
1080  bool pass = false;
1081  TLorentzVector v1; TLorentzVector v2;
1082  if(!pass) {
1083  v1.SetXYZM(extrapolatedPerigee1->momentum().x(),extrapolatedPerigee1->momentum().y(),extrapolatedPerigee1->momentum().z(),m_mass_proton);
1084  v2.SetXYZM(extrapolatedPerigee2->momentum().x(),extrapolatedPerigee2->momentum().y(),extrapolatedPerigee2->momentum().z(),m_mass_pion);
1085  if((v1+v2).M()>1030.0 && (v1+v2).M()<1200.0) pass = true;
1086  }
1087  if(!pass) {
1088  v1.SetXYZM(extrapolatedPerigee1->momentum().x(),extrapolatedPerigee1->momentum().y(),extrapolatedPerigee1->momentum().z(),m_mass_pion);
1089  v2.SetXYZM(extrapolatedPerigee2->momentum().x(),extrapolatedPerigee2->momentum().y(),extrapolatedPerigee2->momentum().z(),m_mass_proton);
1090  if((v1+v2).M()>1030.0 && (v1+v2).M()<1200.0) pass = true;
1091  }
1092  if(!pass) {
1093  v1.SetXYZM(extrapolatedPerigee1->momentum().x(),extrapolatedPerigee1->momentum().y(),extrapolatedPerigee1->momentum().z(),m_mass_pion);
1094  v2.SetXYZM(extrapolatedPerigee2->momentum().x(),extrapolatedPerigee2->momentum().y(),extrapolatedPerigee2->momentum().z(),m_mass_pion);
1095  if((v1+v2).M()>430.0 && (v1+v2).M()<565.0) pass = true;
1096  }
1097  if(pass) {
1098  std::vector<const xAOD::TrackParticle*> tracksV0;
1099  tracksV0.push_back(TP1); tracksV0.push_back(TP2);
1100  std::unique_ptr<xAOD::Vertex> V0vtx = std::unique_ptr<xAOD::Vertex>( m_iV0Fitter->fit(tracksV0, startingPoint) );
1101  if(V0vtx && V0vtx->chiSquared()>=0) {
1102  double chi2DOF = V0vtx->chiSquared()/V0vtx->numberDoF();
1103  if(chi2DOF>m_chi2cut_V0) continue;
1104 
1105  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);
1106  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);
1107  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);
1108  if(massSig_V0_Lambda1<=massSig_V0_Lambda2 && massSig_V0_Lambda1<=massSig_V0_Ks) {
1109  mDec_type(*V0vtx.get()) = "Lambda";
1110  }
1111  else if(massSig_V0_Lambda2<=massSig_V0_Lambda1 && massSig_V0_Lambda2<=massSig_V0_Ks) {
1112  mDec_type(*V0vtx.get()) = "Lambdabar";
1113  }
1114  else if(massSig_V0_Ks<=massSig_V0_Lambda1 && massSig_V0_Ks<=massSig_V0_Lambda2) {
1115  mDec_type(*V0vtx.get()) = "Ks";
1116  }
1117 
1118  int gamma_fit = 0; int gamma_ndof = 0; double gamma_chisq = 999999.;
1119  double gamma_prob = -1., gamma_mass = -1., gamma_massErr = -1.;
1120  std::unique_ptr<xAOD::Vertex> gammaVtx = std::unique_ptr<xAOD::Vertex>( m_iGammaFitter->fit(tracksV0, m_V0Tools->vtx(V0vtx.get())) );
1121  if (gammaVtx) {
1122  gamma_fit = 1;
1123  gamma_mass = m_V0Tools->invariantMass(gammaVtx.get(),m_mass_e,m_mass_e);
1124  gamma_massErr = m_V0Tools->invariantMassError(gammaVtx.get(),m_mass_e,m_mass_e);
1125  gamma_chisq = m_V0Tools->chisq(gammaVtx.get());
1126  gamma_ndof = m_V0Tools->ndof(gammaVtx.get());
1127  gamma_prob = m_V0Tools->vertexProbability(gammaVtx.get());
1128  }
1129  mDec_gfit(*V0vtx.get()) = gamma_fit;
1130  mDec_gmass(*V0vtx.get()) = gamma_mass;
1131  mDec_gmasserr(*V0vtx.get()) = gamma_massErr;
1132  mDec_gchisq(*V0vtx.get()) = gamma_chisq;
1133  mDec_gndof(*V0vtx.get()) = gamma_ndof;
1134  mDec_gprob(*V0vtx.get()) = gamma_prob;
1135 
1136  xAOD::BPhysHelper V0_helper(V0vtx.get());
1137  V0_helper.setRefTrks(); // AOD only method
1138 
1139  if(not trackCols.empty()){
1140  try {
1141  JpsiUpsilonCommon::RelinkVertexTracks(trackCols, V0vtx.get());
1142  } catch (std::runtime_error const& e) {
1143  ATH_MSG_ERROR(e.what());
1144  return;
1145  }
1146  }
1147 
1148  V0ContainerNew->push_back(std::move(V0vtx));
1149  }
1150  }
1151  }
1152  }
1153  }
1154  }
1155  }
1156 
1157  template<size_t NTracks>
1159  for (const xAOD::Vertex* v1 : *cont) {
1160  assert(v1->nTrackParticles() == NTracks);
1161  std::array<const xAOD::TrackParticle*, NTracks> a1;
1162  std::array<const xAOD::TrackParticle*, NTracks> a2;
1163  for(size_t i=0; i<NTracks; i++){
1164  a1[i] = v1->trackParticle(i);
1165  a2[i] = v->trackParticle(i);
1166  }
1167  std::sort(a1.begin(), a1.end());
1168  std::sort(a2.begin(), a2.end());
1169  if(a1 == a2) return v1;
1170  }
1171  return nullptr;
1172  }
1173 }
xAOD::BPhysHypoHelper::setMass
bool setMass(const float val)
Set given invariant mass and its error.
Definition: BPhysHypoHelper.cxx:52
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
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
DerivationFramework::JpsiXPlus2V0::V0Enum
V0Enum
Definition: JpsiXPlus2V0.h:42
DerivationFramework::JpsiXPlus2V0::UNKNOWN
@ UNKNOWN
Definition: JpsiXPlus2V0.h:42
V0Tools.h
DerivationFramework::JpsiXPlus2V0::m_constrMainV
bool m_constrMainV
Definition: JpsiXPlus2V0.h:104
DerivationFramework::JpsiXPlus2V0::m_mass_phi
double m_mass_phi
Definition: JpsiXPlus2V0.h:143
DerivationFramework::JpsiXPlus2V0::m_diTrackMassLower
double m_diTrackMassLower
Definition: JpsiXPlus2V0.h:70
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_constrJX
bool m_constrJX
Definition: JpsiXPlus2V0.h:98
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:56
DerivationFramework::JpsiXPlus2V0::LAMBDA
@ LAMBDA
Definition: JpsiXPlus2V0.h:42
DerivationFramework::JpsiXPlus2V0::m_chi2cut_gamma
double m_chi2cut_gamma
Definition: JpsiXPlus2V0.h:81
DerivationFramework::JpsiXPlus2V0::m_refitPV
bool m_refitPV
Definition: JpsiXPlus2V0.h:130
DerivationFramework::JpsiXPlus2V0::m_constrV01
bool m_constrV01
Definition: JpsiXPlus2V0.h:101
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
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
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:118
make_coralServer_rep.opt
opt
Definition: make_coralServer_rep.py:19
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
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 std::vector< const xAOD::TrackParticleContainer * > &trackCols) const
Definition: JpsiXPlus2V0.cxx:779
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
DerivationFramework::JpsiXPlus2V0::m_mass_Bpm
double m_mass_Bpm
Definition: JpsiXPlus2V0.h:142
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
DerivationFramework::JpsiXPlus2V0::m_pvRefitter
ToolHandle< Analysis::PrimaryVertexRefitter > m_pvRefitter
Definition: JpsiXPlus2V0.h:120
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
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:85
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:72
DerivationFramework::JpsiXPlus2V0::m_massesV0_pip
std::vector< double > m_massesV0_pip
Definition: JpsiXPlus2V0.h:146
DerivationFramework::JpsiXPlus2V0::m_mass_Lambdab
double m_mass_Lambdab
Definition: JpsiXPlus2V0.h:140
skel.it
it
Definition: skel.GENtoEVGEN.py:407
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:108
ParticleTest.tp
tp
Definition: ParticleTest.py:25
DerivationFramework::JpsiXPlus2V0::m_jpsiMassUpper
double m_jpsiMassUpper
Definition: JpsiXPlus2V0.h:69
DerivationFramework::JpsiXPlus2V0::m_PV_minNTracks
size_t m_PV_minNTracks
Definition: JpsiXPlus2V0.h:132
DerivationFramework::JpsiXPlus2V0::KS
@ KS
Definition: JpsiXPlus2V0.h:42
DerivationFramework::JpsiXPlus2V0::m_useImprovedMass
bool m_useImprovedMass
Definition: JpsiXPlus2V0.h:65
DerivationFramework::JpsiXPlus2V0::m_iVertexFitter
ToolHandle< Trk::TrkVKalVrtFitter > m_iVertexFitter
Definition: JpsiXPlus2V0.h:117
IExtrapolator.h
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:260
DerivationFramework::JpsiXPlus2V0::m_V02Hypothesis
std::string m_V02Hypothesis
Definition: JpsiXPlus2V0.h:73
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
SG::WriteHandle::cptr
const_pointer_type cptr() const
Dereference the pointer.
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
DerivationFramework::JpsiXPlus2V0::m_PV_max
int m_PV_max
Definition: JpsiXPlus2V0.h:131
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
SG::ReadHandleKey< xAOD::TrackParticleContainer >
Trk::VxCascadeInfo::nDoF
int nDoF() const
Definition: VxCascadeInfo.h:133
DerivationFramework::JpsiXPlus2V0::m_chi2cut
double m_chi2cut
Definition: JpsiXPlus2V0.h:109
DerivationFramework::JpsiXPlus2V0::m_jxDaug2MassHypo
double m_jxDaug2MassHypo
Definition: JpsiXPlus2V0.h:88
DerivationFramework::JpsiXPlus2V0::m_jxDaug_num
int m_jxDaug_num
Definition: JpsiXPlus2V0.h:86
DerivationFramework::JpsiXPlus2V0::m_jxDaug3MassHypo
double m_jxDaug3MassHypo
Definition: JpsiXPlus2V0.h:89
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
DerivationFramework::JpsiXPlus2V0::m_mass_e
double m_mass_e
Definition: JpsiXPlus2V0.h:135
DerivationFramework::JpsiXPlus2V0::m_v0TrkSelector
ToolHandle< Trk::ITrackSelectorTool > m_v0TrkSelector
Definition: JpsiXPlus2V0.h:123
DerivationFramework::JpsiXPlus2V0::m_trackToVertexTool
ToolHandle< Reco::ITrackToVertex > m_trackToVertexTool
Definition: JpsiXPlus2V0.h:122
TrkVKalVrtFitter.h
DerivationFramework::JpsiXPlus2V0::m_lxyV02_cut
double m_lxyV02_cut
Definition: JpsiXPlus2V0.h:79
DerivationFramework::JpsiXPlus2V0::m_d0_cut
double m_d0_cut
Definition: JpsiXPlus2V0.h:112
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:112
DerivationFramework::JpsiXPlus2V0::m_massX
double m_massX
Definition: JpsiXPlus2V0.h:93
DerivationFramework::JpsiXPlus2V0::m_iGammaFitter
ToolHandle< Trk::IVertexFitter > m_iGammaFitter
Definition: JpsiXPlus2V0.h:119
DerivationFramework::JpsiXPlus2V0::m_useTRT
bool m_useTRT
Definition: JpsiXPlus2V0.h:110
DerivationFramework::JpsiXPlus2V0::m_constrV02
bool m_constrV02
Definition: JpsiXPlus2V0.h:102
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_mass_mu
double m_mass_mu
Definition: JpsiXPlus2V0.h:136
DerivationFramework::JpsiXPlus2V0::d0Pass
bool d0Pass(const xAOD::TrackParticle *track, const xAOD::Vertex *PV) const
Definition: JpsiXPlus2V0.cxx:768
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:141
DerivationFramework::JpsiXPlus2V0::fitV0Container
void fitV0Container(xAOD::VertexContainer *V0ContainerNew, const std::vector< const xAOD::TrackParticle * > &selectedTracks, const std::vector< const xAOD::TrackParticleContainer * > &trackCols) const
Definition: JpsiXPlus2V0.cxx:1044
DerivationFramework::JpsiXPlus2V0::m_KsMassUpper
double m_KsMassUpper
Definition: JpsiXPlus2V0.h:77
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:59
DerivationFramework::JpsiXPlus2V0::m_CascadeTools
ToolHandle< DerivationFramework::CascadeTools > m_CascadeTools
Definition: JpsiXPlus2V0.h:124
lumiFormat.i
int i
Definition: lumiFormat.py:85
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:367
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
DerivationFramework::JpsiXPlus2V0::m_massesV0_ppi
std::vector< double > m_massesV0_ppi
Definition: JpsiXPlus2V0.h:145
BPhysHypoHelper.h
: B-physics xAOD helpers.
DerivationFramework::JpsiXPlus2V0::m_LambdaMassUpper
double m_LambdaMassUpper
Definition: JpsiXPlus2V0.h:75
Trk::VxCascadeInfo::fitChi2
double fitChi2() const
Definition: VxCascadeInfo.h:134
DerivationFramework::JpsiXPlus2V0::m_JXSubVtx
bool m_JXSubVtx
Definition: JpsiXPlus2V0.h:105
DerivationFramework::JpsiXPlus2V0::m_massMainV
double m_massMainV
Definition: JpsiXPlus2V0.h:97
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
DerivationFramework::JpsiXPlus2V0::m_vertexV0ContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexV0ContainerKey
Definition: JpsiXPlus2V0.h:54
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:100
DerivationFramework::JpsiXPlus2V0::m_massLd
double m_massLd
Definition: JpsiXPlus2V0.h:94
DerivationFramework::JpsiXPlus2V0::m_ptTRT
double m_ptTRT
Definition: JpsiXPlus2V0.h:111
DerivationFramework::JpsiXPlus2V0::m_constrJXV02
bool m_constrJXV02
Definition: JpsiXPlus2V0.h:103
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DerivationFramework::JpsiXPlus2V0::m_lxyV01_cut
double m_lxyV01_cut
Definition: JpsiXPlus2V0.h:78
DerivationFramework::JpsiXPlus2V0::m_hypoName
std::string m_hypoName
Definition: JpsiXPlus2V0.h:63
DerivationFramework::JpsiXPlus2V0::JpsiXPlus2V0
JpsiXPlus2V0(const std::string &type, const std::string &name, const IInterface *parent)
Definition: JpsiXPlus2V0.cxx:29
DerivationFramework::JpsiXPlus2V0::LAMBDABAR
@ LAMBDABAR
Definition: JpsiXPlus2V0.h:42
JpsiUpsilonCommon.h
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
Trk::ParametersBase
Definition: ParametersBase.h:55
python.TrackLeptonConfig.trackContainer
string trackContainer
Definition: TrackLeptonConfig.py:23
DerivationFramework
THE reconstruction tool.
Definition: ParticleSortingAlg.h:24
DerivationFramework::JpsiXPlus2V0::m_massJXV02
double m_massJXV02
Definition: JpsiXPlus2V0.h:96
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::JpsiXPlus2V0::m_JXV02MassUpper
double m_JXV02MassUpper
Definition: JpsiXPlus2V0.h:83
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:794
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:92
DerivationFramework::JpsiXPlus2V0::m_diTrackMassUpper
double m_diTrackMassUpper
Definition: JpsiXPlus2V0.h:71
Analysis::JpsiUpsilonCommon::RelinkVertexTracks
static void RelinkVertexTracks(const std::vector< const xAOD::TrackParticleContainer * > &trkcols, xAOD::Vertex *vtx)
Definition: JpsiUpsilonCommon.cxx:126
DerivationFramework::JpsiXPlus2V0::m_vertexJXHypoNames
std::vector< std::string > m_vertexJXHypoNames
Definition: JpsiXPlus2V0.h:55
DerivationFramework::JpsiXPlus2V0::m_maxV0Candidates
unsigned int m_maxV0Candidates
Definition: JpsiXPlus2V0.h:114
DerivationFramework::JpsiXPlus2V0::m_RelinkContainers
SG::ReadHandleKeyArray< xAOD::TrackParticleContainer > m_RelinkContainers
Definition: JpsiXPlus2V0.h:62
DerivationFramework::JpsiXPlus2V0::m_vertexJXContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexJXContainerKey
Definition: JpsiXPlus2V0.h:53
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
Trk::d0
@ d0
Definition: ParamDefs.h:63
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
DerivationFramework::BPhysPVCascadeTools
Definition: BPhysPVCascadeTools.h:34
DerivationFramework::JpsiXPlus2V0::initialize
virtual StatusCode initialize() override
Definition: JpsiXPlus2V0.cxx:179
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
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_vertexEstimator
ToolHandle< InDet::VertexPointEstimator > m_vertexEstimator
Definition: JpsiXPlus2V0.h:125
DerivationFramework::JpsiXPlus2V0::m_DoVertexType
int m_DoVertexType
Definition: JpsiXPlus2V0.h:133
IVertexFitter.h
DerivationFramework::JpsiXPlus2V0::m_partPropSvc
ServiceHandle< IPartPropSvc > m_partPropSvc
Definition: JpsiXPlus2V0.h:128
DerivationFramework::JpsiXPlus2V0::m_JXV02SubVtx
bool m_JXV02SubVtx
Definition: JpsiXPlus2V0.h:106
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.
ReadCellNoiseFromCoolCompare.v2
v2
Definition: ReadCellNoiseFromCoolCompare.py:364
DerivationFramework::JpsiXPlus2V0::m_jxMassUpper
double m_jxMassUpper
Definition: JpsiXPlus2V0.h:67
python.PyAthena.v
v
Definition: PyAthena.py:154
DerivationFramework::JpsiXPlus2V0::m_extrapolator
ToolHandle< Trk::IExtrapolator > m_extrapolator
Definition: JpsiXPlus2V0.h:126
DerivationFramework::JpsiXPlus2V0::FindVertex
const xAOD::Vertex * FindVertex(const xAOD::VertexContainer *cont, const xAOD::Vertex *v) const
Definition: JpsiXPlus2V0.cxx:1158
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:113
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DerivationFramework::JpsiXPlus2V0::performSearch
StatusCode performSearch(std::vector< Trk::VxCascadeInfo * > &cascadeinfoContainer, const std::vector< std::pair< const xAOD::Vertex *, V0Enum > > &selectedV0Candidates) const
Definition: JpsiXPlus2V0.cxx:276
V0Container
V0Container
Definition: TrkEventTPCnv.cxx:157
DerivationFramework::JpsiXPlus2V0::m_mass_proton
double m_mass_proton
Definition: JpsiXPlus2V0.h:138
DerivationFramework::JpsiXPlus2V0::m_massJX
double m_massJX
Definition: JpsiXPlus2V0.h:91
DerivationFramework::JpsiXPlus2V0::m_v0VtxOutputKey
SG::WriteHandleKey< xAOD::VertexContainer > m_v0VtxOutputKey
Definition: JpsiXPlus2V0.h:57
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:269
Analysis::JpsiUpsilonCommon
Definition: JpsiUpsilonCommon.h:39
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
AthAlgTool
Definition: AthAlgTool.h:26
DerivationFramework::JpsiXPlus2V0::m_jxDaug1MassHypo
double m_jxDaug1MassHypo
Definition: JpsiXPlus2V0.h:87
DerivationFramework::JpsiXPlus2V0::m_massKs
double m_massKs
Definition: JpsiXPlus2V0.h:95
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
DerivationFramework::JpsiXPlus2V0::m_massesV0_pipi
std::vector< double > m_massesV0_pipi
Definition: JpsiXPlus2V0.h:147
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
DerivationFramework::JpsiXPlus2V0::addBranches
virtual StatusCode addBranches() const override
Pass the thinning service
Definition: JpsiXPlus2V0.cxx:424
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:121
DerivationFramework::JpsiXPlus2V0::m_constrJpsi
bool m_constrJpsi
Definition: JpsiXPlus2V0.h:99
DerivationFramework::JpsiXPlus2V0::m_maxMainVCandidates
unsigned int m_maxMainVCandidates
Definition: JpsiXPlus2V0.h:115
HepMCHelpers.h
xAOD::BPhysHypoHelper::setMassErr
bool setMassErr(const float val)
invariant mass error
Definition: BPhysHypoHelper.cxx:57
DerivationFramework::JpsiXPlus2V0::m_mass_Lambda
double m_mass_Lambda
Definition: JpsiXPlus2V0.h:139
DerivationFramework::JpsiXPlus2V0::m_mass_pion
double m_mass_pion
Definition: JpsiXPlus2V0.h:137
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:107
DerivationFramework::JpsiXPlus2V0::m_jxDaug4MassHypo
double m_jxDaug4MassHypo
Definition: JpsiXPlus2V0.h:90
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37