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 if (not m_skipExperimentCheck) {
97 const FileMetaData& fileMetaData = fileInfo.getFileMetaData();
98 // we assume lowest experiment/run numbers are enough
99 if (experiment != fileMetaData.getExperimentLow()) {
100 B2FATAL("The BG sample used is aimed for a different experiment number. Please check what you are doing."
101 << LogVar("File name", fileName)
102 << LogVar("Experiment number of the basf2 process", experiment)
103 << LogVar("Experiment number of the BG file", fileMetaData.getExperimentLow()));
104 }
105 if (not m_ignoreRunNumbers) {
106 m_runFileNamesMap[fileMetaData.getRunLow()].push_back(fileName);
107 }
108 }
109 } catch (const std::invalid_argument& e) {
110 B2FATAL("One of the BG files can not be opened."
111 << LogVar("File name", fileName));
112 } catch (const std::runtime_error& e) {
113 B2FATAL("Something went wrong with one of the BG files."
114 << LogVar("File name", fileName)
115 << LogVar("Issue", e.what()));
116 }
117 }
118
119 // make a chain including all overlay files; get number of entries
121 for (const string& fileName : m_inputFileNames) {
122 m_tree->AddFile(fileName.c_str());
123 }
124 m_numEvents = m_tree->GetEntries();
125 if (m_numEvents == 0) B2ERROR(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entries");
126
127 // register selected branches to DataStore
128 bool ok = registerBranches();
129 if (!ok) {
130 B2ERROR("No branches found to be registered and connected");
131 }
132
133 // add BackgroundInfo to persistent tree
135 bkgInfo.registerInDataStore();
136 bkgInfo.create();
137 bkgInfo->setMethod(BackgroundInfo::c_Overlay);
138 bkgInfo->setExtensionName(m_extensionName);
139
140 // set flag for steering between run-independent (false) and run-dependent (true) overlay
141 m_runByRun = experiment > 0 and experiment < 1000 and not m_runFileNamesMap.empty();
142 if (m_runByRun) return;
143
144 // run-independent overlay: choose randomly the first event and connect branches
145 m_firstEvent = gRandom->Integer(m_numEvents);
146 B2INFO("BGOverlayInput: run-independent overlay starting with event " << m_firstEvent << " of " << m_numEvents);
148 m_start = true;
150
151 // add description to BackgroundInfo
154 descr.type = std::string(BackgroundMetaData::getDefaultBackgroundOverlayType());
155 descr.fileNames = m_inputFileNames;
156 descr.numEvents = m_numEvents;
157 m_index = bkgInfo->appendBackgroundDescr(descr);
158}
159
160
162{
163 if (not m_runByRun) return;
164
165 // run-dependent overlay: delete the old one and make new chain with overlay files for the current run; get number of entries
166 if (m_tree) delete m_tree;
168 int run = m_eventMetaData->getRun();
169 std::vector<std::string> inputFileNames;
170 for (const string& fileName : m_runFileNamesMap[run]) {
171 auto status = m_tree->AddFile(fileName.c_str());
172 if (status > 0) inputFileNames.push_back(fileName);
173 }
174 if (inputFileNames.empty()) B2FATAL("No overlay files for run " << run);
175
176 m_numEvents = m_tree->GetEntries();
177 if (m_numEvents == 0) B2FATAL(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entries for run " << run);
178
179 // choose randomly the first event and connect branches
180 m_firstEvent = gRandom->Integer(m_numEvents);
181 B2INFO("BGOverlayInput: run " << run << " starting with event " << m_firstEvent << " of " << m_numEvents);
183 m_start = true;
185
186 // add description for this run to BackgroundInfo
189 descr.type = std::string(BackgroundMetaData::getDefaultBackgroundOverlayType());
190 descr.fileNames = inputFileNames;
191 descr.numEvents = m_numEvents;
192 descr.runNumber = run;
194 m_index = bkgInfo->appendBackgroundDescr(descr);
195}
196
197
199{
201
202 for (auto entry : m_storeEntries) {
203 entry->resetForGetEntry();
204 }
205
206 if (m_eventCount == m_firstEvent and !m_start) {
207 B2INFO("BGOverlayInput: events for BG overlay will be reused");
208 bkgInfo->incrementReusedCounter(m_index);
209 }
210 m_start = false;
211
212 m_tree->GetEntry(m_eventCount);
213 m_eventCount++;
214 if (m_eventCount >= m_numEvents) {
215 m_eventCount = 0;
216 }
217
218 for (auto entry : m_storeEntries) {
219 if (entry->object) {
220 entry->ptr = entry->object;
221 } else {
222 entry->recoverFromNullObject();
223 entry->ptr = 0;
224 }
225 }
226
227}
228
229
231{
232
233 if (m_tree) delete m_tree;
234
235}
236
237
239{
240
241 auto durability = DataStore::c_Event;
243 auto& map = DataStore::Instance().getStoreEntryMap(durability);
244
245 // StoreObjPointers have to be included explicitly
246 const std::set<std::string> objPtrNames = {"Belle2::ECLWaveforms", "Belle2::PXDInjectionBGTiming", "Belle2::EventLevelTriggerTimeInfo",
247 "Belle2::TRGSummary", "Belle2::TOPInjectionVeto"
248 };
249
250 const TObjArray* branches = m_tree->GetListOfBranches();
251 if (!branches) return false;
252
253 for (int jj = 0; jj < branches->GetEntriesFast(); jj++) {
254 TBranch* branch = static_cast<TBranch*>(branches->At(jj));
255 if (!branch) continue;
256 const std::string branchName = branch->GetName();
257
258 TObject* objectPtr = 0;
259 branch->SetAddress(&objectPtr);
260 branch->GetEntry();
261 std::string objName = branch->GetClassName();
262
263 if (objName == "TClonesArray") {
264 TClass* objClass = (static_cast<TClonesArray*>(objectPtr))->GetClass();
265 branch->ResetAddress();
266 delete objectPtr;
267
268 const std::string className = objClass->GetName();
269 if (className.find("Belle2::") == std::string::npos) { // only Belle2 classes
270 m_otherBranchNames.push_back(branchName);
271 continue;
272 }
273
274 std::string name = branchName + m_extensionName;
275 bool ok = DataStore::Instance().registerEntry(name, durability, objClass,
276 true, storeFlags);
277 if (!ok) {
278 m_otherBranchNames.push_back(branchName);
279 continue;
280 }
281 DataStore::StoreEntry& entry = (map.find(name))->second;
282 m_branchNames.push_back(branchName);
283 m_storeEntries.push_back(&entry);
284 } else if (objPtrNames.find(objName) != objPtrNames.end()) {
285 std::string name = branchName;
286 if (objName == "Belle2::TRGSummary") name += m_extensionName; // to distinguish it from the one provided by simulation
287 // Determine the storeFlags for the current branch
288 auto currentStoreFlags = storeFlags;
289 if (objName == "Belle2::EventLevelTriggerTimeInfo") {
290 // Allow writing by RootOutput
291 currentStoreFlags = DataStore::c_ErrorIfAlreadyRegistered;
292 }
293 bool ok = DataStore::Instance().registerEntry(name, durability, objectPtr->IsA(),
294 false, currentStoreFlags);
295 branch->ResetAddress();
296 delete objectPtr;
297
298 if (!ok) {
299 m_otherBranchNames.push_back(branchName);
300 continue;
301 }
302 DataStore::StoreEntry& entry = (map.find(name))->second;
303 m_branchNames.push_back(branchName);
304 m_storeEntries.push_back(&entry);
305 } else {
306 m_otherBranchNames.push_back(branchName);
307 branch->ResetAddress();
308 delete objectPtr;
309 }
310
311 }
312
313 return !m_storeEntries.empty();
314}
315
316
318{
319 for (size_t i = 0; i < m_storeEntries.size(); i++) {
320 m_tree->SetBranchAddress(m_branchNames[i].c_str(), &(m_storeEntries[i]->object));
321 }
322
323 for (const auto& branchName : m_otherBranchNames) {
324 m_tree->SetBranchStatus(branchName.c_str(), 0);
325 }
326}
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:189
Metadata information about a file.
int getRunLow() const
Lowest run number 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.