Belle II Software development
BGOverlayInputModule.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/* Own header. */
10#include <background/modules/BGOverlayInput/BGOverlayInputModule.h>
11
12/* Basf2 headers. */
13#include <framework/dataobjects/BackgroundInfo.h>
14#include <framework/dataobjects/BackgroundMetaData.h>
15#include <framework/dataobjects/FileMetaData.h>
16#include <framework/io/RootFileInfo.h>
17#include <framework/io/RootIOUtilities.h>
18#include <framework/logging/Logger.h>
19
20/* ROOT headers. */
21#include <TClonesArray.h>
22#include <TRandom.h>
23
24/* C++ headers. */
25#include <set>
26
27using namespace std;
28using namespace Belle2;
29
30//-----------------------------------------------------------------
31// Register module
32//-----------------------------------------------------------------
33
34REG_MODULE(BGOverlayInput);
35
36//-----------------------------------------------------------------
37// Implementation
38//-----------------------------------------------------------------
39
41
42{
43 // module description
44 setDescription("Input for BG overlay, either in form of Digits or raw data. For run-dependent MC (experiments 1 to 999) "
45 "the overlay samples corresponding to the simulated run are automatically selected from the input list "
46 "at each beginRun(), enabling production of multiple runs in a single job. "
47 "This feature can be turned off by setting ignoreRunNumbers to True.");
48
49 // Add parameters
50 addParam("inputFileNames", m_inputFileNames,
51 "List of files with measured beam background ");
52 addParam("extensionName", m_extensionName,
53 "Name added to default branch names", string("_beamBG"));
54 addParam("bkgInfoName", m_BackgroundInfoInstanceName, "Name of the BackgroundInfo StoreObjPtr", string(""));
55 addParam("skipExperimentCheck", m_skipExperimentCheck,
56 "If True, skip the check on the experiment number consistency between the basf2 process and the beam background files; "
57 "for experiments 1 to 999 ignore also run numbers. "
58 "By default, it is set to false, since the check should be skipped only by experts.",
59 false);
60 addParam("ignoreRunNumbers", m_ignoreRunNumbers,
61 "If True, ignore run numbers in case of run-dependend MC (experiments 1 to 999).",
62 false);
63}
64
66{
68 B2WARNING(R"RAW(The BGOverlayInput module will skip the check on the experiment number
69 consistency between the basf2 process and the beam background files.
70 It will also ignore run numbers in case of run-dependent MC.
71
72 This should be done only if you are extremely sure about what you are doing.
73
74 Be aware that you are not protected by the possible usage of beam background
75 files not suitabile for the experiment number you selected.)RAW");
76 }
77
78 // expand possible wildcards
80 if (m_inputFileNames.empty()) {
81 B2FATAL("No valid files specified!");
82 }
83
84 // get the experiment number from the EventMetaData
85 int experiment = m_eventMetaData->getExperiment();
86
87 // check files
88 for (const string& fileName : m_inputFileNames) {
89 try {
90 RootIOUtilities::RootFileInfo fileInfo{fileName};
91 const std::set<std::string>& branchNames = fileInfo.getBranchNames(true);
92 if (branchNames.count("BackgroundMetaData")) {
93 B2FATAL("The BG sample used is aimed for BG mixing, not for BG overlay."
94 << LogVar("File name", fileName));
95 }
96 // skip empty BG files
97 const FileMetaData& fileMetaData = fileInfo.getFileMetaData();
98 if (fileMetaData.getNEvents() == 0) {
99 B2WARNING("BG file is empty: skipping."
100 << LogVar("FileName", fileName));
101 continue;
102 }
103 if (not m_skipExperimentCheck) {
104 // we assume lowest experiment/run numbers are enough
105 if (experiment != fileMetaData.getExperimentLow()) {
106 B2FATAL("The BG sample used is aimed for a different experiment number. Please check what you are doing."
107 << LogVar("File name", fileName)
108 << LogVar("Experiment number of the basf2 process", experiment)
109 << LogVar("Experiment number of the BG file", fileMetaData.getExperimentLow()));
110 }
111 if (not m_ignoreRunNumbers) {
112 m_runFileNamesMap[fileMetaData.getRunLow()].push_back(fileName);
113 }
114 }
115 } catch (const std::invalid_argument& e) {
116 B2FATAL("One of the BG files can not be opened."
117 << LogVar("File name", fileName));
118 } catch (const std::runtime_error& e) {
119 B2FATAL("Something went wrong with one of the BG files."
120 << LogVar("File name", fileName)
121 << LogVar("Issue", e.what()));
122 }
123 }
124
125 // make a chain including all overlay files; get number of entries
127 for (const string& fileName : m_inputFileNames) {
128 m_tree->AddFile(fileName.c_str());
129 }
130 m_numEvents = m_tree->GetEntries();
131 if (m_numEvents == 0) B2ERROR(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entries");
132
133 // register selected branches to DataStore
134 bool ok = registerBranches();
135 if (!ok) {
136 B2ERROR("No branches found to be registered and connected");
137 }
138
139 // add BackgroundInfo to persistent tree
141 bkgInfo.registerInDataStore();
142 bkgInfo.create();
143 bkgInfo->setMethod(BackgroundInfo::c_Overlay);
144 bkgInfo->setExtensionName(m_extensionName);
145
146 // set flag for steering between run-independent (false) and run-dependent (true) overlay
147 m_runByRun = experiment > 0 and experiment < 1000 and not m_runFileNamesMap.empty();
148 if (m_runByRun) return;
149
150 // run-independent overlay: choose randomly the first event and connect branches
151 m_firstEvent = gRandom->Integer(m_numEvents);
152 B2INFO("BGOverlayInput: run-independent overlay starting with event " << m_firstEvent << " of " << m_numEvents);
154 m_start = true;
156
157 // add description to BackgroundInfo
160 descr.type = std::string(BackgroundMetaData::getDefaultBackgroundOverlayType());
161 descr.fileNames = m_inputFileNames;
162 descr.numEvents = m_numEvents;
163 m_index = bkgInfo->appendBackgroundDescr(descr);
164}
165
166
168{
169 if (not m_runByRun) return;
170
171 // run-dependent overlay: delete the old one and make new chain with overlay files for the current run; get number of entries
172 if (m_tree) delete m_tree;
174 int run = m_eventMetaData->getRun();
175 std::vector<std::string> inputFileNames;
176 for (const string& fileName : m_runFileNamesMap[run]) {
177 auto status = m_tree->AddFile(fileName.c_str());
178 if (status > 0) inputFileNames.push_back(fileName);
179 }
180 if (inputFileNames.empty()) B2FATAL("No overlay files for run " << run);
181
182 m_numEvents = m_tree->GetEntries();
183 if (m_numEvents == 0) B2FATAL(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entries for run " << run);
184
185 // choose randomly the first event and connect branches
186 m_firstEvent = gRandom->Integer(m_numEvents);
187 B2INFO("BGOverlayInput: run " << run << " starting with event " << m_firstEvent << " of " << m_numEvents);
189 m_start = true;
191
192 // add description for this run to BackgroundInfo
195 descr.type = std::string(BackgroundMetaData::getDefaultBackgroundOverlayType());
196 descr.fileNames = inputFileNames;
197 descr.numEvents = m_numEvents;
198 descr.runNumber = run;
200 m_index = bkgInfo->appendBackgroundDescr(descr);
201}
202
203
205{
207
208 for (auto entry : m_storeEntries) {
209 entry->resetForGetEntry();
210 }
211
212 if (m_eventCount == m_firstEvent and !m_start) {
213 B2INFO("BGOverlayInput: events for BG overlay will be reused");
214 bkgInfo->incrementReusedCounter(m_index);
215 }
216 m_start = false;
217
218 m_tree->GetEntry(m_eventCount);
219 m_eventCount++;
220 if (m_eventCount >= m_numEvents) {
221 m_eventCount = 0;
222 }
223
224 for (auto entry : m_storeEntries) {
225 if (entry->object) {
226 entry->ptr = entry->object;
227 } else {
228 entry->recoverFromNullObject();
229 entry->ptr = 0;
230 }
231 }
232
233}
234
235
237{
238
239 if (m_tree) delete m_tree;
240
241}
242
243
245{
246
247 auto durability = DataStore::c_Event;
249 auto& map = DataStore::Instance().getStoreEntryMap(durability);
250
251 // StoreObjPointers have to be included explicitly
252 const std::set<std::string> objPtrNames = {"Belle2::ECLWaveforms", "Belle2::PXDInjectionBGTiming", "Belle2::EventLevelTriggerTimeInfo",
253 "Belle2::TRGSummary", "Belle2::TOPInjectionVeto"
254 };
255
256 const TObjArray* branches = m_tree->GetListOfBranches();
257 if (!branches) return false;
258
259 for (int jj = 0; jj < branches->GetEntriesFast(); jj++) {
260 TBranch* branch = static_cast<TBranch*>(branches->At(jj));
261 if (!branch) continue;
262 const std::string branchName = branch->GetName();
263
264 TObject* objectPtr = 0;
265 branch->SetAddress(&objectPtr);
266 branch->GetEntry();
267 std::string objName = branch->GetClassName();
268
269 if (objName == "TClonesArray") {
270 TClass* objClass = (static_cast<TClonesArray*>(objectPtr))->GetClass();
271 branch->ResetAddress();
272 delete objectPtr;
273
274 const std::string className = objClass->GetName();
275 if (className.find("Belle2::") == std::string::npos) { // only Belle2 classes
276 m_otherBranchNames.push_back(branchName);
277 continue;
278 }
279
280 std::string name = branchName + m_extensionName;
281 bool ok = DataStore::Instance().registerEntry(name, durability, objClass,
282 true, storeFlags);
283 if (!ok) {
284 m_otherBranchNames.push_back(branchName);
285 continue;
286 }
287 DataStore::StoreEntry& entry = (map.find(name))->second;
288 m_branchNames.push_back(branchName);
289 m_storeEntries.push_back(&entry);
290 } else if (objPtrNames.find(objName) != objPtrNames.end()) {
291 std::string name = branchName;
292 if (objName == "Belle2::TRGSummary") name += m_extensionName; // to distinguish it from the one provided by simulation
293 // Determine the storeFlags for the current branch
294 auto currentStoreFlags = storeFlags;
295 if (objName == "Belle2::EventLevelTriggerTimeInfo") {
296 // Allow writing by RootOutput
297 currentStoreFlags = DataStore::c_ErrorIfAlreadyRegistered;
298 }
299 bool ok = DataStore::Instance().registerEntry(name, durability, objectPtr->IsA(),
300 false, currentStoreFlags);
301 branch->ResetAddress();
302 delete objectPtr;
303
304 if (!ok) {
305 m_otherBranchNames.push_back(branchName);
306 continue;
307 }
308 DataStore::StoreEntry& entry = (map.find(name))->second;
309 m_branchNames.push_back(branchName);
310 m_storeEntries.push_back(&entry);
311 } else {
312 m_otherBranchNames.push_back(branchName);
313 branch->ResetAddress();
314 delete objectPtr;
315 }
316
317 }
318
319 return !m_storeEntries.empty();
320}
321
322
324{
325 for (size_t i = 0; i < m_storeEntries.size(); i++) {
326 m_tree->SetBranchAddress(m_branchNames[i].c_str(), &(m_storeEntries[i]->object));
327 }
328
329 for (const auto& branchName : m_otherBranchNames) {
330 m_tree->SetBranchStatus(branchName.c_str(), 0);
331 }
332}
std::string m_BackgroundInfoInstanceName
name of BackgroundInfo branch
bool m_skipExperimentCheck
flag for skipping the check on the experiment number
std::vector< std::string > m_otherBranchNames
other branch names found in the tree
void initialize() override
Initialize the Module.
bool m_start
flag denoting first call of event function (of each run if overlay is run-dependent)
void event() override
Event processor.
void connectBranches()
Connect registered branches to the data store.
void terminate() override
Termination action.
std::vector< std::string > m_inputFileNames
list of file names
StoreObjPtr< EventMetaData > m_eventMetaData
event meta data
std::string m_extensionName
name added to default branch names
bool m_runByRun
internal flag for steering between run-independent (false) and run-dependent (true) overlay
void beginRun() override
Called when entering a new run.
bool registerBranches()
Register branches of the given event tree to the data store, except EventMetaData and all relations.
bool m_ignoreRunNumbers
flag for ignoring the run numbers in run-dependent MC
std::map< int, std::vector< std::string > > m_runFileNamesMap
Map between runs and file names.
std::vector< std::string > m_branchNames
names of registered branches
unsigned m_eventCount
current event (tree entry)
unsigned m_index
index of BackgroundDescr in BackgroundInfo object
unsigned m_firstEvent
randomly chosen first event (tree entry)
unsigned m_numEvents
number of events (tree entries) in the sample
std::vector< DataStore::StoreEntry * > m_storeEntries
store entries of registered branches
@ bg_other
Other type of background.
static constexpr std::string_view getDefaultBackgroundOverlayType()
Returns the default name for background overlay type.
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition DataStore.h:71
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition DataStore.h:72
StoreEntryMap & getStoreEntryMap(EDurability durability)
Get a reference to the object/array map.
Definition DataStore.h:325
@ c_Persistent
Object is available during entire execution time.
Definition DataStore.h:60
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition DataStore.h:59
Belle2::StoreEntry StoreEntry
Wraps a stored array/object, stored under unique (name, durability) key.
Definition DataStore.h:84
static DataStore & Instance()
Instance of singleton Store.
Definition DataStore.cc:53
bool registerEntry(const std::string &name, EDurability durability, TClass *objClass, bool array, EStoreFlags storeFlags)
Register an entry in the DataStore map.
Definition DataStore.cc:187
Metadata information about a file.
int getRunLow() const
Lowest run number getter.
unsigned int getNEvents() const
Number of events getter.
int getExperimentLow() const
Lowest experiment number getter.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
Helper class to factorize some necessary tasks when working with Belle2 output files.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool create(bool replace=false)
Create a default object in the data store.
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
Class to store variables with their name which were sent to the logging service.
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
const std::string c_treeNames[]
Names of trees.
std::vector< std::string > expandWordExpansions(const std::vector< std::string > &filenames)
Performs wildcard expansion using wordexp(), returns matches.
Abstract base class for different kinds of events.
STL namespace.
Structure for background description.