ATLAS Offline Software
NonPromptLeptonVertexingAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Local
8 
9 // Athena
12 
13 // C/C++
14 #include <cmath>
15 #include <iostream>
16 #include <sstream>
17 
18 using namespace std;
19 
20 //======================================================================================================
21 Prompt::NonPromptLeptonVertexingAlg::NonPromptLeptonVertexingAlg(const std::string& name, ISvcLocator *pSvcLocator):
22  AthAlgorithm (name, pSvcLocator),
23  m_countEvents (0)
24 {}
25 
26 //=============================================================================
28 {
29  if(m_printTime) {
30  //
31  // Reset timers
32  //
33  m_timerAll .Reset();
34  m_timerExec.Reset();
35 
36  //
37  // Start full timer
38  //
39  m_timerAll.Start();
40  }
41 
42  if(m_svContainerName.empty()) {
43  ATH_MSG_ERROR("NonPromptLeptonVertexingAlg::initialize - empty SV container name: \"" << m_svContainerName << "\"");
44  return StatusCode::FAILURE;
45  }
46 
47  ATH_CHECK(m_vertexMerger.retrieve());
48  ATH_CHECK(m_vertexFitterTool.retrieve());
49 
50  ATH_CHECK(m_inDetTracksKey.initialize());
51  ATH_CHECK(m_leptonContainerKey.initialize());
52  ATH_CHECK(m_primaryVertexContainerName.initialize());
53  ATH_CHECK(m_refittedPriVtxContainerName.initialize());
54 
55  ATH_CHECK(m_svContainerName.initialize());
56 
57  m_indexVectorDec = std::make_unique<decoratorVecInt_t> (m_decoratorNameIndexVector);
58  m_indexVectorDecDeepMerge = std::make_unique<decoratorVecInt_t> (m_decoratorNameIndexVector+"DeepMerge");
59 
60  m_lepSVElementLinksDec = std::make_unique<decoratorVecElemVtx_t>(m_decoratorNameSecVtxLinks);
61  m_lepDeepMergedSVElementLinksDec = std::make_unique<decoratorVecElemVtx_t>(m_decoratorNameDeepMergedSecVtxLinks);
62 
63  ATH_MSG_DEBUG("LeptonContainerName = " << m_leptonContainerKey);
64  ATH_MSG_DEBUG("ReFitPriVtxContainerName = " << m_refittedPriVtxContainerName);
65  ATH_MSG_DEBUG("SVContainerName = " << m_svContainerName);
66  ATH_MSG_DEBUG("IndexVectorName = " << m_decoratorNameIndexVector);
67 
68  ATH_MSG_DEBUG("mergeMinVtxDist = " << m_mergeMinVtxDist);
69  ATH_MSG_DEBUG("mergeChi2OverDoF = " << m_mergeChi2OverDoF);
70 
71  ATH_MSG_DEBUG("minTrackLeptonDR = " << m_minTrackLeptonDR);
72  ATH_MSG_DEBUG("maxTrackLeptonDR = " << m_maxTrackLeptonDR);
73 
74  ATH_MSG_DEBUG("selectTracks = " << m_selectTracks);
75  ATH_MSG_DEBUG("minTrackpT = " << m_minTrackpT);
76  ATH_MSG_DEBUG("maxTrackEta = " << m_maxTrackEta);
77  ATH_MSG_DEBUG("maxTrackZ0Sin = " << m_maxTrackZ0Sin);
78 
79  ATH_MSG_DEBUG("minTrackSiHits = " << m_minTrackSiHits);
80  ATH_MSG_DEBUG("maxTrackSharedSiHits = " << m_maxTrackSharedSiHits);
81  ATH_MSG_DEBUG("maxTrackSiHoles = " << m_maxTrackSiHoles);
82  ATH_MSG_DEBUG("maxTrackPixHoles = " << m_maxTrackPixHoles);
83 
84  return StatusCode::SUCCESS;
85 }
86 
87 //=============================================================================
89 {
90  if(m_printTime) {
91  //
92  // Print full time stopwatch
93  //
94  m_timerAll.Stop();
95 
96  ATH_MSG_INFO("NonPromptLeptonVertexingAlg - total time: " << PrintResetStopWatch(m_timerAll));
97  ATH_MSG_INFO("NonPromptLeptonVertexingAlg - execute time: " << PrintResetStopWatch(m_timerExec));
98  }
99 
100  return StatusCode::SUCCESS;
101 }
102 
103 //=============================================================================
105 {
106  //
107  // Start execute timer for new event
108  //
109  TimerScopeHelper timer(m_timerExec);
110 
111  m_countEvents++;
112 
113  //
114  // Find Inner Detector tracks save them class member variable for convenience.
115  //
116  SG::ReadHandle<xAOD::TrackParticleContainer> h_inDetTracks(m_inDetTracksKey);
117  if (!h_inDetTracks.isValid()){
118  ATH_MSG_FATAL("execute - failed to find the InDetTrackParticles");
119  return StatusCode::FAILURE;
120  }
121 
122  const xAOD::TrackParticleContainer inDetTracks = *h_inDetTracks;
123 
124  //
125  // Create vertex containers and record them in StoreGate
126  //
127  std::set< xAOD::Vertex* > svSet;
128 
129  SG::WriteHandle<xAOD::VertexContainer> h_SVContainer (m_svContainerName);
130  ATH_CHECK(h_SVContainer.record(
131  std::make_unique< xAOD::VertexContainer>(), std::make_unique< xAOD::VertexAuxContainer>()
132  ));
133  xAOD::VertexContainer &SVContainerRef = *(h_SVContainer.ptr());
134 
135  //
136  // Retrieve containers from evtStore
137  //
138  SG::ReadHandle<xAOD::IParticleContainer> leptonContainer (m_leptonContainerKey);
139  SG::ReadHandle<xAOD::VertexContainer> vertices (m_primaryVertexContainerName);
140  SG::ReadHandle<xAOD::VertexContainer> refittedVertices(m_refittedPriVtxContainerName);
141 
142  ATH_MSG_DEBUG ("NonPromptLeptonVertexingAlg::execute - Read " << vertices->size() << " primary vertices");
143  ATH_MSG_DEBUG ("NonPromptLeptonVertexingAlg::execute - Read " << refittedVertices->size() << " refitted primary vertices");
144 
145  //
146  // Find default Primary Vertex
147  //
148  Prompt::FittingInput fittingInput(&inDetTracks, 0, 0);
149 
150  for(const xAOD::Vertex *vertex: *vertices) {
151  if(vertex->vertexType() == xAOD::VxType::PriVtx) {
152  fittingInput.priVtx = vertex;
153  break;
154  }
155  }
156 
157  if(!fittingInput.priVtx) {
158  ATH_MSG_INFO("Failed to find primary vertex - skip this event");
159 
160  return StatusCode::SUCCESS;
161  }
162 
163  //
164  // Find the refitted Primary Vertex
165  //
166  for(const xAOD::Vertex *vertex: *refittedVertices) {
167  short refittedVertexType = 0;
168 
169  if(getVar(vertex, refittedVertexType, m_refittedVertexTypeName) && refittedVertexType == xAOD::VxType::PriVtx) {
170  fittingInput.refittedPriVtx = vertex;
171  }
172 
173  if(fittingInput.refittedPriVtx) {
174  break;
175  }
176  }
177 
178  //
179  // Dynamic cast IParticle container to electron or muon container
180  //
181  ATH_MSG_DEBUG("\n\t\t\t Size of lepton container: " << leptonContainer ->size());
182 
183  SG::AuxElement::ConstAccessor<ElementLink<xAOD::VertexContainer> > priVtxWithoutLepAcc(m_linkNameRefittedPriVtxWithoutLepton);
184 
185  for(const xAOD::IParticle *lepton: *leptonContainer) {
186  const xAOD::TrackParticle *tracklep = 0;
187  const xAOD::Electron *elec = dynamic_cast<const xAOD::Electron*>(lepton);
188  const xAOD::Muon *muon = dynamic_cast<const xAOD::Muon *>(lepton);
189 
190  if(elec) {
191  //
192  // Get GSF track
193  //
194  const xAOD::TrackParticle *bestmatchedGSFElTrack = elec->trackParticle(0);
195 
196  //
197  // Get original ID track for vertex fitting
198  //
199  if(passElecCand(*elec) && bestmatchedGSFElTrack) {
200  tracklep = xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(bestmatchedGSFElTrack);
201  }
202  }
203  else if(muon) {
204  if(passMuonCand(*muon) && muon->inDetTrackParticleLink().isValid()) {
205  tracklep = *(muon->inDetTrackParticleLink());
206  }
207  }
208  else {
209  ATH_MSG_WARNING("NonPromptLeptonVertexingAlg::execute - failed to find electron or muon: should never happen!");
210  }
211 
212  if(!tracklep) {
213  (*m_lepSVElementLinksDec) (*lepton) = std::vector<ElementLink<xAOD::VertexContainer> >();
214  (*m_lepDeepMergedSVElementLinksDec)(*lepton) = std::vector<ElementLink<xAOD::VertexContainer> >();
215  (*m_indexVectorDec) (*lepton) = std::vector<int>();
216  (*m_indexVectorDecDeepMerge) (*lepton) = std::vector<int>();
217 
218  ATH_MSG_DEBUG("NonPromptLeptonVertexingAlg::execute - cannot find muon->inDetTrackParticleLink() nor electron->trackParticle()");
219  continue;
220  }
221 
222  ATH_MSG_DEBUG("NonPromptLeptonVertexingAlg::execute - process new lepton track " << tracklep);
223 
224  //
225  // Find refitted primary vertex with lepton track excluded
226  //
227  fittingInput.refittedPriVtxWithoutLep = 0;
228 
229  if(priVtxWithoutLepAcc.isAvailable(*lepton)) {
230  ElementLink<xAOD::VertexContainer> vtxLink = priVtxWithoutLepAcc(*lepton);
231 
232  if(vtxLink.isValid()) {
233  fittingInput.refittedPriVtxWithoutLep = *vtxLink;
234 
235  ATH_MSG_DEBUG("DecorateSecondaryVertex - found refitted primary vertex without lepton: "
236  << m_linkNameRefittedPriVtxWithoutLepton << " with Ntrack =" << fittingInput.refittedPriVtxWithoutLep->nTrackParticles());
237  }
238  }
239 
240  //
241  // Collect tracks around the lepton track
242  //
243  std::vector<const xAOD::TrackParticle* > ifitTracks = findNearbyTracks(*tracklep, inDetTracks, *fittingInput.priVtx);
244 
245  //
246  // Fit 2-track vertices
247  //
248  std::vector<std::unique_ptr<xAOD::Vertex>> twoTrkVertices = prepLepWithTwoTrkSVVec(
249  fittingInput, tracklep, ifitTracks
250  );
251 
252  // We make a copy so we can store the list of original
253  // two-track vertices
254  std::vector<std::unique_ptr<xAOD::Vertex>> twoTrkVerticesCopy;
255  for (std::unique_ptr<xAOD::Vertex> &vtx : twoTrkVertices) {
256  std::unique_ptr<xAOD::Vertex> newVtx = std::make_unique<xAOD::Vertex>(*vtx);
257  twoTrkVerticesCopy.push_back(std::move(newVtx));
258  }
259 
260  // Deep merge 2-track vertices.
261  ATH_MSG_DEBUG("Getting deep merged vertices");
262  ATH_MSG_DEBUG("Starting with " << twoTrkVertices.size() << " 2-track vertices");
263  Prompt::MergeResultNotOwner deep_merged_result = m_vertexMerger->mergeInitVertices(
264  fittingInput, tracklep, twoTrkVertices, ifitTracks);
265 
266  //
267  // Save secondary vertices
268  //
269  std::vector<ElementLink<xAOD::VertexContainer> > svLinks;
270  std::vector<ElementLink<xAOD::VertexContainer> > deepmergeSVLinks;
271 
272  std::vector<int> indexVectorTwoTrk;
273  std::vector<int> indexVectorDeepMerged;
274 
275  //
276  // Record 2-track vertexes and simple merged vertexes
277  //
278  ATH_MSG_DEBUG("NonPromptLeptonVertexingAlg::execute --- recording " << twoTrkVerticesCopy.size() << " 2-track and simple merged vertices");
279  saveSecondaryVertices(twoTrkVerticesCopy, indexVectorTwoTrk, svLinks, SVContainerRef, svSet);
280 
281  //
282  // Record both merged multi-track vertices and also unmerged 2-track vertices
283  //
284  ATH_MSG_DEBUG("NonPromptLeptonVertexingAlg::execute --- recording " << deep_merged_result.vtxsNewMerged.size() << " merged multi-track vertices");
285  saveSecondaryVertices(deep_merged_result.vtxsNewMerged, indexVectorDeepMerged, deepmergeSVLinks, SVContainerRef, svSet);
286 
287  ATH_MSG_DEBUG("NonPromptLeptonVertexingAlg::execute --- recording " << deep_merged_result.vtxsInitPassedNotMerged.size() << " unmerged 2-track vertices");
288  saveSecondaryVertices(deep_merged_result.vtxsInitPassedNotMerged, indexVectorDeepMerged, deepmergeSVLinks, SVContainerRef, svSet);
289 
290  ATH_MSG_DEBUG ("NonPromptLeptonVertexingAlg::execute -- number of two-track SV = " << twoTrkVertices.size());
291  ATH_MSG_DEBUG ("NonPromptLeptonVertexingAlg::execute -- number of deep merged SV = " << deep_merged_result.vtxsNewMerged.size());
292 
293  (*m_lepSVElementLinksDec) (*lepton) = svLinks;
294  (*m_lepDeepMergedSVElementLinksDec)(*lepton) = deepmergeSVLinks;
295  (*m_indexVectorDec) (*lepton) = indexVectorTwoTrk;
296  (*m_indexVectorDecDeepMerge) (*lepton) = indexVectorDeepMerged;
297 
298  ATH_MSG_DEBUG("NonPromptLeptonVertexingAlg - done with lepton pT=" << tracklep->pt() << ", " << truthAsStr(*lepton) << endl
299  << "___________________________________________________________________________");
300  }
301 
302  ATH_MSG_DEBUG("SV Vertex container " << m_svContainerName << " recorded in store");
303 
304  ATH_MSG_DEBUG(" NonPromptLeptonVertexingAlg::execute - done with this event" << endl
305  << "___________________________________________________________________________");
306 
307  return StatusCode::SUCCESS;
308 }
309 
310 //=============================================================================
312 {
313  //
314  // Check whether electron candidate passes loose selection
315  //
316  char lh_loose = -1;
317 
318  Prompt::GetAuxVar(elec, lh_loose, "DFCommonElectronsLHLoose");
319 
320  ATH_MSG_DEBUG("NonPromptLeptonVertexingAlg::passElecCand - "
321  << "pT=" << elec.pt() << ", eta=" << elec.eta() << ", phi=" << elec.phi() << std::endl
322  << " DFCommonElectronsLHLoose = " << int(lh_loose) << std::endl
323  << " " << truthAsStr(elec));
324 
325  if(!lh_loose) {
326  return false;
327  }
328 
329  return true;
330 }
331 
332 //=============================================================================
334 {
335  //
336  // Check whether muon candidate is a combined muon
337  //
338  const bool combined = (muon.muonType() == xAOD::Muon::Combined);
339 
340  ATH_MSG_DEBUG("NonPromptLeptonVertexingAlg::passMuonCand - "
341  << "pT=" << muon.pt() << ", eta=" << muon.eta() << ", phi=" << muon.phi() << std::endl
342  << " Type = " << muon.muonType() << std::endl
343  << " Combined = " << combined << std::endl
344  << " " << truthAsStr(muon));
345 
346  return combined;
347 }
348 
349 //=============================================================================
350 std::vector<const xAOD::TrackParticle*> Prompt::NonPromptLeptonVertexingAlg::findNearbyTracks(
351  const xAOD::TrackParticle &tracklep,
352  const xAOD::TrackParticleContainer &inDetTracks,
353  const xAOD::Vertex &priVtx
354 ) const {
355  //
356  // Select tracks -- avoid using track selection tool since z0 definition is different
357  //
358  std::vector<const xAOD::TrackParticle *> mytracks;
359 
360  for(const xAOD::TrackParticle *track: inDetTracks) {
361  if(!track) {
362  ATH_MSG_WARNING("skip null track pointer - should never happen");
363  continue;
364  }
365 
366  //
367  // Check minimum track and lepton DR: skip the track that is probably the lepton track
368  //
369  if(tracklep.p4().DeltaR(track->p4()) < m_minTrackLeptonDR) {
370  ATH_MSG_DEBUG("skip the track very close to the lepton ");
371  continue;
372  }
373 
374  //
375  // Check track and lepton maximum DR
376  //
377  if(tracklep.p4().DeltaR(track->p4()) > m_maxTrackLeptonDR) {
378  continue;
379  }
380 
381  const double delta_z0 = track->z0() + track->vz() - priVtx.z();
382  const double Z0Sin = std::abs(delta_z0*std::sin(track->theta()));
383  const double abs_eta = std::abs(track->eta());
384 
391 
392  if(!(track->summaryValue(numberOfPixelHits, xAOD::numberOfPixelHits))) continue;
393  if(!(track->summaryValue(numberOfSCTHits, xAOD::numberOfSCTHits))) continue;
394  if(!(track->summaryValue(numberOfPixelHoles, xAOD::numberOfPixelHoles))) continue;
395  if(!(track->summaryValue(numberOfSCTHoles, xAOD::numberOfSCTHoles))) continue;
396  if(!(track->summaryValue(numberOfPixelSharedHits, xAOD::numberOfPixelSharedHits))) continue;
397  if(!(track->summaryValue(numberOfSCTSharedHits, xAOD::numberOfSCTSharedHits))) continue;
398 
399  const uint8_t NSiHits = numberOfPixelHits + numberOfSCTHits;
400  const uint8_t NSiHoles = numberOfPixelHoles + numberOfSCTHoles;
401  const float NSiShHits = float(numberOfPixelSharedHits) + float(numberOfSCTSharedHits)/2.0;
402 
403  if(m_selectTracks) {
404  //
405  // Kinematic track selection
406  //
407  if(track->pt() < m_minTrackpT) continue;
408  if(abs_eta > m_maxTrackEta) continue;
409  if(Z0Sin > m_maxTrackZ0Sin) continue;
410 
411  //
412  // Hit quality track selection
413  //
414  if(NSiHits < m_minTrackSiHits) continue;
415  if(NSiShHits > m_maxTrackSharedSiHits) continue;
416  if(NSiHoles > m_maxTrackSiHoles ) continue;
417  if(numberOfPixelHoles > m_maxTrackPixHoles ) continue;
418  }
419 
420  mytracks.push_back(track);
421  }
422 
423  return mytracks;
424 }
425 
426 //=============================================================================
427 std::vector<std::unique_ptr<xAOD::Vertex>> Prompt::NonPromptLeptonVertexingAlg::prepLepWithTwoTrkSVVec(
428  const FittingInput &input,
429  const xAOD::TrackParticle* tracklep,
430  const std::vector<const xAOD::TrackParticle*> &tracks
431 )
432 {
433  //
434  // Decorate lepton with vector of two-track vertices.
435  // Return vector of finding vertices
436  //
437  std::vector<std::unique_ptr<xAOD::Vertex>> twoTrkVertices;
438  std::vector<const xAOD::TrackParticle*> tracksForFit;
439 
440  if(!input.priVtx) {
441  ATH_MSG_WARNING("prepLepWithTwoTrkSVVec -- invalid primary vertex: nothing to do");
442  return twoTrkVertices;
443  }
444 
445  for(const xAOD::TrackParticle *selectedtrack: tracks) {
446  tracksForFit.clear();
447  tracksForFit.push_back(tracklep);
448  tracksForFit.push_back(selectedtrack);
449 
450  std::unique_ptr<xAOD::Vertex> newSecondaryVertex = m_vertexFitterTool->fitVertexWithPrimarySeed(
451  input, tracksForFit, kTwoTrackVtx
452  );
453 
454  if(!newSecondaryVertex) {
455  ATH_MSG_DEBUG("prepLepWithTwoTrkSVVec -- failed to fit 2-track vertex");
456  continue;
457  }
458 
459  twoTrkVertices.push_back(std::move(newSecondaryVertex));
460  }
461 
462  return twoTrkVertices;
463 }
464 
465 //=============================================================================
466 std::vector<std::unique_ptr<xAOD::Vertex>> Prompt::NonPromptLeptonVertexingAlg::prepLepWithMergedSVVec(
467  const FittingInput &input,
468  const xAOD::TrackParticle* tracklep,
469  std::vector<std::unique_ptr<xAOD::Vertex>> &twoTrkVertices
470 )
471 {
472  //
473  // Merge the two vertices if the distance between them with in 0.5 mm.
474  // Re-fit a three-track vertex using the input tracks from the vertices above.
475  //
476  std::vector<std::unique_ptr<xAOD::Vertex>> twoTrkVerticesPass;
477  std::vector<std::unique_ptr<xAOD::Vertex>> twoTrkVerticesPassFixed;
478  std::vector<std::unique_ptr<xAOD::Vertex>> twoTrkVerticesMerged;
479  std::vector<std::unique_ptr<xAOD::Vertex>> resultVertices;
480 
481  if(!input.priVtx) {
482  ATH_MSG_WARNING("prepLepWithMergedSVVec -- invalid primary vertex: nothing to do");
483  return resultVertices;
484  }
485 
486  for(std::unique_ptr<xAOD::Vertex> &vtx: twoTrkVertices) {
487  double chi2OverDoF = -99.;
488 
489  if(vtx->numberDoF() > 0 && vtx->chiSquared() > 0) {
490  chi2OverDoF = vtx->chiSquared()/double(vtx->numberDoF());
491  }
492 
493  if(chi2OverDoF >= 0.0 && chi2OverDoF < m_mergeChi2OverDoF) {
494  twoTrkVerticesPass .push_back(std::move(vtx));
495  twoTrkVerticesPassFixed.push_back(std::move(vtx));
496  }
497  }
498 
499  std::vector<std::unique_ptr<xAOD::Vertex>>::iterator curr_iter = twoTrkVerticesPass.begin();
500 
501  while(curr_iter != twoTrkVerticesPass.end()) {
502  std::vector<std::unique_ptr<xAOD::Vertex>> clusterVtxs;
503  clusterVtxs.push_back(std::move(*curr_iter));
504 
505  twoTrkVerticesPass.erase(curr_iter);
506 
507  makeVertexCluster(clusterVtxs, twoTrkVerticesPass);
508 
509  curr_iter = twoTrkVerticesPass.begin();
510 
511  //
512  // Fit vertex cluster
513  //
514  std::vector<const xAOD::TrackParticle*> tracksForFit;
515 
516  for(std::unique_ptr<xAOD::Vertex> &vtx: clusterVtxs) {
517  for(unsigned k = 0; k < vtx->nTrackParticles(); ++k) {
518  const xAOD::TrackParticle *track = vtx->trackParticle(k);
519 
520  if(track) {
521  tracksForFit.push_back(track);
522  }
523  }
524  }
525 
526  //
527  // Ignore standalone vertexes
528  //
529  if(clusterVtxs.size() < 2) {
530  continue;
531  }
532 
533  //
534  // Fit merged vertex
535  //
536  tracksForFit.push_back(tracklep);
537 
538  std::unique_ptr<xAOD::Vertex> newSecondaryVertex = m_vertexFitterTool->fitVertexWithPrimarySeed(
539  input, tracksForFit, kSimpleMergedVtx
540  );
541 
542  if(!newSecondaryVertex) {
543  ATH_MSG_DEBUG("DecorateLepWithMergedSVVec -- failed to fit merged vertex");
544  continue;
545  }
546 
547  resultVertices.push_back(std::move(newSecondaryVertex));
548 
549  for(std::unique_ptr<xAOD::Vertex> &vtx: clusterVtxs) {
550  twoTrkVerticesMerged.push_back(std::move(vtx));
551  }
552 
553  ATH_MSG_DEBUG("DecorateLepWithMergedSVVec -- NTrack of merged vertex = " << newSecondaryVertex->nTrackParticles());
554  }
555 
556  //
557  // Include passed 2-track vertexes that were NOT merged
558  //
559  for(std::unique_ptr<xAOD::Vertex> &vtx: twoTrkVerticesPassFixed) {
560  const std::vector<std::unique_ptr<xAOD::Vertex>>::const_iterator fit = std::find(
561  twoTrkVerticesMerged.begin(),
562  twoTrkVerticesMerged.end(),
563  vtx
564  );
565 
566  if(fit == twoTrkVerticesMerged.end()) {
567  resultVertices.push_back(std::move(vtx));
568  }
569  }
570 
571  return resultVertices;
572 }
573 
574 //=============================================================================
576  std::vector<std::unique_ptr<xAOD::Vertex>> &clusterVtxs,
577  std::vector<std::unique_ptr<xAOD::Vertex>> &inputVtxs
578 )
579 {
580  ATH_MSG_DEBUG("makeVertexCluster - before: clusterVtxs.size()=" << clusterVtxs.size() << ", inputVtxs.size()=" << inputVtxs.size());
581 
582  std::vector<std::unique_ptr<xAOD::Vertex>>::iterator vit = inputVtxs.begin();
583 
584  while(vit != inputVtxs.end()) {
585  bool pass = false;
586 
587  for(std::vector<std::unique_ptr<xAOD::Vertex>>::const_iterator cit = clusterVtxs.begin(); cit != clusterVtxs.end(); ++cit) {
588  if(vit->get() == cit->get()) {
589  ATH_MSG_DEBUG("makeVertexCluster - logic error - found the same vertex twice: " << ((*vit).get()));
590  continue;
591  }
592 
593  const double vdist = getDistance((*vit)->position(), (*cit)->position());
594 
595  ATH_MSG_DEBUG("makeVertexCluster - vdist=" << vdist );
596 
597  if(vdist < m_mergeMinVtxDist) {
598  pass = true;
599  break;
600  }
601  }
602 
603  if(pass) {
604  clusterVtxs.push_back(std::move(*vit));
605  inputVtxs.erase(vit);
606 
607  vit = inputVtxs.begin();
608  }
609  else {
610  ++vit;
611  }
612  }
613 
614  ATH_MSG_DEBUG("makeVertexCluster - after: clusterVtxs.size()=" << clusterVtxs.size() << ", inputVtxs.size()=" << inputVtxs.size());
615 }
616 
617 //=============================================================================
619  std::vector<std::unique_ptr<xAOD::Vertex>> &vtxs,
620  std::vector<int> &indexVector,
621  std::vector<ElementLink<xAOD::VertexContainer> > &svLinks,
622  xAOD::VertexContainer &SVContainer,
623  std::set< xAOD::Vertex* >& svSet
624 )
625 {
626  //
627  // Record created xAOD::Vertex in output vertex container
628  //
629  ATH_MSG_DEBUG("saveSecondaryVertices - will save " << vtxs.size() << " vertexes");
630 
631  for(std::unique_ptr<xAOD::Vertex> &vtx: vtxs) {
632  int index = -99;
633  if(getVar(vtx, index, "SecondaryVertexIndex")) {
634  indexVector.push_back(index);
635  }
636  else {
637  ATH_MSG_WARNING("saveSecondaryVertices - missing \"SecondaryVertexIndex\" variable");
638  }
639 
640  if(svSet.insert(vtx.get()).second) {
641  //
642  // First time seeing this this vertex - record it in output container
643  //
644  SVContainer.push_back(std::move(vtx));
645  ElementLink<xAOD::VertexContainer> svLink(SVContainer,SVContainer.size()-1);
646  svLinks.push_back(svLink);
647  } else {
648  ATH_MSG_ERROR("saveSecondaryVertices --- the same vertex has been encountered more than once! Is this a logic error?");
649  }
650  }
651 
652  ATH_MSG_DEBUG("saveSecondaryVertices - all done");
653 }
654 
655 
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Prompt::kSimpleMergedVtx
@ kSimpleMergedVtx
Definition: IVertexFittingTool.h:60
xAOD::TrackParticle_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: TrackParticle_v1.cxx:73
xAOD::numberOfPixelHoles
@ numberOfPixelHoles
number of pixel layers on track with absence of hits [unit8_t].
Definition: TrackingPrimitives.h:261
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
PromptUtils.h
xAOD::Vertex_v1::nTrackParticles
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
Definition: Vertex_v1.cxx:270
Prompt::FittingInput::refittedPriVtxWithoutLep
const xAOD::Vertex * refittedPriVtxWithoutLep
Definition: IVertexFittingTool.h:73
xAOD::numberOfSCTSharedHits
@ numberOfSCTSharedHits
number of SCT hits shared by several tracks [unit8_t].
Definition: TrackingPrimitives.h:272
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:575
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Prompt::GetAuxVar
bool GetAuxVar(const T1 &obj, T2 &value, const std::string &var_name)
Definition: PromptUtils.h:93
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
index
Definition: index.py:1
Prompt::getVar
bool getVar(T1 &obj, T2 &value, const std::string &var_name)
Definition: PromptUtils.h:72
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:259
xAOD::Electron_v1::trackParticle
const xAOD::TrackParticle * trackParticle(size_t index=0) const
Pointer to the xAOD::TrackParticle/s that match the electron candidate.
Definition: Electron_v1.cxx:55
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:54
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:40
Prompt::FittingInput
Definition: IVertexFittingTool.h:60
Prompt::NonPromptLeptonVertexingAlg::prepLepWithTwoTrkSVVec
std::vector< std::unique_ptr< xAOD::Vertex > > prepLepWithTwoTrkSVVec(const FittingInput &input, const xAOD::TrackParticle *tracklep, const std::vector< const xAOD::TrackParticle * > &tracks)
Definition: NonPromptLeptonVertexingAlg.cxx:427
Prompt::NonPromptLeptonVertexingAlg::initialize
virtual StatusCode initialize() override
Definition: NonPromptLeptonVertexingAlg.cxx:27
Prompt::PrintResetStopWatch
std::string PrintResetStopWatch(TStopwatch &watch)
Definition: PromptUtils.cxx:244
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
python.utils.AtlRunQueryTimer.timer
def timer(name, disabled=False)
Definition: AtlRunQueryTimer.py:86
Prompt::Def::Z0Sin
@ Z0Sin
Definition: VarHolder.h:86
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
Prompt::MergeResultNotOwner::vtxsInitPassedNotMerged
std::vector< std::unique_ptr< xAOD::Vertex > > vtxsInitPassedNotMerged
Definition: PhysicsAnalysis/AnalysisCommon/LeptonTaggers/LeptonTaggers/IVertexMergingTool.h:73
xAOD::TrackParticle_v1::p4
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
Definition: TrackParticle_v1.cxx:129
xAOD::numberOfPixelSharedHits
@ numberOfPixelSharedHits
number of Pixel all-layer hits shared by several tracks [unit8_t].
Definition: TrackingPrimitives.h:262
EgammaxAODHelpers.h
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Prompt::getDistance
double getDistance(const xAOD::Vertex *vtx1, const xAOD::Vertex *vtx2)
Definition: PromptUtils.cxx:41
Prompt::NonPromptLeptonVertexingAlg::passElecCand
bool passElecCand(const xAOD::Electron &elec) const
Definition: NonPromptLeptonVertexingAlg.cxx:311
Prompt::FittingInput::priVtx
const xAOD::Vertex * priVtx
Definition: IVertexFittingTool.h:71
Prompt::NonPromptLeptonVertexingAlg::saveSecondaryVertices
void saveSecondaryVertices(std::vector< std::unique_ptr< xAOD::Vertex >> &vtxs, std::vector< int > &indexVector, std::vector< ElementLink< xAOD::VertexContainer > > &svLinks, xAOD::VertexContainer &SVContainer, std::set< xAOD::Vertex * > &svSet)
Definition: NonPromptLeptonVertexingAlg.cxx:618
Prompt::NonPromptLeptonVertexingAlg::prepLepWithMergedSVVec
std::vector< std::unique_ptr< xAOD::Vertex > > prepLepWithMergedSVVec(const FittingInput &input, const xAOD::TrackParticle *tracklep, std::vector< std::unique_ptr< xAOD::Vertex >> &twoTrkVertices)
Definition: NonPromptLeptonVertexingAlg.cxx:466
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
xAOD::VxType::PriVtx
@ PriVtx
Primary vertex.
Definition: TrackingPrimitives.h:571
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::Egamma_v1::phi
virtual double phi() const override final
The azimuthal angle ( ) of the particle.
Definition: Egamma_v1.cxx:75
NonPromptLeptonVertexingAlg.h
xAOD::Vertex_v1::z
float z() const
Returns the z position.
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
xAOD::numberOfSCTHoles
@ numberOfSCTHoles
number of SCT holes [unit8_t].
Definition: TrackingPrimitives.h:270
Prompt::NonPromptLeptonVertexingAlg::findNearbyTracks
std::vector< const xAOD::TrackParticle * > findNearbyTracks(const xAOD::TrackParticle &tracklep, const xAOD::TrackParticleContainer &inDetTracks, const xAOD::Vertex &priVtx) const
Definition: NonPromptLeptonVertexingAlg.cxx:350
DataVector< xAOD::TrackParticle_v1 >
AthAlgorithm
Definition: AthAlgorithm.h:47
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Prompt::FittingInput::refittedPriVtx
const xAOD::Vertex * refittedPriVtx
Definition: IVertexFittingTool.h:72
MuonValidation_CreateResolutionProfiles.fit
def fit(h, emin, emax)
Definition: MuonValidation_CreateResolutionProfiles.py:69
Prompt::NonPromptLeptonVertexingAlg::execute
virtual StatusCode execute() override
Definition: NonPromptLeptonVertexingAlg.cxx:104
Trk::Combined
@ Combined
Definition: TrackSummaryTool.h:32
Prompt::truthAsStr
std::string truthAsStr(const xAOD::IParticle &particle)
Definition: PromptUtils.cxx:213
Prompt::NonPromptLeptonVertexingAlg::finalize
virtual StatusCode finalize() override
Definition: NonPromptLeptonVertexingAlg.cxx:88
Prompt::NonPromptLeptonVertexingAlg::passMuonCand
bool passMuonCand(const xAOD::Muon &muon) const
Definition: NonPromptLeptonVertexingAlg.cxx:333
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF
const xAOD::TrackParticle * getOriginalTrackParticleFromGSF(const xAOD::TrackParticle *trkPar)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the GSF Track Particle...
Definition: ElectronxAODHelpers.cxx:22
xAOD::Electron_v1
Definition: Electron_v1.h:34
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
Prompt::MergeResultNotOwner::vtxsNewMerged
std::vector< std::unique_ptr< xAOD::Vertex > > vtxsNewMerged
Definition: PhysicsAnalysis/AnalysisCommon/LeptonTaggers/LeptonTaggers/IVertexMergingTool.h:70
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::Egamma_v1::pt
virtual double pt() const override final
The transverse momentum ( ) of the particle.
Definition: Egamma_v1.cxx:65
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:268
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
xAOD::Egamma_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: Egamma_v1.cxx:70
Prompt::NonPromptLeptonVertexingAlg::makeVertexCluster
void makeVertexCluster(std::vector< std::unique_ptr< xAOD::Vertex >> &clusterVtxs, std::vector< std::unique_ptr< xAOD::Vertex >> &inputVtxs)
Definition: NonPromptLeptonVertexingAlg.cxx:575
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Prompt::TimerScopeHelper
Definition: PromptUtils.h:112
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
readCCLHist.float
float
Definition: readCCLHist.py:83
VertexAuxContainer.h
fitman.k
k
Definition: fitman.py:528
Prompt::kTwoTrackVtx
@ kTwoTrackVtx
Definition: IVertexFittingTool.h:59
Prompt::NonPromptLeptonVertexingAlg::NonPromptLeptonVertexingAlg
NonPromptLeptonVertexingAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: NonPromptLeptonVertexingAlg.cxx:21
Prompt::MergeResultNotOwner
Definition: PhysicsAnalysis/AnalysisCommon/LeptonTaggers/LeptonTaggers/IVertexMergingTool.h:69