Belle II Software  release-08-01-10
DQMHistAnalysisPXDCM.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 : DQMHistAnalysisPXDCM.cc
10 // Description : Analysis of PXD Common Modes
11 //-
12 
13 
14 #include <dqm/analysis/modules/DQMHistAnalysisPXDCM.h>
15 #include <TROOT.h>
16 #include <TLatex.h>
17 #include <TPaveText.h>
18 #include <vxd/geometry/GeoCache.h>
19 #include <framework/core/ModuleParam.templateDetails.h>
20 
21 using namespace std;
22 using namespace Belle2;
23 
24 //-----------------------------------------------------------------
25 // Register the Module
26 //-----------------------------------------------------------------
27 REG_MODULE(DQMHistAnalysisPXDCM);
28 
29 //-----------------------------------------------------------------
30 // Implementation
31 //-----------------------------------------------------------------
32 
33 DQMHistAnalysisPXDCMModule::DQMHistAnalysisPXDCMModule()
35 {
36  // This module CAN NOT be run in parallel!
37  setDescription("DQM Analysis for PXD Common Mode");
38 
39  // Parameter definition
40  addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir", std::string("PXDDAQ"));
41  addParam("minEntries", m_minEntries, "minimum number of new entries for last time slot", 10000);
42 
43  addParam("warnMeanAdhoc", m_warnMeanAdhoc, "warn level for peak position", 2.0);
44  addParam("errorMeanAdhoc", m_errorMeanAdhoc, "error level for peak position", 3.0);
45  addParam("warnOutsideAdhoc", m_warnOutsideAdhoc, "warn level for outside fraction", 1e-5);
46  addParam("errorOutsideAdhoc", m_errorOutsideAdhoc, "error level for outside fraction", 1e-4);
47  addParam("upperLineAdhoc", m_upperLineAdhoc, "upper threshold and line for outside fraction", 17);
48 
49  addParam("gateMaskModuleList", m_parModuleList, "Module List for Gate Masking");
50  addParam("gateMaskGateList", m_parGateList, "Gate List for Gate Masking");
51  addParam("excluded", m_excluded, "excluded module (indizes starting from 0 to 39)");
52 
53  B2DEBUG(99, "DQMHistAnalysisPXDCM: Constructor done.");
54 }
55 
57 {
58 }
59 
61 {
64 
65  // collect the list of all PXD Modules in the geometry here
66  std::vector<VxdID> sensors = geo.getListOfSensors();
67  for (VxdID& aVxdID : sensors) {
68  VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
69  if (info.getType() != VXD::SensorInfoBase::PXD) continue;
70  m_PXDModules.push_back(aVxdID); // reorder, sort would be better
71  }
72  std::sort(m_PXDModules.begin(), m_PXDModules.end()); // back to natural order
73 
74  gROOT->cd(); // this seems to be important, or strange things happen
75 
76  if (m_PXDModules.size() == 0) {
77  // Backup if no geometry is present (testing...)
78  B2WARNING("No PXDModules in Geometry found! Use hard-coded setup.");
79  std::vector <string> mod = {
80  "1.1.1", "1.1.2", "1.2.1", "1.2.2", "1.3.1", "1.3.2", "1.4.1", "1.4.2",
81  "1.5.1", "1.5.2", "1.6.1", "1.6.2", "1.7.1", "1.7.2", "1.8.1", "1.8.2",
82  "2.1.1", "2.1.2", "2.2.1", "2.2.2", "2.3.1", "2.3.2", "2.4.1", "2.4.2",
83  "2.5.1", "2.5.2", "2.6.1", "2.6.2", "2.7.1", "2.7.2", "2.8.1", "2.8.2",
84  "2.9.1", "2.9.2", "2.10.1", "2.10.2", "2.11.1", "2.11.2", "2.12.1", "2.12.2"
85  };
86  for (auto& it : mod) m_PXDModules.push_back(VxdID(it));
87  }
88  m_cCommonModeDelta = new TCanvas((m_histogramDirectoryName + "/c_CommonModeDelta").data());
89 
90  m_hCommonModeDelta = new TH2D("hPXDCommonModeAdhoc", "PXD CommonMode Adhoc; Module; CommonMode", m_PXDModules.size(), 0,
91  m_PXDModules.size(), 63, 0, 63);
92  m_hCommonModeDelta->SetDirectory(0);// dont mess with it, this is MY histogram
93  m_hCommonModeDelta->SetStats(false);
94 
95  for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
96  TString ModuleName = (std::string)m_PXDModules[i];
97  m_hCommonModeDelta->GetXaxis()->SetBinLabel(i + 1, ModuleName);
98  addDeltaPar(m_histogramDirectoryName, "PXDDAQCM_" + (std::string)m_PXDModules[i], HistDelta::c_Underflow, m_minEntries,
99  1); // register delta
100  }
101  //Unfortunately this only changes the labels, but can't fill the bins by the VxdIDs
102  m_hCommonModeDelta->Draw("colz");
103 
105 
106  if (m_parModuleList.size() != m_parGateList.size()) {
107  B2FATAL("Parameter list need same length");
108  return;
109  }
110  for (size_t i = 0; i < m_parModuleList.size(); i++) {
111  for (auto n : m_parGateList[i]) {
112  m_maskedGates[VxdID(m_parModuleList[i])].push_back(n);
113  }
114  }
115 
117  m_line1 = new TLine(0, 10, m_PXDModules.size(), 10);
118  m_lineA = new TLine(0, m_upperLineAdhoc, m_PXDModules.size(), m_upperLineAdhoc);
119  m_line1->SetHorizontal(true);
120  m_line1->SetLineColor(3);// Green
121  m_line1->SetLineWidth(3);
122  m_lineA->SetHorizontal(true);
123  m_lineA->SetLineColor(1);// Black
124  m_lineA->SetLineWidth(3);
125 
126 
127  registerEpicsPV("PXD:CommonMode:Status_Adhoc", "Status");
128  registerEpicsPV("PXD:CommonMode:Outside", "Outside");
129  registerEpicsPV("PXD:CommonMode:CM63", "CM63");
130  //registerEpicsPV("PXD:CommonMode:CM62", "CM62");
131 
132  for (VxdID& aPXDModule : m_PXDModules) {
133  auto buff = (std::string)aPXDModule;
134  replace(buff.begin(), buff.end(), '.', '_');
135  registerEpicsPV("PXD:CommonMode:Mean:" + buff, (std::string)aPXDModule);
136  }
137  B2DEBUG(99, "DQMHistAnalysisPXDCM: initialized.");
138 }
139 
141 {
142  B2DEBUG(99, "DQMHistAnalysisPXDCM: beginRun called.");
143 
144  m_cCommonModeDelta->Clear();
145  m_cCommonModeDelta->SetLogz();
146 
147  // this is needed at least for the "Old" and "Delta" one or update doesnt work
148  m_hCommonModeDelta->Reset();
149 }
150 
152 {
153  double all_outside = 0.0, all = 0.0;
154  double all_cm = 0.0;
155  bool error_adhoc_flag = false;
156  bool warn_adhoc_flag = false;
157  bool anyupdate = false;
158 
159  auto leg = new TPaveText(0.1, 0.6, 0.90, 0.95, "NDC");
160  leg->SetFillStyle(0);
161  leg->SetBorderSize(0);
162 
163  for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
164  auto modname = (std::string)m_PXDModules[i];
165  std::string name = "PXDDAQCM_" + modname;
166 
167  auto hh1 = getDelta(m_histogramDirectoryName, name); // default, only updated
168  if (hh1) {
169  auto scale = hh1->GetBinContent(0); // misuse underflow as event counter
170  bool update = scale >= m_minEntries ; // filter initial sampling
171  anyupdate |= update;
172  if (scale > 0) scale = 1.0 / scale;
173  else scale = 1.; // worst case, no events at run start
174 
175  auto& gm = m_maskedGates[m_PXDModules[i]];
176  // We loop over a 2d histogram!
177  // loop CM values
178  for (int bin = 1; bin <= 64; bin++) { // including CM63!!!
179  // loop gates*asics
180  double v = 0;
181  for (int gate = 0; gate < 192; gate++) {
182  // attention, gate is not bin nr!
183  if (std::find(gm.begin(), gm.end(), gate) == gm.end()) {
184  v += hh1->GetBinContent(hh1->GetBin(gate + 1 + 192 * 0, bin)) +
185  hh1->GetBinContent(hh1->GetBin(gate + 1 + 192 * 1, bin)) +
186  hh1->GetBinContent(hh1->GetBin(gate + 1 + 192 * 2, bin)) +
187  hh1->GetBinContent(hh1->GetBin(gate + 1 + 192 * 3, bin));
188  }
189  }
190  // integration intervalls depend on CM default value, this seems to be agreed =10
191  // FIXME currently we have to much noise below the line ... thus excluding this to avoid false alarms
192  // outside_full += hh1->Integral(1 /*0*/, 5); /// FIXME we exclude bin 0 as we use it for debugging/timing pixels
193  // attention, n bins!
194  // we integrate up including value 62 (cm overflow), but not 63 (fifo full)
195  if (bin == 63 + 1) { // CM63
196  all_cm += v;
197  } else { // excluding CM63
198  all += v;
199  if (bin > m_upperLineAdhoc + 1) all_outside += v;
200  }
201  m_hCommonModeDelta->SetBinContent(i + 1, bin, v * scale); // attention, mixing bin nr and index
202  }
203 
204  if (update) {
205  Double_t mean_adhoc = 0.;
206  Double_t entries_adhoc = 0.;
207  Double_t outside_adhoc = 0.;
208 
209  // Attention, Bins
210  // we do not need to re-scale it as the scale is the same for all bins
211  for (int cm_y = 0; cm_y < m_upperLineAdhoc; cm_y++) {
212  auto v = m_hCommonModeDelta->GetBinContent(m_hCommonModeDelta->GetBin(i + 1, cm_y + 1));
213  entries_adhoc += v;
214  mean_adhoc += v * (cm_y + 1);
215  }
216  // Attention, Bins
217  // We ignore CM63 in outside and overall count
218  for (int cm_y = m_upperLineAdhoc; cm_y < 63; cm_y++) {
219  auto v = m_hCommonModeDelta->GetBinContent(m_hCommonModeDelta->GetBin(i + 1, cm_y + 1));
220  entries_adhoc += v;
221  outside_adhoc += v;
222  }
223  if (entries_adhoc > 0 && scale < 1e-3) { // ignore modules with minimum events
224  // scale <1e-3 == >1000 events
225  mean_adhoc /= entries_adhoc; // calculate mean
226  auto warn_tmp_m = fabs(10.0 - mean_adhoc) > m_warnMeanAdhoc;
227  auto err_tmp_m = fabs(10.0 - mean_adhoc) > m_errorMeanAdhoc;
228  auto warn_tmp_os = outside_adhoc / entries_adhoc > m_warnOutsideAdhoc;
229  auto err_tmp_os = outside_adhoc / entries_adhoc > m_errorOutsideAdhoc;
230  warn_adhoc_flag |= warn_tmp_m || warn_tmp_os;
231  error_adhoc_flag |= err_tmp_m || err_tmp_os;
232 
233  if (warn_tmp_m || err_tmp_m) {
234  TString tmp;
235  tmp.Form("%s: Mean %f", modname.c_str(), mean_adhoc);
236  leg->AddText(tmp);
237  B2INFO(name << " Mean " << mean_adhoc << " " << warn_tmp_m << err_tmp_m);
238  }
239  if (warn_tmp_os || err_tmp_os) {
240  TString tmp;
241  tmp.Form("%s: Outside %f %%", modname.c_str(), 100. * outside_adhoc / entries_adhoc);
242  leg->AddText(tmp);
243  B2INFO(name << " Outside " << outside_adhoc / entries_adhoc << " (" << outside_adhoc << "/" << entries_adhoc << ") " << warn_tmp_os
244  << err_tmp_os);
245  }
246  m_monObj->setVariable(("cm_" + modname).c_str(), mean_adhoc);
247 
248  setEpicsPV((std::string)m_PXDModules[i], mean_adhoc);
249  }
250  }
251  }
252  }
253 
254  {
255  int status_adhoc = 0;
256  m_cCommonModeDelta->cd();
257  // not enough Entries
258 
259  if (all < 100.) { // delta cannot be more than all
260  m_cCommonModeDelta->Pad()->SetFillColor(kGray);// Magenta or Gray
261  status_adhoc = 0; // default
262  } else {
264  if (error_adhoc_flag) {
265  m_cCommonModeDelta->Pad()->SetFillColor(kRed);// Red
266  status_adhoc = 4;
267  } else if (warn_adhoc_flag) {
268  m_cCommonModeDelta->Pad()->SetFillColor(kYellow);// Yellow
269  status_adhoc = 3;
270  } else {
271  m_cCommonModeDelta->Pad()->SetFillColor(kGreen);// Green
272  status_adhoc = 2;
273  /* } else { // between 0 and 50 ...
274  m_cCommonModeDelta->Pad()->SetFillColor(kWhite);// White
275  status_adhoc = 1;*/
276  }
277  }
278  if (anyupdate) {
279  double dataoutside = all > 0 ? (all_outside / all) : 0;
280  double datacm = all > 0 ? (all_cm / all) : 0;
281  setEpicsPV("Status", status_adhoc);
282  setEpicsPV("Outside", dataoutside);
283  setEpicsPV("CM63", datacm);
284  }
285  if (m_hCommonModeDelta) {
286  m_hCommonModeDelta->Draw("colz");
287  leg->Draw();
288  m_line1->Draw();
289  m_lineA->Draw();
290  }
291 
292  for (auto& it : m_excluded) {
293  auto tt = new TLatex(it + 0.5, 0, (" " + std::string(m_PXDModules[it]) + " Module is excluded, please ignore").c_str());
294  tt->SetTextSize(0.035);
295  tt->SetTextAngle(90);// Rotated
296  tt->SetTextAlign(12);// Centered
297  tt->Draw();
298  }
299 
301  m_cCommonModeDelta->Modified();
302  m_cCommonModeDelta->Update();
303  }
304 
305 }
306 
308 {
309  B2DEBUG(99, "DQMHistAnalysisPXDCM: terminate called");
310 }
311 
The base class for the histogram analysis module.
int registerEpicsPV(std::string pvname, std::string keyname="", bool update_pvs=true)
EPICS related Functions.
void addDeltaPar(const std::string &dirname, const std::string &histname, HistDelta::EDeltaType t, int p, unsigned int a=1)
Add Delta histogram parameters.
TH1 * getDelta(const std::string &fullname, int n=0, bool onlyIfUpdated=true)
Get Delta histogram.
void setEpicsPV(std::string keyname, double value)
Write value to a EPICS PV.
void UpdateCanvas(std::string name, bool updated=true)
Mark canvas as updated (or not)
static MonitoringObject * getMonitoringObject(const std::string &histname)
Get MonitoringObject with given name (new object is created if non-existing)
void terminate(void) override final
This method is called at the end of the event processing.
int m_minEntries
Update entry intervall.
double m_warnMeanAdhoc
warn level for mean adhoc plot
TCanvas * m_cCommonModeDelta
Final Canvas.
double m_errorMeanAdhoc
error level for mean adhoc plot
void initialize(void) override final
Initializer.
TLine * m_lineA
Line in the Canvas to guide the eye.
MonitoringObject * m_monObj
Monitoring Object.
TH2D * m_hCommonModeDelta
histogram covering all modules
std::vector< VxdID > m_PXDModules
IDs of all PXD Modules to iterate over.
std::string m_histogramDirectoryName
name of histogram directory
int m_upperLineAdhoc
threshold level/line for outside fraction
std::map< VxdID, std::vector< int > > m_maskedGates
Module wise gate masking in CM plot and alarm.
double m_errorOutsideAdhoc
error level for outside fraction
TLine * m_line1
Line in the Canvas to guide the eye.
std::vector< std::vector< int > > m_parGateList
Gate list for masking.
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.
std::vector< std::string > m_parModuleList
Module list for masking.
double m_warnOutsideAdhoc
warn level for outside fraction
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setVariable(const std::string &var, float val, float upErr=-1., float dwErr=-1)
set value to float variable (new variable is made if not yet existing)
void addCanvas(TCanvas *canv)
Add Canvas to monitoring object.
Class to faciliate easy access to sensor information of the VXD like coordinate transformations or pi...
Definition: GeoCache.h:39
const std::vector< VxdID > getListOfSensors() const
Get list of all sensors.
Definition: GeoCache.cc:59
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne 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:33
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.