ATLAS Offline Software
Loading...
Searching...
No Matches
JpsiPlusDpstCascade.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
5// JpsiPlusDpstCascade.cxx, (c) ATLAS Detector software
12#include "BPhysPVCascadeTools.h"
18
20#include <algorithm>
21
22namespace DerivationFramework {
24 typedef std::vector<VertexLink> VertexLinkVector;
25 typedef std::vector<const xAOD::TrackParticle*> TrackBag;
26
27
29
30 // retrieving vertex Fitter
31 ATH_CHECK( m_iVertexFitter.retrieve());
32
33 // retrieving the V0 tools
34 ATH_CHECK( m_V0Tools.retrieve());
35
36 // retrieving the Cascade tools
37 ATH_CHECK( m_CascadeTools.retrieve());
38
39 // Get the beam spot service
40 ATH_CHECK(m_eventInfo_key.initialize());
41
42 auto gendata = std::make_shared<GenData>();
43 if(m_mass_jpsi < 0. ) m_mass_jpsi = gendata->particleMass(MC::JPSI).value();
44 if(m_vtx0MassHypo < 0.) m_vtx0MassHypo = gendata->particleMass(MC::BCPLUS).value();
45 if(m_vtx1MassHypo < 0.) m_vtx1MassHypo = gendata->particleMass(MC::D0).value();
46 if(m_vtx0Daug1MassHypo < 0.) m_vtx0Daug1MassHypo = gendata->particleMass(MC::MUON).value();
47 if(m_vtx0Daug2MassHypo < 0.) m_vtx0Daug2MassHypo = gendata->particleMass(MC::MUON).value();
48 if(m_vtx0Daug3MassHypo < 0.) m_vtx0Daug3MassHypo = gendata->particleMass(MC::PIPLUS).value();
49 if(m_vtx1Daug1MassHypo < 0.) m_vtx1Daug1MassHypo = gendata->particleMass(MC::PIPLUS).value();
50 if(m_vtx1Daug2MassHypo < 0.) m_vtx1Daug2MassHypo = gendata->particleMass(MC::KPLUS).value();
51
52 return StatusCode::SUCCESS;
53 }
54
55
56 StatusCode JpsiPlusDpstCascade::addBranches(const EventContext& ctx) const
57 {
58 std::vector<Trk::VxCascadeInfo*> cascadeinfoContainer;
59 constexpr int topoN = 2;
60 std::array<xAOD::VertexContainer*, topoN> Vtxwritehandles;
61 std::array<xAOD::VertexAuxContainer*, topoN> Vtxwritehandlesaux;
62 if(m_cascadeOutputsKeys.size() !=topoN) { ATH_MSG_FATAL("Incorrect number of VtxContainers"); return StatusCode::FAILURE; }
63
64 for(int i =0; i<topoN;i++){
65 Vtxwritehandles[i] = new xAOD::VertexContainer();
66 Vtxwritehandlesaux[i] = new xAOD::VertexAuxContainer();
67 Vtxwritehandles[i]->setStore(Vtxwritehandlesaux[i]);
68 ATH_CHECK(evtStore()->record(Vtxwritehandles[i] , m_cascadeOutputsKeys[i] )); // FIXME Use Handles
69 ATH_CHECK(evtStore()->record(Vtxwritehandlesaux[i], m_cascadeOutputsKeys[i] + "Aux.")); // FIXME Use Handles
70 }
71
72 //----------------------------------------------------
73 // retrieve primary vertices
74 //----------------------------------------------------
75 const xAOD::Vertex * primaryVertex{};
76 const xAOD::VertexContainer *pvContainer{};
77 ATH_CHECK(evtStore()->retrieve(pvContainer, m_VxPrimaryCandidateName)); // FIXME Use Handles
78 ATH_MSG_DEBUG("Found " << m_VxPrimaryCandidateName << " in StoreGate!");
79
80 if (pvContainer->size()==0){
81 ATH_MSG_WARNING("You have no primary vertices: " << pvContainer->size());
82 return StatusCode::RECOVERABLE;
83 } else {
84 primaryVertex = (*pvContainer)[0];
85 }
86
87 //----------------------------------------------------
88 // Try to retrieve refitted primary vertices
89 //----------------------------------------------------
90 xAOD::VertexContainer* refPvContainer{};
91 xAOD::VertexAuxContainer* refPvAuxContainer{};
92 if (m_refitPV) {
94 // refitted PV container exists. Get it from the store gate
95 ATH_CHECK(evtStore()->retrieve(refPvContainer , m_refPVContainerName )); // FIXME Use Handles
96 ATH_CHECK(evtStore()->retrieve(refPvAuxContainer, m_refPVContainerName + "Aux.")); // FIXME Use Handles
97 } else {
98 // refitted PV container does not exist. Create a new one.
99 refPvContainer = new xAOD::VertexContainer;
100 refPvAuxContainer = new xAOD::VertexAuxContainer;
101 refPvContainer->setStore(refPvAuxContainer);
102 ATH_CHECK(evtStore()->record(refPvContainer , m_refPVContainerName)); // FIXME Use Handles
103 ATH_CHECK(evtStore()->record(refPvAuxContainer, m_refPVContainerName+"Aux.")); // FIXME Use Handles
104 }
105 }
106
107 ATH_CHECK(performSearch(&cascadeinfoContainer, ctx));
108
110 if(not evt.isValid()) ATH_MSG_ERROR("Cannot Retrieve " << evt.key() );
111 BPhysPVCascadeTools helper(&(*m_CascadeTools), evt.cptr());
112 helper.SetMinNTracksInPV(m_PV_minNTracks);
113
114 // Decorators for the main vertex: chi2, ndf, pt and pt error, plus the D0 vertex variables
115 SG::Decorator<VertexLinkVector> CascadeLinksDecor("CascadeVertexLinks");
116 SG::Decorator<VertexLinkVector> JpsipiLinksDecor("JpsipiVertexLinks");
117 SG::Decorator<VertexLinkVector> D0LinksDecor("D0VertexLinks");
118 SG::Decorator<float> chi2_decor("ChiSquared");
119 SG::Decorator<float> ndof_decor("NumberDoF");
120 SG::Decorator<float> Pt_decor("Pt");
121 SG::Decorator<float> PtErr_decor("PtErr");
122 SG::Decorator<float> Mass_svdecor("D0_mass");
123 SG::Decorator<float> MassErr_svdecor("D0_massErr");
124 SG::Decorator<float> Pt_svdecor("D0_Pt");
125 SG::Decorator<float> PtErr_svdecor("D0_PtErr");
126 SG::Decorator<float> Lxy_svdecor("D0_Lxy");
127 SG::Decorator<float> LxyErr_svdecor("D0_LxyErr");
128 SG::Decorator<float> Tau_svdecor("D0_Tau");
129 SG::Decorator<float> TauErr_svdecor("D0_TauErr");
130
131 SG::Decorator<float> MassMumu_decor("Mumu_mass");
132 SG::Decorator<float> MassKpi_svdecor("Kpi_mass");
133 SG::Decorator<float> MassJpsi_decor("Jpsi_mass");
134 SG::Decorator<float> MassPiD0_decor("PiD0_mass");
135
136 ATH_MSG_DEBUG("cascadeinfoContainer size " << cascadeinfoContainer.size());
137
138 // Get Jpsi+pi container and identify the input Jpsi+pi
139 const xAOD::VertexContainer *jpsipiContainer{};
140 ATH_CHECK(evtStore()->retrieve(jpsipiContainer , m_vertexContainerKey )); // FIXME Use Handles
141 const xAOD::VertexContainer *d0Container{};
142 ATH_CHECK(evtStore()->retrieve(d0Container , m_vertexD0ContainerKey )); // FIXME Use Handles
143
144 for (Trk::VxCascadeInfo* x : cascadeinfoContainer) {
145 if(x==nullptr) {
146 ATH_MSG_ERROR("cascadeinfoContainer is null");
147 //x is dereferenced if we pass this
148 return StatusCode::FAILURE;
149 }
150
151 // the cascade fitter returns:
152 // std::vector<xAOD::Vertex*>, each xAOD::Vertex contains the refitted track parameters (perigee at the vertex position)
153 // vertices[iv] the links to the original TPs and a covariance of size 3+5*NTRK; the chi2 of the total fit
154 // is split between the cascade vertices as per track contribution
155 // std::vector< std::vector<TLorentzVector> >, each std::vector<TLorentzVector> contains the refitted momenta (TLorentzVector)
156 // momenta[iv][...] of all tracks in the corresponding vertex, including any pseudotracks (from cascade vertices)
157 // originating in this vertex; the masses are as assigned in the cascade fit
158 // std::vector<Amg::MatrixX>, the corresponding covariance matrices in momentum space
159 // covariance[iv]
160 // int nDoF, double Chi2
161 //
162 // the invariant mass, pt, lifetime etc. errors should be calculated using the covariance matrices in momentum space as these
163 // take into account the full track-track and track-vertex correlations
164 //
165 // in the case of Jpsi+V0: vertices[0] is the V0 vertex, vertices[1] is the B/Lambda_b(bar) vertex, containing the 2 Jpsi tracks.
166 // The covariance terms between the two vertices are not stored. In momentum space momenta[0] contains the 2 V0 tracks,
167 // their momenta add up to the momentum of the 3rd track in momenta[1], the first two being the Jpsi tracks
168
169 const std::vector<xAOD::Vertex*> &cascadeVertices = x->vertices();
170 if(cascadeVertices.size()!=topoN)
171 ATH_MSG_ERROR("Incorrect number of vertices");
172 if(cascadeVertices[0] == nullptr || cascadeVertices[1] == nullptr) ATH_MSG_ERROR("Error null vertex");
173 // Keep vertices (bear in mind that they come in reverse order!)
174 for(int i =0;i<topoN;i++) Vtxwritehandles[i]->push_back(cascadeVertices[i]);
175
176 x->setSVOwnership(false); // Prevent Container from deleting vertices
177 const auto mainVertex = cascadeVertices[1]; // this is the B_c+/- vertex
178 const std::vector< std::vector<TLorentzVector> > &moms = x->getParticleMoms();
179
180 // Set links to cascade vertices
181 std::vector<const xAOD::Vertex*> verticestoLink;
182 verticestoLink.push_back(cascadeVertices[0]);
183 if(Vtxwritehandles[1] == nullptr) ATH_MSG_ERROR("Vtxwritehandles[1] is null");
184 if(!BPhysPVCascadeTools::LinkVertices(CascadeLinksDecor, verticestoLink, Vtxwritehandles[0], cascadeVertices[1]))
185 ATH_MSG_ERROR("Error decorating with cascade vertices");
186
187 // Identify the input Jpsi+pi
188 const xAOD::Vertex* jpsipiVertex = BPhysPVCascadeTools::FindVertex<3>(jpsipiContainer, cascadeVertices[1]);
189 ATH_MSG_DEBUG("1 pt Jpsi+pi tracks " << cascadeVertices[1]->trackParticle(0)->pt() << ", " << cascadeVertices[1]->trackParticle(1)->pt() << ", " << cascadeVertices[1]->trackParticle(2)->pt());
190 if (jpsipiVertex) ATH_MSG_DEBUG("2 pt Jpsi+pi tracks " << jpsipiVertex->trackParticle(0)->pt() << ", " << jpsipiVertex->trackParticle(1)->pt() << ", " << jpsipiVertex->trackParticle(2)->pt());
191
192 // Identify the input D0
193 const xAOD::Vertex* d0Vertex = BPhysPVCascadeTools::FindVertex<2>(d0Container, cascadeVertices[0]);;
194 ATH_MSG_DEBUG("1 pt D0 tracks " << cascadeVertices[0]->trackParticle(0)->pt() << ", " << cascadeVertices[0]->trackParticle(1)->pt());
195 if (d0Vertex) ATH_MSG_DEBUG("2 pt D0 tracks " << d0Vertex->trackParticle(0)->pt() << ", " << d0Vertex->trackParticle(1)->pt());
196
197 // Set links to input vertices
198 std::vector<const xAOD::Vertex*> jpsipiVerticestoLink;
199 if (jpsipiVertex) jpsipiVerticestoLink.push_back(jpsipiVertex);
200 else ATH_MSG_WARNING("Could not find linking Jpsi+pi");
201 if(!BPhysPVCascadeTools::LinkVertices(JpsipiLinksDecor, jpsipiVerticestoLink, jpsipiContainer, cascadeVertices[1]))
202 ATH_MSG_ERROR("Error decorating with Jpsi+pi vertices");
203
204 std::vector<const xAOD::Vertex*> d0VerticestoLink;
205 if (d0Vertex) d0VerticestoLink.push_back(d0Vertex);
206 else ATH_MSG_WARNING("Could not find linking D0");
207 if(!BPhysPVCascadeTools::LinkVertices(D0LinksDecor, d0VerticestoLink, d0Container, cascadeVertices[1]))
208 ATH_MSG_ERROR("Error decorating with D0 vertices");
209
210 bool tagD0(true);
211 if (jpsipiVertex){
212 if(abs(m_Dx_pid)==421 && (jpsipiVertex->trackParticle(2)->charge()==-1)) tagD0 = false;
213 }
214
215 double mass_b = m_vtx0MassHypo;
216 double mass_d0 = m_vtx1MassHypo;
217 std::vector<double> massesJpsipi;
218 massesJpsipi.push_back(m_vtx0Daug1MassHypo);
219 massesJpsipi.push_back(m_vtx0Daug2MassHypo);
220 massesJpsipi.push_back(m_vtx0Daug3MassHypo);
221 std::vector<double> massesD0;
222 if(tagD0){
223 massesD0.push_back(m_vtx1Daug1MassHypo);
224 massesD0.push_back(m_vtx1Daug2MassHypo);
225 }else{ // Change the oreder of masses for D*-->D0bar pi-, D0bar->K+pi-
226 massesD0.push_back(m_vtx1Daug2MassHypo);
227 massesD0.push_back(m_vtx1Daug1MassHypo);
228 }
229 std::vector<double> Masses;
230 Masses.push_back(m_vtx0Daug1MassHypo);
231 Masses.push_back(m_vtx0Daug2MassHypo);
232 Masses.push_back(m_vtx0Daug3MassHypo);
233 Masses.push_back(m_vtx1MassHypo);
234
235 // loop over candidates -- Don't apply PV_minNTracks requirement here
236 // because it may result in exclusion of the high-pt PV.
237 // get good PVs
238
239 xAOD::BPhysHypoHelper vtx(m_hypoName, mainVertex);
240
241 // Get refitted track momenta from all vertices, charged tracks only
243
244 // Decorate main vertex
245 //
246 // 1.a) mass, mass error
247 BPHYS_CHECK( vtx.setMass(m_CascadeTools->invariantMass(moms[1])) );
248 BPHYS_CHECK( vtx.setMassErr(m_CascadeTools->invariantMassError(moms[1],x->getCovariance()[1])) );
249 // 1.b) pt and pT error (the default pt of mainVertex is != the pt of the full cascade fit!)
250 Pt_decor(*mainVertex) = m_CascadeTools->pT(moms[1]);
251 PtErr_decor(*mainVertex) = m_CascadeTools->pTError(moms[1],x->getCovariance()[1]);
252 // 1.c) chi2 and ndof (the default chi2 of mainVertex is != the chi2 of the full cascade fit!)
253 chi2_decor(*mainVertex) = x->fitChi2();
254 ndof_decor(*mainVertex) = x->nDoF();
255
256 float massMumu = 0.;
257 if (jpsipiVertex) {
258 TLorentzVector p4_mu1, p4_mu2;
259 p4_mu1.SetPtEtaPhiM(jpsipiVertex->trackParticle(0)->pt(),
260 jpsipiVertex->trackParticle(0)->eta(),
261 jpsipiVertex->trackParticle(0)->phi(), m_vtx0Daug1MassHypo);
262 p4_mu2.SetPtEtaPhiM(jpsipiVertex->trackParticle(1)->pt(),
263 jpsipiVertex->trackParticle(1)->eta(),
264 jpsipiVertex->trackParticle(1)->phi(), m_vtx0Daug2MassHypo);
265 massMumu = (p4_mu1 + p4_mu2).M();
266 }
267 MassMumu_decor(*mainVertex) = massMumu;
268
269 float massKpi = 0.;
270 if (d0Vertex) {
271 TLorentzVector p4_ka, p4_pi;
272 if(tagD0){
273 p4_pi.SetPtEtaPhiM(d0Vertex->trackParticle(0)->pt(),
274 d0Vertex->trackParticle(0)->eta(),
275 d0Vertex->trackParticle(0)->phi(), m_vtx1Daug1MassHypo);
276 p4_ka.SetPtEtaPhiM(d0Vertex->trackParticle(1)->pt(),
277 d0Vertex->trackParticle(1)->eta(),
278 d0Vertex->trackParticle(1)->phi(), m_vtx1Daug2MassHypo);
279 }else{ // Change the oreder of masses for D*-->D0bar pi-, D0bar->K+pi-
280 p4_pi.SetPtEtaPhiM(d0Vertex->trackParticle(1)->pt(),
281 d0Vertex->trackParticle(1)->eta(),
282 d0Vertex->trackParticle(1)->phi(), m_vtx1Daug1MassHypo);
283 p4_ka.SetPtEtaPhiM(d0Vertex->trackParticle(0)->pt(),
284 d0Vertex->trackParticle(0)->eta(),
285 d0Vertex->trackParticle(0)->phi(), m_vtx1Daug2MassHypo);
286 }
287 massKpi = (p4_ka + p4_pi).M();
288 }
289 MassKpi_svdecor(*mainVertex) = massKpi;
290 MassJpsi_decor(*mainVertex) = (moms[1][0] + moms[1][1]).M();
291 MassPiD0_decor(*mainVertex) = (moms[1][2] + moms[1][3]).M();
292
293
294 ATH_CHECK(helper.FillCandwithRefittedVertices(m_refitPV, pvContainer,
295 refPvContainer, &(*m_pvRefitter), m_PV_max, m_DoVertexType, x, 1, mass_b, vtx));
296
297 // 4) decorate the main vertex with D0 vertex mass, pt, lifetime and lxy values (plus errors)
298 // D0 points to the main vertex, so lifetime and lxy are w.r.t the main vertex
299 Mass_svdecor(*mainVertex) = m_CascadeTools->invariantMass(moms[0]);
300 MassErr_svdecor(*mainVertex) = m_CascadeTools->invariantMassError(moms[0],x->getCovariance()[0]);
301 Pt_svdecor(*mainVertex) = m_CascadeTools->pT(moms[0]);
302 PtErr_svdecor(*mainVertex) = m_CascadeTools->pTError(moms[0],x->getCovariance()[0]);
303 Lxy_svdecor(*mainVertex) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
304 LxyErr_svdecor(*mainVertex) = m_CascadeTools->lxyError(moms[0],x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
305 Tau_svdecor(*mainVertex) = m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1]);
306 TauErr_svdecor(*mainVertex) = m_CascadeTools->tauError(moms[0],x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1]);
307
308 // Some checks in DEBUG mode
309 ATH_MSG_DEBUG("chi2 " << x->fitChi2()
310 << " chi2_1 " << m_V0Tools->chisq(cascadeVertices[0])
311 << " chi2_2 " << m_V0Tools->chisq(cascadeVertices[1])
312 << " vprob " << m_CascadeTools->vertexProbability(x->nDoF(),x->fitChi2()));
313 ATH_MSG_DEBUG("ndf " << x->nDoF() << " ndf_1 " << m_V0Tools->ndof(cascadeVertices[0]) << " ndf_2 " << m_V0Tools->ndof(cascadeVertices[1]));
314 ATH_MSG_DEBUG("V0Tools mass_d0 " << m_V0Tools->invariantMass(cascadeVertices[0],massesD0)
315 << " error " << m_V0Tools->invariantMassError(cascadeVertices[0],massesD0)
316 << " mass_J " << m_V0Tools->invariantMass(cascadeVertices[1],massesJpsipi)
317 << " error " << m_V0Tools->invariantMassError(cascadeVertices[1],massesJpsipi));
318 // masses and errors, using track masses assigned in the fit
319 double Mass_B = m_CascadeTools->invariantMass(moms[1]);
320 double Mass_D0 = m_CascadeTools->invariantMass(moms[0]);
321 double Mass_B_err = m_CascadeTools->invariantMassError(moms[1],x->getCovariance()[1]);
322 double Mass_D0_err = m_CascadeTools->invariantMassError(moms[0],x->getCovariance()[0]);
323 ATH_MSG_DEBUG("Mass_B " << Mass_B << " Mass_D0 " << Mass_D0);
324 ATH_MSG_DEBUG("Mass_B_err " << Mass_B_err << " Mass_D0_err " << Mass_D0_err);
325 double mprob_B = m_CascadeTools->massProbability(mass_b,Mass_B,Mass_B_err);
326 double mprob_D0 = m_CascadeTools->massProbability(mass_d0,Mass_D0,Mass_D0_err);
327 ATH_MSG_DEBUG("mprob_B " << mprob_B << " mprob_D0 " << mprob_D0);
328 // masses and errors, assigning user defined track masses
329 ATH_MSG_DEBUG("Mass_b " << m_CascadeTools->invariantMass(moms[1],Masses)
330 << " Mass_d0 " << m_CascadeTools->invariantMass(moms[0],massesD0));
331 ATH_MSG_DEBUG("Mass_b_err " << m_CascadeTools->invariantMassError(moms[1],x->getCovariance()[1],Masses)
332 << " Mass_d0_err " << m_CascadeTools->invariantMassError(moms[0],x->getCovariance()[0],massesD0));
333 ATH_MSG_DEBUG("pt_b " << m_CascadeTools->pT(moms[1])
334 << " pt_d " << m_CascadeTools->pT(moms[0])
335 << " pt_d0 " << m_V0Tools->pT(cascadeVertices[0]));
336 ATH_MSG_DEBUG("ptErr_b " << m_CascadeTools->pTError(moms[1],x->getCovariance()[1])
337 << " ptErr_d " << m_CascadeTools->pTError(moms[0],x->getCovariance()[0])
338 << " ptErr_d0 " << m_V0Tools->pTError(cascadeVertices[0]));
339 ATH_MSG_DEBUG("lxy_B " << m_V0Tools->lxy(cascadeVertices[1],primaryVertex) << " lxy_D " << m_V0Tools->lxy(cascadeVertices[0],cascadeVertices[1]));
340 ATH_MSG_DEBUG("lxy_b " << m_CascadeTools->lxy(moms[1],cascadeVertices[1],primaryVertex) << " lxy_d " << m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]));
341 ATH_MSG_DEBUG("lxyErr_b " << m_CascadeTools->lxyError(moms[1],x->getCovariance()[1],cascadeVertices[1],primaryVertex)
342 << " lxyErr_d " << m_CascadeTools->lxyError(moms[0],x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
343 << " lxyErr_d0 " << m_V0Tools->lxyError(cascadeVertices[0],cascadeVertices[1]));
344 ATH_MSG_DEBUG("tau_B " << m_CascadeTools->tau(moms[1],cascadeVertices[1],primaryVertex,mass_b)
345 << " tau_d0 " << m_V0Tools->tau(cascadeVertices[0],cascadeVertices[1],massesD0));
346 ATH_MSG_DEBUG("tau_b " << m_CascadeTools->tau(moms[1],cascadeVertices[1],primaryVertex)
347 << " tau_d " << m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1])
348 << " tau_D " << m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1],mass_d0));
349 ATH_MSG_DEBUG("tauErr_b " << m_CascadeTools->tauError(moms[1],x->getCovariance()[1],cascadeVertices[1],primaryVertex)
350 << " tauErr_d " << m_CascadeTools->tauError(moms[0],x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
351 << " tauErr_d0 " << m_V0Tools->tauError(cascadeVertices[0],cascadeVertices[1],massesD0));
352 ATH_MSG_DEBUG("TauErr_b " << m_CascadeTools->tauError(moms[1],x->getCovariance()[1],cascadeVertices[1],primaryVertex,mass_b)
353 << " TauErr_d " << m_CascadeTools->tauError(moms[0],x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1],mass_d0)
354 << " TauErr_d0 " << m_V0Tools->tauError(cascadeVertices[0],cascadeVertices[1],massesD0,mass_d0));
355
356 ATH_MSG_DEBUG("CascadeTools main vert wrt PV " << " CascadeTools SV " << " V0Tools SV");
357 ATH_MSG_DEBUG("a0z " << m_CascadeTools->a0z(moms[1],cascadeVertices[1],primaryVertex)
358 << ", " << m_CascadeTools->a0z(moms[0],cascadeVertices[0],cascadeVertices[1])
359 << ", " << m_V0Tools->a0z(cascadeVertices[0],cascadeVertices[1]));
360 ATH_MSG_DEBUG("a0zErr " << m_CascadeTools->a0zError(moms[1],x->getCovariance()[1],cascadeVertices[1],primaryVertex)
361 << ", " << m_CascadeTools->a0zError(moms[0],x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
362 << ", " << m_V0Tools->a0zError(cascadeVertices[0],cascadeVertices[1]));
363 ATH_MSG_DEBUG("a0xy " << m_CascadeTools->a0xy(moms[1],cascadeVertices[1],primaryVertex)
364 << ", " << m_CascadeTools->a0xy(moms[0],cascadeVertices[0],cascadeVertices[1])
365 << ", " << m_V0Tools->a0xy(cascadeVertices[0],cascadeVertices[1]));
366 ATH_MSG_DEBUG("a0xyErr " << m_CascadeTools->a0xyError(moms[1],x->getCovariance()[1],cascadeVertices[1],primaryVertex)
367 << ", " << m_CascadeTools->a0xyError(moms[0],x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
368 << ", " << m_V0Tools->a0xyError(cascadeVertices[0],cascadeVertices[1]));
369 ATH_MSG_DEBUG("a0 " << m_CascadeTools->a0(moms[1],cascadeVertices[1],primaryVertex)
370 << ", " << m_CascadeTools->a0(moms[0],cascadeVertices[0],cascadeVertices[1])
371 << ", " << m_V0Tools->a0(cascadeVertices[0],cascadeVertices[1]));
372 ATH_MSG_DEBUG("a0Err " << m_CascadeTools->a0Error(moms[1],x->getCovariance()[1],cascadeVertices[1],primaryVertex)
373 << ", " << m_CascadeTools->a0Error(moms[0],x->getCovariance()[0],cascadeVertices[0],cascadeVertices[1])
374 << ", " << m_V0Tools->a0Error(cascadeVertices[0],cascadeVertices[1]));
375 ATH_MSG_DEBUG("x0 " << m_V0Tools->vtx(cascadeVertices[0]).x() << " y0 " << m_V0Tools->vtx(cascadeVertices[0]).y() << " z0 " << m_V0Tools->vtx(cascadeVertices[0]).z());
376 ATH_MSG_DEBUG("x1 " << m_V0Tools->vtx(cascadeVertices[1]).x() << " y1 " << m_V0Tools->vtx(cascadeVertices[1]).y() << " z1 " << m_V0Tools->vtx(cascadeVertices[1]).z());
377 ATH_MSG_DEBUG("X0 " << primaryVertex->x() << " Y0 " << primaryVertex->y() << " Z0 " << primaryVertex->z());
378 ATH_MSG_DEBUG("rxy0 " << m_V0Tools->rxy(cascadeVertices[0]) << " rxyErr0 " << m_V0Tools->rxyError(cascadeVertices[0]));
379 ATH_MSG_DEBUG("rxy1 " << m_V0Tools->rxy(cascadeVertices[1]) << " rxyErr1 " << m_V0Tools->rxyError(cascadeVertices[1]));
380 ATH_MSG_DEBUG("Rxy0 wrt PV " << m_V0Tools->rxy(cascadeVertices[0],primaryVertex) << " RxyErr0 wrt PV " << m_V0Tools->rxyError(cascadeVertices[0],primaryVertex));
381 ATH_MSG_DEBUG("Rxy1 wrt PV " << m_V0Tools->rxy(cascadeVertices[1],primaryVertex) << " RxyErr1 wrt PV " << m_V0Tools->rxyError(cascadeVertices[1],primaryVertex));
382 ATH_MSG_DEBUG("number of covariance matrices " << (x->getCovariance()).size());
383 } // loop over cascadeinfoContainer
384
385 // Deleting cascadeinfo since this won't be stored.
386 // Vertices have been kept in m_cascadeOutputs and should be owned by their container
387 for (auto x : cascadeinfoContainer) delete x;
388
389 return StatusCode::SUCCESS;
390 }
391
392
393 JpsiPlusDpstCascade::JpsiPlusDpstCascade(const std::string& t, const std::string& n, const IInterface* p) : base_class(t,n,p),
396 m_cascadeOutputsKeys{ "JpsiPlusDpstCascadeVtx1", "JpsiPlusDpstCascadeVtx2" },
397 m_VxPrimaryCandidateName("PrimaryVertices"),
398 m_jpsiMassLower(0.0),
399 m_jpsiMassUpper(10000.0),
401 m_jpsipiMassUpper(10000.0),
402 m_D0MassLower(0.0),
403 m_D0MassUpper(10000.0),
404 m_DstMassLower(0.0),
405 m_DstMassUpper(10000.0),
406 m_MassLower(0.0),
407 m_MassUpper(20000.0),
408 m_vtx0MassHypo(-1),
409 m_vtx1MassHypo(-1),
415 m_mass_jpsi(-1),
416 m_Dx_pid(421),
417 m_constrD0(true),
418 m_constrJpsi(true),
419 m_chi2cut(-1.0),
420 m_iVertexFitter("Trk::TrkVKalVrtFitter"),
421 m_pvRefitter("Analysis::PrimaryVertexRefitter"),
422 m_V0Tools("Trk::V0Tools"),
423 m_CascadeTools("DerivationFramework::CascadeTools")
424 {
425 declareProperty("JpsipiVertices", m_vertexContainerKey);
426 declareProperty("D0Vertices", m_vertexD0ContainerKey);
427 declareProperty("VxPrimaryCandidateName", m_VxPrimaryCandidateName);
428 declareProperty("RefPVContainerName", m_refPVContainerName = "RefittedPrimaryVertices");
429 declareProperty("JpsiMassLowerCut", m_jpsiMassLower);
430 declareProperty("JpsiMassUpperCut", m_jpsiMassUpper);
431 declareProperty("JpsipiMassLowerCut", m_jpsipiMassLower);
432 declareProperty("JpsipiMassUpperCut", m_jpsipiMassUpper);
433 declareProperty("D0MassLowerCut", m_D0MassLower);
434 declareProperty("D0MassUpperCut", m_D0MassUpper);
435 declareProperty("DstMassLowerCut", m_DstMassLower);
436 declareProperty("DstMassUpperCut", m_DstMassUpper);
437 declareProperty("MassLowerCut", m_MassLower);
438 declareProperty("MassUpperCut", m_MassUpper);
439 declareProperty("HypothesisName", m_hypoName = "Bc");
440 declareProperty("Vtx0MassHypo", m_vtx0MassHypo);
441 declareProperty("Vtx1MassHypo", m_vtx1MassHypo);
442 declareProperty("Vtx0Daug1MassHypo", m_vtx0Daug1MassHypo);
443 declareProperty("Vtx0Daug2MassHypo", m_vtx0Daug2MassHypo);
444 declareProperty("Vtx0Daug3MassHypo", m_vtx0Daug3MassHypo);
445 declareProperty("Vtx1Daug1MassHypo", m_vtx1Daug1MassHypo);
446 declareProperty("Vtx1Daug2MassHypo", m_vtx1Daug2MassHypo);
447 declareProperty("JpsiMass", m_mass_jpsi);
448 declareProperty("DxHypothesis", m_Dx_pid);
449 declareProperty("ApplyD0MassConstraint", m_constrD0);
450 declareProperty("ApplyJpsiMassConstraint", m_constrJpsi);
451 declareProperty("Chi2Cut", m_chi2cut);
452 declareProperty("RefitPV", m_refitPV = true);
453 declareProperty("MaxnPV", m_PV_max = 999);
454 declareProperty("MinNTracksInPV", m_PV_minNTracks = 0);
455 declareProperty("DoVertexType", m_DoVertexType = 7);
456 declareProperty("TrkVertexFitterTool", m_iVertexFitter);
457 declareProperty("PVRefitter", m_pvRefitter);
458 declareProperty("V0Tools", m_V0Tools);
459 declareProperty("CascadeTools", m_CascadeTools);
460 declareProperty("CascadeVertexCollections", m_cascadeOutputsKeys);
461 }
462
464
465 StatusCode JpsiPlusDpstCascade::performSearch(std::vector<Trk::VxCascadeInfo*> *cascadeinfoContainer, const EventContext& ctx) const
466 {
467 ATH_MSG_DEBUG( "JpsiPlusDpstCascade::performSearch" );
468 assert(cascadeinfoContainer!=nullptr);
469
470 // Get TrackParticle container (for setting links to the original tracks)
471 const xAOD::TrackParticleContainer *trackContainer{};
472 ATH_CHECK(evtStore()->retrieve(trackContainer , "InDetTrackParticles" )); // FIXME Use Handles
473
474 // Get Jpsi+pi container
475 const xAOD::VertexContainer *jpsipiContainer{};
476 ATH_CHECK(evtStore()->retrieve(jpsipiContainer , m_vertexContainerKey )); // FIXME Use Handles
477
478 // Get D0 container
479 const xAOD::VertexContainer *d0Container{};
480 ATH_CHECK(evtStore()->retrieve(d0Container , m_vertexD0ContainerKey )); // FIXME Use Handles
481
482 double mass_d0 = m_vtx1MassHypo;
483 std::vector<const xAOD::TrackParticle*> tracksJpsipi;
484 std::vector<const xAOD::TrackParticle*> tracksJpsi;
485 std::vector<const xAOD::TrackParticle*> tracksD0;
486 std::vector<const xAOD::TrackParticle*> tracksBc;
487 std::vector<double> massesJpsipi;
488 massesJpsipi.push_back(m_vtx0Daug1MassHypo);
489 massesJpsipi.push_back(m_vtx0Daug2MassHypo);
490 massesJpsipi.push_back(m_vtx0Daug3MassHypo);
491 std::vector<double> massesD0;
492 massesD0.push_back(m_vtx1Daug1MassHypo);
493 massesD0.push_back(m_vtx1Daug2MassHypo);
494 std::vector<double> massesD0b; // Change the oreder of masses for D*-->D0bar pi-, D0bar->K+pi-
495 massesD0b.push_back(m_vtx1Daug2MassHypo);
496 massesD0b.push_back(m_vtx1Daug1MassHypo);
497 std::vector<double> Masses;
498 Masses.push_back(m_vtx0Daug1MassHypo);
499 Masses.push_back(m_vtx0Daug2MassHypo);
500 Masses.push_back(m_vtx0Daug3MassHypo);
501 Masses.push_back(m_vtx1MassHypo);
502
503 // Select J/psi pi+ candidates before calling cascade fit
504 std::vector<const xAOD::Vertex*> selectedJpsipiCandidates;
505 SG::Accessor<Char_t> flagAcc1("passed_Jpsipi");
506 for(auto vxcItr=jpsipiContainer->cbegin(); vxcItr!=jpsipiContainer->cend(); ++vxcItr) {
507
508 // Check the passed flag first
509 const xAOD::Vertex* vtx = *vxcItr;
510 if(flagAcc1.isAvailable(*vtx)){
511 if(!flagAcc1(*vtx)) continue;
512 }
513
514 // Check J/psi candidate invariant mass and skip if need be
515 TLorentzVector p4Mup_in, p4Mum_in;
516 p4Mup_in.SetPtEtaPhiM((*vxcItr)->trackParticle(0)->pt(),
517 (*vxcItr)->trackParticle(0)->eta(),
518 (*vxcItr)->trackParticle(0)->phi(), m_vtx0Daug1MassHypo);
519 p4Mum_in.SetPtEtaPhiM((*vxcItr)->trackParticle(1)->pt(),
520 (*vxcItr)->trackParticle(1)->eta(),
521 (*vxcItr)->trackParticle(1)->phi(), m_vtx0Daug2MassHypo);
522 double mass_Jpsi = (p4Mup_in + p4Mum_in).M();
523 ATH_MSG_DEBUG("Jpsi mass " << mass_Jpsi);
524 if (mass_Jpsi < m_jpsiMassLower || mass_Jpsi > m_jpsiMassUpper) {
525 ATH_MSG_DEBUG(" Original Jpsi candidate rejected by the mass cut: mass = "
526 << mass_Jpsi << " != (" << m_jpsiMassLower << ", " << m_jpsiMassUpper << ")" );
527 continue;
528 }
529
530 // Check J/psi pi+ candidate invariant mass and skip if need be
531 double mass_Jpsipi = m_V0Tools->invariantMass(*vxcItr, massesJpsipi);
532 ATH_MSG_DEBUG("Jpsipi mass " << mass_Jpsipi);
533 if (mass_Jpsipi < m_jpsipiMassLower || mass_Jpsipi > m_jpsipiMassUpper) {
534 ATH_MSG_DEBUG(" Original Jpsipi candidate rejected by the mass cut: mass = "
535 << mass_Jpsipi << " != (" << m_jpsipiMassLower << ", " << m_jpsipiMassUpper << ")" );
536 continue;
537 }
538
539 selectedJpsipiCandidates.push_back(*vxcItr);
540 }
541 if(selectedJpsipiCandidates.size()<1) return StatusCode::SUCCESS;
542
543 // Select the D0/D0b candidates before calling cascade fit
544 std::vector<const xAOD::Vertex*> selectedD0Candidates;
545 for(auto vxcItr=d0Container->cbegin(); vxcItr!=d0Container->cend(); ++vxcItr) {
546
547 // Check the passed flag first
548 const xAOD::Vertex* vtx = *vxcItr;
549 SG::Accessor<Char_t> flagAcc1("passed_D0");
550 SG::Accessor<Char_t> flagAcc2("passed_D0b");
551 bool isD0(true);
552 bool isD0b(true);
553 if(flagAcc1.isAvailable(*vtx)){
554 if(!flagAcc1(*vtx)) isD0 = false;
555 }
556 if(flagAcc2.isAvailable(*vtx)){
557 if(!flagAcc2(*vtx)) isD0b = false;
558 }
559 if(!(isD0||isD0b)) continue;
560
561 // Ensure the total charge is correct
562 if ((*vxcItr)->trackParticle(0)->charge() != 1 || (*vxcItr)->trackParticle(1)->charge() != -1) {
563 ATH_MSG_DEBUG(" Original D0/D0-bar candidate rejected by the charge requirement: "
564 << (*vxcItr)->trackParticle(0)->charge() << ", " << (*vxcItr)->trackParticle(1)->charge() );
565 continue;
566 }
567
568 // Check D0/D0bar candidate invariant mass and skip if need be
569 double mass_D0 = m_V0Tools->invariantMass(*vxcItr,massesD0);
570 double mass_D0b = m_V0Tools->invariantMass(*vxcItr,massesD0b);
571 ATH_MSG_DEBUG("D0 mass " << mass_D0 << ", D0b mass "<<mass_D0b);
572 if ((mass_D0 < m_D0MassLower || mass_D0 > m_D0MassUpper) && (mass_D0b < m_D0MassLower || mass_D0b > m_D0MassUpper)) {
573 ATH_MSG_DEBUG(" Original D0 candidate rejected by the mass cut: mass = "
574 << mass_D0 << " != (" << m_D0MassLower << ", " << m_D0MassUpper << ") "
575 << mass_D0b << " != (" << m_D0MassLower << ", " << m_D0MassUpper << ") " );
576 continue;
577 }
578
579 selectedD0Candidates.push_back(*vxcItr);
580 }
581 if(selectedD0Candidates.size()<1) return StatusCode::SUCCESS;
582
583 // Select J/psi D*+ candidates
584 // Iterate over Jpsi+pi vertices
585 for(const auto & jpsipi:selectedJpsipiCandidates) {
586
587 size_t jpsipiTrkNum = jpsipi->nTrackParticles();
588 if (jpsipiTrkNum < 3)[[unlikely]]{
589 ATH_MSG_INFO("problems with Jpsi+pi input");
590 }
591 if (jpsipiTrkNum < 1)[[unlikely]] continue; //avoid integer overflow
592
593 tracksJpsipi.clear();
594 tracksJpsi.clear();
595 for( unsigned int it=0; it<jpsipiTrkNum; it++) tracksJpsipi.push_back(jpsipi->trackParticle(it));
596 for( unsigned int it=0; it<jpsipiTrkNum-1; it++) tracksJpsi.push_back(jpsipi->trackParticle(it));
597
598 bool tagD0(true);
599 if(std::abs(m_Dx_pid)==421 && jpsipi->trackParticle(2)->charge()==-1) tagD0 = false;
600
601 TLorentzVector p4_pi1; // Momentum of soft pion
602 p4_pi1.SetPtEtaPhiM(jpsipi->trackParticle(2)->pt(),
603 jpsipi->trackParticle(2)->eta(),
604 jpsipi->trackParticle(2)->phi(), m_vtx0Daug3MassHypo);
605
606 // Iterate over D0/D0bar vertices
607 for(const auto & d0 : selectedD0Candidates) {
608 // Check identical tracks in input
609 if(std::find(tracksJpsipi.cbegin(), tracksJpsipi.cend(), d0->trackParticle(0)) != tracksJpsipi.cend()) continue;
610 if(std::find(tracksJpsipi.cbegin(), tracksJpsipi.cend(), d0->trackParticle(1)) != tracksJpsipi.cend()) continue;
611
612
613 TLorentzVector p4_ka, p4_pi2;
614 if(tagD0){ // for D*+
615 p4_pi2.SetPtEtaPhiM(d0->trackParticle(0)->pt(),
616 d0->trackParticle(0)->eta(),
617 d0->trackParticle(0)->phi(), m_vtx1Daug1MassHypo);
618 p4_ka.SetPtEtaPhiM( d0->trackParticle(1)->pt(),
619 d0->trackParticle(1)->eta(),
620 d0->trackParticle(1)->phi(), m_vtx1Daug2MassHypo);
621 }else{ // change the order in the case of D*-
622 p4_pi2.SetPtEtaPhiM(d0->trackParticle(1)->pt(),
623 d0->trackParticle(1)->eta(),
624 d0->trackParticle(1)->phi(), m_vtx1Daug1MassHypo);
625 p4_ka.SetPtEtaPhiM( d0->trackParticle(0)->pt(),
626 d0->trackParticle(0)->eta(),
627 d0->trackParticle(0)->phi(), m_vtx1Daug2MassHypo);
628 }
629 // Check D*+/- candidate invariant mass and skip if need be
630 double mass_Dst= (p4_pi1 + p4_ka + p4_pi2).M();
631 ATH_MSG_DEBUG("D*+/- mass " << mass_Dst);
632 if (mass_Dst < m_DstMassLower || mass_Dst > m_DstMassUpper) {
633 ATH_MSG_DEBUG(" Original D*+/- candidate rejected by the mass cut: mass = "
634 << mass_Dst << " != (" << m_DstMassLower << ", " << m_DstMassUpper << ")" );
635 continue;
636 }
637
638 size_t d0TrkNum = d0->nTrackParticles();
639 tracksD0.clear();
640 if (d0TrkNum != 2) {
641 ATH_MSG_INFO("problems with D0 input");
642 }
643 for( unsigned int it=0; it<d0TrkNum; it++) tracksD0.push_back(d0->trackParticle(it));
644 ATH_MSG_DEBUG("using tracks" << tracksJpsipi[0] << ", " << tracksJpsipi[1] << ", " << tracksJpsipi[2] << ", " << tracksD0[0] << ", " << tracksD0[1]);
645 ATH_MSG_DEBUG("Charge of Jpsi+pi tracks: "<<jpsipi->trackParticle(0)->charge()<<", "<<jpsipi->trackParticle(1)->charge()<<", "<<jpsipi->trackParticle(2)->charge());
646 ATH_MSG_DEBUG("Charge of D0 tracks: "<<d0->trackParticle(0)->charge()<<", "<<d0->trackParticle(1)->charge());
647
648 tracksBc.clear();
649 for( unsigned int it=0; it<jpsipiTrkNum; it++) tracksBc.push_back(jpsipi->trackParticle(it));
650 for( unsigned int it=0; it<d0TrkNum; it++) tracksBc.push_back(d0->trackParticle(it));
651
652
653 // Apply the user's settings to the fitter
654 // Reset
655 std::unique_ptr<Trk::IVKalState> state (m_iVertexFitter->makeState(ctx));
656 // Robustness
657 int robustness = 0;
658 m_iVertexFitter->setRobustness(robustness, *state);
659 // Build up the topology
660 // Vertex list
661 std::vector<Trk::VertexID> vrtList;
662 // D0 vertex
663 Trk::VertexID vID;
664 if (m_constrD0) {
665 if(tagD0) vID = m_iVertexFitter->startVertex(tracksD0,massesD0,*state,mass_d0);
666 else vID = m_iVertexFitter->startVertex(tracksD0,massesD0b,*state,mass_d0);
667 } else {
668 if(tagD0) vID = m_iVertexFitter->startVertex(tracksD0,massesD0,*state);
669 else vID = m_iVertexFitter->startVertex(tracksD0,massesD0b,*state);
670 }
671 vrtList.push_back(vID);
672 // B vertex including Jpsi+pi
673 Trk::VertexID vID2 = m_iVertexFitter->nextVertex(tracksJpsipi,massesJpsipi,vrtList,*state);
674 if (m_constrJpsi) {
675 std::vector<Trk::VertexID> cnstV;
676 cnstV.clear();
677 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_mass_jpsi).isSuccess() ) {
678 ATH_MSG_WARNING("addMassConstraint failed");
679 //return StatusCode::FAILURE;
680 }
681 }
682 // Do the work
683 std::unique_ptr<Trk::VxCascadeInfo> result(m_iVertexFitter->fitCascade(*state));
684
685 if (result != nullptr) {
686
687 // reset links to original tracks
688 BPhysPVCascadeTools::PrepareVertexLinks(result.get(), trackContainer);
689 ATH_MSG_DEBUG("storing tracks " << ((result->vertices())[0])->trackParticle(0) << ", "
690 << ((result->vertices())[0])->trackParticle(1) << ", "
691 << ((result->vertices())[1])->trackParticle(0) << ", "
692 << ((result->vertices())[1])->trackParticle(1) << ", "
693 << ((result->vertices())[1])->trackParticle(2));
694 // necessary to prevent memory leak
695 result->setSVOwnership(true);
696
697 // Chi2/DOF cut
698 double bChi2DOF = result->fitChi2()/result->nDoF();
699 ATH_MSG_DEBUG("Candidate chi2/DOF is " << bChi2DOF);
700 bool chi2CutPassed = (m_chi2cut <= 0.0 || bChi2DOF < m_chi2cut);
701
702 const std::vector< std::vector<TLorentzVector> > &moms = result->getParticleMoms();
703 double mass = m_CascadeTools->invariantMass(moms[1]);
704 if(chi2CutPassed) {
705 if (mass >= m_MassLower && mass <= m_MassUpper) {
706 cascadeinfoContainer->push_back(result.release());
707 } else {
708 ATH_MSG_DEBUG("Candidate rejected by the mass cut: mass = "
709 << mass << " != (" << m_MassLower << ", " << m_MassUpper << ")" );
710 }
711 }
712 }
713
714 } //Iterate over D0 vertices
715
716 } //Iterate over Jpsi+pi vertices
717
718 ATH_MSG_DEBUG("cascadeinfoContainer size " << cascadeinfoContainer->size());
719
720 return StatusCode::SUCCESS;
721 }
722
723}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
#define BPHYS_CHECK(EXP)
Useful CHECK macro.
: B-physics xAOD helpers.
ATLAS-specific HepMC functions.
#define x
const_iterator cbegin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
const_iterator cend() const noexcept
Return a const_iterator pointing past the end of the collection.
static void PrepareVertexLinks(Trk::VxCascadeInfo *result, const xAOD::TrackParticleContainer *importedTrackCollection)
static const xAOD::Vertex * FindVertex(const xAOD::VertexContainer *c, const xAOD::Vertex *v)
static void SetVectorInfo(xAOD::BPhysHelper &, const Trk::VxCascadeInfo *)
static bool LinkVertices(SG::Decorator< VertexLinkVector > &decor, const std::vector< const xAOD::Vertex * > &vertices, const xAOD::VertexContainer *vertexContainer, const xAOD::Vertex *vert)
PublicToolHandle< Trk::V0Tools > m_V0Tools
std::string m_VxPrimaryCandidateName
Name of primary vertex container // FIXME Use Handles.
PublicToolHandle< Analysis::PrimaryVertexRefitter > m_pvRefitter
ToolHandle< Trk::TrkVKalVrtFitter > m_iVertexFitter
std::vector< std::string > m_cascadeOutputsKeys
std::string m_hypoName
name of the mass hypothesis.
PublicToolHandle< DerivationFramework::CascadeTools > m_CascadeTools
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo_key
JpsiPlusDpstCascade(const std::string &t, const std::string &n, const IInterface *p)
StatusCode performSearch(std::vector< Trk::VxCascadeInfo * > *cascadeinfoContainer, const EventContext &ctx) const
virtual StatusCode addBranches(const EventContext &ctx) const override
Helper class to provide type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
bool setMass(const float val)
Set given invariant mass and its error.
bool setMassErr(const float val)
invariant mass error
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .).
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
float charge() const
Returns the charge.
float z() const
Returns the z position.
const TrackParticle * trackParticle(size_t i) const
Get the pointer to a given track that was used in vertex reco.
float y() const
Returns the y position.
float x() const
Returns the x position.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:116
THE reconstruction tool.
std::vector< const xAOD::TrackParticle * > TrackBag
ElementLink< xAOD::VertexContainer > VertexLink
std::vector< VertexLink > VertexLinkVector
static const int KPLUS
static const int MUON
static const int BCPLUS
static const int PIPLUS
static const int JPSI
static const int D0
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
Definition AuxElement.h:576
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
#define unlikely(x)