Belle II Software development
b2klm-execute-masking.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/* KLM headers. */
10#include <klm/dataobjects/KLMChannelArrayIndex.h>
11#include <klm/dataobjects/KLMElementNumbers.h>
12#include <klm/dataobjects/KLMSectorArrayIndex.h>
13
14/* Basf2 headers. */
15#include <framework/logging/Logger.h>
16
17/* ROOT headers. */
18#include <TFile.h>
19#include <TH1.h>
20#include <TSystem.h>
21
22/* C++ headers. */
23#include <cstdlib>
24#include <iostream>
25#include <string>
26
27using namespace Belle2;
28
29int main(int argc, char* argv[])
30{
31 /* Print the usage message if --help or -h are used. */
32 if (argc == 1 or std::string(argv[1]) == "--help" or std::string(argv[1]) == "-h") {
33 std::cout << "Usage: " << argv[0] << " [INPUT_FILE] [CHANNEL1] [CHANNEL2] ... [CHANNELN]\n\n"
34 " This tool masks the given channels of the KLM DQM reference plots stored\n"
35 " in the given input file (here 'channel' means 'channel number').\n\n"
36 " The plots on which this tool acts are:\n"
37 " KLM/masked_channels;\n"
38 " KLM/strip_hits_subdetector_<X>_section_<Y>_sector_<W>_<Z>.\n\n"
39 " This tool is not intended to be run standalone, since it is executed\n"
40 " by 'b2klm-mask-dqm', which automatically detects the channels to be masked.\n";
41 return 0;
42 }
43 /* Print error messages when needed. */
44 int nChannels = argc - 2;
45 if (nChannels == 0) {
46 B2ERROR("There are no channels to mask!");
47 return 0;
48 }
49 std::string inputFileName(argv[1]);
50 if (inputFileName.find(".root") == std::string::npos) {
51 B2ERROR("The input file is not a .root file!");
52 return 0;
53 }
54 if (gSystem->AccessPathName(inputFileName.c_str())) {
55 B2ERROR("The input file does not exist!");
56 return 0;
57 }
58 TFile* inputFile = new TFile(inputFileName.c_str(), "UPDATE");
59 if (!inputFile or inputFile->IsZombie()) {
60 B2ERROR("The input file is not working!");
61 return 0;
62 }
63 /* Now we can safely execute the masking. */
64 inputFile->cd();
65 const KLMElementNumbers* elementNumbers = &(KLMElementNumbers::Instance());
66 const KLMChannelArrayIndex* channelArrayIndex = &(KLMChannelArrayIndex::Instance());
67 const KLMSectorArrayIndex* sectorArrayIndex = &(KLMSectorArrayIndex::Instance());
68 TH1* histoSummary = (TH1*)inputFile->Get("KLM/masked_channels");
69 if (!histoSummary) {
70 B2ERROR("The histogram KLM/masked_channels is not found!");
71 return 0;
72 }
73 for (int i = 2; i <= nChannels + 1; ++i) {
74 KLMChannelNumber channelNumber = std::atoi(argv[i]);
75 int subdetector, section, sector, layer, plane, strip;
76 elementNumbers->channelNumberToElementNumbers(
77 channelNumber, &subdetector, &section, &sector, &layer, &plane, &strip);
78 /* First: mask the channel in occupancy plot. */
79 KLMChannelNumber channelIndex = channelArrayIndex->getIndex(channelNumber);
80 int nHistoOccupancy;
81 if (subdetector == KLMElementNumbers::c_BKLM)
82 nHistoOccupancy = 2;
83 else
84 nHistoOccupancy = 3;
85 for (int j = 0; j < nHistoOccupancy; ++j) {
86 std::string histoOccupancyName = "KLM/strip_hits_subdetector_" + std::to_string(subdetector) +
87 "_section_" + std::to_string(section) +
88 "_sector_" + std::to_string(sector) +
89 "_" + std::to_string(j);
90 TH1* histoOccupancy = (TH1*)inputFile->Get(histoOccupancyName.c_str());
91 if (!histoOccupancy) {
92 B2ERROR("The histogram " << histoOccupancyName << " is not found!");
93 return 0;
94 }
95 TAxis* xAxis = histoOccupancy->GetXaxis();
96 double xMin = xAxis->GetXmin();
97 double xMax = xAxis->GetXmax();
98 if ((channelIndex >= xMin) and (channelIndex < xMax)) {
99 int bin = xAxis->FindBin(channelIndex);
100 histoOccupancy->SetBinContent(bin, 0);
101 inputFile->Write("", TObject::kOverwrite);
102 }
103 }
104 /* Second: add the masked channel to the summary plot. */
105 KLMSectorNumber sectorNumber;
106 if (subdetector == KLMElementNumbers::c_BKLM)
107 sectorNumber = elementNumbers->sectorNumberBKLM(section, sector);
108 else
109 sectorNumber = elementNumbers->sectorNumberEKLM(section, sector);
110 uint16_t sectorIndex = sectorArrayIndex->getIndex(sectorNumber);
111 histoSummary->Fill(sectorIndex);
112 }
113 inputFile->Write("", TObject::kOverwrite);
114 inputFile->Close();
115 delete inputFile;
116 B2INFO("Masking complete: the reference file " << inputFileName << " is now ready.");
117 return 0;
118}
KLM channel array index.
static const KLMChannelArrayIndex & Instance()
Instantiation.
uint16_t getIndex(uint16_t number) const
Get element index.
KLM element numbers.
KLMSectorNumber sectorNumberEKLM(int section, int sector) const
Get sector number for EKLM.
static const KLMElementNumbers & Instance()
Instantiation.
void channelNumberToElementNumbers(KLMChannelNumber channel, int *subdetector, int *section, int *sector, int *layer, int *plane, int *strip) const
Get element numbers by channel number.
KLMSectorNumber sectorNumberBKLM(int section, int sector) const
Get sector number for BKLM.
KLM sector array index.
static const KLMSectorArrayIndex & Instance()
Instantiation.
uint16_t KLMSectorNumber
Sector number.
uint16_t KLMChannelNumber
Channel number.
Abstract base class for different kinds of events.