Belle II Software  release-06-01-15
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 include. */
10 #include <background/modules/BGOverlayInput/BGOverlayInputModule.h>
11 
12 /* Belle 2 headers. */
13 #include <framework/dataobjects/BackgroundInfo.h>
14 #include <framework/dataobjects/EventMetaData.h>
15 #include <framework/dataobjects/FileMetaData.h>
16 #include <framework/datastore/DataStore.h>
17 #include <framework/datastore/StoreObjPtr.h>
18 #include <framework/io/RootFileInfo.h>
19 #include <framework/io/RootIOUtilities.h>
20 #include <framework/logging/Logger.h>
21 
22 /* ROOT headers. */
23 #include <TClonesArray.h>
24 #include <TFile.h>
25 #include <TRandom.h>
26 
27 /* C++ headers. */
28 #include <set>
29 
30 using namespace std;
31 using namespace Belle2;
32 
33 //-----------------------------------------------------------------
34 // Register module
35 //-----------------------------------------------------------------
36 
37 REG_MODULE(BGOverlayInput)
38 
39 //-----------------------------------------------------------------
40 // Implementation
41 //-----------------------------------------------------------------
42 
44 
45 {
46  // module description
47  setDescription("Input for BG overlay, either in form of Digits or raw data.");
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. By default, it is set to false, since the check should be skipped only by experts.",
57  false);
58 }
59 
60 BGOverlayInputModule::~BGOverlayInputModule()
61 {
62 }
63 
64 void BGOverlayInputModule::initialize()
65 {
66  if (m_skipExperimentCheck)
67  B2WARNING(R"RAW(The BGOverlayInput module will skip the check on the experiment number
68  consistency between the basf2 process and the beam background files.
69 
70  This should be done only if you are extremely sure about what you are doing.
71 
72  Be aware that you are not protected by the possible usage of beam background
73  files not suitabile for the experiment number you selected.)RAW");
74 
75  // expand possible wildcards
76  m_inputFileNames = RootIOUtilities::expandWordExpansions(m_inputFileNames);
77  if (m_inputFileNames.empty()) {
78  B2FATAL("No valid files specified!");
79  }
80 
81  // get the experiment number from the EventMetaData
82  StoreObjPtr<EventMetaData> eventMetaData;
83  int experiment{eventMetaData->getExperiment()};
84 
85  // check files
86  for (const string& fileName : m_inputFileNames) {
87  try {
88  RootIOUtilities::RootFileInfo fileInfo{fileName};
89  const std::set<std::string>& branchNames = fileInfo.getBranchNames(true);
90  if (branchNames.count("BackgroundMetaData"))
91  B2FATAL("The BG sample used is aimed for BG mixing, not for BG mixing."
92  << LogVar("File name", fileName));
93  if (not m_skipExperimentCheck) {
94  const FileMetaData& fileMetaData = fileInfo.getFileMetaData();
95  // we assume lowest experiment number is enough
96  if (experiment != fileMetaData.getExperimentLow())
97  B2FATAL("The BG sample used is aimed for a different experiment number. Please check what you are doing."
98  << LogVar("File name", fileName)
99  << LogVar("Experiment number of the basf2 process", experiment)
100  << LogVar("Experiment number of the BG file", fileMetaData.getExperimentLow()));
101  }
102  } catch (const std::invalid_argument& e) {
103  B2FATAL("One of the BG files can not be opened."
104  << LogVar("File name", fileName));
105  } catch (const std::runtime_error& e) {
106  B2FATAL("Something went wrong with one of the BG files."
107  << LogVar("File name", fileName)
108  << LogVar("Issue", e.what()));
109  }
110  }
111 
112  // get event TTree
113  m_tree = new TChain(RootIOUtilities::c_treeNames[DataStore::c_Event].c_str());
114  for (const string& fileName : m_inputFileNames) {
115  m_tree->AddFile(fileName.c_str());
116  }
117  m_numEvents = m_tree->GetEntries();
118  if (m_numEvents == 0) B2ERROR(RootIOUtilities::c_treeNames[DataStore::c_Event] << " has no entires");
119  m_firstEvent = gRandom->Integer(m_numEvents);
120  B2INFO("BGOverlayInput: starting with event " << m_firstEvent);
121  m_eventCount = m_firstEvent;
122 
123  // connect selected branches to DataStore
124  bool ok = connectBranches();
125  if (!ok) {
126  B2ERROR("No branches found to be connected");
127  }
128 
129  // add BackgroundInfo to persistent tree
130  StoreObjPtr<BackgroundInfo> bkgInfo(m_BackgroundInfoInstanceName, DataStore::c_Persistent);
131  bkgInfo.registerInDataStore();
132  bkgInfo.create();
133  bkgInfo->setMethod(BackgroundInfo::c_Overlay);
135  descr.tag = BackgroundMetaData::bg_other;
136  descr.type = string("RandomTrigger");
137  descr.fileNames = m_inputFileNames;
138  descr.numEvents = m_numEvents;
139  m_index = bkgInfo->appendBackgroundDescr(descr);
140  bkgInfo->setExtensionName(m_extensionName);
141 }
142 
143 
144 void BGOverlayInputModule::beginRun()
145 {
146 }
147 
148 
149 void BGOverlayInputModule::event()
150 {
151  StoreObjPtr<BackgroundInfo> bkgInfo("", DataStore::c_Persistent);
152 
153  for (auto entry : m_storeEntries) {
154  entry->resetForGetEntry();
155  }
156 
157  if (m_eventCount == m_firstEvent and !m_start) {
158  B2INFO("BGOverlayInput: events for BG overlay will be re-used");
159  bkgInfo->incrementReusedCounter(m_index);
160  }
161  m_start = false;
162 
163  m_tree->GetEntry(m_eventCount);
164  m_eventCount++;
165  if (m_eventCount >= m_numEvents) {
166  m_eventCount = 0;
167  }
168 
169  for (auto entry : m_storeEntries) {
170  if (entry->object) {
171  entry->ptr = entry->object;
172  } else {
173  entry->recoverFromNullObject();
174  entry->ptr = 0;
175  }
176  }
177 
178 }
179 
180 
181 void BGOverlayInputModule::endRun()
182 {
183 }
184 
185 void BGOverlayInputModule::terminate()
186 {
187 
188  delete m_tree;
189 
190 }
191 
192 
193 bool BGOverlayInputModule::connectBranches()
194 {
195 
196  auto durability = DataStore::c_Event;
197  auto storeFlags = DataStore::c_DontWriteOut | DataStore::c_ErrorIfAlreadyRegistered;
198  auto& map = DataStore::Instance().getStoreEntryMap(durability);
199 
200  // StoreObjPointers have to be included explicitly
201  const std::set<std::string> objPtrNames = {"Belle2::ECLWaveforms", "Belle2::PXDInjectionBGTiming", "Belle2::EventLevelTriggerTimeInfo"};
202 
203  const TObjArray* branches = m_tree->GetListOfBranches();
204  if (!branches) return false;
205 
206  for (int jj = 0; jj < branches->GetEntriesFast(); jj++) {
207  TBranch* branch = static_cast<TBranch*>(branches->At(jj));
208  if (!branch) continue;
209  const std::string branchName = branch->GetName();
210 
211  TObject* objectPtr = 0;
212  branch->SetAddress(&objectPtr);
213  branch->GetEntry();
214  std::string objName = branch->GetClassName();
215 
216  if (objName == "TClonesArray") {
217  TClass* objClass = (static_cast<TClonesArray*>(objectPtr))->GetClass();
218  branch->ResetAddress();
219  delete objectPtr;
220 
221  const std::string className = objClass->GetName();
222  if (className.find("Belle2::") == std::string::npos) { // only Belle2 classes
223  m_tree->SetBranchStatus(branchName.c_str(), 0);
224  continue;
225  }
226 
227  std::string name = branchName + m_extensionName;
228  bool ok = DataStore::Instance().registerEntry(name, durability, objClass,
229  true, storeFlags);
230  if (!ok) {
231  m_tree->SetBranchStatus(branchName.c_str(), 0);
232  continue;
233  }
234  DataStore::StoreEntry& entry = (map.find(name))->second;
235  m_tree->SetBranchAddress(branchName.c_str(), &(entry.object));
236  m_storeEntries.push_back(&entry);
237  } else if (objPtrNames.find(objName) != objPtrNames.end()) {
238  std::string name = branchName;// + m_extensionName;
239  bool ok = DataStore::Instance().registerEntry(name, durability, objectPtr->IsA(),
240  false, storeFlags);
241  branch->ResetAddress();
242  delete objectPtr;
243 
244  if (!ok) {
245  m_tree->SetBranchStatus(branchName.c_str(), 0);
246  continue;
247  }
248  DataStore::StoreEntry& entry = (map.find(name))->second;
249  m_tree->SetBranchAddress(branchName.c_str(), &(entry.object));
250  m_storeEntries.push_back(&entry);
251 
252  } else {
253  m_tree->SetBranchStatus(branchName.c_str(), 0);
254  branch->ResetAddress();
255  delete objectPtr;
256  }
257 
258  }
259 
260  return !m_storeEntries.empty();
261 }
262 
Beam BG data input, either in form of Digits or raw data.
Metadata information about a file.
Definition: FileMetaData.h:29
int getExperimentLow() const
Lowest experiment number getter.
Definition: FileMetaData.h:45
Base class for Modules.
Definition: Module.h:72
Helper class to factorize some necessary tasks when working with Belle2 output files.
Definition: RootFileInfo.h:26
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.
#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.
Structure for background description.
Wraps a stored array/object, stored under unique (name, durability) key.
Definition: StoreEntry.h:22
TObject * object
The pointer to the actual object.
Definition: StoreEntry.h:48