ATLAS Offline Software
ZeroLifetimePositioner.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // class header include
7 
8 // HepMC includes
9 #include "AtlasHepMC/GenEvent.h"
10 #include "AtlasHepMC/GenVertex.h"
11 
12 // CLHEP includes
13 #include "CLHEP/Vector/LorentzVector.h"
14 
15 #include <limits>
16 #include <algorithm>
17 
20  ISvcLocator* pSvcLocator )
21  : base_class(name, pSvcLocator)
22 {
23 }
24 
25 
28 {
29  ATH_MSG_VERBOSE("Initializing ...");
30  for(auto& pdgcode : m_pdgCodesToCheck) {
31  pdgcode = std::abs(pdgcode);
32  ATH_MSG_DEBUG("Will look for verices where " << pdgcode <<
33  " oscillates into -" << pdgcode << " (and vice versa).");
34  }
35  return StatusCode::SUCCESS;
36 }
37 
38 
41 {
42  ATH_MSG_VERBOSE("Finalizing ...");
43  return StatusCode::SUCCESS;
44 }
45 
46 
48 {
49  ATH_MSG_DEBUG("applyWorkaround");
50  return this->manipulate(ge, m_applyPatch, false);
51 }
52 
53 
55 {
56  ATH_MSG_DEBUG("removeWorkaround");
57  return this->manipulate(ge, false, m_removePatch);
58 }
59 
60 
62 StatusCode Simulation::ZeroLifetimePositioner::manipulate(HepMC::GenEvent& ge, bool applyPatch, bool removePatch) const
63 {
64  // loop over the vertices in the event
65 #ifdef HEPMC3
66 
67  const auto pdgCodesBegin = m_pdgCodesToCheck.begin();
68  const auto pdgCodesEnd = m_pdgCodesToCheck.end();
69  for (auto& curVtx: ge.vertices()) {
70  if (curVtx->particles_in().size()!=1 || curVtx->particles_out().size()!=1) { continue; }
71  const int pdgIn=curVtx->particles_in().front()->pdg_id();
72  const int pdgOut=curVtx->particles_out().front()->pdg_id();
73  if (pdgIn!=-pdgOut ||
74  std::find(pdgCodesBegin, pdgCodesEnd, std::abs(pdgIn))== pdgCodesEnd) {
75  continue;
76  }
77  HepMC::GenVertexPtr nextVtx = curVtx->particles_out().front()->end_vertex();
78  if(!nextVtx) { continue; }
79  ATH_MSG_DEBUG("Found a vertex to correct with incoming PDG code = " << pdgIn);
80  ATH_MSG_VERBOSE("Next Vertex:");
81  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
82  HepMC::Print::line(nextVtx);
83  }
84  // NB Doing this check to explicitly avoid the fallback mechanism in
85  // HepMC3::GenVertex::position() to return the position of
86  // another GenVertex in the event if the position isn't set (or is set to zero)!
87  const HepMC::FourVector &nextVec = (nextVtx->has_set_position()) ? nextVtx->position() : HepMC::FourVector::ZERO_VECTOR();
88  const CLHEP::HepLorentzVector nextPos( nextVec.x(), nextVec.y(), nextVec.z(), nextVec.t() );
89  ATH_MSG_VERBOSE("Current Vertex:");
90  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
91  HepMC::Print::line(curVtx);
92  }
93  if (applyPatch) {
94  HepMC::GenVertexPtr prevVtx = curVtx->particles_in().front()->production_vertex();
95  ATH_MSG_VERBOSE("Previous Vertex:");
96  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
97  HepMC::Print::line(prevVtx);
98  }
99  // NB Doing this check to explicitly avoid the fallback mechanism in
100  // HepMC3::GenVertex::position() to return the position of
101  // another GenVertex in the event if the position isn't set (or is set to zero)!
102  const HepMC::FourVector &prevVec = (prevVtx->has_set_position()) ? prevVtx->position() : HepMC::FourVector::ZERO_VECTOR();
103  const CLHEP::HepLorentzVector prevPos( prevVec.x(), prevVec.y(), prevVec.z(), prevVec.t() );
104  CLHEP::HepLorentzVector newPos = 0.5*(prevPos+nextPos);
105  curVtx->set_position(HepMC::FourVector(newPos.x(),newPos.y(),newPos.z(),newPos.t()));
106  ATH_MSG_DEBUG("Revised current Vertex");
107  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
108  HepMC::Print::line(curVtx);
109  }
110  }
111  if (removePatch) {
112  CLHEP::HepLorentzVector newPos = nextPos;
113  curVtx->set_position(HepMC::FourVector(newPos.x(),newPos.y(),newPos.z(),newPos.t()));
114  ATH_MSG_DEBUG("Revised current Vertex");
115  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
116  HepMC::Print::line(curVtx);
117  }
118  }
119  }
120 #else
121  HepMC::GenEvent::vertex_iterator vtxIt = ge.vertices_begin();
122  const HepMC::GenEvent::vertex_iterator vtxItEnd = ge.vertices_end();
123  const auto pdgCodesBegin = m_pdgCodesToCheck.begin();
124  const auto pdgCodesEnd = m_pdgCodesToCheck.end();
125  for (; vtxIt != vtxItEnd; ++vtxIt) {
126  // quick access:
127  auto curVtx = (*vtxIt);
128  if (curVtx->particles_in_size()!=1 || curVtx->particles_out_size()!=1) { continue; }
129  const int pdgIn=(*(curVtx->particles_in_const_begin()))->pdg_id();
130  const int pdgOut=(*(curVtx->particles_out_const_begin()))->pdg_id();
131  if (pdgIn!=-pdgOut ||
132  std::find(pdgCodesBegin, pdgCodesEnd, std::abs(pdgIn))== pdgCodesEnd) {
133  continue;
134  }
135  auto nextVtx = (*(curVtx->particles_out_const_begin()))->end_vertex();
136  if(!nextVtx) { continue; }
137  ATH_MSG_DEBUG("Found a vertex to correct with incoming PDG code = " << pdgIn);
138  ATH_MSG_VERBOSE("Next Vertex:");
139  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
140  nextVtx->print();
141  }
142  const HepMC::FourVector &nextVec = nextVtx->position();
143  const CLHEP::HepLorentzVector nextPos( nextVec.x(), nextVec.y(), nextVec.z(), nextVec.t() );
144  ATH_MSG_VERBOSE("Current Vertex:");
145  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
146  curVtx->print();
147  }
148  if (applyPatch) {
149  auto prevVtx = (*(curVtx->particles_in_const_begin()))->production_vertex();
150  ATH_MSG_VERBOSE("Previous Vertex:");
151  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
152  prevVtx->print();
153  }
154  const HepMC::FourVector &prevVec = prevVtx->position();
155  const CLHEP::HepLorentzVector prevPos( prevVec.x(), prevVec.y(), prevVec.z(), prevVec.t() );
156  CLHEP::HepLorentzVector newPos = 0.5*(prevPos+nextPos);
157  curVtx->set_position(newPos);
158  ATH_MSG_DEBUG("Revised current Vertex");
159  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
160  curVtx->print();
161  }
162  }
163  if (removePatch) {
164  const CLHEP::HepLorentzVector& newPos = nextPos;
165  curVtx->set_position(newPos);
166  ATH_MSG_DEBUG("Revised current Vertex");
167  if (ATH_UNLIKELY(this->msgLvl (MSG::VERBOSE))) {
168  curVtx->print();
169  }
170  }
171  }
172 #endif
173 
174  return StatusCode::SUCCESS;
175 }
HepMC::GenVertexPtr
HepMC::GenVertex * GenVertexPtr
Definition: GenVertex.h:59
GenEvent.h
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
GenVertex.h
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
HepMC::Print::line
void line(std::ostream &os, const GenEvent &e)
Definition: GenEvent.h:554
Simulation::ZeroLifetimePositioner::initialize
StatusCode initialize() override final
Athena algtool's Hooks.
Definition: ZeroLifetimePositioner.cxx:27
Simulation::ZeroLifetimePositioner::ZeroLifetimePositioner
ZeroLifetimePositioner(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters.
Definition: ZeroLifetimePositioner.cxx:19
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
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
Simulation::ZeroLifetimePositioner::removeWorkaround
virtual StatusCode removeWorkaround(HepMC::GenEvent &ge) const override final
Removes the workaround for zero-lifetime particles from the GenEvent.
Definition: ZeroLifetimePositioner.cxx:54
ZeroLifetimePositioner.h
Simulation::ZeroLifetimePositioner::finalize
StatusCode finalize() override final
Athena algtool's Hooks.
Definition: ZeroLifetimePositioner.cxx:40
Simulation::ZeroLifetimePositioner::manipulate
StatusCode manipulate(HepMC::GenEvent &ge, bool applyPatch, bool removePatch) const
modifies (displaces) the given GenEvent
Definition: ZeroLifetimePositioner.cxx:62
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
Simulation::ZeroLifetimePositioner::applyWorkaround
virtual StatusCode applyWorkaround(HepMC::GenEvent &ge) const override final
Applies the workaround for zero-lifetime particles to the GenEvent.
Definition: ZeroLifetimePositioner.cxx:47