Belle II Software  release-06-00-14
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 <vxd/geometry/GeoCache.h>
18 
19 using namespace std;
20 using namespace Belle2;
21 
22 //-----------------------------------------------------------------
23 // Register the Module
24 //-----------------------------------------------------------------
25 REG_MODULE(DQMHistAnalysisPXDCM)
26 
27 //-----------------------------------------------------------------
28 // Implementation
29 //-----------------------------------------------------------------
30 
33 {
34  // This module CAN NOT be run in parallel!
35 
36  //Parameter definition
37  addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir", std::string("PXDCM"));
38  addParam("PVPrefix", m_pvPrefix, "PV Prefix", std::string("DQM:PXD:CommonMode:"));
39  addParam("useEpics", m_useEpics, "useEpics", true);
40  addParam("minEntries", m_minEntries, "minimum number of new entries for last time slot", 10000);
41 
42  addParam("warnMeanAdhoc", m_warnMeanAdhoc, "warn level for peak position", 2.0);
43  addParam("errorMeanAdhoc", m_errorMeanAdhoc, "error level for peak position", 3.0);
44  addParam("warnOutsideAdhoc", m_warnOutsideAdhoc, "warn level for outside fraction", 1e-5);
45  addParam("errorOutsideAdhoc", m_errorOutsideAdhoc, "error level for outside fraction", 1e-4);
46  addParam("upperLineAdhoc", m_upperLineAdhoc, "upper threshold and line for outside fraction", 17);
47 
48  addParam("warnMeanFull", m_warnMeanFull, "warn level for peak position", 2.0);
49  addParam("errorMeanFull", m_errorMeanFull, "error level for peak position", 3.0);
50  addParam("warnOutsideFull", m_warnOutsideFull, "warn level for outside fraction", 1e-5);
51  addParam("errorOutsideFull", m_errorOutsideFull, "error level for outside fraction", 1e-4);
52  addParam("upperLineFull", m_upperLineFull, "upper threshold and line for outside fraction", 17);
53  B2DEBUG(99, "DQMHistAnalysisPXDCM: Constructor done.");
54 }
55 
56 DQMHistAnalysisPXDCMModule::~DQMHistAnalysisPXDCMModule()
57 {
58 #ifdef _BELLE2_EPICS
59  if (m_useEpics) {
60  if (ca_current_context()) ca_context_destroy();
61  }
62 #endif
63 }
64 
65 void DQMHistAnalysisPXDCMModule::initialize()
66 {
67  m_monObj = getMonitoringObject("pxd");
68  const VXD::GeoCache& geo = VXD::GeoCache::getInstance();
69 
70  // collect the list of all PXD Modules in the geometry here
71  std::vector<VxdID> sensors = geo.getListOfSensors();
72  for (VxdID& aVxdID : sensors) {
73  VXD::SensorInfoBase info = geo.getSensorInfo(aVxdID);
74  if (info.getType() != VXD::SensorInfoBase::PXD) continue;
75  m_PXDModules.push_back(aVxdID); // reorder, sort would be better
76  }
77  std::sort(m_PXDModules.begin(), m_PXDModules.end()); // back to natural order
78 
79  gROOT->cd(); // this seems to be important, or strange things happen
80 
81  m_cCommonMode = new TCanvas((m_histogramDirectoryName + "/c_CommonMode").data());
82  m_cCommonModeDelta = new TCanvas((m_histogramDirectoryName + "/c_CommonModeDelta").data());
83 
84  m_hCommonMode = new TH2D("hPXDCommonMode", "PXD CommonMode; Module; CommonMode", m_PXDModules.size(), 0, m_PXDModules.size(), 63, 0,
85  63);
86  m_hCommonMode->SetDirectory(0);// dont mess with it, this is MY histogram
87  m_hCommonMode->SetStats(false);
88  m_hCommonModeDelta = new TH2D("hPXDCommonModeAdhoc", "PXD CommonMode Adhoc; Module; CommonMode", m_PXDModules.size(), 0,
89  m_PXDModules.size(), 63, 0, 63);
90  m_hCommonModeDelta->SetDirectory(0);// dont mess with it, this is MY histogram
91  m_hCommonModeDelta->SetStats(false);
92  m_hCommonModeOld = new TH2D("hPXDCommonModeOld", "PXD CommonMode Old; Module; CommonMode", m_PXDModules.size(), 0,
93  m_PXDModules.size(),
94  63, 0, 63);
95  m_hCommonModeOld->SetDirectory(0);// dont mess with it, this is MY histogram
96  m_hCommonModeOld->SetStats(false);
97 
98  for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
99  TString ModuleName = (std::string)m_PXDModules[i];
100  m_hCommonMode->GetXaxis()->SetBinLabel(i + 1, ModuleName);
101  m_hCommonModeDelta->GetXaxis()->SetBinLabel(i + 1, ModuleName);
102  m_hCommonModeOld->GetXaxis()->SetBinLabel(i + 1, ModuleName);
103  }
104  //Unfortunately this only changes the labels, but can't fill the bins by the VxdIDs
105  m_hCommonMode->Draw("colz");
106  m_hCommonModeDelta->Draw("colz");
107  m_hCommonModeOld->Draw("colz");
108 
109  m_monObj->addCanvas(m_cCommonMode);
110 
112  m_line1 = new TLine(0, 10, m_PXDModules.size(), 10);
113  m_lineA = new TLine(0, m_upperLineAdhoc, m_PXDModules.size(), m_upperLineAdhoc);
114  m_lineF = new TLine(0, m_upperLineFull, m_PXDModules.size(), m_upperLineFull);
115  m_line1->SetHorizontal(true);
116  m_line1->SetLineColor(3);// Green
117  m_line1->SetLineWidth(3);
118  m_lineA->SetHorizontal(true);
119  m_lineA->SetLineColor(1);// Black
120  m_lineA->SetLineWidth(3);
121  m_lineF->SetHorizontal(true);
122  m_lineF->SetLineColor(1);// Black
123  m_lineF->SetLineWidth(3);
124 
125 
126 #ifdef _BELLE2_EPICS
127  if (m_useEpics) {
128  if (!ca_current_context()) SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
129  mychid.resize(4);
130  SEVCHK(ca_create_channel((m_pvPrefix + "Outside").data(), NULL, NULL, 10, &mychid[0]), "ca_create_channel failure");
131  SEVCHK(ca_create_channel((m_pvPrefix + "Status").data(), NULL, NULL, 10, &mychid[1]), "ca_create_channel failure");
132  SEVCHK(ca_create_channel((m_pvPrefix + "CM63").data(), NULL, NULL, 10, &mychid[2]), "ca_create_channel failure");
133  SEVCHK(ca_create_channel((m_pvPrefix + "Status_Adhoc").data(), NULL, NULL, 10, &mychid[3]), "ca_create_channel failure");
134 
135  for (VxdID& aPXDModule : m_PXDModules) {
136  TString buff = (std::string)aPXDModule;
137  buff.ReplaceAll(".", "_");
138  auto& my = mychid_mean[aPXDModule];
139  SEVCHK(ca_create_channel((m_pvPrefix + "Mean:" + buff).Data(), NULL, NULL, 10, &my), "ca_create_channel failure");
140  }
141  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
142  }
143 #endif
144  B2DEBUG(99, "DQMHistAnalysisPXDCM: initialized.");
145 }
146 
147 void DQMHistAnalysisPXDCMModule::beginRun()
148 {
149  B2DEBUG(99, "DQMHistAnalysisPXDCM: beginRun called.");
150 
151  m_cCommonMode->Clear();
152  m_cCommonModeDelta->Clear();
153  m_cCommonMode->SetLogz();
154  m_cCommonModeDelta->SetLogz();
155 
156  // this is needed at least for the "Old" and "Delta" one or update doesnt work
157  m_hCommonMode->Reset();
158  m_hCommonModeDelta->Reset();
159  m_hCommonModeOld->Reset();
160 }
161 
162 void DQMHistAnalysisPXDCMModule::event()
163 {
164  double all_outside = 0.0, all = 0.0;
165  double all_cm = 0.0;
166  bool error_full_flag = false;
167  bool warn_full_flag = false;
168  bool error_adhoc_flag = false;
169  bool warn_adhoc_flag = false;
170  bool anyupdate = false;
171  if (!m_cCommonMode) return;
172  m_hCommonMode->Reset(); // dont sum up!!!
173 
174  for (unsigned int i = 0; i < m_PXDModules.size(); i++) {
175  std::string name = "PXDDAQCM2_" + (std::string)m_PXDModules[i ];
176  // std::replace( name.begin(), name.end(), '.', '_');
177 
178  TH1* hh1 = findHist(name);
179  if (hh1 == NULL) {
180  hh1 = findHist(m_histogramDirectoryName, name);
181  }
182  if (hh1) {
183  double current_full = 0.0;
184  double outside_full = 0.0;
185 
186  auto nevent = hh1->GetBinContent(0); // misuse underflow as event counter
187  double scale = nevent - m_hCommonModeOld->GetBinContent(i + 1, 0); // number of new events for delta
188  bool update = scale > m_minEntries ;
189  anyupdate |= update;
190  if (update) m_hCommonModeOld->SetBinContent(i + 1, 0, nevent);
191  if (scale > 0) scale = 1.0 / scale;
192  else scale = 1.; // worst case, no events at run start
193  for (int bin = 1; bin <= 63; bin++) { // we ignore CM63!!!
194  double v;
195  v = hh1->GetBinContent(bin);
196  m_hCommonMode->SetBinContent(i + 1, bin, v); // attention, mixing bin nr and index
197  current_full += v;
198  if (nevent < m_minEntries) {
199  m_hCommonModeDelta->SetBinContent(i + 1, bin, v * scale); // attention, mixing bin nr and index
200  } else if (update) {
201  auto old = m_hCommonModeOld->GetBinContent(i + 1, bin); // attention, mixing bin nr and index
202  m_hCommonModeDelta->SetBinContent(i + 1, bin, (v - old)*scale); // attention, mixing bin nr and index
203  m_hCommonModeOld->SetBinContent(i + 1, bin, v); // attention, mixing bin nr and index
204  }
205  }
206 
208  // Attention, Integral uses the bin nr, not the value!
209  outside_full += hh1->Integral(m_upperLineFull + 1, 63);
210  // FIXME currently we have to much noise below the line ... thus excluding this to avoid false alarms
211  // outside_full += hh1->Integral(1 /*0*/, 5); /// FIXME we exclude bin 0 as we use it for debugging/timing pixels
212  all_outside += outside_full;
213  all += current_full;
214  double dhpc = hh1->GetBinContent(64);
215  all_cm += dhpc;
216  if (current_full > 1) {
217  error_full_flag |= (outside_full / current_full > m_errorOutsideFull);
218  warn_full_flag |= (outside_full / current_full > m_warnOutsideFull);
219  }
220 
221  if (update) {
222  Double_t mean_adhoc = 0.;
223  Double_t entries_adhoc = 0.;
224  Double_t outside_adhoc = 0.;
225  // Attention, Bins
226  // we do not need to re-scale it as the scale is the same for all bins
227  for (int cm_y = 0; cm_y < m_upperLineAdhoc; cm_y++) {
228  auto v = m_hCommonModeDelta->GetBinContent(m_hCommonModeDelta->GetBin(i + 1, cm_y + 1));
229  entries_adhoc += v;
230  mean_adhoc += v * (cm_y + 1);
231  }
232  // Attention, Bins
233  for (int cm_y = m_upperLineAdhoc; cm_y < 64; cm_y++) {
234  auto v = m_hCommonModeDelta->GetBinContent(m_hCommonModeDelta->GetBin(i + 1, cm_y + 1));
235  entries_adhoc += v;
236  outside_adhoc += v;
237  }
238  if (entries_adhoc > 0) { // ignore 1.3.2
239  mean_adhoc /= entries_adhoc; // calculate mean
240  // scale <1e-3 == >1000 entries
241  warn_adhoc_flag |= scale < 1e-3 && (fabs(10.0 - mean_adhoc) > m_warnMeanAdhoc || outside_adhoc > m_warnOutsideAdhoc);
242  error_adhoc_flag |= scale < 1e-3 && (fabs(10.0 - mean_adhoc) > m_errorMeanAdhoc || outside_adhoc > m_errorOutsideAdhoc);
243  m_monObj->setVariable(("cm_" + (std::string)m_PXDModules[i]).c_str(), mean_adhoc);
244 #ifdef _BELLE2_EPICS
245  if (m_useEpics) {
246  auto my = mychid_mean[m_PXDModules[i]];
247  // B2ERROR("Mean "<< name << " " << mean_adhoc << " " << outside_adhoc << " " << entries_adhoc << " " <<warn_adhoc_flag <<error_adhoc_flag );
248  if (my) SEVCHK(ca_put(DBR_DOUBLE, my, (void*)&mean_adhoc), "ca_set failure");
249  }
250 #endif
251  }
252  }
253  }
254  }
255 
256  int status = 0;
257  {
258  m_cCommonMode->cd();
259  // not enough Entries
260  if (all < 100.) {
261  m_cCommonMode->Pad()->SetFillColor(kGray);// Magenta or Gray
262  status = 0; // default
263  } else {
265  if (all_outside / all > m_errorOutsideFull || error_full_flag) {
266  m_cCommonMode->Pad()->SetFillColor(kRed);// Red
267  status = 4;
268  } else if (all_outside / all > m_warnOutsideFull || warn_full_flag) {
269  m_cCommonMode->Pad()->SetFillColor(kYellow);// Yellow
270  status = 3;
271  } else if (all_outside == 0. /*&& all_cm == 0.*/) {
272  m_cCommonMode->Pad()->SetFillColor(kGreen);// Green
273  status = 2;
274  } else { // between 0 and 50 ...
275  m_cCommonMode->Pad()->SetFillColor(kWhite);// White
276  status = 1;
277  }
278  }
279 
280  if (m_hCommonMode) {
281  m_hCommonMode->Draw("colz");
282  m_line1->Draw();
283  m_lineA->Draw();
284  }
285 
286  auto tt = new TLatex(5.5, 3, "1.3.2 Module is excluded, please ignore");
287  tt->SetTextAngle(90);// Rotated
288  tt->SetTextAlign(12);// Centered
289  tt->Draw();
290 
291  m_cCommonMode->Modified();
292  m_cCommonMode->Update();
293  }
294 
295  {
296  int status_adhoc = 0;
297  m_cCommonModeDelta->cd();
298  // not enough Entries
299 
300  if (all < 100.) { // delta cannot be more than all
301  m_cCommonModeDelta->Pad()->SetFillColor(kGray);// Magenta or Gray
302  status_adhoc = 0; // default
303  } else {
305  if (error_adhoc_flag) {
306  m_cCommonModeDelta->Pad()->SetFillColor(kRed);// Red
307  status_adhoc = 4;
308  } else if (warn_adhoc_flag) {
309  m_cCommonModeDelta->Pad()->SetFillColor(kYellow);// Yellow
310  status_adhoc = 3;
311  } else {
312  m_cCommonModeDelta->Pad()->SetFillColor(kGreen);// Green
313  status_adhoc = 2;
314  /* } else { // between 0 and 50 ...
315  m_cCommonModeDelta->Pad()->SetFillColor(kWhite);// White
316  status_adhoc = 1;*/
317  }
318  }
319 #ifdef _BELLE2_EPICS
320  if (m_useEpics && anyupdate) SEVCHK(ca_put(DBR_INT, mychid[3], (void*)&status_adhoc), "ca_set failure");
321 #endif
322  if (m_hCommonModeDelta) {
323  m_hCommonModeDelta->Draw("colz");
324  m_line1->Draw();
325  m_lineA->Draw();
326  }
327 
328  auto tt = new TLatex(5.5, 3, "1.3.2 Module is excluded, please ignore");
329  tt->SetTextAngle(90);// Rotated
330  tt->SetTextAlign(12);// Centered
331  tt->Draw();
332 
333  m_cCommonModeDelta->Modified();
334  m_cCommonModeDelta->Update();
335  }
336 
337 #ifdef _BELLE2_EPICS
338  if (m_useEpics) {
339  double data = all > 0 ? (all_outside / all) : 0;
340  double data2 = all > 0 ? (all_cm / all) : 0;
341  SEVCHK(ca_put(DBR_DOUBLE, mychid[0], (void*)&data), "ca_set failure");
342  SEVCHK(ca_put(DBR_INT, mychid[1], (void*)&status), "ca_set failure");
343  SEVCHK(ca_put(DBR_DOUBLE, mychid[2], (void*)&data2), "ca_set failure");
344  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
345  }
346 #endif
347 }
348 
349 void DQMHistAnalysisPXDCMModule::terminate()
350 {
351  B2DEBUG(99, "DQMHistAnalysisPXDCM: terminate called");
352  // should delete canvas here, maybe hist, too? Who owns it?
353 #ifdef _BELLE2_EPICS
354  if (m_useEpics) {
355  for (auto m : mychid) SEVCHK(ca_clear_channel(m), "ca_clear_channel failure");
356  for (auto& m : mychid_mean) SEVCHK(ca_clear_channel(m.second), "ca_clear_channel failure");
357  SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
358  }
359 #endif
360 }
361 
The base class for the histogram analysis module.
DQM Histogram Analysis for PXD Common Modes.
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:58
const SensorInfoBase & getSensorInfo(Belle2::VxdID id) const
Return a referecne to the SensorInfo of a given SensorID.
Definition: GeoCache.cc:66
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
#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.