ATLAS Offline Software
PsiPlusPsiCascade.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  Contact: Xin Chen <xin.chen@cern.ch>
4 */
10 #include "GaudiKernel/IPartPropSvc.h"
15 #include "HepPDT/ParticleDataTable.hh"
17 #include <algorithm>
18 #include <functional>
19 
20 namespace DerivationFramework {
22  typedef std::vector<VertexLink> VertexLinkVector;
23 
25  // retrieving vertex Fitter
26  ATH_CHECK( m_iVertexFitter.retrieve() );
27 
28  // retrieve PV refitter
29  ATH_CHECK( m_pvRefitter.retrieve() );
30 
31  // retrieving the V0 tools
32  ATH_CHECK( m_V0Tools.retrieve() );
33 
34  // retrieving the Cascade tools
35  ATH_CHECK( m_CascadeTools.retrieve() );
36 
37  ATH_CHECK( m_vertexPsi1ContainerKey.initialize() );
38  ATH_CHECK( m_vertexPsi2ContainerKey.initialize() );
39  ATH_CHECK( m_VxPrimaryCandidateName.initialize() );
41  ATH_CHECK( m_refPVContainerName.initialize() );
42  ATH_CHECK( m_cascadeOutputsKeys.initialize() );
44 
45  IPartPropSvc* partPropSvc = nullptr;
46  ATH_CHECK( service("PartPropSvc", partPropSvc, true) );
47  auto pdt = partPropSvc->PDT();
48 
49  // retrieve particle masses
50  // https://gitlab.cern.ch/atlas/athena/-/blob/main/Generators/TruthUtils/TruthUtils/AtlasPID.h
55 
64 
65  return StatusCode::SUCCESS;
66  }
67 
69  if ((m_vtx1Daug_num != 3 && m_vtx1Daug_num != 4) || (m_vtx2Daug_num != 3 && m_vtx2Daug_num != 4)) {
70  ATH_MSG_FATAL("Incorrect number of Psi daughters (should be 3 or 4)");
71  return StatusCode::FAILURE;
72  }
73 
74  constexpr int topoN = 3;
75  if(m_cascadeOutputsKeys.size() != topoN) {
76  ATH_MSG_FATAL("Incorrect number of VtxContainers");
77  return StatusCode::FAILURE;
78  }
79  std::array<SG::WriteHandle<xAOD::VertexContainer>, topoN> VtxWriteHandles; int ikey(0);
81  VtxWriteHandles[ikey] = SG::WriteHandle<xAOD::VertexContainer>(key);
82  ATH_CHECK( VtxWriteHandles[ikey].record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
83  ikey++;
84  }
85 
86  //----------------------------------------------------
87  // retrieve primary vertices
88  //----------------------------------------------------
90  ATH_CHECK( pvContainer.isValid() );
91  if (pvContainer.cptr()->size()==0) {
92  ATH_MSG_WARNING("You have no primary vertices: " << pvContainer.cptr()->size());
93  return StatusCode::RECOVERABLE;
94  }
95 
96  //----------------------------------------------------
97  // Record refitted primary vertices
98  //----------------------------------------------------
100  if(m_refitPV) {
102  ATH_CHECK( refPvContainer.record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()) );
103  }
104 
105  std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
106  std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer_noConstr;
107  ATH_CHECK(performSearch(&cascadeinfoContainer,&cascadeinfoContainer_noConstr));
108 
110  ATH_CHECK( evt.isValid() );
112  helper.SetMinNTracksInPV(m_PV_minNTracks);
113 
114  // Decorators for the main vertex: chi2, ndf, pt and pt error, plus the V0 vertex variables
115  SG::AuxElement::Decorator<VertexLinkVector> CascadeLinksDecor("CascadeVertexLinks");
116  SG::AuxElement::Decorator<VertexLinkVector> Psi1LinksDecor("Psi1VertexLinks");
117  SG::AuxElement::Decorator<VertexLinkVector> Psi2LinksDecor("Psi2VertexLinks");
118  SG::AuxElement::Decorator<float> chi2_decor("ChiSquared");
119  SG::AuxElement::Decorator<int> ndof_decor("nDoF");
120  SG::AuxElement::Decorator<float> chi2_nc_decor("ChiSquared_nc");
121  SG::AuxElement::Decorator<int> ndof_nc_decor("nDoF_nc");
122  SG::AuxElement::Decorator<float> Pt_decor("Pt");
123  SG::AuxElement::Decorator<float> PtErr_decor("PtErr");
124  SG::AuxElement::Decorator<float> chi2_SV1_decor("ChiSquared_SV1");
125  SG::AuxElement::Decorator<float> chi2_nc_SV1_decor("ChiSquared_nc_SV1");
126  SG::AuxElement::Decorator<float> chi2_V1_decor("ChiSquared_V1");
127  SG::AuxElement::Decorator<int> ndof_V1_decor("nDoF_V1");
128  SG::AuxElement::Decorator<float> lxy_SV1_decor("lxy_SV1");
129  SG::AuxElement::Decorator<float> lxyErr_SV1_decor("lxyErr_SV1");
130  SG::AuxElement::Decorator<float> a0xy_SV1_decor("a0xy_SV1");
131  SG::AuxElement::Decorator<float> a0xyErr_SV1_decor("a0xyErr_SV1");
132  SG::AuxElement::Decorator<float> a0z_SV1_decor("a0z_SV1");
133  SG::AuxElement::Decorator<float> a0zErr_SV1_decor("a0zErr_SV1");
134  SG::AuxElement::Decorator<float> chi2_SV2_decor("ChiSquared_SV2");
135  SG::AuxElement::Decorator<float> chi2_nc_SV2_decor("ChiSquared_nc_SV2");
136  SG::AuxElement::Decorator<float> chi2_V2_decor("ChiSquared_V2");
137  SG::AuxElement::Decorator<int> ndof_V2_decor("nDoF_V2");
138  SG::AuxElement::Decorator<float> lxy_SV2_decor("lxy_SV2");
139  SG::AuxElement::Decorator<float> lxyErr_SV2_decor("lxyErr_SV2");
140  SG::AuxElement::Decorator<float> a0xy_SV2_decor("a0xy_SV2");
141  SG::AuxElement::Decorator<float> a0xyErr_SV2_decor("a0xyErr_SV2");
142  SG::AuxElement::Decorator<float> a0z_SV2_decor("a0z_SV2");
143  SG::AuxElement::Decorator<float> a0zErr_SV2_decor("a0zErr_SV2");
144 
145  // Get the container and identify the input Psi's
147  ATH_CHECK( psi1Container.isValid() );
149  ATH_CHECK( psi2Container.isValid() );
150 
151  for(size_t ic=0; ic<cascadeinfoContainer.size(); ic++) {
152  Trk::VxCascadeInfo* cascade_info = cascadeinfoContainer[ic];
153  if(cascade_info==nullptr) ATH_MSG_ERROR("CascadeInfo is null");
154 
155  Trk::VxCascadeInfo* cascade_info_noConstr = cascadeinfoContainer_noConstr[ic];
156 
157  const std::vector<xAOD::Vertex*> &cascadeVertices = cascade_info->vertices();
158  if(cascadeVertices.size() != topoN) ATH_MSG_ERROR("Incorrect number of vertices");
159  if(cascadeVertices[0]==nullptr || cascadeVertices[1]==nullptr || cascadeVertices[2]==nullptr) ATH_MSG_ERROR("Error null vertex");
160  // Keep vertices
161  for(int i=0; i<topoN; i++) VtxWriteHandles[i].ptr()->push_back(cascadeVertices[i]);
162 
163  cascade_info->setSVOwnership(false); // Prevent Container from deleting vertices
164  const auto mainVertex = cascadeVertices[2]; // this is the mother vertex
165  const std::vector< std::vector<TLorentzVector> > &moms = cascade_info->getParticleMoms();
166 
167  // Set links to cascade vertices
168  std::vector<VertexLink> precedingVertexLinks;
169  VertexLink vertexLink1;
170  vertexLink1.setElement(cascadeVertices[0]);
171  vertexLink1.setStorableObject(*VtxWriteHandles[0].ptr());
172  if( vertexLink1.isValid() ) precedingVertexLinks.push_back( vertexLink1 );
173  VertexLink vertexLink2;
174  vertexLink2.setElement(cascadeVertices[1]);
175  vertexLink2.setStorableObject(*VtxWriteHandles[1].ptr());
176  if( vertexLink2.isValid() ) precedingVertexLinks.push_back( vertexLink2 );
177  CascadeLinksDecor(*mainVertex) = precedingVertexLinks;
178 
179  // Identify the input Psi2
180  const xAOD::Vertex* psi2Vertex(0);
181  if(m_vtx2Daug_num==4) psi2Vertex = BPhysPVCascadeTools::FindVertex<4>(psi2Container.cptr(), cascadeVertices[1]);
182  else psi2Vertex = BPhysPVCascadeTools::FindVertex<3>(psi2Container.cptr(), cascadeVertices[1]);
183  // Identify the input Psi1
184  const xAOD::Vertex* psi1Vertex(0);
185  if(m_vtx1Daug_num==4) psi1Vertex = BPhysPVCascadeTools::FindVertex<4>(psi1Container.cptr(), cascadeVertices[0]);
186  else psi1Vertex = BPhysPVCascadeTools::FindVertex<3>(psi1Container.cptr(), cascadeVertices[0]);
187 
188  // Set links to input vertices
189  std::vector<const xAOD::Vertex*> psi2VerticestoLink;
190  if(psi2Vertex) psi2VerticestoLink.push_back(psi2Vertex);
191  else ATH_MSG_WARNING("Could not find linking Jpsi");
192  if(!BPhysPVCascadeTools::LinkVertices(Psi2LinksDecor, psi2VerticestoLink, psi2Container.cptr(), mainVertex)) ATH_MSG_ERROR("Error decorating with Psi2 vertex");
193 
194  std::vector<const xAOD::Vertex*> psi1VerticestoLink;
195  if(psi1Vertex) psi1VerticestoLink.push_back(psi1Vertex);
196  else ATH_MSG_WARNING("Could not find linking Psi1");
197  if(!BPhysPVCascadeTools::LinkVertices(Psi1LinksDecor, psi1VerticestoLink, psi1Container.cptr(), mainVertex)) ATH_MSG_ERROR("Error decorating with Psi1 vertex");
198 
199  xAOD::BPhysHypoHelper vtx(m_hypoName, mainVertex);
200 
201  // Get refitted track momenta from all vertices, charged tracks only
202  BPhysPVCascadeTools::SetVectorInfo(vtx, cascade_info);
203  vtx.setPass(true);
204 
205  //
206  // Decorate main vertex
207  //
208  // mass, mass error
209  // https://gitlab.cern.ch/atlas/athena/-/blob/21.2/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/VxCascadeInfo.h
210  BPHYS_CHECK( vtx.setMass(m_CascadeTools->invariantMass(moms[2])) );
211  BPHYS_CHECK( vtx.setMassErr(m_CascadeTools->invariantMassError(moms[2],cascade_info->getCovariance()[1])) );
212  // pt and pT error (the default pt of mainVertex is != the pt of the full cascade fit!)
213  Pt_decor(*mainVertex) = m_CascadeTools->pT(moms[2]);
214  PtErr_decor(*mainVertex) = m_CascadeTools->pTError(moms[2],cascade_info->getCovariance()[1]);
215  // chi2 and ndof (the default chi2 of mainVertex is != the chi2 of the full cascade fit!)
216  chi2_decor(*mainVertex) = cascade_info->fitChi2();
217  ndof_decor(*mainVertex) = cascade_info->nDoF();
218  chi2_nc_decor(*mainVertex) = cascade_info_noConstr ? cascade_info_noConstr->fitChi2() : -999999.;
219  ndof_nc_decor(*mainVertex) = cascade_info_noConstr ? cascade_info_noConstr->nDoF() : -1;
220 
221  // decorate the Psi1 vertex
222  chi2_SV1_decor(*cascadeVertices[0]) = m_V0Tools->chisq(cascadeVertices[0]);
223  chi2_nc_SV1_decor(*cascadeVertices[0]) = cascade_info_noConstr ? m_V0Tools->chisq(cascade_info_noConstr->vertices()[0]) : -999999.;
224  chi2_V1_decor(*cascadeVertices[0]) = m_V0Tools->chisq(psi1Vertex);
225  ndof_V1_decor(*cascadeVertices[0]) = m_V0Tools->ndof(psi1Vertex);
226  lxy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],mainVertex);
227  lxyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->lxyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
228  a0z_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0z(moms[0],cascadeVertices[0],mainVertex);
229  a0zErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0zError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
230  a0xy_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xy(moms[0],cascadeVertices[0],mainVertex);
231  a0xyErr_SV1_decor(*cascadeVertices[0]) = m_CascadeTools->a0xyError(moms[0],cascade_info->getCovariance()[0],cascadeVertices[0],mainVertex);
232 
233  // decorate the Psi2 vertex
234  chi2_SV2_decor(*cascadeVertices[1]) = m_V0Tools->chisq(cascadeVertices[1]);
235  chi2_nc_SV2_decor(*cascadeVertices[1]) = cascade_info_noConstr ? m_V0Tools->chisq(cascade_info_noConstr->vertices()[1]) : -999999.;
236  chi2_V2_decor(*cascadeVertices[1]) = m_V0Tools->chisq(psi2Vertex);
237  ndof_V2_decor(*cascadeVertices[1]) = m_V0Tools->ndof(psi2Vertex);
238  lxy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxy(moms[1],cascadeVertices[1],mainVertex);
239  lxyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->lxyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
240  a0z_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0z(moms[1],cascadeVertices[1],mainVertex);
241  a0zErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0zError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
242  a0xy_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xy(moms[1],cascadeVertices[1],mainVertex);
243  a0xyErr_SV2_decor(*cascadeVertices[1]) = m_CascadeTools->a0xyError(moms[1],cascade_info->getCovariance()[1],cascadeVertices[1],mainVertex);
244 
245  double Mass_Moth = m_CascadeTools->invariantMass(moms[2]); // size=2
246  ATH_CHECK(helper.FillCandwithRefittedVertices(m_refitPV, pvContainer.cptr(), m_refitPV ? refPvContainer.ptr() : 0, &(*m_pvRefitter), m_PV_max, m_DoVertexType, cascade_info, 2, Mass_Moth, vtx));
247  } // loop over cascadeinfoContainer
248 
249  // Deleting cascadeinfo since this won't be stored.
250  // Vertices have been kept in m_cascadeOutputs and should be owned by their container
251  for (auto cascade_info : cascadeinfoContainer) delete cascade_info;
252  for (auto cascade_info_noConstr : cascadeinfoContainer_noConstr) delete cascade_info_noConstr;
253 
254  return StatusCode::SUCCESS;
255  }
256 
257  PsiPlusPsiCascade::PsiPlusPsiCascade(const std::string& type, const std::string& name, const IInterface* parent) : AthAlgTool(type,name,parent),
258  m_vertexPsi1ContainerKey(""),
259  m_vertexPsi2ContainerKey(""),
260  m_cascadeOutputsKeys({"PsiPlusPsiCascadeVtx1", "PsiPlusPsiCascadeVtx2", "PsiPlusPsiCascadeVtx3"}),
261  m_VxPrimaryCandidateName("PrimaryVertices"),
262  m_trackContainerName("InDetTrackParticles"),
263  m_eventInfo_key("EventInfo"),
264  m_jpsi1MassLower(0.0),
265  m_jpsi1MassUpper(20000.0),
266  m_jpsi2MassLower(0.0),
267  m_jpsi2MassUpper(20000.0),
268  m_diTrack1MassLower(-1.0),
269  m_diTrack1MassUpper(-1.0),
270  m_diTrack2MassLower(-1.0),
271  m_diTrack2MassUpper(-1.0),
272  m_psi1MassLower(0.0),
273  m_psi1MassUpper(25000.0),
274  m_psi2MassLower(0.0),
275  m_psi2MassUpper(25000.0),
276  m_MassLower(0.0),
277  m_MassUpper(31000.0),
278  m_vtx1Daug_num(4),
279  m_vtx1Daug1MassHypo(-1),
280  m_vtx1Daug2MassHypo(-1),
281  m_vtx1Daug3MassHypo(-1),
282  m_vtx1Daug4MassHypo(-1),
283  m_vtx2Daug_num(4),
284  m_vtx2Daug1MassHypo(-1),
285  m_vtx2Daug2MassHypo(-1),
286  m_vtx2Daug3MassHypo(-1),
287  m_vtx2Daug4MassHypo(-1),
288  m_massPsi1(-1),
289  m_massPsi2(-1),
290  m_massJpsi1(-1),
291  m_massJpsi2(-1),
292  m_massDiTrk1(-1),
293  m_massDiTrk2(-1),
294  m_constrPsi1(false),
295  m_constrPsi2(false),
296  m_constrJpsi1(false),
297  m_constrJpsi2(false),
298  m_constrDiTrk1(false),
299  m_constrDiTrk2(false),
300  m_chi2cut_Psi1(-1.0),
301  m_chi2cut_Psi2(-1.0),
302  m_chi2cut(-1.0),
303  m_removeDuplicatePairs(false),
304  m_maxCandidates(0),
305  m_iVertexFitter("Trk::TrkVKalVrtFitter"),
306  m_pvRefitter("Analysis::PrimaryVertexRefitter", this),
307  m_V0Tools("Trk::V0Tools"),
308  m_CascadeTools("DerivationFramework::CascadeTools")
309  {
310  declareProperty("Psi1Vertices", m_vertexPsi1ContainerKey);
311  declareProperty("Psi2Vertices", m_vertexPsi2ContainerKey);
312  declareProperty("Psi1VtxHypoNames", m_vertexPsi1HypoNames);
313  declareProperty("Psi2VtxHypoNames", m_vertexPsi2HypoNames);
314  declareProperty("VxPrimaryCandidateName", m_VxPrimaryCandidateName);
315  declareProperty("TrackContainerName", m_trackContainerName);
316  declareProperty("RefPVContainerName", m_refPVContainerName = "RefittedPrimaryVertices");
317  declareProperty("Jpsi1MassLowerCut", m_jpsi1MassLower);
318  declareProperty("Jpsi1MassUpperCut", m_jpsi1MassUpper);
319  declareProperty("Jpsi2MassLowerCut", m_jpsi2MassLower);
320  declareProperty("Jpsi2MassUpperCut", m_jpsi2MassUpper);
321  declareProperty("DiTrack1MassLower", m_diTrack1MassLower); // only effective when m_vtx1Daug_num=4
322  declareProperty("DiTrack1MassUpper", m_diTrack1MassUpper); // only effective when m_vtx1Daug_num=4
323  declareProperty("DiTrack2MassLower", m_diTrack2MassLower); // only effective when m_vtx2Daug_num=4
324  declareProperty("DiTrack2MassUpper", m_diTrack2MassUpper); // only effective when m_vtx2Daug_num=4
325  declareProperty("Psi1MassLowerCut", m_psi1MassLower);
326  declareProperty("Psi1MassUpperCut", m_psi1MassUpper);
327  declareProperty("Psi2MassLowerCut", m_psi2MassLower);
328  declareProperty("Psi2MassUpperCut", m_psi2MassUpper);
329  declareProperty("MassLowerCut", m_MassLower);
330  declareProperty("MassUpperCut", m_MassUpper);
331  declareProperty("HypothesisName", m_hypoName = "TQ");
332  declareProperty("NumberOfPsi1Daughters", m_vtx1Daug_num); // 3 or 4 only
333  declareProperty("Vtx1Daug1MassHypo", m_vtx1Daug1MassHypo);
334  declareProperty("Vtx1Daug2MassHypo", m_vtx1Daug2MassHypo);
335  declareProperty("Vtx1Daug3MassHypo", m_vtx1Daug3MassHypo);
336  declareProperty("Vtx1Daug4MassHypo", m_vtx1Daug4MassHypo);
337  declareProperty("NumberOfPsi2Daughters", m_vtx2Daug_num); // 3 or 4 only
338  declareProperty("Vtx2Daug1MassHypo", m_vtx2Daug1MassHypo);
339  declareProperty("Vtx2Daug2MassHypo", m_vtx2Daug2MassHypo);
340  declareProperty("Vtx2Daug3MassHypo", m_vtx2Daug3MassHypo);
341  declareProperty("Vtx2Daug4MassHypo", m_vtx2Daug4MassHypo);
342  declareProperty("Jpsi1Mass", m_massJpsi1);
343  declareProperty("Jpsi2Mass", m_massJpsi2);
344  declareProperty("DiTrack1Mass", m_massDiTrk1);
345  declareProperty("DiTrack2Mass", m_massDiTrk2);
346  declareProperty("Psi1Mass", m_massPsi1);
347  declareProperty("Psi2Mass", m_massPsi2);
348  declareProperty("ApplyPsi1MassConstraint", m_constrPsi1);
349  declareProperty("ApplyPsi2MassConstraint", m_constrPsi2);
350  declareProperty("ApplyJpsi1MassConstraint", m_constrJpsi1);
351  declareProperty("ApplyJpsi2MassConstraint", m_constrJpsi2);
352  declareProperty("ApplyDiTrk1MassConstraint",m_constrDiTrk1); // only effective when m_vtx1Daug_num=4
353  declareProperty("ApplyDiTrk2MassConstraint",m_constrDiTrk2); // only effective when m_vtx2Daug_num=4
354  declareProperty("Chi2CutPsi1", m_chi2cut_Psi1);
355  declareProperty("Chi2CutPsi2", m_chi2cut_Psi2);
356  declareProperty("Chi2Cut", m_chi2cut);
357  declareProperty("RemoveDuplicatePairs", m_removeDuplicatePairs); // only effective when m_vertexPsi1ContainerKey == m_vertexPsi2ContainerKey
358  declareProperty("MaxCandidates", m_maxCandidates);
359  declareProperty("RefitPV", m_refitPV = true);
360  declareProperty("MaxnPV", m_PV_max = 1000);
361  declareProperty("MinNTracksInPV", m_PV_minNTracks = 0);
362  declareProperty("DoVertexType", m_DoVertexType = 7);
363  declareProperty("TrkVertexFitterTool", m_iVertexFitter);
364  declareProperty("PVRefitter", m_pvRefitter);
365  declareProperty("V0Tools", m_V0Tools);
366  declareProperty("CascadeTools", m_CascadeTools);
367  declareProperty("CascadeVertexCollections", m_cascadeOutputsKeys);
368  }
369 
370  StatusCode PsiPlusPsiCascade::performSearch(std::vector<Trk::VxCascadeInfo*> *cascadeinfoContainer, std::vector<Trk::VxCascadeInfo*> *cascadeinfoContainer_noConstr) const {
371  ATH_MSG_DEBUG( "PsiPlusPsiCascade::performSearch" );
372  assert(cascadeinfoContainer!=nullptr && cascadeinfoContainer_noConstr!=nullptr);
373 
374  // Get TrackParticle container (for setting links to the original tracks)
376  ATH_CHECK( trackContainer.isValid() );
377 
378  std::vector<const xAOD::TrackParticle*> tracksJpsi1;
379  std::vector<const xAOD::TrackParticle*> tracksJpsi2;
380  std::vector<const xAOD::TrackParticle*> tracksDiTrk1;
381  std::vector<const xAOD::TrackParticle*> tracksDiTrk2;
382  std::vector<const xAOD::TrackParticle*> tracksPsi1;
383  std::vector<const xAOD::TrackParticle*> tracksPsi2;
384  std::vector<double> massesPsi1;
385  massesPsi1.push_back(m_vtx1Daug1MassHypo);
386  massesPsi1.push_back(m_vtx1Daug2MassHypo);
387  massesPsi1.push_back(m_vtx1Daug3MassHypo);
388  if(m_vtx1Daug_num==4) massesPsi1.push_back(m_vtx1Daug4MassHypo);
389  std::vector<double> massesPsi2;
390  massesPsi2.push_back(m_vtx2Daug1MassHypo);
391  massesPsi2.push_back(m_vtx2Daug2MassHypo);
392  massesPsi2.push_back(m_vtx2Daug3MassHypo);
393  if(m_vtx2Daug_num==4) massesPsi2.push_back(m_vtx2Daug4MassHypo);
394 
395  // Get Psi1 container
397  ATH_CHECK( psi1Container.isValid() );
398 
399  // Get Psi2 container
401  ATH_CHECK( psi2Container.isValid() );
402 
403  // Select the Psi2 candidates before calling cascade fit
404  std::vector<const xAOD::Vertex*> selectedPsi2Candidates;
405  for(auto vxcItr=psi2Container.cptr()->cbegin(); vxcItr!=psi2Container.cptr()->cend(); ++vxcItr) {
406  // Check the passed flag first
407  const xAOD::Vertex* vtx = *vxcItr;
408  bool passed = false;
409  for(size_t i=0; i<m_vertexPsi2HypoNames.size(); i++) {
411  if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
412  passed |= 1;
413  }
414  }
415  if(m_vertexPsi2HypoNames.size() && !passed) continue;
416 
417  // Check Psi2 candidate invariant mass and skip if need be
418  double mass_psi2 = m_V0Tools->invariantMass(*vxcItr, massesPsi2);
419  if (mass_psi2 < m_psi2MassLower || mass_psi2 > m_psi2MassUpper) continue;
420 
421  // Add loose cut on Jpsi2 mass from Psi2 -> Jpsi2 pi+ pi-, or on phi mass from Ds+ -> phi pi+
422  TLorentzVector p4_mu1, p4_mu2;
423  p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
424  (*vxcItr)->trackParticle(0)->eta(),
425  (*vxcItr)->trackParticle(0)->phi(), m_vtx2Daug1MassHypo);
426  p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
427  (*vxcItr)->trackParticle(1)->eta(),
428  (*vxcItr)->trackParticle(1)->phi(), m_vtx2Daug2MassHypo);
429  double mass_jpsi2 = (p4_mu1 + p4_mu2).M();
430  if (mass_jpsi2 < m_jpsi2MassLower || mass_jpsi2 > m_jpsi2MassUpper) continue;
431 
433  TLorentzVector p4_trk1, p4_trk2;
434  p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
435  (*vxcItr)->trackParticle(2)->eta(),
436  (*vxcItr)->trackParticle(2)->phi(), m_vtx2Daug3MassHypo);
437  p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
438  (*vxcItr)->trackParticle(3)->eta(),
439  (*vxcItr)->trackParticle(3)->phi(), m_vtx2Daug4MassHypo);
440  double mass_diTrk2 = (p4_trk1 + p4_trk2).M();
441  if (mass_diTrk2 < m_diTrack2MassLower || mass_diTrk2 > m_diTrack2MassUpper) continue;
442  }
443 
444  double chi2DOF = (*vxcItr)->chiSquared()/(*vxcItr)->numberDoF();
445  if(m_chi2cut_Psi2>0 && chi2DOF>m_chi2cut_Psi2) continue;
446 
447  selectedPsi2Candidates.push_back(*vxcItr);
448  }
449  if(selectedPsi2Candidates.size()==0) return StatusCode::SUCCESS;
450 
451  // Select the Psi1 candidates before calling cascade fit
452  std::vector<const xAOD::Vertex*> selectedPsi1Candidates;
453  for(auto vxcItr=psi1Container.cptr()->cbegin(); vxcItr!=psi1Container.cptr()->cend(); ++vxcItr) {
454  // Check the passed flag first
455  const xAOD::Vertex* vtx = *vxcItr;
456  bool passed = false;
457  for(size_t i=0; i<m_vertexPsi1HypoNames.size(); i++) {
459  if(flagAcc.isAvailable(*vtx) && flagAcc(*vtx)) {
460  passed |= 1;
461  }
462  }
463  if(m_vertexPsi1HypoNames.size() && !passed) continue;
464 
465  // Check Psi candidate invariant mass and skip if need be
466  double mass_psi1 = m_V0Tools->invariantMass(*vxcItr,massesPsi1);
467  if(mass_psi1 < m_psi1MassLower || mass_psi1 > m_psi1MassUpper) continue;
468 
469  // Add loose cut on Jpsi1 mass from Psi1 -> Jpsi1 pi+ pi-, or on phi mass from Ds+ -> phi pi+
470  TLorentzVector p4_mu1, p4_mu2;
471  p4_mu1.SetPtEtaPhiM( (*vxcItr)->trackParticle(0)->pt(),
472  (*vxcItr)->trackParticle(0)->eta(),
473  (*vxcItr)->trackParticle(0)->phi(), m_vtx1Daug1MassHypo);
474  p4_mu2.SetPtEtaPhiM( (*vxcItr)->trackParticle(1)->pt(),
475  (*vxcItr)->trackParticle(1)->eta(),
476  (*vxcItr)->trackParticle(1)->phi(), m_vtx1Daug2MassHypo);
477  double mass_jpsi1 = (p4_mu1 + p4_mu2).M();
478  if (mass_jpsi1 < m_jpsi1MassLower || mass_jpsi1 > m_jpsi1MassUpper) continue;
479 
481  TLorentzVector p4_trk1, p4_trk2;
482  p4_trk1.SetPtEtaPhiM( (*vxcItr)->trackParticle(2)->pt(),
483  (*vxcItr)->trackParticle(2)->eta(),
484  (*vxcItr)->trackParticle(2)->phi(), m_vtx1Daug3MassHypo);
485  p4_trk2.SetPtEtaPhiM( (*vxcItr)->trackParticle(3)->pt(),
486  (*vxcItr)->trackParticle(3)->eta(),
487  (*vxcItr)->trackParticle(3)->phi(), m_vtx1Daug4MassHypo);
488  double mass_diTrk1 = (p4_trk1 + p4_trk2).M();
489  if (mass_diTrk1 < m_diTrack1MassLower || mass_diTrk1 > m_diTrack1MassUpper) continue;
490  }
491 
492  double chi2DOF = (*vxcItr)->chiSquared()/(*vxcItr)->numberDoF();
493  if(m_chi2cut_Psi1>0 && chi2DOF>m_chi2cut_Psi1) continue;
494 
495  selectedPsi1Candidates.push_back(*vxcItr);
496  }
497  if(selectedPsi1Candidates.size()==0) return StatusCode::SUCCESS;
498 
499  std::vector<std::pair<const xAOD::Vertex*, const xAOD::Vertex*> > candidatePairs;
500  for(auto psi1Itr=selectedPsi1Candidates.cbegin(); psi1Itr!=selectedPsi1Candidates.cend(); ++psi1Itr) {
501  tracksPsi1.clear();
502  for(size_t i=0; i<(*psi1Itr)->nTrackParticles(); i++) tracksPsi1.push_back((*psi1Itr)->trackParticle(i));
503  for(auto psi2Itr=selectedPsi2Candidates.cbegin(); psi2Itr!=selectedPsi2Candidates.cend(); ++psi2Itr) {
504  bool skip = false;
505  for(size_t j=0; j<(*psi2Itr)->nTrackParticles(); j++) {
506  if(std::find(tracksPsi1.cbegin(), tracksPsi1.cend(), (*psi2Itr)->trackParticle(j)) != tracksPsi1.cend()) { skip = true; break; }
507  }
508  if(skip) continue;
510  for(size_t ic=0; ic<candidatePairs.size(); ic++) {
511  const xAOD::Vertex* psi1Vertex = candidatePairs[ic].first;
512  const xAOD::Vertex* psi2Vertex = candidatePairs[ic].second;
513  if((psi1Vertex == *psi1Itr && psi2Vertex == *psi2Itr) || (psi1Vertex == *psi2Itr && psi2Vertex == *psi1Itr)) { skip = true; break; }
514  }
515  }
516  if(skip) continue;
517  candidatePairs.push_back(std::pair<const xAOD::Vertex*, const xAOD::Vertex*>(*psi1Itr,*psi2Itr));
518  }
519  }
520 
521  std::sort( candidatePairs.begin(), candidatePairs.end(), [](std::pair<const xAOD::Vertex*, const xAOD::Vertex*> a, std::pair<const xAOD::Vertex*, const xAOD::Vertex*> b) { return a.first->chiSquared()/a.first->numberDoF()+a.second->chiSquared()/a.second->numberDoF() < b.first->chiSquared()/b.first->numberDoF()+b.second->chiSquared()/b.second->numberDoF(); } );
522  if(m_maxCandidates>0 && candidatePairs.size()>m_maxCandidates) {
523  candidatePairs.erase(candidatePairs.begin()+m_maxCandidates, candidatePairs.end());
524  }
525 
526  for(size_t ic=0; ic<candidatePairs.size(); ic++) {
527  const xAOD::Vertex* psi1Vertex = candidatePairs[ic].first;
528  const xAOD::Vertex* psi2Vertex = candidatePairs[ic].second;
529 
530  tracksPsi1.clear();
531  for(size_t it=0; it<psi1Vertex->nTrackParticles(); it++) tracksPsi1.push_back(psi1Vertex->trackParticle(it));
532  if (tracksPsi1.size() != massesPsi1.size()) {
533  ATH_MSG_ERROR("Problems with Psi1 input: number of tracks or track mass inputs is not correct!");
534  }
535  tracksPsi2.clear();
536  for(size_t it=0; it<psi2Vertex->nTrackParticles(); it++) tracksPsi2.push_back(psi2Vertex->trackParticle(it));
537  if (tracksPsi2.size() != massesPsi2.size()) {
538  ATH_MSG_ERROR("Problems with Psi2 input: number of tracks or track mass inputs is not correct!");
539  }
540 
541  tracksJpsi1.clear();
542  tracksJpsi1.push_back(psi1Vertex->trackParticle(0));
543  tracksJpsi1.push_back(psi1Vertex->trackParticle(1));
544  tracksDiTrk1.clear();
545  if(m_vtx1Daug_num==4) {
546  tracksDiTrk1.push_back(psi1Vertex->trackParticle(2));
547  tracksDiTrk1.push_back(psi1Vertex->trackParticle(3));
548  }
549  tracksJpsi2.clear();
550  tracksJpsi2.push_back(psi2Vertex->trackParticle(0));
551  tracksJpsi2.push_back(psi2Vertex->trackParticle(1));
552  tracksDiTrk2.clear();
553  if(m_vtx2Daug_num==4) {
554  tracksDiTrk2.push_back(psi2Vertex->trackParticle(2));
555  tracksDiTrk2.push_back(psi2Vertex->trackParticle(3));
556  }
557 
558  TLorentzVector p4_moth;
559  TLorentzVector tmp;
560  for(size_t it=0; it<psi1Vertex->nTrackParticles(); it++) {
561  tmp.SetPtEtaPhiM(psi1Vertex->trackParticle(it)->pt(),psi1Vertex->trackParticle(it)->eta(),psi1Vertex->trackParticle(it)->phi(),massesPsi1[it]);
562  p4_moth += tmp;
563  }
564  for(size_t it=0; it<psi2Vertex->nTrackParticles(); it++) {
565  tmp.SetPtEtaPhiM(psi2Vertex->trackParticle(it)->pt(),psi2Vertex->trackParticle(it)->eta(),psi2Vertex->trackParticle(it)->phi(),massesPsi2[it]);
566  p4_moth += tmp;
567  }
568  if (p4_moth.M() < m_MassLower || p4_moth.M() > m_MassUpper) continue;
569 
570  // Apply the user's settings to the fitter
571  std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
572  // Robustness: http://cdsweb.cern.ch/record/685551
573  int robustness = 0;
574  m_iVertexFitter->setRobustness(robustness, *state);
575  // Build up the topology
576  // Vertex list
577  std::vector<Trk::VertexID> vrtList;
578  // Psi1 vertex
579  Trk::VertexID vID1;
580  // https://gitlab.cern.ch/atlas/athena/-/blob/21.2/Tracking/TrkVertexFitter/TrkVKalVrtFitter/TrkVKalVrtFitter/IVertexCascadeFitter.h
581  if (m_constrPsi1) {
582  vID1 = m_iVertexFitter->startVertex(tracksPsi1,massesPsi1,*state,m_massPsi1);
583  } else {
584  vID1 = m_iVertexFitter->startVertex(tracksPsi1,massesPsi1,*state);
585  }
586  vrtList.push_back(vID1);
587  // Psi2 vertex
588  Trk::VertexID vID2;
589  if (m_constrPsi2) {
590  vID2 = m_iVertexFitter->nextVertex(tracksPsi2,massesPsi2,*state,m_massPsi2);
591  } else {
592  vID2 = m_iVertexFitter->nextVertex(tracksPsi2,massesPsi2,*state);
593  }
594  vrtList.push_back(vID2);
595  // Mother vertex including Psi1 and Psi2
596  std::vector<const xAOD::TrackParticle*> tp; tp.clear();
597  std::vector<double> tp_masses; tp_masses.clear();
598  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList,*state);
599  if (m_constrJpsi1) {
600  std::vector<Trk::VertexID> cnstV; cnstV.clear();
601  if ( !m_iVertexFitter->addMassConstraint(vID1,tracksJpsi1,cnstV,*state,m_massJpsi1).isSuccess() ) {
602  ATH_MSG_WARNING("addMassConstraint for Jpsi1 failed");
603  }
604  }
605  if (m_constrDiTrk1 && m_vtx1Daug_num==4 && m_massDiTrk1>0) {
606  std::vector<Trk::VertexID> cnstV; cnstV.clear();
607  if ( !m_iVertexFitter->addMassConstraint(vID1,tracksDiTrk1,cnstV,*state,m_massDiTrk1).isSuccess() ) {
608  ATH_MSG_WARNING("addMassConstraint for DiTrk1 failed");
609  }
610  }
611  if (m_constrJpsi2) {
612  std::vector<Trk::VertexID> cnstV; cnstV.clear();
613  if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi2,cnstV,*state,m_massJpsi2).isSuccess() ) {
614  ATH_MSG_WARNING("addMassConstraint for Jpsi2 failed");
615  }
616  }
617  if (m_constrDiTrk2 && m_vtx2Daug_num==4 && m_massDiTrk2>0) {
618  std::vector<Trk::VertexID> cnstV; cnstV.clear();
619  if ( !m_iVertexFitter->addMassConstraint(vID2,tracksDiTrk2,cnstV,*state,m_massDiTrk2).isSuccess() ) {
620  ATH_MSG_WARNING("addMassConstraint for DiTrk2 failed");
621  }
622  }
623  // Do the work
624  std::unique_ptr<Trk::VxCascadeInfo> result(m_iVertexFitter->fitCascade(*state));
625 
626  bool pass = false;
627  if (result != nullptr) {
628  for(auto v : result->vertices()) {
629  if(v->nTrackParticles()==0) {
630  std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
631  v->setTrackParticleLinks(nullLinkVector);
632  }
633  }
634  // reset links to original tracks
635  BPhysPVCascadeTools::PrepareVertexLinks(result.get(), trackContainer.cptr());
636 
637  // necessary to prevent memory leak
638  result->setSVOwnership(true);
639 
640  // Chi2/DOF cut
641  double chi2DOF = result->fitChi2()/result->nDoF();
642  bool chi2CutPassed = (m_chi2cut <= 0.0 || chi2DOF < m_chi2cut);
643 
644  if(chi2CutPassed) {
645  cascadeinfoContainer->push_back(result.release());
646  pass = true;
647  }
648  }
649 
650  // do cascade fit again without any mass constraints
651  if(pass) {
653  std::unique_ptr<Trk::IVKalState> state (m_iVertexFitter->makeState());
654  m_iVertexFitter->setRobustness(robustness, *state);
655  std::vector<Trk::VertexID> vrtList_nc;
656  // Psi1 vertex
657  Trk::VertexID vID1_nc = m_iVertexFitter->startVertex(tracksPsi1,massesPsi1,*state);
658  vrtList_nc.push_back(vID1_nc);
659  // Psi2 vertex
660  Trk::VertexID vID2_nc = m_iVertexFitter->nextVertex(tracksPsi2,massesPsi2,*state);
661  vrtList_nc.push_back(vID2_nc);
662  // Mother vertex including Psi1 and Psi2
663  std::vector<const xAOD::TrackParticle*> tp; tp.clear();
664  std::vector<double> tp_masses; tp_masses.clear();
665  m_iVertexFitter->nextVertex(tp,tp_masses,vrtList_nc,*state);
666  // Do the work
667  std::unique_ptr<Trk::VxCascadeInfo> result_nc(m_iVertexFitter->fitCascade(*state));
668 
669  if (result_nc != nullptr) {
670  for(auto v : result_nc->vertices()) {
671  if(v->nTrackParticles()==0) {
672  std::vector<ElementLink<xAOD::TrackParticleContainer> > nullLinkVector;
673  v->setTrackParticleLinks(nullLinkVector);
674  }
675  }
676  // reset links to original tracks
677  BPhysPVCascadeTools::PrepareVertexLinks(result_nc.get(), trackContainer.cptr());
678 
679  // necessary to prevent memory leak
680  result_nc->setSVOwnership(true);
681  cascadeinfoContainer_noConstr->push_back(result_nc.release());
682  }
683  else cascadeinfoContainer_noConstr->push_back(0);
684  }
685  else cascadeinfoContainer_noConstr->push_back(0);
686  }
687  } //Iterate over candidatePairs
688 
689  return StatusCode::SUCCESS;
690  }
691 }
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
DerivationFramework::PsiPlusPsiCascade::m_psi1MassUpper
double m_psi1MassUpper
Definition: PsiPlusPsiCascade.h:62
Trk::VxSecVertexInfo::setSVOwnership
void setSVOwnership(bool Ownership)
Definition: VxSecVertexInfo.h:118
DerivationFramework::PsiPlusPsiCascade::m_PV_minNTracks
size_t m_PV_minNTracks
Definition: PsiPlusPsiCascade.h:106
V0Tools.h
DerivationFramework::PsiPlusPsiCascade::m_MassUpper
double m_MassUpper
Definition: PsiPlusPsiCascade.h:66
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DerivationFramework::PsiPlusPsiCascade::m_refitPV
bool m_refitPV
Definition: PsiPlusPsiCascade.h:101
DerivationFramework::PsiPlusPsiCascade::m_constrDiTrk2
bool m_constrDiTrk2
Definition: PsiPlusPsiCascade.h:89
DerivationFramework::PsiPlusPsiCascade::m_massDiTrk2
double m_massDiTrk2
Definition: PsiPlusPsiCascade.h:83
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
Trk::VxCascadeInfo
Definition: VxCascadeInfo.h:75
Trk::VertexID
int VertexID
Definition: IVertexCascadeFitter.h:23
TrigCompositeUtils::passed
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
Definition: TrigCompositeUtilsRoot.cxx:117
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
DerivationFramework::BPhysPVCascadeTools::LinkVertices
static bool LinkVertices(SG::AuxElement::Decorator< VertexLinkVector > &decor, const std::vector< const xAOD::Vertex * > &vertices, const xAOD::VertexContainer *vertexContainer, const xAOD::Vertex *vert)
Definition: BPhysPVCascadeTools.cxx:460
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:66
DerivationFramework::PsiPlusPsiCascade::m_vtx1Daug_num
int m_vtx1Daug_num
Definition: PsiPlusPsiCascade.h:67
DerivationFramework::PsiPlusPsiCascade::m_jpsi1MassUpper
double m_jpsi1MassUpper
Definition: PsiPlusPsiCascade.h:54
DerivationFramework::PsiPlusPsiCascade::m_vertexPsi2ContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexPsi2ContainerKey
Definition: PsiPlusPsiCascade.h:45
DerivationFramework::PsiPlusPsiCascade::m_eventInfo_key
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo_key
Definition: PsiPlusPsiCascade.h:51
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
xAOD::TrackParticle_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: TrackParticle_v1.cxx:77
DerivationFramework::PsiPlusPsiCascade::m_constrPsi2
bool m_constrPsi2
Definition: PsiPlusPsiCascade.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::PsiPlusPsiCascade::m_vtx2Daug3MassHypo
double m_vtx2Daug3MassHypo
Definition: PsiPlusPsiCascade.h:75
skel.it
it
Definition: skel.GENtoEVGEN.py:423
ParticleTest.tp
tp
Definition: ParticleTest.py:25
DerivationFramework::PsiPlusPsiCascade::m_chi2cut
double m_chi2cut
Definition: PsiPlusPsiCascade.h:92
DataVector::cend
const_iterator cend() const noexcept
Return a const_iterator pointing past the end of the collection.
DerivationFramework::PsiPlusPsiCascade::m_trackContainerName
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trackContainerName
Definition: PsiPlusPsiCascade.h:50
PsiPlusPsiCascade.h
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
Trk::VxCascadeInfo::nDoF
int nDoF() const
Definition: VxCascadeInfo.h:133
Trk::VxCascadeInfo::getCovariance
const std::vector< Amg::MatrixX > & getCovariance() const
Definition: VxCascadeInfo.h:132
DerivationFramework::PsiPlusPsiCascade::m_constrJpsi1
bool m_constrJpsi1
Definition: PsiPlusPsiCascade.h:86
DerivationFramework::PsiPlusPsiCascade::m_massPsi1
double m_massPsi1
Definition: PsiPlusPsiCascade.h:78
DerivationFramework::PsiPlusPsiCascade::m_vertexPsi1ContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexPsi1ContainerKey
Definition: PsiPlusPsiCascade.h:44
DerivationFramework::PsiPlusPsiCascade::m_vertexPsi1HypoNames
std::vector< std::string > m_vertexPsi1HypoNames
Definition: PsiPlusPsiCascade.h:46
TrkVKalVrtFitter.h
DerivationFramework::PsiPlusPsiCascade::addBranches
virtual StatusCode addBranches() const override
Pass the thinning service
Definition: PsiPlusPsiCascade.cxx:68
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:112
DerivationFramework::PsiPlusPsiCascade::m_massDiTrk1
double m_massDiTrk1
Definition: PsiPlusPsiCascade.h:82
DerivationFramework::PsiPlusPsiCascade::m_DoVertexType
int m_DoVertexType
Definition: PsiPlusPsiCascade.h:105
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
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
DerivationFramework::PsiPlusPsiCascade::m_jpsi2MassUpper
double m_jpsi2MassUpper
Definition: PsiPlusPsiCascade.h:56
SG::WriteHandleKey
Property holding a SG store/key/clid from which a WriteHandle is made.
Definition: StoreGate/StoreGate/WriteHandleKey.h:40
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:58
lumiFormat.i
int i
Definition: lumiFormat.py:92
xAOD::BPhysHypoHelper::setPass
bool setPass(bool passVal)
get the pass flag for this hypothesis
Definition: BPhysHypoHelper.cxx:364
DerivationFramework::PsiPlusPsiCascade::m_vtx2Daug4MassHypo
double m_vtx2Daug4MassHypo
Definition: PsiPlusPsiCascade.h:76
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
BPhysHypoHelper.h
: B-physcis xAOD helpers.
DerivationFramework::PsiPlusPsiCascade::m_vtx1Daug4MassHypo
double m_vtx1Daug4MassHypo
Definition: PsiPlusPsiCascade.h:71
Trk::VxCascadeInfo::fitChi2
double fitChi2() const
Definition: VxCascadeInfo.h:134
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
MUON
xAOD::Muon MUON
D3PD INCLUDES.
Definition: TileCellFillerTool.h:37
DerivationFramework::PsiPlusPsiCascade::m_psi2MassUpper
double m_psi2MassUpper
Definition: PsiPlusPsiCascade.h:64
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::Vertex_v1::trackParticle
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
Definition: Vertex_v1.cxx:249
DerivationFramework
THE reconstruction tool.
Definition: ParticleSortingAlg.h:24
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DerivationFramework::VertexLink
ElementLink< xAOD::VertexContainer > VertexLink
Definition: Cascade3Plus1.cxx:23
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
BPhysPVCascadeTools.h
DerivationFramework::PsiPlusPsiCascade::m_chi2cut_Psi1
double m_chi2cut_Psi1
Definition: PsiPlusPsiCascade.h:90
DerivationFramework::PsiPlusPsiCascade::initialize
virtual StatusCode initialize() override
Definition: PsiPlusPsiCascade.cxx:24
DerivationFramework::PsiPlusPsiCascade::m_vtx2Daug1MassHypo
double m_vtx2Daug1MassHypo
Definition: PsiPlusPsiCascade.h:73
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
DerivationFramework::PsiPlusPsiCascade::performSearch
StatusCode performSearch(std::vector< Trk::VxCascadeInfo * > *cascadeinfoContainer, std::vector< Trk::VxCascadeInfo * > *cascadeinfoContainer_noConstr) const
Definition: PsiPlusPsiCascade.cxx:370
DerivationFramework::PsiPlusPsiCascade::m_VxPrimaryCandidateName
SG::ReadHandleKey< xAOD::VertexContainer > m_VxPrimaryCandidateName
Name of primary vertex container.
Definition: PsiPlusPsiCascade.h:49
grepfile.ic
int ic
Definition: grepfile.py:33
DerivationFramework::PsiPlusPsiCascade::m_diTrack1MassUpper
double m_diTrack1MassUpper
Definition: PsiPlusPsiCascade.h:58
DerivationFramework::PsiPlusPsiCascade::m_diTrack1MassLower
double m_diTrack1MassLower
Definition: PsiPlusPsiCascade.h:57
DerivationFramework::PsiPlusPsiCascade::m_vtx2Daug_num
int m_vtx2Daug_num
Definition: PsiPlusPsiCascade.h:72
DerivationFramework::PsiPlusPsiCascade::m_iVertexFitter
ToolHandle< Trk::TrkVKalVrtFitter > m_iVertexFitter
Definition: PsiPlusPsiCascade.h:96
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
DerivationFramework::PsiPlusPsiCascade::m_massJpsi1
double m_massJpsi1
Definition: PsiPlusPsiCascade.h:80
DerivationFramework::PsiPlusPsiCascade::m_refPVContainerName
SG::WriteHandleKey< xAOD::VertexContainer > m_refPVContainerName
Definition: PsiPlusPsiCascade.h:102
DerivationFramework::BPhysPVCascadeTools
Definition: BPhysPVCascadeTools.h:34
DerivationFramework::PsiPlusPsiCascade::m_massJpsi2
double m_massJpsi2
Definition: PsiPlusPsiCascade.h:81
DerivationFramework::PsiPlusPsiCascade::m_MassLower
double m_MassLower
Definition: PsiPlusPsiCascade.h:65
DerivationFramework::PsiPlusPsiCascade::m_maxCandidates
unsigned int m_maxCandidates
Definition: PsiPlusPsiCascade.h:94
CascadeTools.h
Trk::VxCascadeInfo::getParticleMoms
const std::vector< std::vector< TLorentzVector > > & getParticleMoms() const
Definition: VxCascadeInfo.h:131
IVertexFitter.h
DerivationFramework::PsiPlusPsiCascade::m_V0Tools
ToolHandle< Trk::V0Tools > m_V0Tools
Definition: PsiPlusPsiCascade.h:98
VxCascadeInfo.h
python.PyAthena.v
v
Definition: PyAthena.py:157
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
DerivationFramework::PsiPlusPsiCascade::m_constrPsi1
bool m_constrPsi1
Definition: PsiPlusPsiCascade.h:84
DerivationFramework::VertexLinkVector
std::vector< VertexLink > VertexLinkVector
Definition: Cascade3Plus1.cxx:24
a
TList * a
Definition: liststreamerinfos.cxx:10
DerivationFramework::PsiPlusPsiCascade::m_CascadeTools
ToolHandle< DerivationFramework::CascadeTools > m_CascadeTools
Definition: PsiPlusPsiCascade.h:99
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.
DerivationFramework::PsiPlusPsiCascade::m_constrDiTrk1
bool m_constrDiTrk1
Definition: PsiPlusPsiCascade.h:88
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DerivationFramework::PsiPlusPsiCascade::m_diTrack2MassUpper
double m_diTrack2MassUpper
Definition: PsiPlusPsiCascade.h:60
DerivationFramework::PsiPlusPsiCascade::m_massPsi2
double m_massPsi2
Definition: PsiPlusPsiCascade.h:79
DerivationFramework::PsiPlusPsiCascade::m_vtx1Daug2MassHypo
double m_vtx1Daug2MassHypo
Definition: PsiPlusPsiCascade.h:69
DerivationFramework::PsiPlusPsiCascade::m_vertexPsi2HypoNames
std::vector< std::string > m_vertexPsi2HypoNames
Definition: PsiPlusPsiCascade.h:47
DerivationFramework::PsiPlusPsiCascade::m_vtx1Daug3MassHypo
double m_vtx1Daug3MassHypo
Definition: PsiPlusPsiCascade.h:70
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
DerivationFramework::PsiPlusPsiCascade::m_diTrack2MassLower
double m_diTrack2MassLower
Definition: PsiPlusPsiCascade.h:59
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
DataVector::cbegin
const_iterator cbegin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
DerivationFramework::PsiPlusPsiCascade::m_constrJpsi2
bool m_constrJpsi2
Definition: PsiPlusPsiCascade.h:87
skip
bool skip
Definition: TrigGlobEffCorrValidation.cxx:190
DerivationFramework::PsiPlusPsiCascade::m_vtx1Daug1MassHypo
double m_vtx1Daug1MassHypo
Definition: PsiPlusPsiCascade.h:68
AthAlgTool
Definition: AthAlgTool.h:26
DerivationFramework::PsiPlusPsiCascade::m_PV_max
int m_PV_max
Definition: PsiPlusPsiCascade.h:104
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
DerivationFramework::PsiPlusPsiCascade::m_vtx2Daug2MassHypo
double m_vtx2Daug2MassHypo
Definition: PsiPlusPsiCascade.h:74
DerivationFramework::PsiPlusPsiCascade::m_chi2cut_Psi2
double m_chi2cut_Psi2
Definition: PsiPlusPsiCascade.h:91
HepMCHelpers.h
xAOD::BPhysHypoHelper::setMassErr
bool setMassErr(const float val)
invariant mass error
Definition: BPhysHypoHelper.cxx:54
DerivationFramework::PsiPlusPsiCascade::PsiPlusPsiCascade
PsiPlusPsiCascade(const std::string &type, const std::string &name, const IInterface *parent)
Definition: PsiPlusPsiCascade.cxx:257
DerivationFramework::PsiPlusPsiCascade::m_hypoName
std::string m_hypoName
Definition: PsiPlusPsiCascade.h:103
VertexAuxContainer.h
xAOD::TrackParticle_v1::phi
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
DerivationFramework::PsiPlusPsiCascade::m_cascadeOutputsKeys
SG::WriteHandleKeyArray< xAOD::VertexContainer > m_cascadeOutputsKeys
Definition: PsiPlusPsiCascade.h:48
DerivationFramework::PsiPlusPsiCascade::m_pvRefitter
ToolHandle< Analysis::PrimaryVertexRefitter > m_pvRefitter
Definition: PsiPlusPsiCascade.h:97