Belle II Software  release-08-01-10
DQMHistAnalysisSVDDose.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 <dqm/analysis/modules/DQMHistAnalysisSVDDose.h>
10 #include <framework/utilities/Utils.h>
11 #include <TROOT.h>
12 #include <TText.h>
13 
14 using namespace std;
15 using namespace Belle2;
16 
17 // Utility function
18 inline double getClockSeconds() { return Utils::getClock() / 1e9; }
19 
20 REG_MODULE(DQMHistAnalysisSVDDose);
21 
22 DQMHistAnalysisSVDDoseModule::DQMHistAnalysisSVDDoseModule()
23 {
24  setDescription("Monitoring of SVD Dose with events from Poisson trigger w/o inj. veto. See also SVDDQMDoseModule.");
25  // THIS MODULE CAN NOT BE RUN IN PARALLEL
26  addParam("pvPrefix", m_pvPrefix, "Prefix for EPICS PVs.", std::string("DQM:SVD:"));
27  addParam("epicsUpdateSeconds", m_epicsUpdateSeconds,
28  "Minimum interval between two successive PV updates (in seconds).", 1000.0);
29  addParam("pvSuffix", m_pvSuffix, "Suffix for EPICS PVs.", std::string(":Occ:Pois:Avg"));
30  addParam("deltaTPVSuffix", m_deltaTPVSuffix, "Suffix for the PV that monitors the update interval of the PVs.",
31  std::string("Occ:Pois:UpdateInterval"));
32  addParam("statePVSuffix", m_statePVSuffix, "Suffix for the PV with the state of the monitoring.",
33  std::string("Occ:Pois:State"));
34 }
35 
36 DQMHistAnalysisSVDDoseModule::~DQMHistAnalysisSVDDoseModule()
37 {
38 #ifdef _BELLE2_EPICS
39  if (getUseEpics() && ca_current_context()) ca_context_destroy();
40 #endif
41 }
42 
43 void DQMHistAnalysisSVDDoseModule::initialize()
44 {
45  B2DEBUG(18, "DQMHistAnalysisSVDDose: initialize");
46 
47  gROOT->cd(); // Don't know why I need this, but DQMHistAnalysisSVDOnMiraBelle uses it
48 
49  m_monObj = getMonitoringObject("svd"); // To write to MiraBelle
50 
51  m_c_instOccu.reserve(c_sensorGroups.size());
52  m_c_occuLER.reserve(c_sensorGroups.size());
53  m_c_occuHER.reserve(c_sensorGroups.size());
54  m_c_occuLER1.reserve(c_sensorGroups.size());
55  m_c_occuHER1.reserve(c_sensorGroups.size());
56  m_c_instOccuAll.reserve(c_sensorGroups.size());
57  m_c_occuLERAll.reserve(c_sensorGroups.size());
58  m_c_occuHERAll.reserve(c_sensorGroups.size());
59  m_c_occuLER1All.reserve(c_sensorGroups.size());
60  m_c_occuHER1All.reserve(c_sensorGroups.size());
61  for (const auto& group : c_sensorGroups) {
62  TCanvas* c = new TCanvas("SVDDOSE/c_svd_instOccupancy_" + group.nameSuffix + "_pois",
63  "Instantaneous occupancy (Pois. trig.) " + group.titleSuffix);
64  m_c_instOccu.push_back(c);
65  c = new TCanvas("SVDDOSE/c_svd_occuLER_" + group.nameSuffix + "_pois",
66  "Occupancy vs time since LER inj. (Pois. trig.) " + group.titleSuffix);
67  m_c_occuLER.push_back(c);
68  c = new TCanvas("SVDDOSE/c_svd_occuHER_" + group.nameSuffix + "_pois",
69  "Occupancy vs time since HER inj. (Pois. trig.) " + group.titleSuffix);
70  m_c_occuHER.push_back(c);
71  c = new TCanvas("SVDDOSE/c_svd_1DoccuLER_" + group.nameSuffix + "_pois",
72  "Occupancy vs time since LER inj. (Pois. trig.) " + group.titleSuffix);
73  m_c_occuLER1.push_back(c);
74  c = new TCanvas("SVDDOSE/c_svd_1DoccuHER_" + group.nameSuffix + "_pois",
75  "Occupancy vs time since HER inj. (Pois. trig.) " + group.titleSuffix);
76  m_c_occuHER1.push_back(c);
77 
78  c = new TCanvas("SVDDOSE/c_svd_instOccupancy_" + group.nameSuffix + "_all",
79  "Instantaneous occupancy (all events) " + group.titleSuffix);
80  m_c_instOccuAll.push_back(c);
81  c = new TCanvas("SVDDOSE/c_svd_occuLER_" + group.nameSuffix + "_all",
82  "Occupancy vs time since LER inj. (all events) " + group.titleSuffix);
83  m_c_occuLERAll.push_back(c);
84  c = new TCanvas("SVDDOSE/c_svd_occuHER_" + group.nameSuffix + "_all",
85  "Occupancy vs time since HER inj. (all events) " + group.titleSuffix);
86  m_c_occuHERAll.push_back(c);
87  c = new TCanvas("SVDDOSE/c_svd_1DoccuLER_" + group.nameSuffix + "_all",
88  "Occupancy vs time since LER inj. (all events) " + group.titleSuffix);
89  m_c_occuLER1All.push_back(c);
90  c = new TCanvas("SVDDOSE/c_svd_1DoccuHER_" + group.nameSuffix + "_all",
91  "Occupancy vs time since HER inj. (all events) " + group.titleSuffix);
92  m_c_occuHER1All.push_back(c);
93  }
94 
95  // The legend need to be memory-leaked, so we make it once and use it evey time
96  m_legend = new TPaveText(0.53, 0.73, 0.68, 0.88, "brNDC");
97  m_legend->AddText("LER inj."); ((TText*)m_legend->GetListOfLines()->Last())->SetTextColor(kRed);
98  m_legend->AddText("HER inj."); ((TText*)m_legend->GetListOfLines()->Last())->SetTextColor(kAzure);
99  m_legend->AddText("No inj."); ((TText*)m_legend->GetListOfLines()->Last())->SetTextColor(kBlack);
100 
101 #ifdef _BELLE2_EPICS
102  if (getUseEpics()) {
103  if (!ca_current_context())
104  SEVCHK(ca_context_create(ca_disable_preemptive_callback), "ca_context_create");
105  // Channels for the occupancies
106  m_myPVs.resize(c_sensorGroups.size());
107  for (unsigned int g = 0; g < c_sensorGroups.size(); g++)
108  SEVCHK(ca_create_channel((m_pvPrefix + c_sensorGroups[g].pvMiddle + m_pvSuffix).data(),
109  NULL, NULL, 10, &m_myPVs[g].mychid), "ca_create_channel");
110  // Channels for update interval and state
111  SEVCHK(ca_create_channel((m_pvPrefix + m_deltaTPVSuffix).data(),
112  NULL, NULL, 10, &m_timeSinceLastPVUpdateChan), "ca_create_channel");
113  SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
114  NULL, NULL, 10, &m_stateChan), "ca_create_channel");
115  // Actually do create the channels, communicating with the IOC
116  SEVCHK(ca_pend_io(2.0), "ca_pend_io");
117  // Get the state enum
118  if (m_stateChan) {
119  SEVCHK(ca_get(DBR_CTRL_ENUM, m_stateChan, &m_stateCtrl), "ca_get");
120  B2DEBUG(19, "State PV initialized (ca_get)" << LogVar("value", m_stateCtrl.value));
121  SEVCHK(ca_pend_io(2.0), "ca_pend_io");
122  } else {
123  B2DEBUG(18, "State PV failed to initialize, will retry in beginRun(), event() and endRun().");
124  }
125  // First update should happen m_epicsUpdateSeconds from now
126  m_lastPVUpdate = getClockSeconds();
127  }
128 #endif
129 }
130 
131 void DQMHistAnalysisSVDDoseModule::beginRun()
132 {
133  // Set status PV to running, reset last update time
134 #ifdef _BELLE2_EPICS
135  if (getUseEpics()) {
136  B2DEBUG(19, "beginRun: setting state PV to RUNNING");
137  m_stateCtrl.value = 1;
138  if (m_stateChan) {
139  SEVCHK(ca_put(DBR_ENUM, m_stateChan, &m_stateCtrl.value), "ca_put");
140  } else {
141  SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
142  NULL, NULL, 10, &m_stateChan), "ca_create_channel (reconnection)");
143  }
144  SEVCHK(ca_pend_io(2.0), "ca_pend_io");
145  // First update should happen m_epicsUpdateSeconds from now
146  m_lastPVUpdate = getClockSeconds();
147  }
148 #endif
149 }
150 
151 void DQMHistAnalysisSVDDoseModule::event()
152 {
153  // Update PVs ("write" to EPICS)
154 #ifdef _BELLE2_EPICS
155  double timeSinceLastPVUpdate = getClockSeconds() - m_lastPVUpdate;
156  if (getUseEpics() && timeSinceLastPVUpdate >= m_epicsUpdateSeconds) {
157  // Dummy ca_get to ensure reconnection to the IOC in case of past errors
158  if (m_stateChan) {
159  SEVCHK(ca_get(DBR_CTRL_ENUM, m_stateChan, &m_stateCtrl), "ca_get");
160  } else {
161  SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
162  NULL, NULL, 10, &m_stateChan), "ca_create_channel (reconnection)");
163  }
164  SEVCHK(ca_pend_io(2.0), "ca_pend_io");
165 
166  // Write updateInterval PV and state PV first
167  if (m_timeSinceLastPVUpdateChan) {
168  SEVCHK(ca_put(DBR_DOUBLE, m_timeSinceLastPVUpdateChan, (void*)&timeSinceLastPVUpdate), "ca_put");
169  } else {
170  SEVCHK(ca_create_channel((m_pvPrefix + m_deltaTPVSuffix).data(), NULL, NULL, 10, &m_timeSinceLastPVUpdateChan),
171  "ca_create_channel (reconnection)");
172  }
173  m_stateCtrl.value = 1; // If IOC is restarted this PV must be re-updated
174  if (m_stateChan) {
175  SEVCHK(ca_put(DBR_ENUM, m_stateChan, &m_stateCtrl.value), "ca_put");
176  } else {
177  SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
178  NULL, NULL, 10, &m_stateChan), "ca_create_channel (reconnection)");
179  }
180  // Update occupancy PVs
181  for (unsigned int g = 0; g < c_sensorGroups.size(); g++) {
182  const auto& group = c_sensorGroups[g];
183  double nHits = 0.0, nEvts = 0.0;
184  for (TString dir : {"SVDDoseLERInjPois", "SVDDoseHERInjPois", "SVDDoseNoInjPois"}) {
185  auto hHits = findHistT<TH2F>(dir + "/SVDHitsVsTime_" + group.nameSuffix);
186  auto hEvts = findHistT<TH2F>(dir + "/SVDEvtsVsTime");
187  if (!hHits || !hEvts) {
188  B2WARNING("Histograms needed for Average Poisson Occupancy U-side not found.");
189  nEvts = 0.0;
190  break;
191  }
192  nHits += hHits->GetEntries();
193  nEvts += hEvts->GetEntries();
194  }
195 
196  B2DEBUG(19, "DQMHistAnalysisSVDDose: PV write"
197  << LogVar("group", group.nameSuffix.Data())
198  << LogVar("nEvts", nEvts) << LogVar("nHits", nHits));
199 
200  auto& pv = m_myPVs[g];
201  double delta_nHits = nHits - pv.lastNHits;
202  double delta_nEvts = nEvts - pv.lastNEvts;
203  double occ = delta_nEvts > 0.0 ? (delta_nHits / delta_nEvts * 100.0 / group.nStrips) : -1.0;
204  if (pv.mychid) {
205  SEVCHK(ca_put(DBR_DOUBLE, pv.mychid, (void*)&occ), "ca_put");
206  } else {
207  SEVCHK(ca_create_channel((m_pvPrefix + c_sensorGroups[g].pvMiddle + m_pvSuffix).data(),
208  NULL, NULL, 10, &m_myPVs[g].mychid), "ca_create_channel (reconnection)");
209  }
210  pv.lastNEvts = nEvts;
211  pv.lastNHits = nHits;
212  }
213 
214  // Actually write all the PVs
215  SEVCHK(ca_pend_io(2.0), "ca_pend_io");
216  m_lastPVUpdate = getClockSeconds();
217  }
218 #endif
219 
220  updateCanvases();
221 }
222 
223 void DQMHistAnalysisSVDDoseModule::endRun()
224 {
225  B2DEBUG(18, "DQMHistAnalysisSVDDose: endRun");
226 
227  // EPICS: reset the counters used for the delta computation, set state to NOT RUNNING
228 #ifdef _BELLE2_EPICS
229  if (getUseEpics()) {
230  B2DEBUG(19, "endRun: setting state PV to NOT RUNNING");
231  m_stateCtrl.value = 0;
232  if (m_stateChan) {
233  SEVCHK(ca_put(DBR_ENUM, m_stateChan, &m_stateCtrl.value), "ca_put");
234  } else {
235  SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
236  NULL, NULL, 10, &m_stateChan), "ca_create_channel (reconnection)");
237  }
238  SEVCHK(ca_pend_io(2.0), "ca_pend_io");
239  // Reset events and hits counters
240  for (auto& pv : m_myPVs)
241  pv.lastNEvts = pv.lastNHits = 0.0;
242  }
243 #endif
244 
245  // Write to MiraBelle
246  for (unsigned int g = 0; g < c_sensorGroups.size(); g++) {
247  const auto& group = c_sensorGroups[g];
248  double nHits = 0.0, nEvts = 0.0;
249  for (TString dir : {"SVDDoseLERInjPois", "SVDDoseHERInjPois", "SVDDoseNoInjPois"}) {
250  auto hHits = findHistT<TH2F>(dir + "/SVDHitsVsTime_" + group.nameSuffix);
251  auto hEvts = findHistT<TH2F>(dir + "/SVDEvtsVsTime");
252  if (!hHits || !hEvts) {
253  B2WARNING("Histograms needed for Average Poisson Occupancy U-side not found.");
254  nEvts = 0.0;
255  break;
256  }
257  nHits += hHits->GetEntries();
258  nEvts += hEvts->GetEntries();
259  }
260 
261  B2DEBUG(19, "DQMHistAnalysisSVDDose: MonObj write"
262  << LogVar("group", group.nameSuffix.Data())
263  << LogVar("nEvts", nEvts) << LogVar("nHits", nHits));
264 
265  double occ = nEvts ? (nHits / nEvts * 100.0 / group.nStrips) : -1.0;
266  TString vName = group.nameSuffix + "OccPoisAvg"; // e.g. L3XXUOccPoisAvg
267  m_monObj->setVariable(vName.Data(), occ);
268  }
269 
270  updateCanvases();
271 }
272 
273 void DQMHistAnalysisSVDDoseModule::updateCanvases()
274 {
275  B2DEBUG(18, "DQMHistAnalysisSVDDose: updating canvases");
276 
277  for (unsigned int g = 0; g < c_sensorGroups.size(); g++) {
278  const auto& group = c_sensorGroups[g];
279 
280  auto c = m_c_instOccu[g];
281  auto hLER = findHistT<TH1F>("SVDDoseLERInjPois/SVDInstOccu_" + group.nameSuffix);
282  auto hHER = findHistT<TH1F>("SVDDoseHERInjPois/SVDInstOccu_" + group.nameSuffix);
283  auto hNo = findHistT<TH1F>("SVDDoseNoInjPois/SVDInstOccu_" + group.nameSuffix);
284  if (hLER && hHER && hNo) {
285  hLER->SetLineColor(kRed);
286  hHER->SetLineColor(kAzure);
287  hNo->SetLineColor(kBlack);
288  carryOverflowOver(hLER);
289  carryOverflowOver(hHER);
290  carryOverflowOver(hNo);
291  c->Clear();
292  c->cd(0);
293  hNo->SetTitle("SVD instantaneous occu. " + group.titleSuffix + " U-side Pois. trig.");
294  hNo->Draw("hist"); // hNo usually has the larger maximum by far
295  hLER->Draw("hist same");
296  hHER->Draw("hist same");
297  c->SetLogy();
298  m_legend->Draw();
299  }
300 
301  c = m_c_occuLER[g];
302  auto hHits = findHistT<TH2F>("SVDDoseLERInjPois/SVDHitsVsTime_" + group.nameSuffix);
303  auto hEvts = findHistT<TH2F>("SVDDoseLERInjPois/SVDEvtsVsTime");
304  if (hHits && hEvts) {
305  auto hOccu = divide(hHits, hEvts, 100.0f / group.nStrips); // Intentional memory leak
306  hOccu->SetTitle("SVD Occupancy " + group.titleSuffix + " - LER inj. Pois. trig."
307  ";Time since last injection [#mus];Time in beam cycle [#mus]"
308  ";Occupancy [%]");
309  hOccu->SetMinimum(1e-3);
310  hOccu->SetMaximum(10);
311  c->Clear();
312  c->cd(0);
313  c->SetRightMargin(0.16); // For the colorbar
314  hOccu->Draw("COLZ");
315  c->SetLogz();
316  }
317 
318  c = m_c_occuLER1[g];
319  auto hpEvts = findHistT<TH1F>("SVDDoseLERInjPois/SVDEvtsVsTime1");
320  auto hpHits = findHistT<TH1F>("SVDDoseLERInjPois/SVDHitsVsTime1_" + group.nameSuffix);
321  if (hpHits && hpEvts) {
322  auto hpOccu = divide(hpHits, hpEvts, 100.0f / group.nStrips); // Intentional memory leak
323  hpOccu->SetTitle("SVD Occupancy " + group.titleSuffix + " - LER inj. Pois. trig."
324  ";Time since last injection [#mus];Occupancy [%]");
325  hpOccu->SetMinimum(1e-3);
326  hpOccu->SetMaximum(10);
327  c->Clear();
328  c->cd(0);
329  hpOccu->SetMarkerStyle(7);
330  hpOccu->Draw("hist P");
331  c->SetLogy();
332  }
333 
334  c = m_c_occuHER[g];
335  hHits = findHistT<TH2F>("SVDDoseHERInjPois/SVDHitsVsTime_" + group.nameSuffix);
336  hEvts = findHistT<TH2F>("SVDDoseHERInjPois/SVDEvtsVsTime");
337  if (hHits && hEvts) {
338  auto hOccu = divide(hHits, hEvts, 100.0f / group.nStrips); // Intentional memory leak
339  hOccu->SetTitle("SVD Occupancy " + group.titleSuffix + " - HER inj. Pois. trig."
340  ";Time since last injection [#mus];Time in beam cycle [#mus]"
341  ";Occupancy [%]");
342  hOccu->SetMinimum(1e-3);
343  hOccu->SetMaximum(10);
344  c->Clear();
345  c->cd(0);
346  c->SetRightMargin(0.16); // For the colorbar
347  hOccu->Draw("COLZ");
348  c->SetLogz();
349  }
350 
351  c = m_c_occuHER1[g];
352  hpEvts = findHistT<TH1F>("SVDDoseHERInjPois/SVDEvtsVsTime1");
353  hpHits = findHistT<TH1F>("SVDDoseHERInjPois/SVDHitsVsTime1_" + group.nameSuffix);
354  if (hpHits && hpEvts) {
355  auto hpOccu = divide(hpHits, hpEvts, 100.0f / group.nStrips); // Intentional memory leak
356  hpOccu->SetTitle("SVD Occupancy " + group.titleSuffix + " - HER inj. Pois. trig."
357  ";Time since last injection [#mus];Occupancy [%]");
358  hpOccu->SetMinimum(1e-3);
359  hpOccu->SetMaximum(10);
360  c->Clear();
361  c->cd(0);
362  hpOccu->SetMarkerStyle(7);
363  hpOccu->Draw("hist P");
364  c->SetLogy();
365  }
366 
367  // ========== All events =============
368  c = m_c_instOccuAll[g];
369  hLER = findHistT<TH1F>("SVDDoseLERInjAll/SVDInstOccu_" + group.nameSuffix);
370  hHER = findHistT<TH1F>("SVDDoseHERInjAll/SVDInstOccu_" + group.nameSuffix);
371  hNo = findHistT<TH1F>("SVDDoseNoInjAll/SVDInstOccu_" + group.nameSuffix);
372  if (hLER && hHER && hNo) {
373  hLER->SetLineColor(kRed);
374  hHER->SetLineColor(kAzure);
375  hNo->SetLineColor(kBlack);
376  carryOverflowOver(hLER);
377  carryOverflowOver(hHER);
378  carryOverflowOver(hNo);
379  c->Clear();
380  c->cd(0);
381  hNo->SetTitle("SVD instantaneous occu. " + group.titleSuffix + " U-side all events");
382  hNo->Draw("hist"); // hNo usually has the larger maximum by far
383  hLER->Draw("hist same");
384  hHER->Draw("hist same");
385  c->SetLogy();
386  m_legend->Draw();
387  }
388 
389  c = m_c_occuLERAll[g];
390  hHits = findHistT<TH2F>("SVDDoseLERInjAll/SVDHitsVsTime_" + group.nameSuffix);
391  hEvts = findHistT<TH2F>("SVDDoseLERInjAll/SVDEvtsVsTime");
392  if (hHits && hEvts) {
393  auto hOccu = divide(hHits, hEvts, 100.0f / group.nStrips); // Intentional memory leak
394  hOccu->SetTitle("SVD Occupancy " + group.titleSuffix + " - LER inj. all events"
395  ";Time since last injection [#mus];Time in beam cycle [#mus]"
396  ";Occupancy [%]");
397  hOccu->SetMinimum(1e-3);
398  hOccu->SetMaximum(10);
399  c->Clear();
400  c->cd(0);
401  c->SetRightMargin(0.16); // For the colorbar
402  hOccu->Draw("COLZ");
403  c->SetLogz();
404  }
405 
406  c = m_c_occuLER1All[g];
407  hpEvts = findHistT<TH1F>("SVDDoseLERInjAll/SVDEvtsVsTime1");
408  hpHits = findHistT<TH1F>("SVDDoseLERInjAll/SVDHitsVsTime1_" + group.nameSuffix);
409  if (hpHits && hpEvts) {
410  auto hpOccu = divide(hpHits, hpEvts, 100.0f / group.nStrips); // Intentional memory leak
411  hpOccu->SetTitle("SVD Occupancy " + group.titleSuffix + " - LER inj. all events"
412  ";Time since last injection [#mus];Occupancy [%]");
413  hpOccu->SetMinimum(1e-3);
414  hpOccu->SetMaximum(10);
415  c->Clear();
416  c->cd(0);
417  hpOccu->SetMarkerStyle(7);
418  hpOccu->Draw("hist P");
419  c->SetLogy();
420  }
421 
422  c = m_c_occuHERAll[g];
423  hHits = findHistT<TH2F>("SVDDoseHERInjAll/SVDHitsVsTime_" + group.nameSuffix);
424  hEvts = findHistT<TH2F>("SVDDoseHERInjAll/SVDEvtsVsTime");
425  if (hHits && hEvts) {
426  auto hOccu = divide(hHits, hEvts, 100.0f / group.nStrips); // Intentional memory leak
427  hOccu->SetTitle("SVD Occupancy " + group.titleSuffix + " - HER inj. all events"
428  ";Time since last injection [#mus];Time in beam cycle [#mus]"
429  ";Occupancy [%]");
430  hOccu->SetMinimum(1e-3);
431  hOccu->SetMaximum(10);
432  c->Clear();
433  c->cd(0);
434  c->SetRightMargin(0.16); // For the colorbar
435  hOccu->Draw("COLZ");
436  c->SetLogz();
437  }
438 
439  c = m_c_occuHER1All[g];
440  hpEvts = findHistT<TH1F>("SVDDoseHERInjAll/SVDEvtsVsTime1");
441  hpHits = findHistT<TH1F>("SVDDoseHERInjAll/SVDHitsVsTime1_" + group.nameSuffix);
442  if (hpHits && hpEvts) {
443  auto hpOccu = divide(hpHits, hpEvts, 100.0f / group.nStrips); // Intentional memory leak
444  hpOccu->SetTitle("SVD Occupancy " + group.titleSuffix + " - HER inj. all events"
445  ";Time since last injection [#mus];Occupancy [%]");
446  hpOccu->SetMinimum(1e-3);
447  hpOccu->SetMaximum(10);
448  c->Clear();
449  c->cd(0);
450  hpOccu->SetMarkerStyle(7);
451  hpOccu->Draw("hist P");
452  c->SetLogy();
453  }
454  }
455 }
456 
457 void DQMHistAnalysisSVDDoseModule::carryOverflowOver(TH1F* h)
458 {
459  int i = h->GetNbinsX();
460  float t = h->GetBinContent(i) + h->GetBinContent(i + 1);
461  h->SetBinContent(i, t);
462  h->SetBinContent(i + 1, 0);
463 }
464 
465 const vector<DQMHistAnalysisSVDDoseModule::SensorGroup> DQMHistAnalysisSVDDoseModule::c_sensorGroups = {
466  {"L31XU", "L3.1", "L3:1", 768 * 2},
467  {"L32XU", "L3.2", "L3:2", 768 * 2},
468  {"L3XXU", "L3 avg.", "L3", 768 * 14},
469  {"L4XXU", "L4 avg.", "L4", 768 * 30},
470  {"L5XXU", "L5 avg.", "L5", 768 * 48},
471  {"L6XXU", "L6 avg.", "L6", 768 * 80}
472 };
Class to store variables with their name which were sent to the logging service.
#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.