Belle II Software  release-06-02-00
TOPTBCComparatorModule.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 #include <framework/core/HistoModule.h>
10 #include <top/modules/TOPTBCComparator/TOPTBCComparatorModule.h>
11 #include <top/geometry/TOPGeometryPar.h>
12 #include <top/geometry/FrontEndMapper.h>
13 #include "TDirectory.h"
14 #include "TSystemDirectory.h"
15 #include "TSystemFile.h"
16 #include "TString.h"
17 #include "TFile.h"
18 #include <boost/format.hpp>
19 #include <fstream>
20 
21 using namespace std;
22 using boost::format;
23 
24 namespace Belle2 {
29  using namespace TOP;
30  REG_MODULE(TOPTBCComparator)
31 
33  {
34  setDescription("TOP Time Base Correction monitor module ");
35 
36  addParam("inputDirectorList", m_inputDirectoryList,
37  "List of the directories (one per IOV) in which the files with the calibration constants of the SCODS are stored. The format of each line must be: folderpath/ label ",
38  string(" "));
39  addParam("compareToPreviousSet", m_compareToPreviousSet,
40  "If true, each CalSet is compared to the previous one in the order determined by the inputDirectorList file. If false, the reference CalSet is the first of the list",
41  bool(true));
42  addParam("outputFile", m_outputFile,
43  "output file containing the monitoring plots", string("TBCComparisonResults.root"));
44  addParam("minCalPulses", m_minCalPulses,
45  "minimum number of calibration pulses need to flag a sample as non-empty", short(200));
46  addParam("numSamples", m_numSamples,
47  "number of samples that have been calibrated", short(256));
48 
49  }
50 
51 
52  void TOPTBCComparatorModule::defineHisto()
53  {
54  // opens the file contining the list of directories and the labels
55  ifstream inputDirectoryListFile(m_inputDirectoryList.c_str());
56 
57  // checks the input file
58  if (!inputDirectoryListFile) {
59  B2ERROR("Unable to open the input file with the list of CalSets to analyze");
60  return;
61  }
62 
63  B2INFO("Initializing histograms");
64 
65 
66  std::string inputString;
67 
68  // reads the Input file line by-line to initialize the correct number of histogram sets, and reads the labels..
69  // This is effectively a loop over all the calsets.
70  while (std::getline(inputDirectoryListFile, inputString)) {
71 
72  // This initializes m_calSetDirectory and m_calSetLabel, even if now only m_calSetLabel will be used
73  parseInputDirectoryLine(inputString);
74 
75  B2INFO("Initializing histograms for Calibration set located at " << m_calSetDirectory << " with label " << m_calSetLabel);
76 
77  // To be used to initialize the histograms in the following
78  std::string name;
79  std::string title;
80 
81 
82  // ------
83  // Calset-by-calset histograms.
84  // initialize here all the histograms that appear once per calibration set, and not slot-by-slot
85  // ------
86 
87  // Average DeltaT across the whole detector
88  name = str(format("TOPAverageDeltaT_CalSet_%1%") % m_calSetLabel);
89  title = str(format("Average value of #Delta T VS global channel number. CalSet %1%") % m_calSetLabel);
90  m_topAverageDeltaT.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
91 
92  // St.dev. of Delta T across the whole detector
93  name = str(format("TOPSigmaDeltaT_CalSet_%1%") % m_calSetLabel);
94  title = str(format("Sigma value of #Delta T VS global channel number. CalSet %1%") % m_calSetLabel);
95  m_topSigmaDeltaT.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
96 
97  // Average occupancy agross the whole detector
98  name = str(format("TOPSampleOccupancy_CalSet_%1%") % m_calSetLabel);
99  title = str(format("Average number of calpulses per sample VS global channel number. CalSet %1%") % m_calSetLabel);
100  m_topSampleOccupancy.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
101 
102 
103  // Ratio of the average DeltaT across the whole detector
104  name = str(format("TOPAverageDeltaTComparison_CalSet_%1%") % m_calSetLabel);
105  title = str(format("Ratio of the average #Delta T in CalSet %1% over the previous one, over the whole detector") % m_calSetLabel);
106  m_topAverageDeltaTComparison.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
107 
108  // Ratio of the st.dev on DeltaT across the whole detector
109  name = str(format("TOPSigmaDeltaTComparison_CalSet_%1%") % m_calSetLabel);
110  title = str(format("Ratio of the st. dev. of #Delta T in CalSet %1% over the previous one, , over the whole detector") %
111  m_calSetLabel);
112  m_topSigmaDeltaTComparison.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
113 
114  // Ratio of the average number of calpulses across the whole detector
115  name = str(format("TOPSampleOccupancyComparison_CalSet_%1%") % m_calSetLabel);
116  title = str(
117  format("Ratio of the average number of calpulses per sample in CalSet %1% over the previous one, over the whole detector") %
118  m_calSetLabel);
119  m_topSampleOccupancyComparison.push_back(new TH1F(name.c_str(), title.c_str(), 512 * 16, 0., 512 * 16.));
120 
121 
122  // ------
123  // Slot-by-slot histograms.
124  // Use this loop to initialize all the histograms that appear once per calibration set and per each slot
125  // ------
126  for (int iSlot = 0; iSlot < 16; iSlot ++) {
127 
128  // Average DeltaT stuff
129  name = str(format("SlotAverageDeltaT_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
130  title = str(format("Average value of #Delta T VS Channel number. Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
131  m_slotAverageDeltaT[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
132 
133  name = str(format("SlotSigmaDeltaT_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
134  title = str(format("Standard deviation of #Delta T VS Channel number. Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
135  m_slotSigmaDeltaT[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
136 
137  name = str(format("SlotAverageDeltaTMap_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
138  title = str(format("Map of the average value of #Delta T on the 256 samples. Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
139  m_slotAverageDeltaTMap[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
140 
141  name = str(format("SlotSigmaDeltaTMap_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
142  title = str(format("Map of the RMS of #Delta T on the 256 samples . Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
143  m_slotSigmaDeltaTMap[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
144 
145 
146  // Occupancy stuff
147  name = str(format("SlotSampleOccupancy_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
148  title = str(format("Average occupancy per sample. Slot %1%, CalSet %2%") % (iSlot) % m_calSetLabel);
149  m_slotSampleOccupancy[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
150 
151  name = str(format("SlotEmptySamples_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
152  title = str(format("Number samples with less than %3% calpulses per each slot channel. Slot %1%, CalSet %2%") %
153  (iSlot) % m_calSetLabel % m_minCalPulses);
154  m_slotEmptySamples[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
155 
156  name = str(format("SlotSampleOccupancyMap_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
157  title = str(format("Map of the average occupancy per sample. Slot %1%, CalSet %2%") %
158  (iSlot) % m_calSetLabel);
159  m_slotSampleOccupancyMap[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
160 
161  name = str(format("SlotEmptySamplesMap_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
162  title = str(format("Map of the number samples with less than %3% calpulses per each. Slot %1%, CalSet %2%") %
163  (iSlot) % m_calSetLabel % m_minCalPulses);
164  m_slotEmptySamplesMap[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
165 
166 
167 
168  // Ratios
169  name = str(format("SlotAverageDeltaTComparison_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
170  title = str(format("Ratio of the average #Delta T in CalSet %2% over the previous one. Slot %1%") % (iSlot) % m_calSetLabel);
171  m_slotAverageDeltaTComparison[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
172 
173  name = str(format("SlotRMSDeltaTComparison_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
174  title = str(format("Ratio of the RMS of #Delta T in CalSet %2% over the previous one. Slot %1%") % (iSlot) % m_calSetLabel);
175  m_slotSigmaDeltaTComparison[iSlot].push_back(new TH1F(name.c_str(), title.c_str(), 512, 0., 512.));
176 
177  name = str(format("SlotAverageDeltaTMapComparison_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
178  title = str(format("Map of the ratio of the average #Delta T in CalSet %2% over the previous one. Slot %1%") %
179  (iSlot) % m_calSetLabel);
180  m_slotAverageDeltaTMapComparison[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
181 
182  name = str(format("SlotRMSDeltaTMapComparison_Slot%1%_CalSet_%2%") % (iSlot) % m_calSetLabel);
183  title = str(format("Map of the ratio of the RMS of #Delta T in CalSet %2% over the previous one. Slot %1%") %
184  (iSlot) % m_calSetLabel);
185  m_slotSigmaDeltaTMapComparison[iSlot].push_back(new TH2F(name.c_str(), title.c_str(), 64, 0., 64., 8, 0., 8.));
186 
187  }
188 
189  //counts how many sets are there. To be used when doing the ratios
190  m_totCalSets++;
191  }
192  B2INFO("Initialization of the histograms for " << m_totCalSets << " CalSets done.");
193  return;
194  }
195 
196 
197 
198  int TOPTBCComparatorModule::analyzeCalFile()
199  {
200  // Here the histograms are filled
201  // WARNING! What root calls "RMS" is actually a standard deviation
202 
203  // Sanity check on the parsed parameters
204  if (m_slotID < 0 || m_boardstackID < 0 || m_scrodID < 0) {
205  B2WARNING("Negative slot, BS or scrod ID found while calling analyzeCalFile(). Looks like they have not been initialized, or that a function re-initialized them");
206  return 0;
207  }
208 
209  // Loop over all the histograms that should be found in the file
210  for (short iChannel = 0; iChannel < 128; iChannel++) {
211 
212  // Pics up one histogram just to check that the channel iChannel was actually used to calculate the calibrations
213  if (!m_calSetFile->Get(str(format("timeDiff_ch%1%") % (iChannel)).c_str())) {
214  continue;
215  }
216 
217 
218  // ---------
219  // 1) Define some channel numbering quantities
220  // Watchout: m_slotID is in [1..16] so slot m_slotID is on the element m_slotID-1 of the array
221  // ---------
222 
223  short hardwareChannel = iChannel + 128 * m_boardstackID; // 0-511 across the whole module, BS by BS
224  auto& chMapper = TOP::TOPGeometryPar::Instance()->getChannelMapper();
225  short pixelID = chMapper.getPixelID(hardwareChannel); // 1-512 across the whole module, in rows
226  short colNum = (pixelID - 1) % 64 + 1; // 1- 64 column ID (right to left looking from the quartz to the PMTs)
227  short rowNum = (pixelID - 1) / 64 + 1 ; // 1- 8 row ID (bottom to top looking from the quartz to the PMTs)
228  short globalChannel = hardwareChannel + 512 * (m_slotID -
229  1); // channel number across the whole detector, 0-8191. Used for cal monitorin only
230 
231 
232  // ---------
233  // 2) Channel-by-channel DeltaT summaries (average on the 256 samples of each set)
234  // ---------
235 
236  // Checks that the histogram needed here is not corrupted before using it
237  if (!m_calSetFile->Get(str(format("timeDiffcal_ch%1%") % (iChannel)).c_str())) {
238  B2WARNING("Error opening " << str(format("timeDiffcal_ch%1%") % (iChannel)));
239  } else {
240  TH2F* h_timeDiffcal = (TH2F*)m_calSetFile->Get(str(format("timeDiffcal_ch%1%") % (iChannel)).c_str());
241  TH1D* h_projection = h_timeDiffcal->ProjectionY("h_projection", 1, m_numSamples); // full projection
242 
243  m_slotAverageDeltaT[m_slotID - 1][m_calSetID]->SetBinContent(hardwareChannel + 1, h_projection->GetMean());
244  m_slotAverageDeltaT[m_slotID - 1][m_calSetID]->SetBinError(hardwareChannel + 1,
245  h_projection->GetMeanError()); // Do we trust root on this?
246  m_slotSigmaDeltaT[m_slotID - 1][m_calSetID]->SetBinContent(hardwareChannel + 1,
247  h_projection->GetRMS()); // WARNING! What root calls "RMS" is actually a standard deviation
248  m_slotSigmaDeltaT[m_slotID - 1][m_calSetID]->SetBinError(hardwareChannel + 1,
249  h_projection->GetRMSError()); // WARNING! What root calls "RMS" is actually a standard deviation
250 
251  m_slotAverageDeltaTMap[m_slotID - 1][m_calSetID]->SetBinContent(colNum, rowNum, h_projection->GetMean());
252  m_slotSigmaDeltaTMap[m_slotID - 1][m_calSetID]->SetBinContent(colNum, rowNum,
253  h_projection->GetRMS());
254 
255  m_topAverageDeltaT[m_calSetID]->SetBinContent(globalChannel + 1, h_projection->GetMean());
256  m_topSigmaDeltaT[m_calSetID]->SetBinContent(globalChannel + 1, h_projection->GetRMS());
257  }
258 
259  // ---------
260  // 3) Channel-by-channel average occupancy
261  // ---------
262 
263  // Checks that the histogram needed here is not corrupted before using it
264  if (!m_calSetFile->Get(str(format("sampleOccup_ch%1%") % (iChannel)).c_str())) {
265  B2WARNING("Error opening " << str(format("sampleOccup_ch%1%") % (iChannel)));
266  } else {
267  TH1F* h_sampleOccup = (TH1F*)m_calSetFile->Get(str(format("sampleOccup_ch%1%") % (iChannel)).c_str());
268 
269  // reads the occupancy histogram bin-by-by to look for (almost) empty samples
270  int nEmpty = 0;
271  for (int iSample = 1; iSample < m_numSamples + 1 ; iSample++) {
272  if (h_sampleOccup->GetBinContent(iSample) < m_minCalPulses) nEmpty++;
273  }
274 
275  m_slotSampleOccupancy[m_slotID - 1][m_calSetID]->SetBinContent(hardwareChannel + 1, h_sampleOccup->Integral() / m_numSamples);
276  m_slotEmptySamples[m_slotID - 1][m_calSetID]->SetBinContent(hardwareChannel + 1, nEmpty);
277 
278  m_slotSampleOccupancyMap[m_slotID - 1][m_calSetID]->SetBinContent(colNum, rowNum, h_sampleOccup->Integral() / m_numSamples);
279  m_slotEmptySamplesMap[m_slotID - 1][m_calSetID]->SetBinContent(colNum, rowNum, nEmpty);
280 
281  m_topSampleOccupancy[m_calSetID]->SetBinContent(globalChannel + 1, h_sampleOccup->Integral() / m_numSamples);
282 
283  }
284 
285 
286 
287  }
288  return 1;
289  }
290 
291 
292  int TOPTBCComparatorModule::makeComparisons()
293  {
294  // Set to compare with
295  short refSet = 0;
296  B2INFO("Making comparisons for " << m_totCalSets << " sets.");
297 
298  // Loop over the sets. Do not make the comparison for the set #0
299  for (int iSet = 1; iSet < m_totCalSets; iSet++) {
300  if (m_compareToPreviousSet) refSet = iSet - 1;
301 
302  m_topAverageDeltaTComparison[iSet] = calculateHistoRatio(m_topAverageDeltaTComparison[iSet], m_topAverageDeltaT[iSet],
303  m_topAverageDeltaT[refSet]);
304  m_topSigmaDeltaTComparison[iSet] = calculateHistoRatio(m_topSigmaDeltaTComparison[iSet], m_topSigmaDeltaT[iSet],
305  m_topSigmaDeltaT[refSet]);
306  m_topSampleOccupancyComparison[iSet] = calculateHistoRatio(m_topSampleOccupancyComparison[iSet], m_topSampleOccupancy[iSet],
307  m_topSampleOccupancy[refSet]);
308 
309  // Loop over the sets. Do not make the comparison for the set #0
310  for (int iSlot = 0; iSlot < 16; iSlot++) {
311  m_slotAverageDeltaTComparison[iSlot][iSet] = calculateHistoRatio(m_slotAverageDeltaTComparison[iSlot][iSet],
312  m_slotAverageDeltaT[iSlot][iSet], m_slotAverageDeltaT[iSlot][refSet]);
313  m_slotAverageDeltaTMapComparison[iSlot][iSet] = calculateHistoRatio(m_slotAverageDeltaTMapComparison[iSlot][iSet],
314  m_slotAverageDeltaTMap[iSlot][iSet], m_slotAverageDeltaTMap[iSlot][refSet]);
315  m_slotSigmaDeltaTComparison[iSlot][iSet] = calculateHistoRatio(m_slotSigmaDeltaTComparison[iSlot][iSet],
316  m_slotSigmaDeltaT[iSlot][iSet], m_slotSigmaDeltaT[iSlot][refSet]);
317  m_slotSigmaDeltaTMapComparison[iSlot][iSet] = calculateHistoRatio(m_slotSigmaDeltaTMapComparison[iSlot][iSet],
318  m_slotSigmaDeltaTMap[iSlot][iSet], m_slotSigmaDeltaTMap[iSlot][refSet]);
319  }
320  }
321  B2INFO("Comparisons done");
322 
323  return 1;
324  }
325 
326 
327  void TOPTBCComparatorModule::initialize()
328  {
329  REG_HISTOGRAM;
330  }
331 
332  void TOPTBCComparatorModule::beginRun()
333  {
334  return;
335  }
336 
337 
338  void TOPTBCComparatorModule::event()
339  {
340  return;
341  }
342 
343 
344 
345  // This function takes care of looping over the root files. Unless the directory structure is changed, you should
346  // not have to touch this part
347  void TOPTBCComparatorModule::endRun()
348  {
349  // opens the file containing the list of directories and the labels
350  ifstream inputDirectoryListFile(m_inputDirectoryList.c_str());
351 
352  // checsk the input file
353  if (!inputDirectoryListFile) {
354  B2ERROR("Unable to open the input file with the list of CalSets to analyze");
355  return;
356  }
357 
358  std::string inputString;
359  // reads the Input file line by-line
360  while (std::getline(inputDirectoryListFile, inputString)) {
361  // This initializes m_calSetDirectory and m_calSetLabel
362 
363  parseInputDirectoryLine(inputString);
364 
365  B2INFO("Processing the calibration set located in " << m_calSetDirectory << " and labelled " << m_calSetLabel);
366  TSystemDirectory calSetDir(m_calSetDirectory.c_str(), (m_calSetDirectory).c_str());
367 
368  // lists the content of the directory
369  TList* calSetDirContent = calSetDir.GetListOfFiles();
370  if (calSetDirContent) {
371  TSystemFile* entry;
372  TIter next(calSetDirContent);
373  while ((entry = (TSystemFile*)next())) {
374 
375  // gets the name of the entry in the list of the content of m_calSetDirectory
376  std::string entryName = entry->GetName();
377 
378  // Case 1: the entry is already a root file
379  if (!entry->IsDirectory() && TString(entryName.c_str()).EndsWith(".root")) {
380  // Initializes the file name
381  m_calSetFile = new TFile((m_calSetDirectory + entryName).c_str(), " ");
382  // Finds out the Slot and BS ID
383  int parserStatus = parseSlotAndScrodIDfromFileName(entryName);
384  // Fills the histograms
385  if (parserStatus == 1)
386  analyzeCalFile();
387  // Closes the file
388  m_calSetFile->Close();
389  }
390 
391  // Case 2: the entry is a sub-foder, containing the rootfiles
392  // The default direcotry structure is
393  // calSetDirectory/tbc_chxx/*.root,
394  // so this should be the normal case
395  if (entry->IsDirectory() && entryName != "." && entryName != "..") {
396  entryName += "/";
397  // resets the directory where to look for root files
398  TSystemDirectory calSetSubDir((m_calSetDirectory + entryName).c_str(), (m_calSetDirectory + entryName).c_str());
399 
400  // lists the content of the directory
401  TList* calSetSubDirContent = calSetSubDir.GetListOfFiles();
402  if (calSetSubDirContent) {
403  TSystemFile* file;
404  TIter nextSub(calSetSubDirContent);
405  while ((file = (TSystemFile*)nextSub())) {
406  // gets the name of the entry in the list of the content of m_calSetDirectory
407  std::string fileName = file->GetName();
408 
409  if (!file->IsDirectory() && TString(fileName.c_str()).EndsWith(".root")) {
410  // Initializes the file name
411  m_calSetFile = new TFile((m_calSetDirectory + entryName + fileName).c_str(), " ");
412  // Finds out the Slot and BS ID
413  int parserStatus = parseSlotAndScrodIDfromFileName(fileName);
414  // Fills the histograms
415  if (parserStatus == 1)
416  analyzeCalFile();
417  // Closes the file
418  m_calSetFile->Close();
419  } else if (file->IsDirectory() && fileName != "." && fileName != "..") {
420  B2WARNING("Additional subdirectory " << fileName << " found in " << m_calSetDirectory + entryName <<
421  ", where only .root and .log files are expected ");
422  continue;
423  }
424 
425  }
426  }
427  }
428  }
429  } else {
430  B2WARNING("Error in creating the TList form the directory " << m_calSetDirectory);
431  continue;
432  }
433  m_calSetID++; // jump to the next directory (i.e. the next calset)
434  }
435  B2INFO("Analisys concluded.");
436 
437  makeComparisons();
438 
439  return;
440  }
441 
442 
443  // Here the histograms are saved
444  void TOPTBCComparatorModule::terminate()
445  {
446  // writes the histos
447  B2INFO("Creating output file " << m_outputFile);
448  TFile outfile(m_outputFile.c_str(), "recreate");
449 
450  B2INFO("Writing histograms ");
451 
452  // opens the input list to retrive, one last time, the labels
453  ifstream inputDirectoryListFile(m_inputDirectoryList.c_str());
454  std::string inputString;
455  int iSet = 0;
456 
457  while (std::getline(inputDirectoryListFile, inputString)) {
458  parseInputDirectoryLine(inputString);
459  TDirectory* dirSet = outfile.mkdir(m_calSetLabel.c_str());
460  dirSet->cd();
461 
462  m_topAverageDeltaT[iSet]->Write();
463  m_topSigmaDeltaT[iSet]->Write();
464  m_topSampleOccupancy[iSet]->Write();
465  m_topAverageDeltaTComparison[iSet]->Write();
466  m_topSigmaDeltaTComparison[iSet]->Write();
467  m_topSampleOccupancyComparison[iSet]->Write();
468 
469  for (int iSlot = 0; iSlot < 16; iSlot ++) {
470  TDirectory* dirSlot = dirSet->mkdir(str(format("slot%1%") % (iSlot + 1)).c_str());
471  dirSlot->cd();
472 
473  m_slotAverageDeltaT[iSlot][iSet]->Write();
474  m_slotSigmaDeltaT[iSlot][iSet]->Write();
475  m_slotAverageDeltaTMap[iSlot][iSet]->Write();
476  m_slotSigmaDeltaTMap[iSlot][iSet]->Write();
477  m_slotSampleOccupancy[iSlot][iSet]->Write();
478  m_slotEmptySamples[iSlot][iSet]->Write();
479  m_slotSampleOccupancyMap[iSlot][iSet]->Write();
480  m_slotEmptySamplesMap[iSlot][iSet]->Write();
481 
482  m_slotAverageDeltaTComparison[iSlot][iSet]->Write();
483  m_slotSigmaDeltaTComparison[iSlot][iSet]->Write();
484  m_slotAverageDeltaTMapComparison[iSlot][iSet]->Write();
485  m_slotSigmaDeltaTMapComparison[iSlot][iSet]->Write();
486  }
487  dirSet->cd();
488  iSet++;
489  }
490  }
491 
492 
493 
494 
495  // -------------------------------
496  //
497  // UTILITIES
498  //
499  // -------------------------------
500  int TOPTBCComparatorModule::parseInputDirectoryLine(std::string inputString)
501  {
502  // resets the strings
503  m_calSetDirectory.clear();
504  m_calSetLabel.clear();
505 
506  // reads the string char by char to break it up in m_calSetDirectory and m_calSetLabel
507  bool isDirectoryNameChar = true;
508  bool isAtBeginning = true;
509 
510  for (std::string::size_type i = 0; i < inputString.size(); ++i) {
511  char c = inputString[i];
512  // The following ifs should catch all the possible cases
513  if (c == ' ' && isAtBeginning) continue; // and empty space at the beginning of the line
514  if (c == ' ' && !isAtBeginning) { // an empty space between the two parts
515  isDirectoryNameChar = false;
516  isAtBeginning = false;
517  continue;
518  }
519  if (c != ' ' && isDirectoryNameChar) { // a good char belonging to the first part of the string
520  m_calSetDirectory += c;
521  isAtBeginning = false;
522  continue;
523  }
524  if (c != ' ' && !isDirectoryNameChar) { // a good char belonging to the second part of the string
525  m_calSetLabel += c;
526  isAtBeginning = false;
527  continue;
528  }
529  B2WARNING("Uncaught exception in parsing the input string. Ending the parsing."); // I should never reach thispoint
530  return 0;
531  }
532 
533  return 1;
534  }
535 
536 
537 
538  int TOPTBCComparatorModule::parseSlotAndScrodIDfromFileName(std::string inputString)
539  {
540  // resets the IDs
541  m_slotID = -1;
542  m_boardstackID = -1;
543  m_scrodID = -1;
544 
545  // reads the string char by char to break it up in m_calSetDirectory and m_calSetLabel
546 
547 
548  std::string stringSlot = "";
549  std::string stringBS = "";
550  std::string stringScrod = "";
551 
552 
553  // We may eventually implement a more clever parsere that is not so sensitive to the file name...
554  //
555  // tbcSlotXX_Y-scrodZZZ.root
556  // tbcSlotXX_Y-scrodZZ.root
557  // 012345678901234567890
558  //
559 
560  if (!(inputString[0] == 't' && inputString[1] == 'b' && inputString[2] == 'c')) {
561  B2WARNING(inputString << " is not a valid TBC file. Skipping it.");
562  return 0;
563  }
564  stringSlot += inputString[7];
565  stringSlot += inputString[8];
566  stringBS += inputString[10];
567  stringScrod += inputString[17];
568  stringScrod += inputString[18];
569  if (inputString[19] != '.')
570  stringScrod += inputString[19];
571 
572 
573  m_slotID = std::stoi(stringSlot);
574  m_scrodID = std::stoi(stringScrod);
575  m_boardstackID = std::stoi(stringBS);
576 
577  return 1;
578  }
579 
580 
581 
582  TH1F* TOPTBCComparatorModule::calculateHistoRatio(TH1F* hRatio, TH1F* hNum, TH1F* hDen)
583  {
584  // Saves the name and titple of the output histogram, as defined in defineHisto
585  const char* name = hRatio->GetName();
586  const char* title = hRatio->GetTitle();
587 
588  const char* xAxisTitle = hRatio->GetXaxis()->GetTitle();
589  const char* yAxisTitle = hRatio->GetYaxis()->GetTitle();
590 
591  // clone the numerator histogram into the output one
592  hRatio = (TH1F*)hNum->Clone();
593 
594 
595  // makes the ratio
596  hRatio->Divide(hDen);
597 
598  //ri-sets name, title and axis labels
599  hRatio->SetName(name);
600  hRatio->SetTitle(title);
601  hRatio->GetXaxis()->SetTitle(xAxisTitle);
602  hRatio->GetYaxis()->SetTitle(yAxisTitle);
603  return hRatio;
604  }
605 
606  TH2F* TOPTBCComparatorModule::calculateHistoRatio(TH2F* hRatio, TH2F* hNum, TH2F* hDen)
607  {
608  // Saves the name and titple of the output histogram, as defined in defineHisto
609  const char* name = hRatio->GetName();
610  const char* title = hRatio->GetTitle();
611 
612  const char* xAxisTitle = hRatio->GetXaxis()->GetTitle();
613  const char* yAxisTitle = hRatio->GetYaxis()->GetTitle();
614 
615  // clone the numerator histogram into the output one
616  hRatio = (TH2F*)hNum->Clone();
617 
618 
619  // makes the ratio
620  hRatio->Divide(hDen);
621 
622  //ri-sets name, title and axis labels
623  hRatio->SetName(name);
624  hRatio->SetTitle(title);
625  hRatio->GetXaxis()->SetTitle(xAxisTitle);
626  hRatio->GetYaxis()->SetTitle(yAxisTitle);
627  return hRatio;
628  }
629 
630 
632 } // end Belle2 namespace
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
Definition: HistoModule.h:29
Module for the comparison of different sets of time base correction (TBC) constants and to produce mo...
#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.