ATLAS Offline Software
Loading...
Searching...
No Matches
CountHepMC.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef XAOD_ANALYSIS
6
8#include "GaudiKernel/IEventProcessor.h"
9#include "GaudiKernel/IAlgManager.h"
10#include "GaudiKernel/IOpaqueAddress.h"
11#include "GaudiKernel/IProperty.h"
12#include "GaudiKernel/ClassID.h"
13#include "GaudiKernel/IClassIDSvc.h"
14#include "GaudiKernel/IIncidentSvc.h"
15#include "GaudiKernel/ConcurrencyFlags.h"
17#include "EventInfo/EventInfo.h"
18#include "EventInfo/EventID.h"
19#include "EventInfo/EventType.h"
26#include <cmath>
27#include <cassert>
28#include <string>
29
30CountHepMC::CountHepMC(const std::string& name, ISvcLocator* pSvcLocator) :
31 GenBase(name, pSvcLocator)
32{
33 declareProperty("RequestedOutput", m_nCount=5000);
34 declareProperty("FirstEvent", m_firstEv=1);
35 declareProperty("CorrectHepMC", m_corHepMC=false);
36 declareProperty("CorrectEventID", m_corEvtID=false);
37 declareProperty("CorrectRunNumber", m_corRunNumber=false);
38 declareProperty("NewRunNumber", m_newRunNumber=999999);
39 declareProperty("CopyRunNumber", m_copyRunNumber=true);
40 declareProperty("inputKeyName", m_inputKeyName = "GEN_EVENT");
41}
42
44{
46
48
50 ATH_CHECK(m_inputEvtInfoKey.initialize());
51 ATH_CHECK(m_outputEvtInfoKey.initialize());
52 if(!m_mcWeightsKey.empty()) ATH_CHECK(m_mcWeightsKey.initialize());
53 }
54
55 if(Gaudi::Concurrency::ConcurrencyFlags::numProcs()>0) {
56 ServiceHandle<IIncidentSvc> incidentSvc("IncidentSvc",name());
57 ATH_CHECK(incidentSvc.retrieve());
58 incidentSvc->addListener(this, AthenaInterprocess::UpdateAfterFork::type());
59 }
60
61 return StatusCode::SUCCESS;
62}
63
64StatusCode CountHepMC::execute(const EventContext& ctx) {
65
67 m_nPass++;
68 ATH_MSG_DEBUG("Current count = " << m_nPass);
69 ATH_MSG_DEBUG("Options for HepMC event number, EvtID event number, EvtID run number = " << m_corHepMC << ", " << m_corEvtID << ", " << m_corRunNumber );
70 // Fix the event number
71 long long int newnum = m_nPass + m_firstEv - 1;
72 if (newnum<=0){
73 ATH_MSG_ERROR("Event number must be positive-definite; " << newnum << " is not allowed");
74 return StatusCode::FAILURE;
75 }
76
77// Temporary solution to suppress the Warnings from HepMC3 printed for every event.
78// Will be removed when generators authors fix the way they fill the x-section or when we switch to a new HepMC3 version , where the printout is limited.
79 if (m_nPass == 100) {
80 ATH_MSG_INFO("After " << m_nPass << " events we switch off HepMC3 warnings to avoid blowing up logs.");
81 HepMC3::Setup::set_print_warnings(false);
82 }
83 if (m_corHepMC) {
84 std::string key = m_inputKeyName;
85 // retrieve event from Transient Store (Storegate)
86 const McEventCollection* oldmcEvtColl=0;
87 if (evtStore()->retrieve(oldmcEvtColl, key).isSuccess()){
88 McEventCollection* newmcEvtColl = new McEventCollection(*oldmcEvtColl);
89 McEventCollection::iterator evt = newmcEvtColl->begin();
90 HepMC::GenEvent* hepMC = *evt;
91 HepMC::set_ll_event_number(hepMC, newnum);
92 CHECK(evtStore()->overwrite( newmcEvtColl, key));
93 }
94 else{
95 ATH_MSG_ERROR("No McEventCollection object found");
96 return StatusCode::SUCCESS;
97 }
98 }
99
100 xAOD::EventInfo* outputEvtInfo{nullptr};
101 int inpRunNumber{-1};
103 SG::ReadHandle<xAOD::EventInfo> inputEvtInfoHandle(m_inputEvtInfoKey, ctx);
105 ATH_CHECK(outputEvtInfoHandle.record(std::make_unique<xAOD::EventInfo>(), std::make_unique<xAOD::EventAuxInfo>()));
106
107 outputEvtInfo = outputEvtInfoHandle.ptr();
108 *outputEvtInfo = *inputEvtInfoHandle;
109
110 // This is sometimes marked as a decoration in the source, meaning
111 // it won't get copied by the assignment above. Make sure it
112 // gets copied.
113 outputEvtInfo->setMCEventWeights (inputEvtInfoHandle->mcEventWeights());
114
115 inpRunNumber = inputEvtInfoHandle->runNumber();
116 if(!m_mcWeightsKey.empty()) {
118 outputEvtInfo->setMCEventWeights(mcWeights(0));
119 }
120 }
121
122 if (m_corEvtID) {
123 // Change the EventID in the eventinfo header
124 const EventInfo* pInputEvt(nullptr);
125 if (evtStore()->retrieve(pInputEvt).isSuccess()) {
126 assert(pInputEvt);
127 EventID* eventID = const_cast<EventID*>(pInputEvt->event_ID());
128 eventID->set_event_number(newnum);
129 ATH_MSG_DEBUG("Set new event number in event_ID");
130 } else {
131 ATH_MSG_ERROR("No EventInfo object found");
132 return StatusCode::SUCCESS;
133 }
134
135 outputEvtInfo->setEventNumber(newnum);
136 }
137
138
139 // Copy generation run number into mc channel number
140 if (m_copyRunNumber) {
141 // Legacy Event Info
142 const EventInfo* pInputEvt(nullptr);
143 if (evtStore()->retrieve(pInputEvt).isSuccess()) {
144 assert(pInputEvt);
145
146 unsigned int run_number = pInputEvt->event_ID()->run_number();
147
148 EventType* eventType = const_cast<EventType*>(pInputEvt->event_type());
149 eventType->set_mc_channel_number(run_number);
150 eventType->set_mc_event_number (newnum);
151
152 ATH_MSG_DEBUG("Copied run number into mc channel number: " << run_number);
153 } else {
154 ATH_MSG_ERROR("No EventInfo object found");
155 return StatusCode::FAILURE;
156 }
157
158 // xAOD::EventInfo
159 outputEvtInfo->setMCChannelNumber(inpRunNumber);
160 outputEvtInfo->setMCEventNumber(newnum);
161 outputEvtInfo->setEventNumber(newnum);
162 }
163
164
165 if (m_corRunNumber) {
166 // Change the EventID in the eventinfo header
167 const EventInfo* pInputEvt(nullptr);
168 unsigned int oldRunNumber = 0;
169 if (evtStore()->retrieve(pInputEvt).isSuccess()) {
170 assert(pInputEvt);
171 EventID* eventID = const_cast<EventID*>(pInputEvt->event_ID());
172 oldRunNumber = eventID->run_number();
173 eventID->set_run_number(m_newRunNumber);
174 ATH_MSG_DEBUG("Set new run number in event_ID " << m_newRunNumber);
175
176 // also set the MC channel number
177 EventType* event_type = const_cast<EventType*>(pInputEvt->event_type());
179 ATH_MSG_DEBUG("Set new MC channel number " << event_type->mc_channel_number());
180 } else {
181 ATH_MSG_ERROR("No EventInfo object found");
182 return StatusCode::SUCCESS;
183 }
184
185 oldRunNumber = outputEvtInfo->runNumber();
186 outputEvtInfo->setRunNumber(m_newRunNumber);
187 outputEvtInfo->setMCChannelNumber(m_newRunNumber);
188
189 {
190 // change the channel number where /Generation/Parameters are found
191 auto newChannelNumber =
193 auto oldChannelNumber =
194 static_cast< CondAttrListCollection::ChanNum >(oldRunNumber);
195
196 const char* key = "/Generation/Parameters";
197 const IOVMetaDataContainer * iovContainer = nullptr;
198 if (m_metaDataStore->retrieve(iovContainer, key).isSuccess()
199 && iovContainer) {
200 // get a hold of the payload
201 const IOVPayloadContainer * payloadContainer =
202 iovContainer->payloadContainer();
203
204 // Grab the attribute list
205 for (CondAttrListCollection* collection : *payloadContainer) {
206 for(unsigned int index = 0; index < collection->size(); ++index) {
207 if (collection->chanNum(index) != oldChannelNumber) {
208 ATH_MSG_INFO("Not updating \"" << key << "\" on channel number "
209 << collection->chanNum(index));
210 continue;
211 }
212
213 if (collection->fixChanNum(oldChannelNumber, newChannelNumber))
214 ATH_MSG_INFO("Updated \"" << key << "\" channel number from "
215 << oldChannelNumber << " to " << newChannelNumber);
216 else
217 ATH_MSG_ERROR("Channel number update from " << oldChannelNumber
218 << " to " << newChannelNumber << " on \"" << key
219 << "\" FAILED");
220 }
221 }
222
223 {
224 // Update the MC channel number in the "/TagInfo"
225 const char* key = "/TagInfo";
226 const IOVMetaDataContainer * iovContainer = nullptr;
227 if (m_metaDataStore->retrieve(iovContainer, key).isSuccess()
228 && iovContainer) {
229 // get a hold of the payload
230 const IOVPayloadContainer * payloadContainer =
231 iovContainer->payloadContainer();
232
233 // Grab the attribute list
234 for (CondAttrListCollection* collection : *payloadContainer) {
235 for (auto pair : *collection) {
236 // pair is a pair of Channel number and AttributeList
237 if (pair.second.exists("mc_channel_number")) {
238 try {
239 pair.second["mc_channel_number"].setValue(
240 std::to_string(m_newRunNumber));
241 ATH_MSG_INFO("Updated \"" << key << "\" mc_channel_number"
242 << " to " << m_newRunNumber);
243 } catch (std::exception&) {
244 try {
245 pair.second["mc_channel_number"].setValue(m_newRunNumber);
246 ATH_MSG_INFO("Updated \"" << key << "\" mc_channel_number"
247 << " to " << m_newRunNumber);
248 } catch (std::exception&) {
249 ATH_MSG_ERROR("mc_channel_number update from to "
250 << m_newRunNumber << " on \"" << key
251 << "\" FAILED");
252 }
253 }
254 }
255 }
256 }
257 }
258 }
259 } else {
260 ATH_MSG_INFO("Could not retrieve \"" << key << "\" from MetaDataStore");
261 }
262 }
263 }
264
265
266 if (m_nPass == m_nCount) {
267 ATH_MSG_INFO("Stopping the event processing...." << m_nPass << "/" << m_nCount);
268 // Try the MP ELM first
269 SmartIF<IEventProcessor> apm(serviceLocator()->service("AthMpEvtLoopMgr", /*createIf*/false));
270 if(apm) {
271 ATH_CHECK(apm->stopRun());
272 }
273 else {
274 apm = serviceLocator()->service("AthenaEventLoopMgr", /*createIf*/false);
275 if (apm) {
276 ATH_CHECK(apm->stopRun());
277 }
278 else {
279 ATH_MSG_WARNING("No EventLoop Manager found ");
280 }
281 }
282 }
283
284 return StatusCode::SUCCESS;
285}
286
287
289 ATH_MSG_INFO("Events passing all checks and written = " << m_nPass);
290 return StatusCode::SUCCESS;
291}
292
293void CountHepMC::handle(const Incident& inc) {
294 using AfterForkInc = AthenaInterprocess::UpdateAfterFork;
295 if(inc.type()==AfterForkInc::type()) {
296 int nProcs= Gaudi::Concurrency::ConcurrencyFlags::numProcs();
297 const AfterForkInc* afInc = dynamic_cast<const AfterForkInc*>(&inc);
298 if(afInc) {
299 int rem = m_nCount%nProcs;
300 m_nCount = m_nCount/nProcs
301 + (afInc->workerID() <= rem-1 ? 1 : 0);
302 }
303 else {
304 ATH_MSG_ERROR("Failed to dyn-cast the incident to UpdateAfterFork!");
305 throw std::runtime_error("Wrong incident type handled by CountHepMC");
306 }
307 }
308}
309
310#endif
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
Helpers for checking error return status codes and reporting errors.
#define CHECK(...)
Evaluate an expression and check for errors.
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
This class provides general information about an event.
This class is a container for conditions data.
This class is a container for the payload of conditions data.
Handle class for reading a decoration on an object.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
static const std::string & type()
Incident type.
Definition Incidents.h:49
This class is a collection of AttributeLists where each one is associated with a channel number.
SG::ReadDecorHandleKey< xAOD::EventInfo > m_mcWeightsKey
Definition CountHepMC.h:56
bool m_copyRunNumber
Definition CountHepMC.h:50
bool m_corEvtID
Definition CountHepMC.h:48
SG::ReadHandleKey< xAOD::EventInfo > m_inputEvtInfoKey
Definition CountHepMC.h:53
uint64_t m_nPass
Definition CountHepMC.h:41
ServiceHandle< StoreGateSvc > m_metaDataStore
Definition CountHepMC.h:39
virtual StatusCode finalize() override
std::string m_inputKeyName
Definition CountHepMC.h:51
SG::WriteHandleKey< xAOD::EventInfo > m_outputEvtInfoKey
Definition CountHepMC.h:54
CountHepMC(const std::string &name, ISvcLocator *pSvcLocator)
uint32_t m_newRunNumber
Definition CountHepMC.h:45
bool m_corHepMC
Definition CountHepMC.h:47
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
uint64_t m_nCount
Definition CountHepMC.h:42
virtual StatusCode initialize() override
bool m_corRunNumber
Definition CountHepMC.h:49
uint64_t m_firstEv
Definition CountHepMC.h:44
virtual void handle(const Incident &inc) override
DataModel_detail::iterator< DataVector > iterator
Definition DataVector.h:842
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
Definition EventID.h:35
EventID * event_ID()
the unique identification of the event.
EventType * event_type()
the type of the event, e.g. simulation, testbeam, etc
This class represents the "type of event" where the type is given by one or more "characteristics".
Definition EventType.h:92
void set_mc_channel_number(number_type chan)
Add in the MC generator channel number (aka gen run number).
number_type mc_channel_number() const
Access to the MC generator channel number (was used as run number for generator events).
void set_mc_event_number(uint64_t evt)
Add in the MC generator event number.
virtual StatusCode initialize() override
Definition GenBase.cxx:17
GenBase(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Definition GenBase.cxx:11
This class is a container for conditions data.
const IOVPayloadContainer * payloadContainer() const
Access to payload container.
This class is a container for the payload of conditions data.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
Handle class for reading a decoration on an object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
STL class.
void setMCEventNumber(uint64_t value)
Set the MC generator's event number.
void setEventNumber(uint64_t value)
Set the current event's event number.
void setMCChannelNumber(uint32_t value)
Set the MC generator's channel number.
void setMCEventWeights(const std::vector< float > &value)
Set the weights of all the MC events used in the simulation.
void setRunNumber(uint32_t value)
Set the current event's run number.
uint32_t runNumber() const
The current event's run number.
bool set_ll_event_number(HepMC3::GenEvent *e, long long int num)
Definition GenEvent.h:337
HepMC3::GenEvent GenEvent
Definition GenEvent.h:39
Definition index.py:1
EventInfo_v1 EventInfo
Definition of the latest event info version.