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() {
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#ifndef HEPMC3
79 constexpr long long int max32 = std::pow(2, 31) - 1;
80 if (newnum >= max32) {
81 ATH_MSG_ERROR("Event number " << newnum << " exceeds 32bit limit. In HepMC2 it is not allowed.");
82 return StatusCode::FAILURE;
83 }
84#else
85// Temporary solution to suppress the Warnings from HepMC3 printed for every event.
86// 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.
87 if (m_nPass == 100) {
88 ATH_MSG_INFO("After " << m_nPass << " events we switch off HepMC3 warnings to avoid blowing up logs.");
89 HepMC3::Setup::set_print_warnings(false);
90 }
91#endif
92
93 if (m_corHepMC) {
94 std::string key = m_inputKeyName;
95 // retrieve event from Transient Store (Storegate)
96 const McEventCollection* oldmcEvtColl=0;
97 if (evtStore()->retrieve(oldmcEvtColl, key).isSuccess()){
98 McEventCollection* newmcEvtColl = new McEventCollection(*oldmcEvtColl);
99 McEventCollection::iterator evt = newmcEvtColl->begin();
100 HepMC::GenEvent* hepMC = *evt;
101 HepMC::set_ll_event_number(hepMC, newnum);
102 CHECK(evtStore()->overwrite( newmcEvtColl, key));
103 }
104 else{
105 ATH_MSG_ERROR("No McEventCollection object found");
106 return StatusCode::SUCCESS;
107 }
108 }
109
110 xAOD::EventInfo* outputEvtInfo{nullptr};
111 int inpRunNumber{-1};
115 ATH_CHECK(outputEvtInfoHandle.record(std::make_unique<xAOD::EventInfo>(), std::make_unique<xAOD::EventAuxInfo>()));
116
117 outputEvtInfo = outputEvtInfoHandle.ptr();
118 *outputEvtInfo = *inputEvtInfoHandle;
119
120 // This is sometimes marked as a decoration in the source, meaning
121 // it won't get copied by the assignment above. Make sure it
122 // gets copied.
123 outputEvtInfo->setMCEventWeights (inputEvtInfoHandle->mcEventWeights());
124
125 inpRunNumber = inputEvtInfoHandle->runNumber();
126 if(!m_mcWeightsKey.empty()) {
128 outputEvtInfo->setMCEventWeights(mcWeights(0));
129 }
130 }
131
132 if (m_corEvtID) {
133 // Change the EventID in the eventinfo header
134 const EventInfo* pInputEvt(nullptr);
135 if (evtStore()->retrieve(pInputEvt).isSuccess()) {
136 assert(pInputEvt);
137 EventID* eventID = const_cast<EventID*>(pInputEvt->event_ID());
138 eventID->set_event_number(newnum);
139 ATH_MSG_DEBUG("Set new event number in event_ID");
140 } else {
141 ATH_MSG_ERROR("No EventInfo object found");
142 return StatusCode::SUCCESS;
143 }
144
145 outputEvtInfo->setEventNumber(newnum);
146 }
147
148
149 // Copy generation run number into mc channel number
150 if (m_copyRunNumber) {
151 // Legacy Event Info
152 const EventInfo* pInputEvt(nullptr);
153 if (evtStore()->retrieve(pInputEvt).isSuccess()) {
154 assert(pInputEvt);
155
156 unsigned int run_number = pInputEvt->event_ID()->run_number();
157
158 EventType* eventType = const_cast<EventType*>(pInputEvt->event_type());
159 eventType->set_mc_channel_number(run_number);
160 eventType->set_mc_event_number (newnum);
161
162 ATH_MSG_DEBUG("Copied run number into mc channel number: " << run_number);
163 } else {
164 ATH_MSG_ERROR("No EventInfo object found");
165 return StatusCode::FAILURE;
166 }
167
168 // xAOD::EventInfo
169 outputEvtInfo->setMCChannelNumber(inpRunNumber);
170 outputEvtInfo->setMCEventNumber(newnum);
171 outputEvtInfo->setEventNumber(newnum);
172 }
173
174
175 if (m_corRunNumber) {
176 // Change the EventID in the eventinfo header
177 const EventInfo* pInputEvt(nullptr);
178 unsigned int oldRunNumber = 0;
179 if (evtStore()->retrieve(pInputEvt).isSuccess()) {
180 assert(pInputEvt);
181 EventID* eventID = const_cast<EventID*>(pInputEvt->event_ID());
182 oldRunNumber = eventID->run_number();
183 eventID->set_run_number(m_newRunNumber);
184 ATH_MSG_DEBUG("Set new run number in event_ID " << m_newRunNumber);
185
186 // also set the MC channel number
187 EventType* event_type = const_cast<EventType*>(pInputEvt->event_type());
189 ATH_MSG_DEBUG("Set new MC channel number " << event_type->mc_channel_number());
190 } else {
191 ATH_MSG_ERROR("No EventInfo object found");
192 return StatusCode::SUCCESS;
193 }
194
195 oldRunNumber = outputEvtInfo->runNumber();
196 outputEvtInfo->setRunNumber(m_newRunNumber);
197 outputEvtInfo->setMCChannelNumber(m_newRunNumber);
198
199 {
200 // change the channel number where /Generation/Parameters are found
201 auto newChannelNumber =
203 auto oldChannelNumber =
204 static_cast< CondAttrListCollection::ChanNum >(oldRunNumber);
205
206 const char* key = "/Generation/Parameters";
207 const IOVMetaDataContainer * iovContainer = nullptr;
208 if (m_metaDataStore->retrieve(iovContainer, key).isSuccess()
209 && iovContainer) {
210 // get a hold of the payload
211 const IOVPayloadContainer * payloadContainer =
212 iovContainer->payloadContainer();
213
214 // Grab the attribute list
215 for (CondAttrListCollection* collection : *payloadContainer) {
216 for(unsigned int index = 0; index < collection->size(); ++index) {
217 if (collection->chanNum(index) != oldChannelNumber) {
218 ATH_MSG_INFO("Not updating \"" << key << "\" on channel number "
219 << collection->chanNum(index));
220 continue;
221 }
222
223 if (collection->fixChanNum(oldChannelNumber, newChannelNumber))
224 ATH_MSG_INFO("Updated \"" << key << "\" channel number from "
225 << oldChannelNumber << " to " << newChannelNumber);
226 else
227 ATH_MSG_ERROR("Channel number update from " << oldChannelNumber
228 << " to " << newChannelNumber << " on \"" << key
229 << "\" FAILED");
230 }
231 }
232
233 {
234 // Update the MC channel number in the "/TagInfo"
235 const char* key = "/TagInfo";
236 const IOVMetaDataContainer * iovContainer = nullptr;
237 if (m_metaDataStore->retrieve(iovContainer, key).isSuccess()
238 && iovContainer) {
239 // get a hold of the payload
240 const IOVPayloadContainer * payloadContainer =
241 iovContainer->payloadContainer();
242
243 // Grab the attribute list
244 for (CondAttrListCollection* collection : *payloadContainer) {
245 for (auto pair : *collection) {
246 // pair is a pair of Channel number and AttributeList
247 if (pair.second.exists("mc_channel_number")) {
248 try {
249 pair.second["mc_channel_number"].setValue(
250 std::to_string(m_newRunNumber));
251 ATH_MSG_INFO("Updated \"" << key << "\" mc_channel_number"
252 << " to " << m_newRunNumber);
253 } catch (std::exception&) {
254 try {
255 pair.second["mc_channel_number"].setValue(m_newRunNumber);
256 ATH_MSG_INFO("Updated \"" << key << "\" mc_channel_number"
257 << " to " << m_newRunNumber);
258 } catch (std::exception&) {
259 ATH_MSG_ERROR("mc_channel_number update from to "
260 << m_newRunNumber << " on \"" << key
261 << "\" FAILED");
262 }
263 }
264 }
265 }
266 }
267 }
268 }
269 } else {
270 ATH_MSG_INFO("Could not retrieve \"" << key << "\" from MetaDataStore");
271 }
272 }
273 }
274
275
276 if (m_nPass == m_nCount) {
277 ATH_MSG_INFO("Stopping the event processing...." << m_nPass << "/" << m_nCount);
278 // Try the MP ELM first
279 SmartIF<IEventProcessor> apm(serviceLocator()->service("AthMpEvtLoopMgr", /*createIf*/false));
280 if(apm) {
281 ATH_CHECK(apm->stopRun());
282 }
283 else {
284 apm = serviceLocator()->service("AthenaEventLoopMgr", /*createIf*/false);
285 if (apm) {
286 ATH_CHECK(apm->stopRun());
287 }
288 else {
289 ATH_MSG_WARNING("No EventLoop Manager found ");
290 }
291 }
292 }
293
294 return StatusCode::SUCCESS;
295}
296
297
299 ATH_MSG_INFO("Events passing all checks and written = " << m_nPass);
300 return StatusCode::SUCCESS;
301}
302
303void CountHepMC::handle(const Incident& inc) {
304 using AfterForkInc = AthenaInterprocess::UpdateAfterFork;
305 if(inc.type()==AfterForkInc::type()) {
306 int nProcs= Gaudi::Concurrency::ConcurrencyFlags::numProcs();
307 const AfterForkInc* afInc = dynamic_cast<const AfterForkInc*>(&inc);
308 if(afInc) {
309 int rem = m_nCount%nProcs;
310 m_nCount = m_nCount/nProcs
311 + (afInc->workerID() <= rem-1 ? 1 : 0);
312 }
313 else {
314 ATH_MSG_ERROR("Failed to dyn-cast the incident to UpdateAfterFork!");
315 throw std::runtime_error("Wrong incident type handled by CountHepMC");
316 }
317 }
318}
319
320#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)
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
virtual StatusCode execute() override
CountHepMC(const std::string &name, ISvcLocator *pSvcLocator)
uint32_t m_newRunNumber
Definition CountHepMC.h:45
bool m_corHepMC
Definition CountHepMC.h:47
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(HepMC::GenEvent *e, long long int num)
Definition GenEvent.h:613
Definition index.py:1
EventInfo_v1 EventInfo
Definition of the latest event info version.