Belle II Software development
SVDHotStripsCalibrationsAlgorithm.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#include <svd/calibration/SVDHotStripsCalibrationsAlgorithm.h>
9
10
11#include <svd/calibration/SVDHotStripsCalibrations.h>
12
13#include <TH1F.h>
14#include <framework/logging/Logger.h>
15#include <iostream>
16#include <TString.h>
17
18using namespace Belle2;
19
21 CalibrationAlgorithm("SVDOccupancyCalibrationsCollector")
22{
23 setDescription("SVDHotStripsCalibrations calibration algorithm");
24 m_id = str;
25}
26
28{
29
30 bool isHotStrip = 0;
31 bool vecHS[768];
32 double stripOccAfterAbsCut[768];
33
34 // float occCal = 1.;
35 float occThr = m_absoluteOccupancyThreshold; // first absolute cut for strips with occupancy >20%
36
37 // auto HSBitmap = new Belle2::SVDCalibrationsBitmap();
38 auto payload = new Belle2::SVDHotStripsCalibrations::t_payload(isHotStrip, m_id);
39
40 auto tree = getObjectPtr<TTree>("HTreeOccupancyCalib");
41 auto hNEvents = getObjectPtr<TH1F>("HNEvents");
42
43 TH1F* hocc = new TH1F("", "", 768, 0, 768);
44
45 if (!tree) {
46 B2WARNING("No tree object.");
47 } else if (!tree->GetEntries()) {
48 B2WARNING("No data in the tree.");
49 }
50 if (!hNEvents) {
51 B2WARNING("No histogram object containing the number of events.");
52 }
53
54 int layer = 0;
55 int ladder = 0;
56 int sensor = 0;
57 int side = 0;
58
59 tree->SetBranchAddress("hist", &hocc);
60 tree->SetBranchAddress("layer", &layer);
61 tree->SetBranchAddress("ladder", &ladder);
62 tree->SetBranchAddress("sensor", &sensor);
63 tree->SetBranchAddress("view", &side);
64
65 std::map<std::tuple<int, int, int, int>, TH1F*> map_hocc;
66
67 for (int i = 0; i < tree->GetEntries(); i++) {
68 tree->GetEntry(i);
69
70 TH1F*& hOccupancy = map_hocc[std::make_tuple(layer, ladder, sensor, side)];
71 if (hOccupancy == nullptr) {
72 hOccupancy = (TH1F*)hocc->Clone(Form("hocc_L%dL%dS%d_%d", layer, ladder, sensor, side));
73 } else {
74 hOccupancy->Add(hocc);
75 }
76 }
77
78 FileStat_t info;
79 int cal_rev = 1;
80 while (gSystem->GetPathInfo(Form("algorithm_SVDHotStripsCalibrations_output_rev_%d.root", cal_rev), info) == 0)
81 cal_rev++;
82 std::unique_ptr<TFile> f(new TFile(Form("algorithm_SVDHotStripsCalibrations_output_rev_%d.root", cal_rev), "RECREATE"));
83
84 int nevents = 0;
85 if (hNEvents) {
86 f->WriteTObject(hNEvents.get());
87 nevents = ((TH1F*)hNEvents.get())->GetEntries();
88 }
89
90 for (const auto& key : map_hocc) {
91 std::tie(layer, ladder, sensor, side) = key.first;
92 int nstrips = 768;
93 if (!side && layer != 3) nstrips = 512;
94
95 TH1F* hOccupancy = (TH1F*)key.second;
96 if (nevents != 0) hOccupancy->Scale(1. / nevents);
97 else B2ERROR("No events to compute the occupancy as strip_count/nevents");
98
99 f->WriteTObject(hOccupancy);
100
101 for (int i = 0; i < nstrips; i++) { vecHS[i] = 0;}
102
103 for (int iterStrip = 0; iterStrip < nstrips; iterStrip++) {
104 float occCal = hOccupancy->GetBinContent(iterStrip + 1);
105 B2DEBUG(40, "Occupancy for: " << layer << "." << ladder << "." << sensor << "." << side << ", strip:" << iterStrip << ": " <<
106 occCal);
107
108 if (occCal > occThr) {
109 vecHS[iterStrip] = 1;
110 stripOccAfterAbsCut[iterStrip] = 0;
111 } else stripOccAfterAbsCut[iterStrip] = occCal;
112 }
113
114 // iterative procedure
115 while (theHSFinder(stripOccAfterAbsCut, vecHS, nstrips)) {}
116
117 for (int l = 0; l < nstrips; l++) {
118 isHotStrip = (int) vecHS[l];
119
120 payload->set(layer, ladder, sensor, bool(side), l, isHotStrip);
121 }
122 }
123
124 saveCalibration(payload, "SVDHotStripsCalibrations");
125
126 // probably not needed - would trigger re-doing the collection
127 // if ( ... too large corrections ... ) return c_Iterate;
128 return c_OK;
129}
130
131
132bool SVDHotStripsCalibrationsAlgorithm::theHSFinder(double* stripOccAfterAbsCut, bool* hsflag, int nstrips)
133{
134 bool found = false;
135
136 int base = nstrips;
137 if (m_computeAverageOccupancyPerChip) base = 128;
138
139 int N = nstrips / base;
140
141 for (int sector = 0; sector < N; sector++) {
142
143 int nafter = 0;
144 double sensorOccAverage = 0;
145
146 for (int l = sector * base; l < sector * base + base; l++) {
147 sensorOccAverage += stripOccAfterAbsCut[l];
148 if (stripOccAfterAbsCut[l] > 0) nafter++;
149 }
150 sensorOccAverage = sensorOccAverage / nafter;
151
152 B2DEBUG(1, "Average occupancy: " << sensorOccAverage);
153
154 for (int l = sector * base; l < sector * base + base; l++) {
155
156 // flag additional HS by comparing each strip occupancy with the sensor/side-based average occupancy
157 if (stripOccAfterAbsCut[l] > sensorOccAverage * m_relativeOccupancyThreshold) {
158 hsflag[l] = 1;
159 found = true;
160 stripOccAfterAbsCut[l] = 0;
161 }
162 }
163 }
164
165 return found;
166}
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
float m_relativeOccupancyThreshold
occupancy relative to the average sensor occupancy used to define a strip as hot.
std::string m_id
Parameter given to set the UniqueID of the payload.
bool m_computeAverageOccupancyPerChip
granularity used to estimate average occupancy.
bool theHSFinder(double *stripOccAfterAbsCut, bool *hsflag, int nstrips)
returns true if the strip is hot
float m_absoluteOccupancyThreshold
absolute occupancy thresold to define a strip as hot.
SVDHotStripsCalibrationsAlgorithm(const std::string &str)
Constructor set the prefix to SVDHotStripsCalibrationsCollector.
virtual EResult calibrate() override
Run algo on data.
SVDCalibrationsBase< SVDCalibrationsBitmap > t_payload
typedef of the SVDHotStripsCalibrations payload for all SVD strips
Abstract base class for different kinds of events.