Belle II Software  release-08-01-10
EventInfoSetterModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <framework/modules/core/EventInfoSetterModule.h>
10 
11 #include <framework/core/Environment.h>
12 #include <framework/utilities/Utils.h>
13 
14 #include <chrono>
15 #include <set>
16 
17 using namespace std;
18 using namespace Belle2;
19 
20 //-----------------------------------------------------------------
21 // Register the Module
22 //-----------------------------------------------------------------
23 REG_MODULE(EventInfoSetter);
24 
25 //-----------------------------------------------------------------
26 // Implementation
27 //-----------------------------------------------------------------
28 
29 EventInfoSetterModule::EventInfoSetterModule() : Module()
30 {
31  if (getenv("BELLE2_PRODUCTION"))
32  m_production = stoi(getenv("BELLE2_PRODUCTION"));
33 
34  //Set module properties
36  "Sets the event meta data information (exp, run, evt). You must use this "
37  "module to tell basf2 about the number of events you want to generate, "
38  "unless you have an input module that already does so. Note that all "
39  "experiment/run combinations specified must be unique."
40  );
41 
42  //Parameter definition
43  addParam("expList", m_expList, "List of experiment numbers. Can be overridden via --experiment argument to basf2.", m_expList);
44  addParam("runList", m_runList, "List of run numbers. Can be overridden via --run argument to basf2.", m_runList);
45  addParam("evtNumList", m_evtNumList, "List of the number of events which "
46  "should be processed. Can be overridden via -n argument to basf2.",
47  m_evtNumList);
48  addParam("skipNEvents", m_eventsToSkip, "Skip this number of events before "
49  "starting. Equivalent to running over this many events without performing "
50  "any action, to allow starting at higher event numbers.", m_eventsToSkip);
51  addParam("skipToEvent", m_skipToEvent, "Skip events until the event with "
52  "the specified (experiment, run, event number) occurs. This parameter "
53  "is useful for debugging to start with a specific event.", m_skipToEvent);
54 }
55 
57 
59 {
60  //Register the EventMetaData in the data store
62 
63  //steering file content overwritten via command line arguments?
64  unsigned int numEventsArgument = Environment::Instance().getNumberEventsOverride();
65  int runOverride = Environment::Instance().getRunOverride();
66  int expOverride = Environment::Instance().getExperimentOverride();
67  if (numEventsArgument > 0 or runOverride >= 0 or expOverride >= 0) {
68  if (m_evtNumList.size() > 1) {
69  B2ERROR("The -n/--events, --run, and --experiment options cannot be used when multiple runs are specified for EventInfoSetter!");
70  }
71  m_evtNumList[0] = numEventsArgument;
72  if (runOverride >= 0)
73  m_runList[0] = runOverride;
74  if (expOverride >= 0)
75  m_expList[0] = expOverride;
76  }
77 
78  unsigned int skipNEventsOverride = Environment::Instance().getSkipEventsOverride();
79  if (skipNEventsOverride != 0)
80  m_eventsToSkip = skipNEventsOverride;
81 
82  //Make sure all lists have the same size
83  unsigned int defListSize = m_expList.size();
84  if ((m_runList.size() != defListSize) || (m_evtNumList.size() != defListSize)) {
85  B2ERROR("Parameters are inconsistent. The exp, run and evt lists must have the same number of entries.");
86  } else if (defListSize == 0) {
87  B2ERROR("There are no events to be processed!");
88  } else {
89  set<pair<int, int>> expRunSet;
90  for (unsigned int i = 0; i < defListSize; i++) {
91  auto ret = expRunSet.insert(make_pair(m_expList[i], m_runList[i]));
92  if (!ret.second) {
93  B2ERROR("Exp " << ret.first->first << ", run " << ret.first->second <<
94  " used more than once! Please make sure all experiment/run combinations are unique.");
95  }
96  if (m_expList[i] < 0 or m_expList[i] > 1023)
97  B2ERROR("Experiment " << m_expList[i] << " is out of range, should be in [0, 1023]!");
98  if (m_runList[i] < 0)
99  B2ERROR("Run " << m_runList[i] << " is out of range, should be >= 0!");
100  unsigned int nevents = m_evtNumList[i];
101  if (nevents == std::numeric_limits<unsigned int>::max()) {
102  B2ERROR("Invalid number of events (valid range: 0.." << std::numeric_limits<unsigned int>::max() - 1 << ")!");
103  }
104  }
105  }
106 
107  if (!m_skipToEvent.empty()) {
108  // make sure the number of entries is exactly 3
109  if (m_skipToEvent.size() != 3) {
110  B2ERROR("skipToEvent must be a list of three values: experiment, run, event number");
111  // ignore the value
112  m_skipToEvent.clear();
113  }
114  if (m_eventsToSkip > 0) {
115  B2ERROR("You cannot supply a number of events to skip (skipNEvents) and an "
116  "event to skip to (skipToEvent) at the same time, ignoring skipNEvents");
117  //force the number of skipped events to be zero
118  m_eventsToSkip = 0;
119  }
120  }
121 
122  m_evtNumber = 1;
123  m_colIndex = 0; //adjusted in event() if mismatched
124 
125  //determine number of events we will process
126  unsigned int totalevents = 0;
127  Belle2::EventInfoSetterModule copy(*this);
128  while (copy.advanceEventCounter()) {
129  copy.m_evtNumber++;
130  totalevents++;
131  }
132  B2DEBUG(100, "EventInfoSetter: will process " << totalevents << " events in total.");
133  if (totalevents == 0) {
134  B2FATAL("Total processed number of events is 0, please check your inputs, -n and --skip-events arguments!");
135  }
137 }
138 
139 
141 {
142  // optimized for the assumed normal case of few runs with lots of events
143  // and no skipping.
144  // In the case of 1e9 events, the branch prediction hints give the following
145  // improvements:
146  // clang: -18% real time
147  // gcc (opt): -52% real time
148  while (true) {
150 
151  //Search for a column where the event number is greater than 0.
152  do {
153  m_colIndex++;
154  } while ((m_colIndex < static_cast<int>(m_expList.size())) &&
155  (m_evtNumList[m_colIndex] == 0));
156 
157  if (m_colIndex < static_cast<int>(m_expList.size())) {
158  m_evtNumber = 1;
159  } else { //no experiment/run with non-zero number of events found
160  return false;
161  }
162  }
163 
164  // check if we want to skip to a specific event
165  if (branch_unlikely(!m_skipToEvent.empty())) {
166  // if current experiment and run number is different to what we're looking for
168  // then we set the m_evtNumber to the max+1
170  } else {
171  // otherwise we start at the event number we want to skip to
173  // and reset the variable as skipping is done
174  m_skipToEvent.clear();
175  }
176  // and check again if the event number is in the range we want to generate
177  } else if (branch_unlikely(m_eventsToSkip != 0)) { //are we still skipping?
178  unsigned int nskip = 1;
179  const unsigned int eventsInList = m_evtNumList[m_colIndex];
180  if (m_evtNumber <= eventsInList) //skip to end of current run?
181  nskip = eventsInList - m_evtNumber + 1;
182  if (nskip > m_eventsToSkip)
183  nskip = m_eventsToSkip;
184 
185  m_eventsToSkip -= nskip;
186  m_evtNumber += nskip;
187  } else {
188  break;
189  }
190  }
191  return true;
192 }
193 
195 {
196  if (!advanceEventCounter())
197  return;
198 
199  m_eventMetaDataPtr.create();
200  m_eventMetaDataPtr->setProduction(m_production);
201  m_eventMetaDataPtr->setExperiment(m_expList[m_colIndex]);
203  m_eventMetaDataPtr->setEvent(m_evtNumber);
204  auto time = std::chrono::high_resolution_clock::now().time_since_epoch();
205  m_eventMetaDataPtr->setTime(std::chrono::duration_cast<std::chrono::nanoseconds>(time).count());
206 
207  m_evtNumber++;
208 }
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
unsigned int getSkipEventsOverride() const
Get skipNEvents override, or 0 if unset.
Definition: Environment.h:88
int getExperimentOverride() const
Get experiment override, or -1 if unset.
Definition: Environment.h:83
int getRunOverride() const
Get run override, or -1 if unset.
Definition: Environment.h:81
static Environment & Instance()
Static method to get a reference to the Environment instance.
Definition: Environment.cc:28
unsigned int getNumberEventsOverride() const
Returns number of events in run 1 for EventInfoSetter module, or 0 for no override.
Definition: Environment.h:66
void setNumberOfMCEvents(unsigned int n)
Set number of generated events (for EventInfoSetter).
Definition: Environment.h:97
Module to set event, run, experiment numbers.
std::vector< unsigned int > m_evtNumList
The list (column) of the number of events which should be processed.
virtual void initialize() override
Initializes the Module.
std::vector< int > m_runList
The list (column) of runs.
virtual void event() override
Stores the event meta data into the DataStore.
virtual ~EventInfoSetterModule()
Destructor.
unsigned int m_evtNumber
The current event number.
int m_production
The production number.
unsigned int m_eventsToSkip
skip this many events before starting.
StoreObjPtr< EventMetaData > m_eventMetaDataPtr
Output object.
std::vector< int > m_skipToEvent
The (expNo, runNo, evtNo) tuple to skip to, empty if not used.
std::vector< int > m_expList
The list (column) of experiments.
bool advanceEventCounter()
Advances member variables to the next event (which is given by m_evtNumber).
int m_colIndex
The current index for the exp and run lists.
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define branch_unlikely(x)
A macro to tell the compiler that the argument x will be very likely be false.
Definition: Utils.h:134
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.