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 = static_cast<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 = static_cast<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}
static const KLMChannelArrayIndex & Instance()
Instantiation.
uint16_t getIndex(uint16_t number) const
Get element index.
KLMSectorNumber sectorNumberEKLM(int section, int sector) const
Get sector number for EKLM.
static KLMSectorNumber sectorNumberBKLM(int section, int sector)
Get sector number for BKLM.
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.
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.