Belle II Software development
DQMHistAnalysisECLShapers.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//THIS MODULE
10#include <dqm/analysis/modules/DQMHistAnalysisECLShapers.h>
11
12//ROOT
13#include <TProfile.h>
14
15//boost
16#include "boost/format.hpp"
17
18//std
19#include <numeric>
20
21using namespace Belle2;
22
23REG_MODULE(DQMHistAnalysisECLShapers);
24
27{
28 B2DEBUG(20, "DQMHistAnalysisECLShapers: Constructor done.");
29 setDescription("Processes information involving ECL pedestals (widths and rms).");
30
31 addParam("pvPrefix", m_pvPrefix, "Prefix to use for PVs registered by this module",
32 std::string("ECL:"));
33}
34
35
37
39{
40 for (int i = 0; i < c_collector_count; i++) {
41 std::string pv_name = (boost::format("logic_check:crate%02d") %
42 (i + 1)).str();
43 registerEpicsPV(m_pvPrefix + pv_name, pv_name);
44 }
45 for (auto part_id : {"fw", "br", "bw", "al"}) {
46 std::string pv_name = "pedwidth:max_";
47 pv_name += part_id;
48 registerEpicsPV(m_pvPrefix + pv_name, pv_name);
49
50 pv_name = "pedwidth:avg_";
51 pv_name += part_id;
52 registerEpicsPV(m_pvPrefix + pv_name, pv_name);
53 }
54
56
57 m_c_main = new TCanvas("ecl_main");
58 m_monObj->addCanvas(m_c_main);
59
60 B2DEBUG(20, "DQMHistAnalysisECLShapers: initialized.");
61}
62
64{
65 B2DEBUG(20, "DQMHistAnalysisECLShapers: beginRun called.");
66}
67
69{
70 TH1* h_fail_crateid = findHist("ECL/fail_crateid");
71 TProfile* h_pedrms_cellid = (TProfile*)findHist("ECL/pedrms_cellid");
72
73 if (h_pedrms_cellid != NULL) {
74 double pedwidth_sum = 0;
75 // Using multiset to automatically sort the added values.
76 // (so we can easily calculate the max value)
77 std::multiset<double> barrel_pedwidth;
78 std::multiset<double> bwd_pedwidth;
79 std::multiset<double> fwd_pedwidth;
80
81 for (int i = 0; i < ECLElementNumbers::c_NCrystals; i++) {
82 const int cellid = i + 1;
83 if (h_pedrms_cellid->GetBinEntries(cellid) < 100) continue;
84 double pedrms = h_pedrms_cellid->GetBinContent(cellid);
85 pedwidth_sum += pedrms;
86 if (cellid < 1153) {
87 fwd_pedwidth.insert(pedrms);
88 } else if (cellid < 7777) {
89 barrel_pedwidth.insert(pedrms);
90 } else {
91 bwd_pedwidth.insert(pedrms);
92 }
93 }
94
95 // Use approximate conversion factor
96 // to convert from ADC units to MeV.
97 const double adc_to_mev = 0.05;
98
99 m_pedwidth_max[0] = robust_max(fwd_pedwidth) * adc_to_mev;
100 m_pedwidth_max[1] = robust_max(barrel_pedwidth) * adc_to_mev;
101 m_pedwidth_max[2] = robust_max(bwd_pedwidth) * adc_to_mev;
102 m_pedwidth_max[3] = *std::max_element(&m_pedwidth_max[0], &m_pedwidth_max[2]);
103
104 // Sum of a given multiset
105 auto sum = [](std::multiset<double> x) { return std::accumulate(x.begin(), x.end(), 0.0); };
106
107 m_pedwidth_avg[0] = sum(fwd_pedwidth) / fwd_pedwidth.size() * adc_to_mev;
108 m_pedwidth_avg[1] = sum(barrel_pedwidth) / barrel_pedwidth.size() * adc_to_mev;
109 m_pedwidth_avg[2] = sum(bwd_pedwidth) / bwd_pedwidth.size() * adc_to_mev;
110 m_pedwidth_avg[3] = pedwidth_sum / ECLElementNumbers::c_NCrystals * adc_to_mev;
111 } else {
112 for (int i = 0; i < 4; i++) {
113 m_pedwidth_max[i] = 0;
114 m_pedwidth_avg[i] = 0;
115 }
116 }
117
118 //== Set EPICS PVs
119
120 if (h_fail_crateid != NULL) {
121 // Set fit consistency check PVs
122 for (int i = 0; i < c_collector_count; i++) {
123 std::string pv_name = (boost::format("logic_check:crate%02d") %
124 (i + 1)).str();
125 int errors_count = h_fail_crateid->GetBinContent(i + 1);
126 setEpicsPV(pv_name, errors_count);
127 }
128 // Set pedestal width PVs
129 static const char* part_id[] = {"fw", "br", "bw", "al"};
130 for (int i = 0; i < 4; i++) {
131 if (m_pedwidth_max[i] <= 0) continue;
132 std::string pv_name = "pedwidth:max_";
133 pv_name += part_id[i];
134 setEpicsPV(pv_name, m_pedwidth_max[i]);
135 }
136 for (int i = 0; i < 4; i++) {
137 if (m_pedwidth_avg[i] <= 0) continue;
138 std::string pv_name = "pedwidth:avg_";
139 pv_name += part_id[i];
140 setEpicsPV(pv_name, m_pedwidth_avg[i]);
141 }
142 }
143}
144
146{
147 B2DEBUG(20, "DQMHistAnalysisECLShapers: endRun called");
148
149 //= Set the contents of ECL monitoring object
150 m_c_main->Clear(); // clear existing content
151
152 TProfile* h_pedrms_cellid = (TProfile*)findHist("ECL/pedrms_cellid");
153 if (h_pedrms_cellid == nullptr) {
154 m_monObj->setVariable("comment", "No ECL pedestal width histograms available");
155 B2INFO("Histogram named ECL/pedrms_cellid is not found.");
156 return;
157 }
158
159 m_c_main->cd();
160 h_pedrms_cellid->Draw();
161
162 // set values of monitoring variables (if variable already exists this will
163 // change its value, otherwise it will insert new variable)
164 m_monObj->setVariable("pedwidthmaxFWD", m_pedwidth_max[0]);
165 m_monObj->setVariable("pedwidthmaxBarrel", m_pedwidth_max[1]);
166 m_monObj->setVariable("pedwidthmaxBWD", m_pedwidth_max[2]);
167 m_monObj->setVariable("pedwidthmaxTotal", m_pedwidth_max[3]);
168 m_monObj->setVariable("pedwidthavgFWD", m_pedwidth_avg[0]);
169 m_monObj->setVariable("pedwidthavgBarrel", m_pedwidth_avg[1]);
170 m_monObj->setVariable("pedwidthavgBWD", m_pedwidth_avg[2]);
171 m_monObj->setVariable("pedwidthavgTotal", m_pedwidth_avg[3]);
172}
173
174
175double DQMHistAnalysisECLShapersModule::robust_max(std::multiset<double> values)
176{
177 int len = values.size();
178 if (len < 10) {
179 return 0;
180 }
181 // Move end iterator back by 10% to remove
182 // noisy values.
183 auto end_iter = std::prev(values.end(), len * 0.1);
184
185 return *end_iter;
186}
187
void initialize() override final
Initialize the module.
double m_pedwidth_avg[4]
Average pedestal width array See m_pedwidth_max for the details.
DQMHistAnalysisECLShapersModule()
< derived from DQMHistAnalysisModule class.
std::string m_pvPrefix
Prefix to use for PVs registered by this module.
MonitoringObject * m_monObj
monitoring object
double robust_max(std::multiset< double > values)
Remove upper 10% of the values, return the maximum in the remaining 90%.
double m_pedwidth_max[4]
Max pedestal width array [0] -> Max pedestal width in FWD endcap [1] -> Max pedestal width in barrel ...
void event() override final
Event processor.
TCanvas * m_c_main
main panel for monitoring object
void endRun() override final
Call when a run ends.
void beginRun() override final
Call when a run begins.
static const int c_collector_count
Number of ECLCollector modules (normally 52)
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
void setEpicsPV(std::string keyname, double value)
Write value to a EPICS PV.
DQMHistAnalysisModule()
Constructor / Destructor.
int registerEpicsPV(std::string pvname, std::string keyname="")
EPICS related Functions.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.