Belle II Software  release-05-02-19
BeamBkgHitRateMonitorModule.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2019 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Marko Staric *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 // Own include
12 #include <background/modules/BeamBkgHitRateMonitor/BeamBkgHitRateMonitorModule.h>
13 #include <background/modules/BeamBkgHitRateMonitor/PXDHitRateCounter.h>
14 #include <background/modules/BeamBkgHitRateMonitor/SVDHitRateCounter.h>
15 #include <background/modules/BeamBkgHitRateMonitor/CDCHitRateCounter.h>
16 #include <background/modules/BeamBkgHitRateMonitor/TOPHitRateCounter.h>
17 #include <background/modules/BeamBkgHitRateMonitor/ARICHHitRateCounter.h>
18 #include <background/modules/BeamBkgHitRateMonitor/ECLHitRateCounter.h>
19 #include <background/modules/BeamBkgHitRateMonitor/KLMHitRateCounter.h>
20 
21 // framework aux
22 #include <framework/logging/Logger.h>
23 
24 #include <framework/io/RootIOUtilities.h>
25 #include <framework/core/RandomNumbers.h>
26 #include <framework/core/Environment.h>
27 #include <framework/core/ModuleParam.templateDetails.h>
28 #include <framework/database/Database.h>
29 #include <framework/utilities/EnvironmentVariables.h>
30 
31 #include <boost/python.hpp>
32 #include <boost/optional.hpp>
33 #include <boost/filesystem/path.hpp>
34 #include <boost/filesystem/operations.hpp>
35 #include <boost/algorithm/string.hpp>
36 
37 using namespace std;
38 
39 namespace Belle2 {
45  //-----------------------------------------------------------------
46  // Register module
47  //-----------------------------------------------------------------
48 
49  REG_MODULE(BeamBkgHitRateMonitor)
50 
51  //-----------------------------------------------------------------
52  // Implementation
53  //-----------------------------------------------------------------
54 
56 
57  {
58  // set module description
59  setDescription("A module for off-line monitoring of beam background hit rates.");
60 
61  /* No multiprocessing allowed!
62  * setPropertyFlags(c_ParallelProcessingCertified);
63  */
64 
65  // Add parameters
66  addParam("outputFileName", m_outputFileName, "output file name",
67  string("beamBkgHitRates.root"));
68  addParam("treeName", m_treeName, "output tree name",
69  string("tree"));
70  m_trgTypes.push_back(TRGSummary::TTYP_DPHY);
71  m_trgTypes.push_back(TRGSummary::TTYP_RAND);
72  addParam("trgTypes", m_trgTypes,
73  "trigger types for event selection (see TRGSummary.h for definitions). "
74  "Empty list means all trigger types.",
75  m_trgTypes);
76  addParam("writeEmptyTimeStamps", m_writeEmptyTimeStamps,
77  "if true, write to ntuple also empty time stamps", false);
78  addParam("topTimeOffset", m_topTimeOffset,
79  "TOP: time offset of hits (to be subtracted) [ns]", 25.0);
80  addParam("topTimeWindow", m_topTimeWindow,
81  "TOP: time window in which to count hits [ns]", 100.0);
82  addParam("svdShaperDigitsName", m_svdShaperDigitsName,
83  "SVDShaperDigits collection name", string(""));
84  addParam("svdThrCharge", m_svdThrCharge,
85  "Energy cur on SVD Cluster charge in electrons", 15000.);
86  addParam("svdIgnoreHotStripsPayload", m_svdIgnoreHotStripsPayload,
87  "If true, also SVD hot strips are counted as active", false);
88  addParam("svdIgnoreMaskedStripsPayload", m_svdIgnoreMaskedStripsPayload,
89  "If true, also SVD FADC-masked strips are counted as active", false);
90  addParam("additionalDataDescription", m_additionalDataDescription,
91  "Additional dictionary of "
92  "name->value pairs to be added to the file metadata to describe the data",
93  m_additionalDataDescription);
94  addParam("cdcTimeWindowLowerEdgeSmallCell", m_cdcTimeWindowLowerEdgeSmallCell,
95  "CDC: lower edge of the time window for small cells [tdc count = ns]",
96  4550);
97  addParam("cdcTimeWindowUpperEdgeSmallCell", m_cdcTimeWindowUpperEdgeSmallCell,
98  "CDC: upper edge of the time window for small cells [tdc count = ns]",
99  5050);
100  addParam("cdcTimeWindowLowerEdgeNormalCell", m_cdcTimeWindowLowerEdgeNormalCell,
101  "CDC: lower edge of the time window for normal cells [tdc count = ns]",
102  4200);
103  addParam("cdcTimeWindowUpperEdgeNormalCell", m_cdcTimeWindowUpperEdgeNormalCell,
104  "CDC: upper edge of the time window for normal cells [tdc count = ns]",
105  5050);
106  addParam("cdcEnableBadWireTreatment", m_cdcEnableBadWireTreatment,
107  "CDC: flag to enable the bad wire treatment", true);
108  addParam("cdcEnableBackgroundHitFilter", m_cdcEnableBackgroundHitFilter,
109  "CDC: flag to enable the CDC background hit (crosstakl, noise) filter", true);
110  addParam("cdcEnableMarkBackgroundHit", m_cdcEnableMarkBackgroundHit,
111  "CDC: flag to enable to mark background flag on CDCHit (set 0x100 bit for CDCHit::m_status).", false);
112 
113  }
114 
115  BeamBkgHitRateMonitorModule::~BeamBkgHitRateMonitorModule()
116  {
117  for (auto& monitor : m_monitors) {
118  if (monitor) delete monitor;
119  }
120  }
121 
122  void BeamBkgHitRateMonitorModule::initialize()
123  {
124  // collections registration
125  m_eventMetaData.isRequired();
126  if (m_trgTypes.empty()) {
127  m_trgSummary.isOptional(); // enables to run the module when TRGSummary is absent
128  } else {
129  m_trgSummary.isRequired();
130  }
131  m_fileMetaData.isOptional(); // enables to run the module with simulation
132 
133  // create, set and append hit rate monitoring classes
134  auto* pxd = new Background::PXDHitRateCounter();
135  m_monitors.push_back(pxd);
136  auto* svd = new Background::SVDHitRateCounter(m_svdShaperDigitsName, m_svdThrCharge,
137  m_svdIgnoreHotStripsPayload,
138  m_svdIgnoreMaskedStripsPayload);
139  m_monitors.push_back(svd);
140  auto* cdc = new Background::CDCHitRateCounter(m_cdcTimeWindowLowerEdgeSmallCell, m_cdcTimeWindowUpperEdgeSmallCell,
141  m_cdcTimeWindowLowerEdgeNormalCell, m_cdcTimeWindowUpperEdgeNormalCell,
142  m_cdcEnableBadWireTreatment, m_cdcEnableBackgroundHitFilter,
143  m_cdcEnableMarkBackgroundHit);
144  m_monitors.push_back(cdc);
145  auto* top = new Background::TOPHitRateCounter(m_topTimeOffset, m_topTimeWindow);
146  m_monitors.push_back(top);
147  auto* arich = new Background::ARICHHitRateCounter();
148  m_monitors.push_back(arich);
149  auto* ecl = new Background::ECLHitRateCounter();
150  m_monitors.push_back(ecl);
151  auto* klm = new Background::KLMHitRateCounter();
152  m_monitors.push_back(klm);
153 
154  // open output root file
155  m_file = TFile::Open(m_outputFileName.c_str(), "RECREATE");
156  if (not m_file) {
157  B2FATAL("Cannot open output file '" << m_outputFileName << "' for writing");
158  }
159 
160  // create tree
161  m_tree = new TTree(m_treeName.c_str(), "hit rates of selected events");
162 
163  // create persistent tree to store fileMetaData
164  m_persistent = new TTree("persistent", "persistent data");
165  m_persistent->Branch("FileMetaData", &m_outputFileMetaData);
166 
167  // set tree branches
168  m_tree->Branch("run", &m_run, "run/I");
169  m_tree->Branch("numEvents", &m_numEvents, "numEvents/I");
170  m_tree->Branch("timeStamp", &m_timeStamp, "timeStamp/i");
171  m_tree->Branch("time", &m_time, "time/I");
172  for (auto& monitor : m_monitors) {
173  monitor->initialize(m_tree);
174  }
175 
176  // control histograms
177  m_trgAll = new TH1F("trgAll", "trigger types of all events", 16, -0.5, 15.5);
178  m_trgAll->SetXTitle("type of trigger timing source");
179  m_trgSel = new TH1F("trgSel", "trigger types of selected events", 16, -0.5, 15.5);
180  m_trgSel->SetXTitle("type of trigger timing source");
181 
182  }
183 
184  void BeamBkgHitRateMonitorModule::beginRun()
185  {
186  // clear buffers
187  for (auto& monitor : m_monitors) {
188  monitor->clear();
189  }
190  m_eventCounts.clear();
191 
192  // clear counters
193  m_numEventsSelected = 0;
194  m_trgTypesCount.clear();
195 
196  // set run number
197  m_run = m_eventMetaData->getRun();
198 
199  // set unix time of the first event in the run
200  unsigned utime = m_eventMetaData->getTime() / 1000000000;
201  m_utimeFirst = utime;
202  m_utimeMin = utime;
203  m_utimeMax = utime + 1;
204 
205  }
206 
207  void BeamBkgHitRateMonitorModule::event()
208  {
209  // get unix time of the event
210  unsigned utime = m_eventMetaData->getTime() / 1000000000;
211  m_utimeMin = std::min(m_utimeMin, utime);
212  m_utimeMax = std::max(m_utimeMax, utime + 1);
213 
214  // collect file meta data
215  collectFileMetaData();
216 
217  // event selection
218  if (not isEventSelected()) return;
219  m_numEventsSelected++;
220 
221  // accumulate
222  for (auto& monitor : m_monitors) {
223  monitor->accumulate(utime);
224  }
225  m_eventCounts[utime] += 1;
226 
227  }
228 
229  void BeamBkgHitRateMonitorModule::endRun()
230  {
231  // fill ntuple
232  for (unsigned utime = m_utimeMin; utime < m_utimeMax; utime++) {
233  if (not m_writeEmptyTimeStamps) {
234  if (m_eventCounts.find(utime) == m_eventCounts.end()) continue;
235  }
236  m_numEvents = m_eventCounts[utime];
237  m_timeStamp = utime;
238  m_time = utime - m_utimeMin;
239  for (auto& monitor : m_monitors) {
240  monitor->normalize(utime);
241  }
242  m_tree->Fill();
243  }
244 
245  // count selected events in all runs
246  m_allEventsSelected += m_numEventsSelected;
247 
248  // print a summary for this run
249  std::string trigs;
250  for (const auto& trgType : m_trgTypesCount) {
251  trigs += " trigger type " + std::to_string(trgType.first) + ": " +
252  std::to_string(trgType.second) + " events\n";
253  }
254  B2INFO("Run " << m_run << ": " << m_numEventsSelected
255  << " events selected for beam background hit rate monitoring.\n"
256  << trigs
257  << LogVar("first event utime ", m_utimeMin)
258  << LogVar("start utime ", m_utimeMin)
259  << LogVar("stop utime ", m_utimeMax)
260  << LogVar("duration [seconds]", m_utimeMax - m_utimeMin)
261  );
262  }
263 
264  void BeamBkgHitRateMonitorModule::terminate()
265  {
266  setFileMetaData();
267  m_persistent->Fill();
268 
269  // write to file and close
270  m_file->cd();
271  m_file->Write();
272  m_file->Close();
273 
274  B2INFO("Output file: " << m_outputFileName);
275  }
276 
277  bool BeamBkgHitRateMonitorModule::isEventSelected()
278  {
279  auto trgType = TRGSummary::TTYP_NONE;
280  if (m_trgSummary.isValid()) trgType = m_trgSummary->getTimType();
281  m_trgAll->Fill(trgType);
282 
283  if (m_trgTypes.empty()) {
284  m_trgTypesCount[trgType] += 1;
285  m_trgSel->Fill(trgType);
286  return true;
287  }
288  for (auto type : m_trgTypes) {
289  if (trgType == type) {
290  m_trgTypesCount[trgType] += 1;
291  m_trgSel->Fill(trgType);
292  return true;
293  }
294  }
295  return false;
296  }
297 
298 
299  void BeamBkgHitRateMonitorModule::collectFileMetaData()
300  {
301  // add file name to the list
302  if (m_fileMetaData.isValid()) {
303  std::string lfn = m_fileMetaData->getLfn();
304  if (not lfn.empty() and (m_parentLfns.empty() or (m_parentLfns.back() != lfn))) {
305  m_parentLfns.push_back(lfn);
306  }
307  }
308 
309  // low and high experiment, run and event numbers
310  unsigned long experiment = m_eventMetaData->getExperiment();
311  unsigned long run = m_eventMetaData->getRun();
312  unsigned long event = m_eventMetaData->getEvent();
313  if (m_experimentLow > m_experimentHigh) { //starting condition
314  m_experimentLow = m_experimentHigh = experiment;
315  m_runLow = m_runHigh = run;
316  m_eventLow = m_eventHigh = event;
317  } else {
318  if ((experiment < m_experimentLow) or ((experiment == m_experimentLow) and ((run < m_runLow) or ((run == m_runLow)
319  and (event < m_eventLow))))) {
320  m_experimentLow = experiment;
321  m_runLow = run;
322  m_eventLow = event;
323  }
324  if ((experiment > m_experimentHigh) or ((experiment == m_experimentHigh) and ((run > m_runHigh) or ((run == m_runHigh)
325  and (event > m_eventHigh))))) {
326  m_experimentHigh = experiment;
327  m_runHigh = run;
328  m_eventHigh = event;
329  }
330  }
331 
332  }
333 
334 
335  void BeamBkgHitRateMonitorModule::setFileMetaData()
336  {
337 
338  if (m_fileMetaData.isValid() and not m_fileMetaData->isMC()) {
339  m_outputFileMetaData.declareRealData();
340  }
341 
342  m_outputFileMetaData.setNEvents(m_allEventsSelected);
343 
344  if (m_experimentLow > m_experimentHigh) {
345  // starting condition so apparently no events at all
346  m_outputFileMetaData.setLow(-1, -1, 0);
347  m_outputFileMetaData.setHigh(-1, -1, 0);
348  } else {
349  m_outputFileMetaData.setLow(m_experimentLow, m_runLow, m_eventLow);
350  m_outputFileMetaData.setHigh(m_experimentHigh, m_runHigh, m_eventHigh);
351  }
352 
353  m_outputFileMetaData.setParents(m_parentLfns);
354  RootIOUtilities::setCreationData(m_outputFileMetaData);
355  m_outputFileMetaData.setRandomSeed(RandomNumbers::getSeed());
356  m_outputFileMetaData.setSteering(Environment::Instance().getSteering());
357  auto mcEvents = Environment::Instance().getNumberOfMCEvents();
358  m_outputFileMetaData.setMcEvents(mcEvents);
359  m_outputFileMetaData.setDatabaseGlobalTag(Database::Instance().getGlobalTags());
360 
361  for (const auto& item : m_additionalDataDescription) {
362  m_outputFileMetaData.setDataDescription(item.first, item.second);
363  }
364 
365  std::string lfn = m_file->GetName();
366  lfn = boost::filesystem::absolute(lfn, boost::filesystem::initial_path()).string();
367  std::string format = EnvironmentVariables::get("BELLE2_LFN_FORMATSTRING", "");
368  if (!format.empty()) {
369  auto format_filename = boost::python::import("B2Tools.format").attr("format_filename");
370  lfn = boost::python::extract<std::string>(format_filename(format, m_outputFileName, m_outputFileMetaData.getJsonStr()));
371  }
372  m_outputFileMetaData.setLfn(lfn);
373 
374  }
375 
376 
378 } // end Belle2 namespace
379 
Belle2::Background::ARICHHitRateCounter
Class for monitoring beam background hit rates of ARICH.
Definition: ARICHHitRateCounter.h:41
Belle2::Background::KLMHitRateCounter
Class for monitoring beam background hit rates of EKLM.
Definition: KLMHitRateCounter.h:47
Belle2::Background::SVDHitRateCounter
Class for monitoring beam background hit rates of SVD.
Definition: SVDHitRateCounter.h:44
REG_MODULE
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:652
Belle2::Background::PXDHitRateCounter
Class for monitoring beam background hit rates of PXD.
Definition: PXDHitRateCounter.h:43
Belle2::Module
Base class for Modules.
Definition: Module.h:74
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
LogVar
Class to store variables with their name which were sent to the logging service.
Definition: LogVariableStream.h:24
Belle2::BeamBkgHitRateMonitorModule
A module to monitor detector hit rates of beam background Output is to a flat ntuple.
Definition: BeamBkgHitRateMonitorModule.h:45
Belle2::Background::ECLHitRateCounter
Class for monitoring beam background hit rates of ECL.
Definition: ECLHitRateCounter.h:38
Belle2::Background::CDCHitRateCounter
Class for monitoring beam background hit rates of CDC.
Definition: CDCHitRateCounter.h:38
Belle2::Background::TOPHitRateCounter
Class for monitoring beam background hit rates of TOP.
Definition: TOPHitRateCounter.h:43