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