Belle II Software development
TOPChannelMaskAlgorithm.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 <top/calibration/TOPChannelMaskAlgorithm.h>
10#include <framework/logging/Logger.h>
11#include "TROOT.h"
12#include <TH1F.h>
13#include <TH2F.h>
14#include <string>
15#include <vector>
16#include <algorithm>
17#include <cmath>
18
19using namespace std;
20
21namespace Belle2 {
26 namespace TOP {
27
29 CalibrationAlgorithm("TOPChannelMaskCollector")
30 {
31 setDescription("Calibration algorithm for masking of dead and hot channels");
32 }
33
35 {
36 gROOT->SetBatch();
37
38 // check if the statistics is sufficient
39
40 auto nhits = getObjectPtr<TH1F>("nhits");
41 if (not nhits) return c_NotEnoughData;
42 double averageChannelHits = nhits->GetEntries() * nhits->GetMean() / 16 / 512;
43 B2INFO("Average number of good hits per channel: " << averageChannelHits);
44 if (averageChannelHits < m_minHits) return c_NotEnoughData;
45
46 // construct file name and open output root file
47
48 const auto& expRun = getRunList();
49 string expNo = to_string(expRun[0].first);
50 while (expNo.length() < 4) expNo.insert(0, "0");
51 string runNo = to_string(expRun[0].second);
52 while (runNo.length() < 5) runNo.insert(0, "0");
53 string outputFileName = "channelMask-e" + expNo + "-r" + runNo + ".root";
54 m_file = TFile::Open(outputFileName.c_str(), "recreate");
55
56 nhits->Write();
57
58 // create payload
59
61
62 // dead and hot channels
63
64 auto meanHits = new TH1F("meanHits", "Average number of hits per channel; slot number; average", 16, 0.5, 16.5);
65 auto rmsHits = new TH1F("rmsHits", "r.m.s of number of hits per channel; slot number; r.m.s", 16, 0.5, 16.5);
66 for (int slot = 1; slot <= 16; slot++) {
67 string name = "hits_" + to_string(slot);
68 auto h = getObjectPtr<TH1F>(name);
69 if (not h) continue;
70 h->Write();
71
72 double mean = 0;
73 double rms = h->GetMaximum();
74 for (int iter = 0; iter < 5; iter++) {
75 double sumy = 0;
76 double sumyy = 0;
77 int n = 0;
78 for (int chan = 0; chan < h->GetNbinsX(); chan++) {
79 double y = h->GetBinContent(chan + 1);
80 if (y == 0 or fabs(y - mean) > 3 * rms) continue;
81 sumy += y;
82 sumyy += y * y;
83 n++;
84 }
85 if (n == 0) break;
86 mean = sumy / n;
87 rms = sqrt(sumyy / n - mean * mean);
88 }
89 meanHits->SetBinContent(slot, mean);
90 rmsHits->SetBinContent(slot, rms);
91 double deadCut = mean / 5;
92 double hotCut = std::max(mean * 2, mean + 6 * rms);
93
94 for (int chan = 0; chan < h->GetNbinsX(); chan++) {
95 double y = h->GetBinContent(chan + 1);
96 if (y <= deadCut) {
97 m_channelMask->setDead(slot, chan);
98 } else if (y > hotCut) {
99 m_channelMask->setNoisy(slot, chan);
100 }
101 }
102 }
103
104 // ASICs with window corruption
105
106 for (int slot = 1; slot <= 16; slot++) {
107 string name = "window_vs_asic_" + to_string(slot);
108 auto h = getObjectPtr<TH2F>(name);
109 if (not h) continue;
110 h->Write();
111 auto h0 = h->ProjectionX();
112 auto h1 = h->ProjectionX("_tmp", m_minWindow, m_maxWindow);
113 for (int asic = 0; asic < h->GetNbinsX(); asic++) {
114 double r = 1 - h1->GetBinContent(asic + 1) / h0->GetBinContent(asic + 1);
115 if (r > 0.20) {
116 for (int chan = 0; chan < 8; chan++) m_channelMask->setNoisy(slot, chan + asic * 8);
117 }
118 }
119 delete h0;
120 delete h1;
121 }
122
123 // write the results and close the file
124
125 auto dead = new TH1F("numDead", "Number of dead channels; slot number; dead channels", 16, 0.5, 16.5);
126 auto hot = new TH1F("numHot", "Number of noisy channels; slot number; noisy channels", 16, 0.5, 16.5);
127 auto active = new TH1F("activeFract", "Fraction of active channels; slot number; active fraction", 16, 0.5, 16.5);
128 for (int slot = 1; slot <= 16; slot++) {
129 dead->SetBinContent(slot, m_channelMask->getNumOfDeadChannels(slot));
130 hot->SetBinContent(slot, m_channelMask->getNumOfNoisyChannels(slot));
131 active->SetBinContent(slot, m_channelMask->getActiveFraction(slot));
132 }
133 m_file->Write();
134 m_file->Close();
135
136 // import payload to DB
137
139
140 return c_OK;
141 }
142
143
144 } // end namespace TOP
146} // end namespace Belle2
147
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)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
CalibrationAlgorithm(const std::string &collectorModuleName)
Constructor - sets the prefix for collected objects (won't be accesses until execute(....
Channel status for all 512 channels of 16 modules.
double m_minHits
minimal number of hits per channel needed for calibration
virtual EResult calibrate() final
algorithm implementation
int m_maxWindow
band upper limit in window_vs_asic
TOPCalChannelMask * m_channelMask
masks of dead and hot channels
int m_minWindow
band lower limit in window_vs_asic
std::shared_ptr< T > getObjectPtr(const std::string &name, const std::vector< Calibration::ExpRun > &requestedRuns)
Get calibration data object by name and list of runs, the Merge function will be called to generate t...
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
Abstract base class for different kinds of events.
STL namespace.