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