Belle II Software light-2406-ragdoll
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 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.",
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;
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]);
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: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.
Definition: ClusterUtils.h:24
STL namespace.