Belle II Software development
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
17using namespace std;
18using namespace Belle2;
19
20//-----------------------------------------------------------------
21// Register the Module
22//-----------------------------------------------------------------
23REG_MODULE(EventInfoSetter);
24
25//-----------------------------------------------------------------
26// Implementation
27//-----------------------------------------------------------------
28
30{
31 const char* production = getenv("BELLE2_PRODUCTION");
32 if (production)
33 m_production = stoi(production);
34
35 //Set module properties
37 "Sets the event meta data information (exp, run, evt). You must use this "
38 "module to tell basf2 about the number of events you want to generate, "
39 "unless you have an input module that already does so. Note that all "
40 "experiment/run combinations specified must be unique."
41 );
42
43 //Parameter definition
44 addParam("expList", m_expList, "List of experiment numbers. Can be overridden via --experiment argument to basf2.", m_expList);
45 addParam("runList", m_runList, "List of run numbers. Can be overridden via --run argument to basf2.", m_runList);
46 addParam("evtNumList", m_evtNumList, "List of the number of events which "
47 "should be processed. Can be overridden via -n argument to basf2.",
49 addParam("skipNEvents", m_eventsToSkip, "Skip this number of events before "
50 "starting. Equivalent to running over this many events without performing "
51 "any action, to allow starting at higher event numbers.", m_eventsToSkip);
52 addParam("skipToEvent", m_skipToEvent, "Skip events until the event with "
53 "the specified (experiment, run, event number) occurs. This parameter "
54 "is useful for debugging to start with a specific event.", m_skipToEvent);
55}
56
58
60{
61 //Register the EventMetaData in the data store
63
64 //steering file content overwritten via command line arguments?
65 unsigned int numEventsArgument = Environment::Instance().getNumberEventsOverride();
66 int runOverride = Environment::Instance().getRunOverride();
67 int expOverride = Environment::Instance().getExperimentOverride();
68 if (numEventsArgument > 0 or runOverride >= 0 or expOverride >= 0) {
69 if (m_evtNumList.size() > 1) {
70 B2ERROR("The -n/--events, --run, and --experiment options cannot be used when multiple runs are specified for EventInfoSetter!");
71 }
72 m_evtNumList[0] = numEventsArgument;
73 if (runOverride >= 0)
74 m_runList[0] = runOverride;
75 if (expOverride >= 0)
76 m_expList[0] = expOverride;
77 }
78
79 unsigned int skipNEventsOverride = Environment::Instance().getSkipEventsOverride();
80 if (skipNEventsOverride != 0)
81 m_eventsToSkip = skipNEventsOverride;
82
83 //Make sure all lists have the same size
84 unsigned int defListSize = m_expList.size();
85 if ((m_runList.size() != defListSize) || (m_evtNumList.size() != defListSize)) {
86 B2ERROR("Parameters are inconsistent. The exp, run and evt lists must have the same number of entries.");
87 } else if (defListSize == 0) {
88 B2ERROR("There are no events to be processed!");
89 } else {
90 set<pair<int, int>> expRunSet;
91 for (unsigned int i = 0; i < defListSize; i++) {
92 auto ret = expRunSet.insert(make_pair(m_expList[i], m_runList[i]));
93 if (!ret.second) {
94 B2ERROR("Exp " << ret.first->first << ", run " << ret.first->second <<
95 " used more than once! Please make sure all experiment/run combinations are unique.");
96 }
97 if (m_expList[i] < 0 or m_expList[i] > 1023)
98 B2ERROR("Experiment " << m_expList[i] << " is out of range, should be in [0, 1023]!");
99 if (m_runList[i] < 0)
100 B2ERROR("Run " << m_runList[i] << " is out of range, should be >= 0!");
101 unsigned int nevents = m_evtNumList[i];
102 if (nevents == std::numeric_limits<unsigned int>::max()) {
103 B2ERROR("Invalid number of events (valid range: 0.." << std::numeric_limits<unsigned int>::max() - 1 << ")!");
104 }
105 }
106 }
107
108 if (!m_skipToEvent.empty()) {
109 // make sure the number of entries is exactly 3
110 if (m_skipToEvent.size() != 3) {
111 B2ERROR("skipToEvent must be a list of three values: experiment, run, event number");
112 // ignore the value
113 m_skipToEvent.clear();
114 }
115 if (m_eventsToSkip > 0) {
116 B2ERROR("You cannot supply a number of events to skip (skipNEvents) and an "
117 "event to skip to (skipToEvent) at the same time, ignoring skipNEvents");
118 //force the number of skipped events to be zero
119 m_eventsToSkip = 0;
120 }
121 }
122
123 m_evtNumber = 1;
124 m_colIndex = 0; //adjusted in event() if mismatched
125
126 //determine number of events we will process
127 unsigned int totalevents = 0;
129 while (copy.advanceEventCounter()) {
130 copy.m_evtNumber++;
131 totalevents++;
132 }
133 B2DEBUG(100, "EventInfoSetter: will process " << totalevents << " events in total.");
134 if (totalevents == 0) {
135 B2FATAL("Total processed number of events is 0, please check your inputs, -n and --skip-events arguments!");
136 }
138}
139
140
142{
143 // optimized for the assumed normal case of few runs with lots of events
144 // and no skipping.
145 // In the case of 1e9 events, the branch prediction hints give the following
146 // improvements:
147 // clang: -18% real time
148 // gcc (opt): -52% real time
149 while (true) {
151
152 //Search for a column where the event number is greater than 0.
153 do {
154 m_colIndex++;
155 } while ((m_colIndex < static_cast<int>(m_expList.size())) &&
156 (m_evtNumList[m_colIndex] == 0));
157
158 if (m_colIndex < static_cast<int>(m_expList.size())) {
159 m_evtNumber = 1;
160 } else { //no experiment/run with non-zero number of events found
161 return false;
162 }
163 }
164
165 // check if we want to skip to a specific event
166 if (branch_unlikely(!m_skipToEvent.empty())) {
167 // if current experiment and run number is different to what we're looking for
169 // then we set the m_evtNumber to the max+1
171 } else {
172 // otherwise we start at the event number we want to skip to
174 // and reset the variable as skipping is done
175 m_skipToEvent.clear();
176 }
177 // and check again if the event number is in the range we want to generate
178 } else if (branch_unlikely(m_eventsToSkip != 0)) { //are we still skipping?
179 unsigned int nskip = 1;
180 const unsigned int eventsInList = m_evtNumList[m_colIndex];
181 if (m_evtNumber <= eventsInList) //skip to end of current run?
182 nskip = eventsInList - m_evtNumber + 1;
183 if (nskip > m_eventsToSkip)
184 nskip = m_eventsToSkip;
185
186 m_eventsToSkip -= nskip;
187 m_evtNumber += nskip;
188 } else {
189 break;
190 }
191 }
192 return true;
193}
194
196{
197 if (!advanceEventCounter())
198 return;
199
200 m_eventMetaDataPtr.create();
201 m_eventMetaDataPtr->setProduction(m_production);
202 m_eventMetaDataPtr->setExperiment(m_expList[m_colIndex]);
205 auto time = std::chrono::high_resolution_clock::now().time_since_epoch();
206 m_eventMetaDataPtr->setTime(std::chrono::duration_cast<std::chrono::nanoseconds>(time).count());
207
208 m_evtNumber++;
209}
@ 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:89
int getExperimentOverride() const
Get experiment override, or -1 if unset.
Definition: Environment.h:84
int getRunOverride() const
Get run override, or -1 if unset.
Definition: Environment.h:82
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:67
void setNumberOfMCEvents(unsigned int n)
Set number of generated events (for EventInfoSetter).
Definition: Environment.h:109
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.
STL namespace.