ATLAS Offline Software
Cascade3Plus1.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
5 // Cascade3Plus1.cxx, (c) ATLAS Detector software
17 #include "xAODBPhys/BPhysHelper.h"
18 #include "Math/Vector4D.h"
19 
21 
22 namespace DerivationFramework {
24 typedef std::vector<VertexLink> VertexLinkVector;
25 typedef std::vector<const xAOD::TrackParticle*> TrackBag;
27 typedef ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> > GenVecFourMom_t;
28 
29 template<size_t N>
30 struct Candidate {
31  std::array<const xAOD::TrackParticle*, N> tracks;
32 };
33 
34 struct VertexCand : Candidate<4> {
35  std::unique_ptr<Trk::VxCascadeInfo> cascVertex;
36 };
37 
38 template<size_t N>
39 GenVecFourMom_t SumVector(const std::array<GenVecFourMom_t, N> &vectors) {
40  GenVecFourMom_t total = vectors[0];
41  for(size_t i =1; i<N; i++) total+= vectors[i];
42  return total;
43 }
44 
45 Cascade3Plus1::Cascade3Plus1(const std::string& t, const std::string& n, const IInterface* p) : AthAlgTool(t,n,p),
46  m_trkSelector("InDet::TrackSelectorTool"),
47  m_iVertexFitter("Trk::TrkVKalVrtFitter"),
48  m_V0Tools("Trk::V0Tools"),
49  m_CascadeTools("DerivationFramework::CascadeTools"),
50  m_pvRefitter("Analysis::PrimaryVertexRefitter"),
51  m_cascadeOutputsKeys{ "CascadeVtx1", "CascadeVtx2" }
52 {
53  declareProperty("V0Tools", m_V0Tools);
54  declareProperty("TrackMassHyp", m_trackMasses);
55  declareProperty("CascadeVertexCollections", m_cascadeOutputsKeys);
56  declareProperty("TwoTrackMassMin", m_2trackmassMin);
57  declareProperty("TwoTrackMassMax", m_2trackmassMax);
58  declareProperty("ThreeTrackMassMin", m_3trackmassMin);
59  declareProperty("ThreeTrackMassMax", m_3trackmassMax);
60  declareProperty("FourTrackMassMin", m_4trackmassMin);
61  declareProperty("FourTrackMassMax", m_4trackmassMax);
62  declareProperty("TwoTracksMass", m_2tracksMass);
63  declareProperty("ThreeTracksMass", m_3tracksMass);
64  declareProperty("FourTracksMass", m_4tracksMass);
65  declareProperty("TrackSelectorTool",m_trkSelector);
66  declareProperty("CascadeTools", m_CascadeTools);
67  declareProperty("MinNTracksInPV", m_PV_minNTracks = 0);
68  declareProperty("HypothesisName", m_hypoName = "Bs");
69  declareProperty("Track3Name", m_3TrackName = "Ds");
70  declareProperty("MaxnPV", m_PV_max = 999);
71  declareProperty("DoVertexType", m_DoVertexType = 7);
72  declareProperty("RefitPV", m_refitPV = true);
73  declareProperty("RefPVContainerName", m_refPVContainerName = "RefittedPrimaryVertices");
74  declareProperty("PVRefitter", m_pvRefitter);
75  declareProperty("TrkVertexFitterTool", m_iVertexFitter);
76  declareProperty("PVContainerName", m_VxPrimaryCandidateName);
77  declareProperty("ThreeTrackMassConstraint", m_3TrackMassConstraint);
78  declareProperty("TwoTrackMassConstraint", m_2TrackMassConstraint);
79  declareProperty("Chi2NDFCut", m_Chi2NDFCut);
80 
81  declareProperty("FourTrackMassFinalMin", m_4trackmassFinalMin);
82  declareProperty("FourTrackMassFinalMax", m_4trackmassFinalMax);
83  declareProperty("FourTrackTauCut", m_tauCut);
84  declareProperty("UseMuonsForTracks", m_requireMuonsOnTrack);
85  declareProperty("ThreeVertexOutputContainer", m_3TrackVertexOutput);
86  declareProperty("VertexEstimator", m_vertexEstimator);
87  declareProperty("ThreeTrackChi2NDF", m_3TrackChi2NDFCut);
88  declareProperty("EliminateBad3Tracksfrom4Track", m_eliminateBad3Tracksfrom4Track);
89  declareProperty("CopyAllVertices", m_copyAllVertices);
90  declareProperty("PTCutPerTrack", m_ptCutPerTrack);
91  m_ptCutPerVertex.fill(0);
92  declareProperty("PTCutVertex1", m_ptCutPerVertex[0]);
93  declareProperty("PTCutVertex2", m_ptCutPerVertex[1]);
94  declareProperty("PTCutVertex3", m_ptCutPerVertex[2]);
95 }
96 
98  if(m_trackMasses.size()!=4) {
99  ATH_MSG_ERROR("4 mass hypotheses must be provided");
100  return StatusCode::FAILURE;
101  }
102  if(m_cascadeOutputsKeys.size() !=s_topoN) {
103  ATH_MSG_FATAL("Incorrect number of VtxContainers");
104  return StatusCode::FAILURE;
105  }
106  // retrieving vertex Fitter
107  ATH_CHECK( m_iVertexFitter.retrieve());
108 
109  // retrieving the Cascade tools
110  ATH_CHECK( m_CascadeTools.retrieve());
111 
112  // Get the beam spot service
114 
115  ATH_CHECK(m_vertexEstimator.retrieve());
117  ATH_MSG_FATAL("Invalid configuration");
118  return StatusCode::FAILURE;
119  }
120 
121  if(m_ptCutPerTrack.size() == 1 || m_ptCutPerTrack.size() > 4){
122  ATH_MSG_FATAL("Invalid configuration");
123  return StatusCode::FAILURE;
124  }
125  if(m_ptCutPerTrack.size() >=2 && m_ptCutPerTrack[0] != m_ptCutPerTrack[1]){
126  ATH_MSG_FATAL("Invalid configuration");
127  return StatusCode::FAILURE;
128  }
129  m_muonTrackBit.reset();
130  for(int i : m_requireMuonsOnTrack) {
131  if(i>=4) {
132  ATH_MSG_FATAL("Invalid configuration" << " muon track " << i);
133  return StatusCode::FAILURE;
134  }
135  m_muonTrackBit[i] = true;
136  }
137  m_requireMuonsOnTrack.clear();
138  m_requireMuonsOnTrack.shrink_to_fit();
139 
140  if(m_muonTrackBit[0] != m_muonTrackBit[1])
141  {
142  ATH_MSG_FATAL("Invalid configuration" << " variable is " << m_muonTrackBit.to_string());
143  return StatusCode::FAILURE;
144  }
145 
146 
147  return StatusCode::SUCCESS;
148 }
149 
151 
152 
153 const TrackBag& Cascade3Plus1::ApplyAdditionalCuts(const TrackBag& alltracks, const TrackBag& muonTracks, TrackBag& cuttracks, size_t track) const {
154  const TrackBag& tracks = m_muonTrackBit[track] ? muonTracks : alltracks;
155  if(track >= m_ptCutPerTrack.size()) return tracks;
156  double ptCut = m_ptCutPerTrack.at(track);
157  if(ptCut <=0.0) return tracks;
158  cuttracks.clear();//reset any previous selections
159  for(auto ptr : tracks){
160  if(ptr->pt() > ptCut) cuttracks.push_back(ptr);
161  }
162  return cuttracks;
163 }
164 
166 {
167  const xAOD::TrackParticleContainer *trackContainer(nullptr);
168  ATH_CHECK(evtStore()->retrieve(trackContainer, "InDetTrackParticles" ));
169 
170  //----------------------------------------------------
171  // Try to retrieve refitted primary vertices
172  //----------------------------------------------------
173  xAOD::VertexContainer* refPvContainer = nullptr;
174  xAOD::VertexAuxContainer* refPvAuxContainer = nullptr;
175  if (m_refitPV) {
176  if (evtStore()->contains<xAOD::VertexContainer>(m_refPVContainerName)) {
177  // refitted PV container exists. Get it from the store gate
178  ATH_CHECK(evtStore()->retrieve(refPvContainer, m_refPVContainerName ));
179  ATH_CHECK(evtStore()->retrieve(refPvAuxContainer, m_refPVContainerName + "Aux."));
180  } else {
181  // refitted PV container does not exist. Create a new one.
182  refPvContainer = new xAOD::VertexContainer;
183  refPvAuxContainer = new xAOD::VertexAuxContainer;
184  refPvContainer->setStore(refPvAuxContainer);
185  ATH_CHECK(evtStore()->record(refPvContainer, m_refPVContainerName));
186  ATH_CHECK(evtStore()->record(refPvAuxContainer, m_refPVContainerName+"Aux."));
187  }
188  }
189 
190  std::array<xAOD::VertexContainer*, s_topoN> Vtxwritehandles;
191  std::array<xAOD::VertexAuxContainer*, s_topoN> Vtxwritehandlesaux;
192 
193  for(int i =0; i<s_topoN; i++) {
194  Vtxwritehandles[i] = new xAOD::VertexContainer();
195  Vtxwritehandlesaux[i] = new xAOD::VertexAuxContainer();
196  Vtxwritehandles[i]->setStore(Vtxwritehandlesaux[i]);
197  ATH_CHECK(evtStore()->record(Vtxwritehandles[i], m_cascadeOutputsKeys[i] ));
198  ATH_CHECK(evtStore()->record(Vtxwritehandlesaux[i], m_cascadeOutputsKeys[i] + "Aux."));
199  }
200  xAOD::VertexContainer *v3container = nullptr;
201  if(!m_3TrackVertexOutput.empty()) {
202  v3container = new xAOD::VertexContainer();
203  auto vcontaineraux = new xAOD::VertexAuxContainer();
204  v3container->setStore(vcontaineraux);
205  ATH_CHECK(evtStore()->record(v3container, m_3TrackVertexOutput ));
206  ATH_CHECK(evtStore()->record(vcontaineraux, m_3TrackVertexOutput + "Aux."));
207  }
208  //----------------------------------------------------
209  // retrieve primary vertices
210  //----------------------------------------------------
211 
212  const xAOD::Vertex * primaryVertex(nullptr);
213  const xAOD::VertexContainer *pvContainer(nullptr);
215 
216  if (pvContainer->size()==0) {
217  ATH_MSG_WARNING("You have no primary vertices: " << pvContainer->size());
218  return StatusCode::RECOVERABLE;
219  } else {
220  primaryVertex = (*pvContainer)[0];
221  }
222 
223 
224  TrackBag theIDTracksAfterSelection;
225  TrackBag theIDTracksAfterAdditionalSelection;
226  for(auto x : *trackContainer) {
227  if ( m_trkSelector->decision(*x, nullptr) ) theIDTracksAfterSelection.push_back(x);
228  }
229  ATH_MSG_DEBUG("Found good tracks N="<<theIDTracksAfterSelection.size());
230  TrackBag theMuonsAfterSelection;
231  if(m_muonTrackBit.any()) {
232  const xAOD::MuonContainer* importedMuonCollection(0);
233  ATH_CHECK(evtStore()->retrieve(importedMuonCollection, "Muons"));
234  for(auto muon : *importedMuonCollection) {
235  if(muon->muonType() == xAOD::Muon::SiliconAssociatedForwardMuon) continue;
236  auto ptr = muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
237  if(ptr) theMuonsAfterSelection.push_back(ptr);
238  }
239  }
240 
241  std::vector<Candidate<2>> Initialcandidates;
242  { //Isolate scope for safety
243  const TrackBag &Tracksfor2Vertex = ApplyAdditionalCuts(theIDTracksAfterSelection, theMuonsAfterSelection, theIDTracksAfterAdditionalSelection, 0);
244  for(auto track1itr = Tracksfor2Vertex.cbegin(); track1itr != Tracksfor2Vertex.cend(); ++track1itr) {
245  Candidate<2> cand;
246  std::array<GenVecFourMom_t, 2> vectors;
247  cand.tracks[0] = *track1itr;
248  vectors[0].SetCoordinates(cand.tracks[0]->pt(), cand.tracks[0]->eta(), cand.tracks[0]->phi(), m_trackMasses[0]);
249  for(auto track2itr = track1itr+1; track2itr != Tracksfor2Vertex.cend(); ++track2itr) {
250  cand.tracks[1] = *track2itr;
251  if(cand.tracks[0]->qOverP() * cand.tracks[1]->qOverP() >= 0.) continue; //Skip same signed
252  vectors[1].SetCoordinates(cand.tracks[1]->pt(), cand.tracks[1]->eta(), cand.tracks[1]->phi(), m_trackMasses[1]);
253  GenVecFourMom_t pair = SumVector(vectors);
254  if(pair.Pt() < m_ptCutPerVertex[0]) continue;
255  if(pair.M() >= m_2trackmassMin && pair.M() < m_2trackmassMax) {
256  ATH_MSG_VERBOSE("2 Track candidate found: " << pair.M() << " Within " << m_2trackmassMin << " and " << m_2trackmassMax);
257  Initialcandidates.push_back(cand);
258  }
259  }
260  }
261  }
262  ATH_MSG_DEBUG("2 Track candidates found: " << Initialcandidates.size());
263  if(Initialcandidates.empty()) {
264  //No work to do Leave method early
265  return StatusCode::SUCCESS;
266  }
267  std::vector<Candidate<3>> Candidates3;
268 
269  {//isolate scope
270  const TrackBag &Tracksfor3Vertex = ApplyAdditionalCuts(theIDTracksAfterSelection, theMuonsAfterSelection, theIDTracksAfterAdditionalSelection, 2);
271  for(auto &c : Initialcandidates) {
273  std::copy(c.tracks.begin(), c.tracks.end(), c3.tracks.begin());
274  std::array<GenVecFourMom_t, 3> vectors;
275  vectors[0].SetCoordinates(c.tracks[0]->pt(), c.tracks[0]->eta(), c.tracks[0]->phi(), m_trackMasses[0]);
276  vectors[1].SetCoordinates(c.tracks[1]->pt(), c.tracks[1]->eta(), c.tracks[1]->phi(), m_trackMasses[1]);
277  for(auto track3itr = Tracksfor3Vertex.cbegin(); track3itr != Tracksfor3Vertex.cend(); ++track3itr) {
278  if(std::find(c3.tracks.begin(), c3.tracks.end(), *track3itr) != c3.tracks.end()) continue;
279  c3.tracks[2] = *track3itr;
280  vectors[2].SetCoordinates(c3.tracks[2]->pt(), c3.tracks[2]->eta(), c3.tracks[2]->phi(), m_trackMasses[2]);
281  GenVecFourMom_t tripple = SumVector(vectors);
282  if(tripple.Pt() < m_ptCutPerVertex[1]) continue;
283  if(tripple.M() >= m_3trackmassMin && tripple.M() < m_3trackmassMax) {
284  ATH_MSG_VERBOSE("3 Track candidate found: " << tripple.M() << " Within " << m_3trackmassMin << " and " << m_3trackmassMax);
285  Candidates3.push_back(c3);
286  }
287  }
288  }
289  }
290  Initialcandidates.clear();
291  Initialcandidates.shrink_to_fit();
292 
293  ATH_MSG_DEBUG("3 Track candidates found: " << Candidates3.size());
294  std::map<const std::array<const xAOD::TrackParticle*, 3>, xAOD::Vertex* > threeVertexMap;
295 
296  if(!m_3TrackVertexOutput.empty()) {
298  if(not evt.isValid()) ATH_MSG_ERROR("Cannot Retrieve " << evt.key() );
299  BPhysPVTools helper(&(*m_V0Tools), evt.cptr());
300  helper.SetMinNTracksInPV(0);
301  helper.SetSave3d(false);
302  std::vector<const xAOD::TrackParticle*> tracksforfit;
303  std::vector<Candidate<3>> Candidates3PassCuts;
304  if(m_eliminateBad3Tracksfrom4Track) Candidates3PassCuts.reserve(Candidates3.size());
305  for(const auto &c3 : Candidates3) {
306  tracksforfit.assign(c3.tracks.begin(), c3.tracks.end());
307  auto v = StandardFit(tracksforfit, trackContainer);
308  if(v==nullptr) {
309  ATH_MSG_DEBUG("3Vertex fit returned null");
310  continue;
311  }
312  if(m_3TrackChi2NDFCut > 0. && v->chiSquared() / v->numberDoF() > m_3TrackChi2NDFCut) {
313  ATH_MSG_DEBUG("Rejecting 3 track vertex because Chi " << v->chiSquared() / v->numberDoF() << " > " << m_3TrackChi2NDFCut);
314  continue;
315  }
316  if(m_eliminateBad3Tracksfrom4Track) Candidates3PassCuts.push_back(c3);
317  threeVertexMap[c3.tracks] = v.get();
318  xAOD::BPhysHelper bHelper(v.get());//"get" does not "release" still automatically deleted
319  bHelper.setRefTrks();
320  v3container->push_back(v.release());
321  }
322 
323  if(v3container->size() >0) ATH_CHECK(helper.FillCandExistingVertices(v3container, pvContainer, 1));
324 
326  ATH_MSG_DEBUG("Swapping container to N = "<< Candidates3PassCuts.size() << " from " << Candidates3.size());
327  Candidates3PassCuts.swap(Candidates3);//Swap old container with one that passed cuts
328  }
329 
330  }
331  std::vector<VertexCand> Candidates4;
332  {//isolate scope
333  const TrackBag &Tracksfor4Vertex = ApplyAdditionalCuts(theIDTracksAfterSelection, theMuonsAfterSelection, theIDTracksAfterAdditionalSelection, 3);
334  for(auto &c : Candidates3) {
335  VertexCand c4;
336  std::copy(c.tracks.begin(), c.tracks.end(), c4.tracks.begin());
337  std::array<GenVecFourMom_t, 4> vectors;
338  vectors[0].SetCoordinates(c.tracks[0]->pt(), c.tracks[0]->eta(), c.tracks[0]->phi(), m_trackMasses[0]);
339  vectors[1].SetCoordinates(c.tracks[1]->pt(), c.tracks[1]->eta(), c.tracks[1]->phi(), m_trackMasses[1]);
340  vectors[2].SetCoordinates(c.tracks[2]->pt(), c.tracks[2]->eta(), c.tracks[2]->phi(), m_trackMasses[2]);
341  for(auto track4itr = Tracksfor4Vertex.cbegin(); track4itr != Tracksfor4Vertex.cend(); ++track4itr) {
342  if(std::find(c4.tracks.begin(), c4.tracks.end(), *track4itr) != c4.tracks.end()) continue;
343  c4.tracks[3] = *track4itr;
344  if(c4.tracks[2]->qOverP() * c4.tracks[3]->qOverP() >= 0.) continue; //Skip same signed
345  vectors[3].SetCoordinates(c4.tracks[3]->pt(), c4.tracks[3]->eta(), c4.tracks[3]->phi(), m_trackMasses[3]);
346  GenVecFourMom_t fourtrack = SumVector(vectors);
347  if(fourtrack.Pt() < m_ptCutPerVertex[2]) continue;
348  if(fourtrack.M() >= m_4trackmassMin && fourtrack.M() < m_4trackmassMax) {
349  ATH_MSG_VERBOSE("3 Track candidate found: " << fourtrack.M() << " Within " << m_4trackmassMin << " and " << m_4trackmassMax);
350  Candidates4.push_back(std::move(c4));
351  }
352  }
353  }
354  }
355  Candidates3.clear();
356  Candidates3.shrink_to_fit();
357 
358  ATH_MSG_DEBUG("4 Track candidates found: " << Candidates4.size() << " running cascade");
359  for(auto &c : Candidates4) {
360  c.cascVertex = CascadeFit(c.tracks);
361  if(c.cascVertex!=nullptr) {
362  c.cascVertex->setSVOwnership(true);
363  }
364  }
365 
366  SG::AuxElement::Decorator<VertexLinkVector> CascadeLinksDecor("CascadeVertexLinks");
367  SG::AuxElement::Decorator<VertexLink> Vertex3Decor(m_3TrackName+ "_VertexLink");
368  SG::AuxElement::Decorator<float> chi2_decor("ChiSquared");
369  SG::AuxElement::Decorator<float> ndof_decor("NumberDoF");
370 // SG::AuxElement::Decorator<float> TotalProb_decor("TotalProb");
371  SG::AuxElement::Decorator<float> Pt_decor("Pt");
372  SG::AuxElement::Decorator<float> PtErr_decor("PtErr");
373  SG::AuxElement::Decorator<float> Mass_svdecor(m_3TrackName+ "_mass");
374  SG::AuxElement::Decorator<float> MassErr_svdecor(m_3TrackName+"_massErr");
376  SG::AuxElement::Decorator<float> PtErr_svdecor(m_3TrackName+"_PtErr");
378  SG::AuxElement::Decorator<float> LxyErr_svdecor(m_3TrackName+"_LxyErr");
380  SG::AuxElement::Decorator<float> TauErr_svdecor(m_3TrackName+"_TauErr");
381 
382 
384  if(not evt.isValid()) ATH_MSG_ERROR("Cannot Retrieve " << m_eventInfo_key.key() );
386  helper.SetMinNTracksInPV(m_PV_minNTracks);
387  helper.m_copyAllVertices = this->m_copyAllVertices;
388 
389 
390 
391  int totalnotnull=0;
392  for(auto &c : Candidates4) {
393  if(c.cascVertex==nullptr) {
394  totalnotnull++;
395  continue;
396  }
397  auto x = c.cascVertex.get();
398  const std::vector<xAOD::Vertex*> &cascadeVertices = x->vertices();
399  if(cascadeVertices.size()!=s_topoN) {
400  ATH_MSG_ERROR("Incorrect number of vertices");
401  continue;
402  }
403  if(cascadeVertices[0] == nullptr || cascadeVertices[1] == nullptr) {
404  ATH_MSG_ERROR("Error null vertex");
405  continue;
406  }
407  if( m_Chi2NDFCut > 0.0 && (x->fitChi2() / x->nDoF()) > m_Chi2NDFCut) {
408  continue;
409  }
410  BPhysPVCascadeTools::PrepareVertexLinks(c.cascVertex.get(), trackContainer);
411  const std::vector< std::vector<TLorentzVector> > &moms = x->getParticleMoms();
412  double mass1 = m_CascadeTools->invariantMass(moms[1]);
413  if(m_4trackmassFinalMin > 0. && mass1 < m_4trackmassFinalMin) continue;
414  if(m_4trackmassFinalMax > 0. && mass1 > m_4trackmassFinalMax) continue;
415  double tau = m_CascadeTools->tau(moms[1],cascadeVertices[1],primaryVertex);
416  if(tau < m_tauCut) continue;
417 // ATH_MSG_INFO("Total chi " << x->fitChi2()<< " sum chi2 " << cascadeVertices[0]->chiSquared() + cascadeVertices[1]->chiSquared() );
418  // Keep vertices (bear in mind that they come in reverse order!)
419  for(int i =0; i<s_topoN; i++) Vtxwritehandles[i]->push_back(cascadeVertices[i]);
420  x->setSVOwnership(false); // Prevent Container from deleting vertices
421  const auto mainVertex = cascadeVertices[1]; // this is the B vertex
422 
423  // Set links to cascade vertices
424  std::vector<const xAOD::Vertex*> verticestoLink;
425  verticestoLink.push_back(cascadeVertices[0]);
426  if(!BPhysPVCascadeTools::LinkVertices(CascadeLinksDecor, verticestoLink, Vtxwritehandles[0], cascadeVertices[1])) {
427  ATH_MSG_ERROR("Error decorating with cascade vertices");
428  }
429 
430  // loop over candidates -- Don't apply PV_minNTracks requirement here
431  // because it may result in exclusion of the high-pt PV.
432  // get good PVs
433 
434  xAOD::BPhysHypoHelper vtx(m_hypoName, mainVertex);
435 
436  // Get refitted track momenta from all vertices, charged tracks only
438 
439  // Decorate main vertex
440  //
441  // 1.a) mass, mass error
442 
443  BPHYS_CHECK( vtx.setMass(m_CascadeTools->invariantMass(moms[1])) );
444  BPHYS_CHECK( vtx.setMassErr(m_CascadeTools->invariantMassError(moms[1],x->getCovariance()[1])) );
445  // 1.b) pt and pT error (the default pt of mainVertex is != the pt of the full cascade fit!)
446  Pt_decor(*mainVertex) = m_CascadeTools->pT(moms[1]);
447  PtErr_decor(*mainVertex) = m_CascadeTools->pTError(moms[1],x->getCovariance()[1]);
448  // 1.c) chi2 and ndof (the default chi2 of mainVertex is != the chi2 of the full cascade fit!)
449  chi2_decor(*mainVertex) = x->fitChi2();
450  ndof_decor(*mainVertex) = x->nDoF();
451  ATH_CHECK(helper.FillCandwithRefittedVertices(m_refitPV, pvContainer,
452  refPvContainer, &(*m_pvRefitter), m_PV_max, m_DoVertexType, x, 1, m_4tracksMass, vtx));
453  // 4) decorate the main vertex with D0 vertex mass, pt, lifetime and lxy values (plus errors)
454  // D0 points to the main vertex, so lifetime and lxy are w.r.t the main vertex
455  Mass_svdecor(*mainVertex) = m_CascadeTools->invariantMass(moms[0]);
456  MassErr_svdecor(*mainVertex) = m_CascadeTools->invariantMassError(moms[0],x->getCovariance()[0]);
457  Pt_svdecor(*mainVertex) = m_CascadeTools->pT(moms[0]);
458  PtErr_svdecor(*mainVertex) = m_CascadeTools->pTError(moms[0],x->getCovariance()[0]);
459  Lxy_svdecor(*mainVertex) = m_CascadeTools->lxy(moms[0],cascadeVertices[0],cascadeVertices[1]);
460  LxyErr_svdecor(*mainVertex) = m_CascadeTools->lxyError(moms[0],x->getCovariance()[0], cascadeVertices[0],cascadeVertices[1]);
461  Tau_svdecor(*mainVertex) = m_CascadeTools->tau(moms[0],cascadeVertices[0],cascadeVertices[1]);
462  TauErr_svdecor(*mainVertex) = m_CascadeTools->tauError(moms[0],x->getCovariance()[0], cascadeVertices[0],cascadeVertices[1]);
463  if(!threeVertexMap.empty()) {
464  std::array<const xAOD::TrackParticle*, 3> lookuparray;
465  std::copy(c.tracks.begin(), c.tracks.begin()+3, lookuparray.begin());
466  auto ptr = threeVertexMap[lookuparray];
467  if(ptr == nullptr) ATH_MSG_WARNING("3Vertex lookup found null");
468  Vertex3Decor(*mainVertex) = ptr ? VertexLink(ptr, *v3container) : VertexLink();
469  }
470  }
471 
472 
473  ATH_MSG_DEBUG("Found " << Vtxwritehandles[0]->size() << " candidates " << totalnotnull << " were null");
474  if(Vtxwritehandles[0]->size() > 200) ATH_MSG_WARNING("A lot of candidates N=" << Vtxwritehandles[0]->size());
475  return StatusCode::SUCCESS;
476 }
477 
478 std::unique_ptr<Trk::VxCascadeInfo> Cascade3Plus1::CascadeFit(std::array<const xAOD::TrackParticle*, 4> &Track) const {
479 // ATH_MSG_DEBUG("Running Cascade Fit");
480  std::vector<const xAOD::TrackParticle*> tracksDs(Track.begin(), Track.begin()+3);
481  std::vector<const xAOD::TrackParticle*> tracksBs(1, Track[3]);
482 
483  std::vector<double> massesDs(m_trackMasses.begin(), m_trackMasses.begin()+3);
484  std::vector<double> massesBs(1, m_trackMasses[3]);
485 
486  std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
487  int robustness = 0;
488  m_iVertexFitter->setRobustness(robustness, *state);
489 // if(tracksDs.size() != massesDs.size()) ATH_MSG_ERROR("Track sizes do not match");
490 // for(int i =0;i < tracksDs.size();i++) ATH_MSG_DEBUG("Num " << i << " track " << tracksDs[i] << " mass " << massesDs[i]);
491  // Vertex list
492  std::vector<Trk::VertexID> vrtList;
493  // Ds vertex
494  auto vID = m_iVertexFitter->startVertex(tracksDs, massesDs, *state, m_3TrackMassConstraint ? m_3tracksMass : 0.0);
495  std::vector<Trk::VertexID> cnstV;
496  if (m_2TrackMassConstraint && !m_iVertexFitter->addMassConstraint(vID, tracksDs, cnstV, *state, m_2tracksMass).isSuccess() ) {
497  ATH_MSG_WARNING("addMassConstraint failed");
498  }
499  vrtList.push_back(vID);
500  // Bs vertex
501  m_iVertexFitter->nextVertex(tracksBs,massesBs,vrtList, *state);
502  // Do the work
503  auto x = std::unique_ptr<Trk::VxCascadeInfo> (m_iVertexFitter->fitCascade(*state));
504  if(x==nullptr) ATH_MSG_VERBOSE("Cascade returned null");
505  return x;
506 }
507 
508 std::unique_ptr<xAOD::Vertex> Cascade3Plus1::StandardFit(const std::vector<const xAOD::TrackParticle*> &inputTracks, const xAOD::TrackParticleContainer* importedTrackCollection) const {
509  assert(inputTracks.size() >=2);
510  const Trk::Perigee& aPerigee1 = inputTracks[0]->perigeeParameters();
511  const Trk::Perigee& aPerigee2 = inputTracks[1]->perigeeParameters();
512  int sflag = 0;
513  int errorcode = 0;
514  Amg::Vector3D startingPoint = m_vertexEstimator->getCirclesIntersectionPoint(&aPerigee1,&aPerigee2,sflag,errorcode);
515  if (errorcode != 0) {
516  startingPoint(0) = 0.0;
517  startingPoint(1) = 0.0;
518  startingPoint(2) = 0.0;
519  }
520  std::unique_ptr<Trk::IVKalState> state = m_iVertexFitter->makeState();
521  auto theResult = std::unique_ptr<xAOD::Vertex>( m_iVertexFitter->fit(inputTracks, startingPoint, *state));
522  if(theResult) BPhysPVTools::PrepareVertexLinks(theResult.get(), importedTrackCollection);
523  return theResult;
524 }
525 
526 }
BPhysPVTools.h
DerivationFramework::Cascade3Plus1::m_copyAllVertices
bool m_copyAllVertices
Definition: Cascade3Plus1.h:86
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::BPhysHypoHelper::setMass
bool setMass(const float val)
Set given invariant mass and its error.
Definition: BPhysHypoHelper.cxx:49
DerivationFramework::Cascade3Plus1::m_muonTrackBit
std::bitset< 4 > m_muonTrackBit
Definition: Cascade3Plus1.h:87
V0Tools.h
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
DerivationFramework::Cascade3Plus1::m_refPVContainerName
std::string m_refPVContainerName
Definition: Cascade3Plus1.h:78
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
xAOD::BPhysHelper
Definition: BPhysHelper.h:71
xAOD::VertexAuxContainer_v1
Temporary container used until we have I/O for AuxStoreInternal.
Definition: VertexAuxContainer_v1.h:32
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
DerivationFramework::Cascade3Plus1::m_3TrackVertexOutput
std::string m_3TrackVertexOutput
Definition: Cascade3Plus1.h:89
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
DerivationFramework::Cascade3Plus1::m_2TrackMassConstraint
bool m_2TrackMassConstraint
Definition: Cascade3Plus1.h:84
DerivationFramework::BPhysPVCascadeTools::LinkVertices
static bool LinkVertices(SG::AuxElement::Decorator< VertexLinkVector > &decor, const std::vector< const xAOD::Vertex * > &vertices, const xAOD::VertexContainer *vertexContainer, const xAOD::Vertex *vert)
Definition: BPhysPVCascadeTools.cxx:460
DerivationFramework::VertexCand
Definition: Cascade3Plus1.cxx:34
DerivationFramework::Cascade3Plus1::addBranches
virtual StatusCode addBranches() const override
Pass the thinning service
Definition: Cascade3Plus1.cxx:165
DerivationFramework::Cascade3Plus1::m_trackMasses
std::vector< double > m_trackMasses
Definition: Cascade3Plus1.h:58
DerivationFramework::Cascade3Plus1::m_Chi2NDFCut
double m_Chi2NDFCut
Definition: Cascade3Plus1.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
DerivationFramework::Cascade3Plus1::m_4tracksMass
double m_4tracksMass
Definition: Cascade3Plus1.h:67
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
DerivationFramework::Cascade3Plus1::m_vertexEstimator
ToolHandle< InDet::VertexPointEstimator > m_vertexEstimator
Definition: Cascade3Plus1.h:53
DerivationFramework::Cascade3Plus1::m_2tracksMass
double m_2tracksMass
Definition: Cascade3Plus1.h:68
DerivationFramework::Cascade3Plus1::m_eliminateBad3Tracksfrom4Track
bool m_eliminateBad3Tracksfrom4Track
Definition: Cascade3Plus1.h:85
DerivationFramework::BPhysPVTools
Definition: BPhysPVTools.h:25
DerivationFramework::Cascade3Plus1::CascadeFit
std::unique_ptr< Trk::VxCascadeInfo > CascadeFit(std::array< const xAOD::TrackParticle *, 4 > &Track) const
Definition: Cascade3Plus1.cxx:478
beamspotPlotBcids.evt
evt
Definition: beamspotPlotBcids.py:505
DerivationFramework::Cascade3Plus1::m_cascadeOutputsKeys
std::vector< std::string > m_cascadeOutputsKeys
Definition: Cascade3Plus1.h:59
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
DerivationFramework::Cascade3Plus1::m_2trackmassMin
double m_2trackmassMin
Definition: Cascade3Plus1.h:60
DerivationFramework::Cascade3Plus1::StandardFit
std::unique_ptr< xAOD::Vertex > StandardFit(const std::vector< const xAOD::TrackParticle * > &inputTracks, const xAOD::TrackParticleContainer *importedTrackCollection) const
Definition: Cascade3Plus1.cxx:508
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
DerivationFramework::Cascade3Plus1::m_eventInfo_key
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfo_key
Definition: Cascade3Plus1.h:54
xAOD::VertexContainer
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Definition: VertexContainer.h:14
x
#define x
DerivationFramework::Candidate::tracks
std::array< const xAOD::TrackParticle *, N > tracks
Definition: Cascade3Plus1.cxx:31
DerivationFramework::Cascade3Plus1::m_3trackmassMax
double m_3trackmassMax
Definition: Cascade3Plus1.h:63
TrkVKalVrtFitter.h
DerivationFramework::Cascade3Plus1::m_hypoName
std::string m_hypoName
name of the mass hypothesis.
Definition: Cascade3Plus1.h:72
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:112
DerivationFramework::Cascade3Plus1::m_ptCutPerVertex
std::array< double, 3 > m_ptCutPerVertex
Definition: Cascade3Plus1.h:92
DerivationFramework::Cascade3Plus1::initialize
virtual StatusCode initialize() override
Definition: Cascade3Plus1.cxx:97
compileRPVLLRates_emergingFilterTest.c3
c3
Definition: compileRPVLLRates_emergingFilterTest.py:559
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
DerivationFramework::Cascade3Plus1::m_3TrackChi2NDFCut
float m_3TrackChi2NDFCut
Definition: Cascade3Plus1.h:80
DerivationFramework::Cascade3Plus1::m_4trackmassFinalMax
double m_4trackmassFinalMax
Definition: Cascade3Plus1.h:71
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
xAOD::BPhysHypoHelper
Definition: BPhysHypoHelper.h:73
DerivationFramework::BPhysPVCascadeTools::SetVectorInfo
static void SetVectorInfo(xAOD::BPhysHelper &, const Trk::VxCascadeInfo *)
Definition: BPhysPVCascadeTools.cxx:424
BPHYS_CHECK
#define BPHYS_CHECK(EXP)
Useful CHECK macro.
Definition: BPhysHelper.h:738
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
DerivationFramework::Cascade3Plus1::m_ptCutPerTrack
std::vector< double > m_ptCutPerTrack
Definition: Cascade3Plus1.h:91
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:58
python.TrigInDetConfig.inputTracks
inputTracks
Definition: TrigInDetConfig.py:179
xAOD::VertexAuxContainer
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
Definition: VertexAuxContainer.h:19
DerivationFramework::Cascade3Plus1::m_trkSelector
ToolHandle< Trk::ITrackSelectorTool > m_trkSelector
Definition: Cascade3Plus1.h:48
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
DerivationFramework::Cascade3Plus1::m_pvRefitter
ToolHandle< Analysis::PrimaryVertexRefitter > m_pvRefitter
Definition: Cascade3Plus1.h:52
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
DerivationFramework::Cascade3Plus1::m_tauCut
double m_tauCut
Definition: Cascade3Plus1.h:81
DerivationFramework::BPhysPVCascadeTools::PrepareVertexLinks
static void PrepareVertexLinks(Trk::VxCascadeInfo *result, const xAOD::TrackParticleContainer *importedTrackCollection)
Definition: BPhysPVCascadeTools.cxx:204
DerivationFramework::Cascade3Plus1::m_PV_minNTracks
size_t m_PV_minNTracks
Definition: Cascade3Plus1.h:76
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DerivationFramework::Cascade3Plus1::m_4trackmassMin
double m_4trackmassMin
Definition: Cascade3Plus1.h:64
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
DerivationFramework::BPhysPVTools::PrepareVertexLinks
static void PrepareVertexLinks(xAOD::Vertex *theResult, const xAOD::TrackParticleContainer *importedTrackCollection)
Definition: BPhysPVTools.cxx:530
DerivationFramework::GenVecFourMom_t
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > GenVecFourMom_t
Base 4 Momentum type for TrackParticle.
Definition: Cascade3Plus1.cxx:27
DerivationFramework::TrackBag
std::vector< const xAOD::TrackParticle * > TrackBag
Definition: BPhysAddMuonBasedInvMass.h:32
DerivationFramework
THE reconstruction tool.
Definition: ParticleSortingAlg.h:24
DerivationFramework::Cascade3Plus1::m_3TrackMassConstraint
bool m_3TrackMassConstraint
Definition: Cascade3Plus1.h:83
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DerivationFramework::VertexLink
ElementLink< xAOD::VertexContainer > VertexLink
Definition: Cascade3Plus1.cxx:23
DataVector< xAOD::TrackParticle_v1 >
BPhysPVCascadeTools.h
DerivationFramework::Cascade3Plus1::m_VxPrimaryCandidateName
std::string m_VxPrimaryCandidateName
Name of primary vertex container.
Definition: Cascade3Plus1.h:77
DerivationFramework::BPhysPVCascadeTools
Definition: BPhysPVCascadeTools.h:34
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DerivationFramework::Cascade3Plus1::Cascade3Plus1
Cascade3Plus1(const std::string &t, const std::string &n, const IInterface *p)
Definition: Cascade3Plus1.cxx:45
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
VxCascadeInfo.h
BPhysHelper.h
: B-physics xAOD helpers.
TrackParticle.h
python.PyAthena.v
v
Definition: PyAthena.py:157
DerivationFramework::Cascade3Plus1::m_requireMuonsOnTrack
std::vector< int > m_requireMuonsOnTrack
Definition: Cascade3Plus1.h:88
xAOD::BPhysHelper::setRefTrks
bool setRefTrks(std::vector< float > px, std::vector< float > py, std::vector< float > pz)
Sets refitted track momenta.
Definition: BPhysHelper.cxx:286
DerivationFramework::VertexLinkVector
std::vector< VertexLink > VertexLinkVector
Definition: Cascade3Plus1.cxx:24
VertexContainer.h
DerivationFramework::Cascade3Plus1::m_V0Tools
ToolHandle< Trk::V0Tools > m_V0Tools
Definition: Cascade3Plus1.h:50
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DerivationFramework::Cascade3Plus1::m_CascadeTools
ToolHandle< DerivationFramework::CascadeTools > m_CascadeTools
Definition: Cascade3Plus1.h:51
DerivationFramework::VertexCand::cascVertex
std::unique_ptr< Trk::VxCascadeInfo > cascVertex
Definition: Cascade3Plus1.cxx:35
DerivationFramework::SumVector
GenVecFourMom_t SumVector(const std::array< GenVecFourMom_t, N > &vectors)
Definition: Cascade3Plus1.cxx:39
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
DerivationFramework::Cascade3Plus1::m_iVertexFitter
ToolHandle< Trk::TrkVKalVrtFitter > m_iVertexFitter
Definition: Cascade3Plus1.h:49
DerivationFramework::Cascade3Plus1::m_3trackmassMin
double m_3trackmassMin
Definition: Cascade3Plus1.h:62
Track
Definition: TriggerChamberClusterOnTrackCreator.h:21
DerivationFramework::Cascade3Plus1::m_3tracksMass
double m_3tracksMass
Definition: Cascade3Plus1.h:66
Cascade3Plus1.h
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
calibdata.copy
bool copy
Definition: calibdata.py:27
AthAlgTool
Definition: AthAlgTool.h:26
DerivationFramework::Cascade3Plus1::~Cascade3Plus1
virtual ~Cascade3Plus1()
Definition: Cascade3Plus1.cxx:150
DerivationFramework::Cascade3Plus1::m_2trackmassMax
double m_2trackmassMax
Definition: Cascade3Plus1.h:61
DerivationFramework::Cascade3Plus1::s_topoN
static constexpr int s_topoN
Definition: Cascade3Plus1.h:46
DerivationFramework::Cascade3Plus1::ApplyAdditionalCuts
const std::vector< const xAOD::TrackParticle * > & ApplyAdditionalCuts(const std::vector< const xAOD::TrackParticle * > &, const std::vector< const xAOD::TrackParticle * > &, std::vector< const xAOD::TrackParticle * > &, size_t) const
Definition: Cascade3Plus1.cxx:153
ITrackSelectorTool.h
DerivationFramework::Cascade3Plus1::m_DoVertexType
int m_DoVertexType
Definition: Cascade3Plus1.h:75
DerivationFramework::Cascade3Plus1::m_PV_max
int m_PV_max
Definition: Cascade3Plus1.h:74
python.compressB64.c
def c
Definition: compressB64.py:93
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
TrackParticleContainer.h
DerivationFramework::Cascade3Plus1::m_4trackmassFinalMin
double m_4trackmassFinalMin
Definition: Cascade3Plus1.h:70
DerivationFramework::Cascade3Plus1::m_refitPV
bool m_refitPV
Definition: Cascade3Plus1.h:82
xAOD::BPhysHypoHelper::setMassErr
bool setMassErr(const float val)
invariant mass error
Definition: BPhysHypoHelper.cxx:54
DerivationFramework::Cascade3Plus1::m_3TrackName
std::string m_3TrackName
Definition: Cascade3Plus1.h:73
VertexAuxContainer.h
DerivationFramework::Candidate
Definition: Cascade3Plus1.cxx:30
DerivationFramework::Cascade3Plus1::m_4trackmassMax
double m_4trackmassMax
Definition: Cascade3Plus1.h:65