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{
67}
68
70{
72 B2WARNING(R"RAW(The BGOverlayInput module will skip the check on the experiment number
73 consistency between the basf2 process and the beam background files.
74 It will also ignore run numbers in case of run-dependent MC.
75
76 This should be done only if you are extremely sure about what you are doing.
77
78 Be aware that you are not protected by the possible usage of beam background
79 files not suitabile for the experiment number you selected.)RAW");
80 }
81
82 // expand possible wildcards
84 if (m_inputFileNames.empty()) {
85 B2FATAL("No valid files specified!");
86 }
87
88 // get the experiment number from the EventMetaData
89 int experiment = m_eventMetaData->getExperiment();
90
91 // check files
92 for (const string& fileName : m_inputFileNames) {
93 try {
94 RootIOUtilities::RootFileInfo fileInfo{fileName};
95 const std::set<std::string>& branchNames = fileInfo.getBranchNames(true);
96 if (branchNames.count("BackgroundMetaData")) {
97 B2FATAL("The BG sample used is aimed for BG mixing, not for BG overlay."
98 << LogVar("File name", fileName));
99 }
100 if (not m_skipExperimentCheck) {
101 const FileMetaData& fileMetaData = fileInfo.getFileMetaData();
102 // we assume lowest experiment/run numbers are enough
103 if (experiment != fileMetaData.getExperimentLow()) {
104 B2FATAL("The BG sample used is aimed for a different experiment number. Please check what you are doing."
105 << LogVar("File name", fileName)
106 << LogVar("Experiment number of the basf2 process", experiment)
107 << LogVar("Experiment number of the BG file", fileMetaData.getExperimentLow()));
108 }
109 if (not m_ignoreRunNumbers) {
110 m_runFileNamesMap[fileMetaData.getRunLow()].push_back(fileName);
111 }
112 }
113 } catch (const std::invalid_argument& e) {
114 B2FATAL("One of the BG files can not be opened."
115 << LogVar("File name", fileName));
116 } catch (const std::runtime_error& e) {
117 B2FATAL("Something went wrong with one of the BG files."
118 << LogVar("File name", fileName)
119 << LogVar("Issue", e.what()));
120 }
121 }
122
123 // make a chain including all overlay files; get number of entries
125 for (const string& fileName : m_inputFileNames) {
126 m_tree->AddFile(fileName.c_str());
127 }
128 m_numEvents = m_tree->GetEntries();
129 if (m_numEvents == 0) B2ERROR(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entries");
130
131 // register selected branches to DataStore
132 bool ok = registerBranches();
133 if (!ok) {
134 B2ERROR("No branches found to be registered and connected");
135 }
136
137 // add BackgroundInfo to persistent tree
139 bkgInfo.registerInDataStore();
140 bkgInfo.create();
141 bkgInfo->setMethod(BackgroundInfo::c_Overlay);
142 bkgInfo->setExtensionName(m_extensionName);
143
144 // set flag for steering between run-independent (false) and run-dependent (true) overlay
145 m_runByRun = experiment > 0 and experiment < 1000 and not m_runFileNamesMap.empty();
146 if (m_runByRun) return;
147
148 // run-independent overlay: choose randomly the first event and connect branches
149 m_firstEvent = gRandom->Integer(m_numEvents);
150 B2INFO("BGOverlayInput: run-independent overlay starting with event " << m_firstEvent << " of " << m_numEvents);
152 m_start = true;
154
155 // add description to BackgroundInfo
158 descr.type = std::string(BackgroundMetaData::getDefaultBackgroundOverlayType());
159 descr.fileNames = m_inputFileNames;
160 descr.numEvents = m_numEvents;
161 m_index = bkgInfo->appendBackgroundDescr(descr);
162}
163
164
166{
167 if (not m_runByRun) return;
168
169 // run-dependent overlay: delete the old one and make new chain with overlay files for the current run; get number of entries
170 if (m_tree) delete m_tree;
172 int run = m_eventMetaData->getRun();
173 std::vector<std::string> inputFileNames;
174 for (const string& fileName : m_runFileNamesMap[run]) {
175 auto status = m_tree->AddFile(fileName.c_str());
176 if (status > 0) inputFileNames.push_back(fileName);
177 }
178 if (inputFileNames.empty()) B2FATAL("No overlay files for run " << run);
179
180 m_numEvents = m_tree->GetEntries();
181 if (m_numEvents == 0) B2FATAL(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entries for run " << run);
182
183 // choose randomly the first event and connect branches
184 m_firstEvent = gRandom->Integer(m_numEvents);
185 B2INFO("BGOverlayInput: run " << run << " starting with event " << m_firstEvent << " of " << m_numEvents);
187 m_start = true;
189
190 // add description for this run to BackgroundInfo
193 descr.type = std::string(BackgroundMetaData::getDefaultBackgroundOverlayType());
194 descr.fileNames = inputFileNames;
195 descr.numEvents = m_numEvents;
196 descr.runNumber = run;
198 m_index = bkgInfo->appendBackgroundDescr(descr);
199}
200
201
203{
205
206 for (auto entry : m_storeEntries) {
207 entry->resetForGetEntry();
208 }
209
210 if (m_eventCount == m_firstEvent and !m_start) {
211 B2INFO("BGOverlayInput: events for BG overlay will be reused");
212 bkgInfo->incrementReusedCounter(m_index);
213 }
214 m_start = false;
215
216 m_tree->GetEntry(m_eventCount);
217 m_eventCount++;
218 if (m_eventCount >= m_numEvents) {
219 m_eventCount = 0;
220 }
221
222 for (auto entry : m_storeEntries) {
223 if (entry->object) {
224 entry->ptr = entry->object;
225 } else {
226 entry->recoverFromNullObject();
227 entry->ptr = 0;
228 }
229 }
230
231}
232
233
235{
236}
237
239{
240
241 if (m_tree) delete m_tree;
242
243}
244
245
247{
248
249 auto durability = DataStore::c_Event;
251 auto& map = DataStore::Instance().getStoreEntryMap(durability);
252
253 // StoreObjPointers have to be included explicitly
254 const std::set<std::string> objPtrNames = {"Belle2::ECLWaveforms", "Belle2::PXDInjectionBGTiming", "Belle2::EventLevelTriggerTimeInfo",
255 "Belle2::TRGSummary"
256 };
257
258 const TObjArray* branches = m_tree->GetListOfBranches();
259 if (!branches) return false;
260
261 for (int jj = 0; jj < branches->GetEntriesFast(); jj++) {
262 TBranch* branch = static_cast<TBranch*>(branches->At(jj));
263 if (!branch) continue;
264 const std::string branchName = branch->GetName();
265
266 TObject* objectPtr = 0;
267 branch->SetAddress(&objectPtr);
268 branch->GetEntry();
269 std::string objName = branch->GetClassName();
270
271 if (objName == "TClonesArray") {
272 TClass* objClass = (static_cast<TClonesArray*>(objectPtr))->GetClass();
273 branch->ResetAddress();
274 delete objectPtr;
275
276 const std::string className = objClass->GetName();
277 if (className.find("Belle2::") == std::string::npos) { // only Belle2 classes
278 m_otherBranchNames.push_back(branchName);
279 continue;
280 }
281
282 std::string name = branchName + m_extensionName;
283 bool ok = DataStore::Instance().registerEntry(name, durability, objClass,
284 true, storeFlags);
285 if (!ok) {
286 m_otherBranchNames.push_back(branchName);
287 continue;
288 }
289 DataStore::StoreEntry& entry = (map.find(name))->second;
290 m_branchNames.push_back(branchName);
291 m_storeEntries.push_back(&entry);
292 } else if (objPtrNames.find(objName) != objPtrNames.end()) {
293 std::string name = branchName;
294 if (objName == "Belle2::TRGSummary") name += m_extensionName; // to distinguish it from the one provided by simulation
295 bool ok = DataStore::Instance().registerEntry(name, durability, objectPtr->IsA(),
296 false, storeFlags);
297 branch->ResetAddress();
298 delete objectPtr;
299
300 if (!ok) {
301 m_otherBranchNames.push_back(branchName);
302 continue;
303 }
304 DataStore::StoreEntry& entry = (map.find(name))->second;
305 m_branchNames.push_back(branchName);
306 m_storeEntries.push_back(&entry);
307 } else {
308 m_otherBranchNames.push_back(branchName);
309 branch->ResetAddress();
310 delete objectPtr;
311 }
312
313 }
314
315 return !m_storeEntries.empty();
316}
317
318
320{
321 for (size_t i = 0; i < m_storeEntries.size(); i++) {
322 m_tree->SetBranchAddress(m_branchNames[i].c_str(), &(m_storeEntries[i]->object));
323 }
324
325 for (const auto& branchName : m_otherBranchNames) {
326 m_tree->SetBranchStatus(branchName.c_str(), 0);
327 }
328}
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 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
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.
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:95
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.
Wraps a stored array/object, stored under unique (name, durability) key.
Definition: StoreEntry.h:22