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"
15#include <algorithm>
19
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::AuxElement::Decorator<VertexLinkVector> CascadeLinksDecor("CascadeVertexLinks");
116 SG::AuxElement::Decorator<VertexLinkVector> JpsipiLinksDecor("JpsipiVertexLinks");
117 SG::AuxElement::Decorator<VertexLinkVector> D0LinksDecor("D0VertexLinks");
118 SG::AuxElement::Decorator<float> chi2_decor("ChiSquared");
119 SG::AuxElement::Decorator<float> ndof_decor("NumberDoF");
120 SG::AuxElement::Decorator<float> Pt_decor("Pt");
121 SG::AuxElement::Decorator<float> PtErr_decor("PtErr");
122 SG::AuxElement::Decorator<float> Mass_svdecor("D0_mass");
123 SG::AuxElement::Decorator<float> MassErr_svdecor("D0_massErr");
124 SG::AuxElement::Decorator<float> Pt_svdecor("D0_Pt");
125 SG::AuxElement::Decorator<float> PtErr_svdecor("D0_PtErr");
126 SG::AuxElement::Decorator<float> Lxy_svdecor("D0_Lxy");
127 SG::AuxElement::Decorator<float> LxyErr_svdecor("D0_LxyErr");
128 SG::AuxElement::Decorator<float> Tau_svdecor("D0_Tau");
129 SG::AuxElement::Decorator<float> TauErr_svdecor("D0_TauErr");
130
131 SG::AuxElement::Decorator<float> MassMumu_decor("Mumu_mass");
132 SG::AuxElement::Decorator<float> MassKpi_svdecor("Kpi_mass");
133 SG::AuxElement::Decorator<float> MassJpsi_decor("Jpsi_mass");
134 SG::AuxElement::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 for(auto vxcItr=jpsipiContainer->cbegin(); vxcItr!=jpsipiContainer->cend(); ++vxcItr) {
506
507 // Check the passed flag first
508 const xAOD::Vertex* vtx = *vxcItr;
509 SG::AuxElement::Accessor<Char_t> flagAcc1("passed_Jpsipi");
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::AuxElement::Accessor<Char_t> flagAcc1("passed_D0");
550 SG::AuxElement::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(auto jpsipiItr=selectedJpsipiCandidates.cbegin(); jpsipiItr!=selectedJpsipiCandidates.cend(); ++jpsipiItr) {
586
587 size_t jpsipiTrkNum = (*jpsipiItr)->nTrackParticles();
588 tracksJpsipi.clear();
589 tracksJpsi.clear();
590 for( unsigned int it=0; it<jpsipiTrkNum; it++) tracksJpsipi.push_back((*jpsipiItr)->trackParticle(it));
591 for( unsigned int it=0; it<jpsipiTrkNum-1; it++) tracksJpsi.push_back((*jpsipiItr)->trackParticle(it));
592
593 if (tracksJpsipi.size() != 3 || massesJpsipi.size() != 3 ) {
594 ATH_MSG_INFO("problems with Jpsi+pi input");
595 }
596
597 bool tagD0(true);
598 if(abs(m_Dx_pid)==421 && (*jpsipiItr)->trackParticle(2)->charge()==-1) tagD0 = false;
599
600 TLorentzVector p4_pi1; // Momentum of soft pion
601 p4_pi1.SetPtEtaPhiM((*jpsipiItr)->trackParticle(2)->pt(),
602 (*jpsipiItr)->trackParticle(2)->eta(),
603 (*jpsipiItr)->trackParticle(2)->phi(), m_vtx0Daug3MassHypo);
604
605 // Iterate over D0/D0bar vertices
606 for(auto d0Itr=selectedD0Candidates.cbegin(); d0Itr!=selectedD0Candidates.cend(); ++d0Itr) {
607
608 // Check identical tracks in input
609 if(std::find(tracksJpsipi.cbegin(), tracksJpsipi.cend(), (*d0Itr)->trackParticle(0)) != tracksJpsipi.cend()) continue;
610 if(std::find(tracksJpsipi.cbegin(), tracksJpsipi.cend(), (*d0Itr)->trackParticle(1)) != tracksJpsipi.cend()) continue;
611
612
613 TLorentzVector p4_ka, p4_pi2;
614 if(tagD0){ // for D*+
615 p4_pi2.SetPtEtaPhiM((*d0Itr)->trackParticle(0)->pt(),
616 (*d0Itr)->trackParticle(0)->eta(),
617 (*d0Itr)->trackParticle(0)->phi(), m_vtx1Daug1MassHypo);
618 p4_ka.SetPtEtaPhiM( (*d0Itr)->trackParticle(1)->pt(),
619 (*d0Itr)->trackParticle(1)->eta(),
620 (*d0Itr)->trackParticle(1)->phi(), m_vtx1Daug2MassHypo);
621 }else{ // change the order in the case of D*-
622 p4_pi2.SetPtEtaPhiM((*d0Itr)->trackParticle(1)->pt(),
623 (*d0Itr)->trackParticle(1)->eta(),
624 (*d0Itr)->trackParticle(1)->phi(), m_vtx1Daug1MassHypo);
625 p4_ka.SetPtEtaPhiM( (*d0Itr)->trackParticle(0)->pt(),
626 (*d0Itr)->trackParticle(0)->eta(),
627 (*d0Itr)->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 = (*d0Itr)->nTrackParticles();
639 tracksD0.clear();
640 for( unsigned int it=0; it<d0TrkNum; it++) tracksD0.push_back((*d0Itr)->trackParticle(it));
641 if (tracksD0.size() != 2 || massesD0.size() != 2 ) {
642 ATH_MSG_INFO("problems with D0 input");
643 }
644
645 ATH_MSG_DEBUG("using tracks" << tracksJpsipi[0] << ", " << tracksJpsipi[1] << ", " << tracksJpsipi[2] << ", " << tracksD0[0] << ", " << tracksD0[1]);
646 ATH_MSG_DEBUG("Charge of Jpsi+pi tracks: "<<(*jpsipiItr)->trackParticle(0)->charge()<<", "<<(*jpsipiItr)->trackParticle(1)->charge()<<", "<<(*jpsipiItr)->trackParticle(2)->charge());
647 ATH_MSG_DEBUG("Charge of D0 tracks: "<<(*d0Itr)->trackParticle(0)->charge()<<", "<<(*d0Itr)->trackParticle(1)->charge());
648
649 tracksBc.clear();
650 for( unsigned int it=0; it<jpsipiTrkNum; it++) tracksBc.push_back((*jpsipiItr)->trackParticle(it));
651 for( unsigned int it=0; it<d0TrkNum; it++) tracksBc.push_back((*d0Itr)->trackParticle(it));
652
653
654 // Apply the user's settings to the fitter
655 // Reset
656 std::unique_ptr<Trk::IVKalState> state (m_iVertexFitter->makeState(ctx));
657 // Robustness
658 int robustness = 0;
659 m_iVertexFitter->setRobustness(robustness, *state);
660 // Build up the topology
661 // Vertex list
662 std::vector<Trk::VertexID> vrtList;
663 // D0 vertex
664 Trk::VertexID vID;
665 if (m_constrD0) {
666 if(tagD0) vID = m_iVertexFitter->startVertex(tracksD0,massesD0,*state,mass_d0);
667 else vID = m_iVertexFitter->startVertex(tracksD0,massesD0b,*state,mass_d0);
668 } else {
669 if(tagD0) vID = m_iVertexFitter->startVertex(tracksD0,massesD0,*state);
670 else vID = m_iVertexFitter->startVertex(tracksD0,massesD0b,*state);
671 }
672 vrtList.push_back(vID);
673 // B vertex including Jpsi+pi
674 Trk::VertexID vID2 = m_iVertexFitter->nextVertex(tracksJpsipi,massesJpsipi,vrtList,*state);
675 if (m_constrJpsi) {
676 std::vector<Trk::VertexID> cnstV;
677 cnstV.clear();
678 if ( !m_iVertexFitter->addMassConstraint(vID2,tracksJpsi,cnstV,*state,m_mass_jpsi).isSuccess() ) {
679 ATH_MSG_WARNING("addMassConstraint failed");
680 //return StatusCode::FAILURE;
681 }
682 }
683 // Do the work
684 std::unique_ptr<Trk::VxCascadeInfo> result(m_iVertexFitter->fitCascade(*state));
685
686 if (result != nullptr) {
687
688 // reset links to original tracks
689 BPhysPVCascadeTools::PrepareVertexLinks(result.get(), trackContainer);
690 ATH_MSG_DEBUG("storing tracks " << ((result->vertices())[0])->trackParticle(0) << ", "
691 << ((result->vertices())[0])->trackParticle(1) << ", "
692 << ((result->vertices())[1])->trackParticle(0) << ", "
693 << ((result->vertices())[1])->trackParticle(1) << ", "
694 << ((result->vertices())[1])->trackParticle(2));
695 // necessary to prevent memory leak
696 result->setSVOwnership(true);
697
698 // Chi2/DOF cut
699 double bChi2DOF = result->fitChi2()/result->nDoF();
700 ATH_MSG_DEBUG("Candidate chi2/DOF is " << bChi2DOF);
701 bool chi2CutPassed = (m_chi2cut <= 0.0 || bChi2DOF < m_chi2cut);
702
703 const std::vector< std::vector<TLorentzVector> > &moms = result->getParticleMoms();
704 double mass = m_CascadeTools->invariantMass(moms[1]);
705 if(chi2CutPassed) {
706 if (mass >= m_MassLower && mass <= m_MassUpper) {
707 cascadeinfoContainer->push_back(result.release());
708 } else {
709 ATH_MSG_DEBUG("Candidate rejected by the mass cut: mass = "
710 << mass << " != (" << m_MassLower << ", " << m_MassUpper << ")" );
711 }
712 }
713 }
714
715 } //Iterate over D0 vertices
716
717 } //Iterate over Jpsi+pi vertices
718
719 ATH_MSG_DEBUG("cascadeinfoContainer size " << cascadeinfoContainer->size());
720
721 return StatusCode::SUCCESS;
722 }
723
724}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(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 bool LinkVertices(SG::AuxElement::Decorator< VertexLinkVector > &decor, const std::vector< const xAOD::Vertex * > &vertices, const xAOD::VertexContainer *vertexContainer, const xAOD::Vertex *vert)
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 *)
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
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
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".