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