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 <TFile.h>
23#include <TRandom.h>
24
25/* C++ headers. */
26#include <set>
27
28using namespace std;
29using namespace Belle2;
30
31//-----------------------------------------------------------------
32// Register module
33//-----------------------------------------------------------------
34
35REG_MODULE(BGOverlayInput);
36
37//-----------------------------------------------------------------
38// Implementation
39//-----------------------------------------------------------------
40
42
43{
44 // module description
45 setDescription("Input for BG overlay, either in form of Digits or raw data. For run-dependent MC (experiments 1 to 999) "
46 "the overlay samples corresponding to the simulated run are automatically selected from the input list "
47 "at each beginRun(), enabling production of multiple runs in a single job. "
48 "This feature can be turned off by setting ignoreRunNumbers to True.");
49
50 // Add parameters
51 addParam("inputFileNames", m_inputFileNames,
52 "List of files with measured beam background ");
53 addParam("extensionName", m_extensionName,
54 "Name added to default branch names", string("_beamBG"));
55 addParam("bkgInfoName", m_BackgroundInfoInstanceName, "Name of the BackgroundInfo StoreObjPtr", string(""));
56 addParam("skipExperimentCheck", m_skipExperimentCheck,
57 "If True, skip the check on the experiment number consistency between the basf2 process and the beam background files; "
58 "for experiments 1 to 999 ignore also run numbers. "
59 "By default, it is set to false, since the check should be skipped only by experts.",
60 false);
61 addParam("ignoreRunNumbers", m_ignoreRunNumbers,
62 "If True, ignore run numbers in case of run-dependend MC (experiments 1 to 999).",
63 false);
64}
65
67{
68}
69
71{
73 B2WARNING(R"RAW(The BGOverlayInput module will skip the check on the experiment number
74 consistency between the basf2 process and the beam background files.
75 It will also ingnore run numbers in case of run-dependent MC.
76
77 This should be done only if you are extremely sure about what you are doing.
78
79 Be aware that you are not protected by the possible usage of beam background
80 files not suitabile for the experiment number you selected.)RAW");
81 }
82
83 // expand possible wildcards
85 if (m_inputFileNames.empty()) {
86 B2FATAL("No valid files specified!");
87 }
88
89 // get the experiment number from the EventMetaData
90 int experiment = m_eventMetaData->getExperiment();
91
92 // check files
93 for (const string& fileName : m_inputFileNames) {
94 try {
95 RootIOUtilities::RootFileInfo fileInfo{fileName};
96 const std::set<std::string>& branchNames = fileInfo.getBranchNames(true);
97 if (branchNames.count("BackgroundMetaData")) {
98 B2FATAL("The BG sample used is aimed for BG mixing, not for BG overlay."
99 << LogVar("File name", fileName));
100 }
101 if (not m_skipExperimentCheck) {
102 const FileMetaData& fileMetaData = fileInfo.getFileMetaData();
103 // we assume lowest experiment/run numbers are enough
104 if (experiment != fileMetaData.getExperimentLow()) {
105 B2FATAL("The BG sample used is aimed for a different experiment number. Please check what you are doing."
106 << LogVar("File name", fileName)
107 << LogVar("Experiment number of the basf2 process", experiment)
108 << LogVar("Experiment number of the BG file", fileMetaData.getExperimentLow()));
109 }
110 if (not m_ignoreRunNumbers) {
111 m_runFileNamesMap[fileMetaData.getRunLow()].push_back(fileName);
112 }
113 }
114 } catch (const std::invalid_argument& e) {
115 B2FATAL("One of the BG files can not be opened."
116 << LogVar("File name", fileName));
117 } catch (const std::runtime_error& e) {
118 B2FATAL("Something went wrong with one of the BG files."
119 << LogVar("File name", fileName)
120 << LogVar("Issue", e.what()));
121 }
122 }
123
124 // make a chain including all overlay files; get number of entries
126 for (const string& fileName : m_inputFileNames) {
127 m_tree->AddFile(fileName.c_str());
128 }
129 m_numEvents = m_tree->GetEntries();
130 if (m_numEvents == 0) B2ERROR(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entries");
131
132 // register selected branches to DataStore
133 bool ok = registerBranches();
134 if (!ok) {
135 B2ERROR("No branches found to be registered and connected");
136 }
137
138 // add BackgroundInfo to persistent tree
140 bkgInfo.registerInDataStore();
141 bkgInfo.create();
142 bkgInfo->setMethod(BackgroundInfo::c_Overlay);
143 bkgInfo->setExtensionName(m_extensionName);
144
145 // set flag for steering between run-independent (false) and run-dependent (true) overlay
146 m_runByRun = experiment > 0 and experiment < 1000 and not m_runFileNamesMap.empty();
147 if (m_runByRun) return;
148
149 // run-independent overlay: choose randomly the first event and connect branches
150 m_firstEvent = gRandom->Integer(m_numEvents);
151 B2INFO("BGOverlayInput: run-independent overlay starting with event " << m_firstEvent << " of " << m_numEvents);
153 m_start = true;
155
156 // add description to BackgroundInfo
159 descr.type = std::string(BackgroundMetaData::getDefaultBackgroundOverlayType());
160 descr.fileNames = m_inputFileNames;
161 descr.numEvents = m_numEvents;
162 m_index = bkgInfo->appendBackgroundDescr(descr);
163}
164
165
167{
168 if (not m_runByRun) return;
169
170 // run-dependent overlay: delete the old one and make new chain with overlay files for the current run; get number of entries
171 if (m_tree) delete m_tree;
173 int run = m_eventMetaData->getRun();
174 std::vector<std::string> inputFileNames;
175 for (const string& fileName : m_runFileNamesMap[run]) {
176 auto status = m_tree->AddFile(fileName.c_str());
177 if (status > 0) inputFileNames.push_back(fileName);
178 }
179 if (inputFileNames.empty()) B2FATAL("No overlay files for run " << run);
180
181 m_numEvents = m_tree->GetEntries();
182 if (m_numEvents == 0) B2FATAL(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entries for run " << run);
183
184 // choose randomly the first event and connect branches
185 m_firstEvent = gRandom->Integer(m_numEvents);
186 B2INFO("BGOverlayInput: run " << run << " starting with event " << m_firstEvent << " of " << m_numEvents);
188 m_start = true;
190
191 // add description for this run to BackgroundInfo
194 descr.type = std::string(BackgroundMetaData::getDefaultBackgroundOverlayType());
195 descr.fileNames = inputFileNames;
196 descr.numEvents = m_numEvents;
197 descr.runNumber = run;
199 m_index = bkgInfo->appendBackgroundDescr(descr);
200}
201
202
204{
206
207 for (auto entry : m_storeEntries) {
208 entry->resetForGetEntry();
209 }
210
211 if (m_eventCount == m_firstEvent and !m_start) {
212 B2INFO("BGOverlayInput: events for BG overlay will be re-used");
213 bkgInfo->incrementReusedCounter(m_index);
214 }
215 m_start = false;
216
217 m_tree->GetEntry(m_eventCount);
218 m_eventCount++;
219 if (m_eventCount >= m_numEvents) {
220 m_eventCount = 0;
221 }
222
223 for (auto entry : m_storeEntries) {
224 if (entry->object) {
225 entry->ptr = entry->object;
226 } else {
227 entry->recoverFromNullObject();
228 entry->ptr = 0;
229 }
230 }
231
232}
233
234
236{
237}
238
240{
241
242 if (m_tree) delete m_tree;
243
244}
245
246
248{
249
250 auto durability = DataStore::c_Event;
252 auto& map = DataStore::Instance().getStoreEntryMap(durability);
253
254 // StoreObjPointers have to be included explicitly
255 const std::set<std::string> objPtrNames = {"Belle2::ECLWaveforms", "Belle2::PXDInjectionBGTiming", "Belle2::EventLevelTriggerTimeInfo",
256 "Belle2::TRGSummary"
257 };
258
259 const TObjArray* branches = m_tree->GetListOfBranches();
260 if (!branches) return false;
261
262 for (int jj = 0; jj < branches->GetEntriesFast(); jj++) {
263 TBranch* branch = static_cast<TBranch*>(branches->At(jj));
264 if (!branch) continue;
265 const std::string branchName = branch->GetName();
266
267 TObject* objectPtr = 0;
268 branch->SetAddress(&objectPtr);
269 branch->GetEntry();
270 std::string objName = branch->GetClassName();
271
272 if (objName == "TClonesArray") {
273 TClass* objClass = (static_cast<TClonesArray*>(objectPtr))->GetClass();
274 branch->ResetAddress();
275 delete objectPtr;
276
277 const std::string className = objClass->GetName();
278 if (className.find("Belle2::") == std::string::npos) { // only Belle2 classes
279 m_otherBranchNames.push_back(branchName);
280 continue;
281 }
282
283 std::string name = branchName + m_extensionName;
284 bool ok = DataStore::Instance().registerEntry(name, durability, objClass,
285 true, storeFlags);
286 if (!ok) {
287 m_otherBranchNames.push_back(branchName);
288 continue;
289 }
290 DataStore::StoreEntry& entry = (map.find(name))->second;
291 m_branchNames.push_back(branchName);
292 m_storeEntries.push_back(&entry);
293 } else if (objPtrNames.find(objName) != objPtrNames.end()) {
294 std::string name = branchName;
295 if (objName == "Belle2::TRGSummary") name += m_extensionName; // to distinguish it from the one provided by simulation
296 bool ok = DataStore::Instance().registerEntry(name, durability, objectPtr->IsA(),
297 false, storeFlags);
298 branch->ResetAddress();
299 delete objectPtr;
300
301 if (!ok) {
302 m_otherBranchNames.push_back(branchName);
303 continue;
304 }
305 DataStore::StoreEntry& entry = (map.find(name))->second;
306 m_branchNames.push_back(branchName);
307 m_storeEntries.push_back(&entry);
308 } else {
309 m_otherBranchNames.push_back(branchName);
310 branch->ResetAddress();
311 delete objectPtr;
312 }
313
314 }
315
316 return !m_storeEntries.empty();
317}
318
319
321{
322 for (size_t i = 0; i < m_storeEntries.size(); i++) {
323 m_tree->SetBranchAddress(m_branchNames[i].c_str(), &(m_storeEntries[i]->object));
324 }
325
326 for (const auto& branchName : m_otherBranchNames) {
327 m_tree->SetBranchStatus(branchName.c_str(), 0);
328 }
329}
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 endRun() override
End-of-run action.
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 choosen 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
static DataStore & Instance()
Instance of singleton Store.
Definition: DataStore.cc:54
bool registerEntry(const std::string &name, EDurability durability, TClass *objClass, bool array, EStoreFlags storeFlags)
Register an entry in the DataStore map.
Definition: DataStore.cc:190
Metadata information about a file.
Definition: FileMetaData.h:29
int getRunLow() const
Lowest run number getter.
Definition: FileMetaData.h:53
int getExperimentLow() const
Lowest experiment number getter.
Definition: FileMetaData.h:49
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Helper class to factorize some necessary tasks when working with Belle2 output files.
Definition: RootFileInfo.h:27
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
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.
Wraps a stored array/object, stored under unique (name, durability) key.
Definition: StoreEntry.h:22