Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
30 CountHepMC::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 
49  if(m_corEvtID || m_corRunNumber) {
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 
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
78  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(
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 
303 void 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
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
IOVPayloadContainer.h
This class is a container for the payload of conditions data. It is intended to be used to store cond...
IOVMetaDataContainer::payloadContainer
const IOVPayloadContainer * payloadContainer() const
Access to payload container.
Definition: IOVMetaDataContainer.h:141
CountHepMC::m_nCount
uint64_t m_nCount
Definition: CountHepMC.h:42
HepMC::set_ll_event_number
bool set_ll_event_number(HepMC::GenEvent *e, long long int num)
Definition: GenEvent.h:612
plotting.plot_kinematics.run_number
run_number
Definition: plot_kinematics.py:29
CountHepMC::m_outputEvtInfoKey
SG::WriteHandleKey< xAOD::EventInfo > m_outputEvtInfoKey
Definition: CountHepMC.h:54
IOVMetaDataContainer
This class is a container for conditions data. It is intended to be used to store conditions data fro...
Definition: IOVMetaDataContainer.h:37
CondAttrListCollection.h
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::EventInfo_v1::mcEventWeights
const std::vector< float > & mcEventWeights() const
The weights of all the MC events used in the simulation.
CountHepMC::m_inputKeyName
std::string m_inputKeyName
Definition: CountHepMC.h:51
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
index
Definition: index.py:1
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
EventType::set_mc_channel_number
void set_mc_channel_number(number_type chan)
Add in the MC generator channel number (aka gen run number)
Definition: EventType.cxx:197
EventType
This class represents the "type of event" where the type is given by one or more "characteristics".
Definition: EventType.h:92
AthenaInterprocess::UpdateAfterFork
Definition: Incidents.h:22
CountHepMC::handle
virtual void handle(const Incident &inc) override
Definition: CountHepMC.cxx:303
CountHepMC::CountHepMC
CountHepMC(const std::string &name, ISvcLocator *pSvcLocator)
Definition: CountHepMC.cxx:30
McEventCollection
McEventCollection
Definition: GeneratorObjectsTPCnv.cxx:60
EventType.h
This class provides general information about an event. It extends EventInfo with a list of sub-evts ...
LArG4FSStartPointFilter.evt
evt
Definition: LArG4FSStartPointFilter.py:42
CondAttrListCollection
This class is a collection of AttributeLists where each one is associated with a channel number....
Definition: CondAttrListCollection.h:52
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
xAOD::EventInfo_v1::runNumber
uint32_t runNumber() const
The current event's run number.
EventType::mc_channel_number
number_type mc_channel_number() const
Access to the MC generator channel number (was used as run number for generator events)
Definition: EventType.cxx:165
CountHepMC::m_corRunNumber
bool m_corRunNumber
Definition: CountHepMC.h:49
AthCommonDataStore< AthCommonMsg< Algorithm > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
CountHepMC::execute
virtual StatusCode execute() override
Definition: CountHepMC.cxx:64
EventID.h
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
CountHepMC.h
CountHepMC::initialize
virtual StatusCode initialize() override
Definition: CountHepMC.cxx:43
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
GenBase
Base class for common behaviour of MC truth algorithms.
Definition: GenBase.h:47
SG::ReadDecorHandle
Handle class for reading a decoration on an object.
Definition: StoreGate/StoreGate/ReadDecorHandle.h:94
DataModel_detail::iterator
(Non-const) Iterator class for DataVector/DataList.
Definition: DVLIterator.h:184
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
Incidents.h
EventInfo::event_ID
EventID * event_ID()
the unique identification of the event.
Definition: EventInfo/EventInfo/EventInfo.h:224
calibdata.exception
exception
Definition: calibdata.py:496
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
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
McEventCollection
This defines the McEventCollection, which is really just an ObjectVector of McEvent objects.
Definition: McEventCollection.h:33
CondAttrListCollection::ChanNum
unsigned int ChanNum
Definition: CondAttrListCollection.h:55
IOVPayloadContainer
This class is a container for the payload of conditions data. It is intended to be used to store cond...
Definition: IOVPayloadContainer.h:35
CountHepMC::m_nPass
uint64_t m_nPass
Definition: CountHepMC.h:41
CountHepMC::m_newRunNumber
uint32_t m_newRunNumber
Definition: CountHepMC.h:45
IOVMetaDataContainer.h
This class is a container for conditions data. It is intended to be used to store conditions data fro...
EventAuxInfo.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
errorcheck.h
Helpers for checking error return status codes and reporting errors.
EventInfo
This class provides general information about an event. Event information is provided by the accessor...
Definition: EventInfo/EventInfo/EventInfo.h:43
AthenaInterprocess::UpdateAfterFork::type
static const std::string & type()
Incident type.
Definition: Incidents.h:49
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
CountHepMC::m_mcWeightsKey
SG::ReadDecorHandleKey< xAOD::EventInfo > m_mcWeightsKey
Definition: CountHepMC.h:56
DeMoScan.index
string index
Definition: DeMoScan.py:364
EventType::set_mc_event_number
void set_mc_event_number(uint64_t evt)
Add in the MC generator event number.
Definition: EventType.cxx:202
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
EventID
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
Definition: EventID.h:35
ReadDecorHandle.h
Handle class for reading a decoration on an object.
CountHepMC::m_inputEvtInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_inputEvtInfoKey
Definition: CountHepMC.h:53
CountHepMC::m_metaDataStore
ServiceHandle< StoreGateSvc > m_metaDataStore
Definition: CountHepMC.h:39
CountHepMC::finalize
virtual StatusCode finalize() override
Definition: CountHepMC.cxx:298
CountHepMC::m_copyRunNumber
bool m_copyRunNumber
Definition: CountHepMC.h:50
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
CountHepMC::m_corEvtID
bool m_corEvtID
Definition: CountHepMC.h:48
GenBase::initialize
virtual StatusCode initialize() override
Definition: GenBase.cxx:17
CountHepMC::m_corHepMC
bool m_corHepMC
Definition: CountHepMC.h:47
CountHepMC::m_firstEv
uint64_t m_firstEv
Definition: CountHepMC.h:44
EventInfo::event_type
EventType * event_type()
the type of the event, e.g. simulation, testbeam, etc
Definition: EventInfo/EventInfo/EventInfo.h:234
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
xAOD::EventInfo_v1::setMCEventWeights
void setMCEventWeights(const std::vector< float > &value)
Set the weights of all the MC events used in the simulation.
ServiceHandle< IIncidentSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37