Belle II Software development
DQMHistAnalysisPXDReduction.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// File : DQMHistAnalysisPXDReduction.cc
10// Description : Analysis of PXD Reduction
11//-
12
13
14#include <dqm/analysis/modules/DQMHistAnalysisPXDReduction.h>
15#include <TROOT.h>
16#include <TLatex.h>
17#include <vxd/geometry/GeoCache.h>
18
19using namespace std;
20using namespace Belle2;
21
22//-----------------------------------------------------------------
23// Register the Module
24//-----------------------------------------------------------------
25REG_MODULE(DQMHistAnalysisPXDReduction);
26
27//-----------------------------------------------------------------
28// Implementation
29//-----------------------------------------------------------------
30
33{
34 // This module CAN NOT be run in parallel!
35 setDescription("PXD DQM analysis module for ONSEN Data Reduction Monitoring");
36
37 // Parameter definition
38 addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir", std::string("PXDDAQ"));
39 addParam("LowerWarnLimit", m_meanLowerWarn, "Mean Reduction Low limit for warning", double(NAN)); // default is NAN =disable
40 addParam("LowerErrorLimit", m_meanLowerAlarm, "Mean Reduction Low limit for alarms", double(NAN)); // default is NAN =disable
41 addParam("UpperWarnLimit", m_meanUpperWarn, "Mean Reduction High limit for warning", double(NAN)); // default is NAN =disable
42 addParam("UpperErrorLimit", m_meanUpperAlarm, "Mean Reduction High limit for alarms", double(NAN)); // default is NAN =disable
43 addParam("minEntries", m_minEntries, "minimum number of new entries for last time slot", 1000);
44 addParam("excluded", m_excluded, "excluded module (indizes starting from 0 to 39)", std::vector<int>());
45 B2DEBUG(1, "DQMHistAnalysisPXDReduction: Constructor done.");
46}
47
49{
50 B2DEBUG(1, "DQMHistAnalysisPXDReduction: initialized.");
51
54
55 //collect the list of all PXD Modules in the geometry here
56 std::vector<VxdID> sensors = geo.getListOfSensors();
57 for (const auto& aVxdID : sensors) {
58 VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
59 if (info.getType() != VXD::SensorInfoBase::PXD) continue;
60 m_PXDModules.push_back(aVxdID); // reorder, sort would be better
61 }
62 std::sort(m_PXDModules.begin(), m_PXDModules.end()); // back to natural order
63
64 gROOT->cd(); // this seems to be important, or strange things happen
65
66 if (m_PXDModules.size() == 0) {
67 // Backup if no geometry is present (testing...)
68 B2WARNING("No PXDModules in Geometry found! Use hard-coded setup.");
69 std::vector <string> mod = {
70 "1.1.1", "1.1.2", "1.2.1", "1.2.2", "1.3.1", "1.3.2", "1.4.1", "1.4.2",
71 "1.5.1", "1.5.2", "1.6.1", "1.6.2", "1.7.1", "1.7.2", "1.8.1", "1.8.2",
72 "2.1.1", "2.1.2", "2.2.1", "2.2.2", "2.3.1", "2.3.2", "2.4.1", "2.4.2",
73 "2.5.1", "2.5.2", "2.6.1", "2.6.2", "2.7.1", "2.7.2", "2.8.1", "2.8.2",
74 "2.9.1", "2.9.2", "2.10.1", "2.10.2", "2.11.1", "2.11.2", "2.12.1", "2.12.2"
75 };
76 for (const auto& it : mod) m_PXDModules.push_back(VxdID(it));
77 }
78
79 m_cReduction = new TCanvas((m_histogramDirectoryName + "/c_Reduction").data());
80 m_hReduction = new TH1F("hPXDReduction", "PXD Reduction; Module; Reduction", m_PXDModules.size(), 0, m_PXDModules.size());
81 m_hReduction->SetDirectory(0);// dont mess with it, this is MY histogram
82 m_hReduction->SetStats(false);
83 for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
84 TString ModuleName = (std::string)m_PXDModules[i];
85 m_hReduction->GetXaxis()->SetBinLabel(i + 1, ModuleName);
87 "PXDDAQDHEDataReduction_" + (std::string)m_PXDModules[i])) addDeltaPar(m_histogramDirectoryName,
88 "PXDDAQDHEDataReduction_" + (std::string)m_PXDModules[i], HistDelta::c_Entries, m_minEntries,
89 1); // register delta
90 }
91 //Unfortunately this only changes the labels, but can't fill the bins by the VxdIDs
92 m_hReduction->Draw("");
93 m_monObj->addCanvas(m_cReduction);
94
95 m_meanLine = new TLine(0, 10, m_PXDModules.size(), 10);
96 m_meanUpperWarnLine = new TLine(0, 16, m_PXDModules.size(), 16);
97 m_meanLowerWarnLine = new TLine(0, 0.9, m_PXDModules.size(), 0.9);
98 m_meanUpperAlarmLine = new TLine(0, 20, m_PXDModules.size(), 20);
99 m_meanLowerAlarmLine = new TLine(0, 0.5, m_PXDModules.size(), 0.5);
100 m_meanLine->SetHorizontal(true);
101 m_meanLine->SetLineColor(kBlue);
102 m_meanLine->SetLineWidth(3);
103 m_meanUpperWarnLine->SetHorizontal(true);
104 m_meanUpperWarnLine->SetLineColor(c_ColorWarning + 2);
105 m_meanUpperWarnLine->SetLineWidth(3);
106 m_meanLowerWarnLine->SetHorizontal(true);
107 m_meanLowerWarnLine->SetLineColor(c_ColorWarning + 2);
108 m_meanLowerWarnLine->SetLineWidth(3);
109 m_meanUpperAlarmLine->SetHorizontal(true);
110 m_meanUpperAlarmLine->SetLineColor(c_ColorError + 2);
111 m_meanUpperAlarmLine->SetLineWidth(3);
112 m_meanLowerAlarmLine->SetHorizontal(true);
113 m_meanLowerAlarmLine->SetLineColor(c_ColorError + 2);
114 m_meanLowerAlarmLine->SetLineWidth(3);
115
116 registerEpicsPV("PXD:Red:Status", "Status");
117 registerEpicsPV("PXD:Red:Value", "Value");
118}
119
120
122{
123 B2DEBUG(1, "DQMHistAnalysisPXDReduction: beginRun called.");
124
125 m_cReduction->Clear();
126 m_hReduction->Reset(); // dont sum up!!!
128
129 // override with limits from EPICS. if they are set
131
132 if (!std::isnan(m_meanLowerAlarm)) {
135 }
136 if (!std::isnan(m_meanLowerWarn)) {
139 }
140 if (!std::isnan(m_meanUpperWarn)) {
143 }
144 if (!std::isnan(m_meanUpperAlarm)) {
147 }
148}
149
151{
152 if (!m_cReduction) return;
153
154 double ireduction = 0.0;
155 int ireductioncnt = 0;
156
157 bool anyupdate = false;
158 for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
159 std::string name = "PXDDAQDHEDataReduction_" + (std::string)m_PXDModules[i ];
160 // std::replace( name.begin(), name.end(), '.', '_');
161
162 TH1* hh1 = getDelta(m_histogramDirectoryName, name);
163 // no initial sampling, we should get plenty of statistics
164 if (hh1) {
165 auto mean = hh1->GetMean();
166 m_hReduction->SetBinContent(i + 1, mean);
167 anyupdate = true;
168 }
169 }
170
171 if (!anyupdate) return; // nothing new -> no update
172
173 // calculate the mean of the mean
174 for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
175 // ignore modules in exclude list
176 if (std::find(m_excluded.begin(), m_excluded.end(), i) != m_excluded.end()) continue;
177 auto mean = m_hReduction->GetBinContent(i + 1);
178 if (mean > 0) { // only for valid values
179 ireduction += mean; // well fit would be better
180 ireductioncnt++;
181 }
182 }
183
184 m_cReduction->cd();
185
186 double value = ireductioncnt > 0 ? ireduction / ireductioncnt : 0;
187
188 // if any if NaN, the comparison is false
189 auto stat_data = makeStatus(ireductioncnt >= 15,
190 value > m_meanUpperWarn || value < m_meanLowerWarn,
191 value > m_meanUpperAlarm || value < m_meanLowerAlarm);
192
193 if (m_hReduction) {
194 m_hReduction->Draw("");
195 if (stat_data != c_StatusTooFew) {
196 m_meanLine->SetY1(value);
197 m_meanLine->SetY2(value); // aka SetHorizontal
198 m_meanLine->Draw();
199 }
200 if (!std::isnan(m_meanLowerAlarm)) m_meanLowerAlarmLine->Draw();
201 if (!std::isnan(m_meanLowerWarn)) m_meanLowerWarnLine->Draw();
202 if (!std::isnan(m_meanUpperWarn)) m_meanUpperWarnLine->Draw();
203 if (!std::isnan(m_meanUpperAlarm)) m_meanUpperAlarmLine->Draw();
204 for (const auto& it : m_excluded) {
205 static std::map <int, TLatex*> ltmap;
206 auto tt = ltmap[it];
207 if (!tt) {
208 tt = new TLatex(it + 0.5, 0, (" " + std::string(m_PXDModules[it]) + " Module is excluded, please ignore").c_str());
209 tt->SetTextSize(0.035);
210 tt->SetTextAngle(90);// Rotated
211 tt->SetTextAlign(12);// Centered
212 ltmap[it] = tt;
213 }
214 tt->Draw();
215 }
216 }
217
218 m_monObj->setVariable("reduction", value);
219
220 colorizeCanvas(m_cReduction, stat_data);
222 m_cReduction->Modified();
223 m_cReduction->Update();
224
225 // better only update if statistics is reasonable, we dont want "0" drops between runs!
226 setEpicsPV("Status", stat_data);
227 setEpicsPV("Value", value);
228}
229
231{
232 B2DEBUG(1, "DQMHistAnalysisPXDReduction: terminate called");
233
234 if (m_cReduction) delete m_cReduction;
235 if (m_hReduction) delete m_hReduction;
236
237 if (m_meanLine) delete m_meanLine;
242}
243
static bool hasDeltaPar(const std::string &dirname, const std::string &histname)
Check if Delta histogram parameters exist for histogram.
int registerEpicsPV(const std::string &pvname, const std::string &keyname="")
EPICS related Functions.
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
static void addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
static void colorizeCanvas(TCanvas *canvas, EStatus status)
Helper function for Canvas colorization.
@ c_ColorWarning
Analysis result: Warning, there may be minor issues.
@ c_ColorError
Analysis result: Severe issue found.
static void UpdateCanvas(const std::string &name, bool updated=true)
Mark canvas as updated (or not)
TH1 * getDelta(const std::string &fullname, int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
DQMHistAnalysisModule()
Constructor / Destructor.
@ c_StatusTooFew
Not enough entries/event to judge.
static EStatus makeStatus(bool enough, bool warn_flag, bool error_flag)
Helper function to judge the status for coloring and EPICS.
bool requestLimitsFromEpicsPVs(chid id, double &lowerAlarm, double &lowerWarn, double &upperWarn, double &upperAlarm)
Get Alarm Limits from EPICS PV.
void setEpicsPV(const std::string &keyname, double value)
Write value to a EPICS PV.
void terminate(void) override final
This method is called at the end of the event processing.
TH1F * m_hReduction
Histogram covering all modules.
TLine * m_meanUpperAlarmLine
Line in the Canvas to indicate limits.
TLine * m_meanLowerAlarmLine
Line in the Canvas to indicate limits.
void initialize(void) override final
Initializer.
MonitoringObject * m_monObj
Monitoring Object.
std::vector< VxdID > m_PXDModules
IDs of all PXD Modules to iterate over.
std::string m_histogramDirectoryName
name of histogram directory
TLine * m_meanLowerWarnLine
Line in the Canvas to indicate limits.
TLine * m_meanLine
Line in the Canvas to guide the eye.
TLine * m_meanUpperWarnLine
Line in the Canvas to indicate limits.
std::vector< int > m_excluded
Indizes of excluded PXD Modules.
void beginRun(void) override final
Called when entering a new run.
void event(void) override final
This method is called for each event.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Class to facilitate easy access to sensor information of the VXD like coordinate transformations or p...
Definition GeoCache.h:38
const std::vector< VxdID > getListOfSensors() const
Get list of all sensors.
Definition GeoCache.cc:59
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a reference to the SensorInfo of a given SensorID.
Definition GeoCache.cc:67
static GeoCache & getInstance()
Return a reference to the singleton instance.
Definition GeoCache.cc:214
Base class to provide Sensor Information for PXD and SVD.
Class to uniquely identify a any structure of the PXD and SVD.
Definition VxdID.h:32
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
Abstract base class for different kinds of events.
STL namespace.