ATLAS Offline Software
CopyMcEventCollection.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "AtlasHepMC/HeavyIon.h"
7 
8 CopyMcEventCollection::CopyMcEventCollection(const std::string &name, ISvcLocator *pSvcLocator)
9  : AthReentrantAlgorithm(name, pSvcLocator)
10 {
11 }
12 
14 {
15  ATH_MSG_DEBUG("Initializing...");
16 
17  // Check and initialize keys
19  ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_bkgInputKey);
21  ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_signalInputKey);
23  ATH_MSG_VERBOSE("Initialized WriteHandleKey: " << m_outputKey);
24 
26 
27  return StatusCode::SUCCESS;
28 }
29 
30 StatusCode CopyMcEventCollection::execute(const EventContext& ctx) const
31 {
32  ATH_MSG_DEBUG("execute() begin");
33 
34  // Reading the input containers
35  ATH_MSG_VERBOSE("Retrieving input containers");
36 
37  const McEventCollection *bkgContainerPtr = nullptr;
38  if (!m_bkgInputKey.key().empty()) {
40  if (!bkgContainer.isValid()) {
41  ATH_MSG_ERROR("Could not get background McEventCollection container " << bkgContainer.name() << " from store " << bkgContainer.store());
42  return StatusCode::FAILURE;
43  }
44  bkgContainerPtr = bkgContainer.cptr();
45 
46  ATH_MSG_DEBUG("Found background McEventCollection container " << bkgContainer.name() << " in store " << bkgContainer.store());
47  }
48 
50  if (!signalContainer.isValid()) {
51  ATH_MSG_ERROR("Could not get signal McEventCollection container " << signalContainer.name() << " from store " << signalContainer.store());
52  return StatusCode::FAILURE;
53  }
54  ATH_MSG_DEBUG("Found signal McEventCollection container " << signalContainer.name() << " in store " << signalContainer.store());
55 
56  // Creating output RDO container
57  SG::WriteHandle<McEventCollection> outputContainer(m_outputKey, ctx);
58  ATH_CHECK(outputContainer.record(std::make_unique<McEventCollection>()));
59  if (!outputContainer.isValid()) {
60  ATH_MSG_ERROR("Could not record output McEventCollection container " << outputContainer.name() << " to store " << outputContainer.store());
61  return StatusCode::FAILURE;
62  }
63  ATH_MSG_DEBUG("Recorded output McEventCollection container " << outputContainer.name() << " in store " << outputContainer.store());
64 
65  unsigned int droppedSeparatorGenEvents{0};
66 #ifdef HEPMC3
67  int backupPileUpType{0};
68  int backupBunchCrossingTime{0};
69 #endif
70  // Copy signal GenEvents
71  for (McEventCollection::const_iterator it = signalContainer->begin(); it != signalContainer->end(); ++it) {
72 #ifdef HEPMC3
73  if ( (*it)->event_number() == -1 ) {
74  ++droppedSeparatorGenEvents;
75  ATH_MSG_VERBOSE("Signal: Skipping a separator GenEvent. " << droppedSeparatorGenEvents << " skipped so far.");
76  backupBunchCrossingTime+=25; // NB This is a bit of a hack, but better than having everything in-time
77  continue;
78  }
79 #endif
80  HepMC::GenEvent* copiedEvent = new HepMC::GenEvent(**it);
81  HepMC::fillBarcodesAttribute(copiedEvent);
82 #ifdef HEPMC3
83  auto bunchCrossingTime = (*it)->attribute<HepMC3::IntAttribute>("BunchCrossingTime");
84  if (bunchCrossingTime) {
85  copiedEvent->add_attribute("BunchCrossingTime",std::make_shared<HepMC3::IntAttribute>(bunchCrossingTime->value()));
86  }
87  else {
88  copiedEvent->add_attribute("BunchCrossingTime",std::make_shared<HepMC3::IntAttribute>(backupBunchCrossingTime));
89  }
90  auto pileupType = (*it)->attribute<HepMC3::IntAttribute>("PileUpType");
91  if (pileupType) {
92  copiedEvent->add_attribute("PileUpType",std::make_shared<HepMC3::IntAttribute>(pileupType->value()));
93  }
94  else {
95  copiedEvent->add_attribute("PileUpType",std::make_shared<HepMC3::IntAttribute>(backupPileUpType));
96  if (backupPileUpType == 0) { backupPileUpType = 1; } // ignore the possibility for cavern background for this back-up case
97  }
98 #endif
99  if (!copiedEvent->heavy_ion() && (*it)->heavy_ion()) {
100  // It should be clarified if we want to get a copy or the
101  // content.
102 #ifdef HEPMC3
103  HepMC::GenHeavyIonPtr hinew=std::make_shared<HepMC::GenHeavyIon>(*((*it)->heavy_ion()));
104  copiedEvent->set_heavy_ion(hinew);
105 #else
106  copiedEvent->set_heavy_ion(*((*it)->heavy_ion()));
107 #endif
108  }
109  outputContainer->push_back(copiedEvent);
110  }
111 
112 #ifdef HEPMC3
113  backupBunchCrossingTime = 0;
114 #endif
115  // Copy background GenEvents if configured
116  if (!m_bkgInputKey.key().empty()) {
117  McEventCollection::const_iterator it = bkgContainerPtr->begin();
118  if (m_removeBkgHardScatterTruth.value()) {
119  // Do not copy the single particle neutrino GenEvent.
120  ++it;
121  }
122  for ( ; it != bkgContainerPtr->end(); ++it) {
123 #ifdef HEPMC3
124  if ( (*it)->event_number() == -1 ) {
125  ++droppedSeparatorGenEvents;
126  ATH_MSG_VERBOSE("Background: Skipping a separator GenEvent. " << droppedSeparatorGenEvents << " skipped so far.");
127  backupBunchCrossingTime+=25; // NB This is a bit of a hack, but better than having everything in-time
128  continue;
129  }
130 #endif
131  HepMC::GenEvent* copiedEvent = new HepMC::GenEvent(**it);
132  HepMC::fillBarcodesAttribute(copiedEvent);
133 #ifdef HEPMC3
134  auto bunchCrossingTime = (*it)->attribute<HepMC3::IntAttribute>("BunchCrossingTime");
135  if (bunchCrossingTime) {
136  copiedEvent->add_attribute("BunchCrossingTime",std::make_shared<HepMC3::IntAttribute>(bunchCrossingTime->value()));
137  }
138  else {
139  copiedEvent->add_attribute("BunchCrossingTime",std::make_shared<HepMC3::IntAttribute>(backupBunchCrossingTime));
140  }
141  auto pileupType = (*it)->attribute<HepMC3::IntAttribute>("PileUpType");
142  if (pileupType) {
143  copiedEvent->add_attribute("PileUpType",std::make_shared<HepMC3::IntAttribute>(pileupType->value()));
144  }
145  else {
146  copiedEvent->add_attribute("PileUpType",std::make_shared<HepMC3::IntAttribute>(backupPileUpType));
147  if (backupPileUpType == 0) { backupPileUpType = 1; } // ignore the possibility for cavern background for this back-up case
148  }
149 #endif
150  if (!copiedEvent->heavy_ion() && (*it)->heavy_ion()) {
151  // It should be clarified if we want to get a copy or the
152  // content.
153 #ifdef HEPMC3
154  HepMC::GenHeavyIonPtr hinew=std::make_shared<HepMC::GenHeavyIon>(*((*it)->heavy_ion()));
155  copiedEvent->set_heavy_ion(hinew);
156 #else
157  copiedEvent->set_heavy_ion(*((*it)->heavy_ion()));
158 #endif
159  }
160  outputContainer->push_back(copiedEvent);
161  }
162  }
163  ATH_MSG_VERBOSE("output size: " << outputContainer->size() << ", Signal Input size: " << signalContainer->size() << ", Bkg Input size: " << bkgContainerPtr->size() << ", dropped neutrino GenEvents: " << (m_removeBkgHardScatterTruth ? 1 : 0) << " , dropped Separator GenEvents: " << droppedSeparatorGenEvents);
164  // dump McEventCollection in debug mode to confirm everything is as expected
165  if (msgLvl(MSG::DEBUG)) {
166  if (!outputContainer->empty()) {
167  ATH_MSG_DEBUG("McEventCollection contents:");
168  for (const HepMC::GenEvent *event : *outputContainer) {
169  ATH_MSG_DEBUG(" GenEvent #" << event->event_number() << ", signal_process_id=" << HepMC::signal_process_id(event));
170  }
171  }
172  }
173 
174  ATH_MSG_DEBUG("execute() end");
175  return StatusCode::SUCCESS;
176 }
CopyMcEventCollection::m_bkgInputKey
SG::ReadHandleKey< McEventCollection > m_bkgInputKey
Definition: CopyMcEventCollection.h:24
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
CopyMcEventCollection::m_eventInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Definition: CopyMcEventCollection.h:23
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
SG::ReadHandle< McEventCollection >
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
HepMC::signal_process_id
int signal_process_id(const GenEvent &e)
Definition: GenEvent.h:635
HeavyIon.h
skel.it
it
Definition: skel.GENtoEVGEN.py:396
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
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
HepMC::fillBarcodesAttribute
void fillBarcodesAttribute(GenEvent *)
Definition: GenEvent.h:626
CopyMcEventCollection.h
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
CopyMcEventCollection::m_signalInputKey
SG::ReadHandleKey< McEventCollection > m_signalInputKey
Definition: CopyMcEventCollection.h:25
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
CopyMcEventCollection::initialize
virtual StatusCode initialize() override
Definition: CopyMcEventCollection.cxx:13
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
SG::VarHandleBase::store
std::string store() const
Return the name of the store holding the object we are proxying.
Definition: StoreGate/src/VarHandleBase.cxx:376
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
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
CopyMcEventCollection::m_removeBkgHardScatterTruth
Gaudi::Property< bool > m_removeBkgHardScatterTruth
Definition: CopyMcEventCollection.h:28
McEventCollection
This defines the McEventCollection, which is really just an ObjectVector of McEvent objects.
Definition: McEventCollection.h:33
CopyMcEventCollection::m_outputKey
SG::WriteHandleKey< McEventCollection > m_outputKey
Definition: CopyMcEventCollection.h:26
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
SG::WriteHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
SG::WriteHandle< McEventCollection >
CopyMcEventCollection::execute
virtual StatusCode execute(const EventContext &ctx) const override
Definition: CopyMcEventCollection.cxx:30
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
DEBUG
#define DEBUG
Definition: page_access.h:11
CopyMcEventCollection::CopyMcEventCollection
CopyMcEventCollection(const std::string &name, ISvcLocator *pSvcLocator)
Definition: CopyMcEventCollection.cxx:8
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.