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