9 #include <dqm/analysis/modules/DQMHistAnalysisSVDDose.h>
10 #include <framework/utilities/Utils.h>
18 inline double getClockSeconds() {
return Utils::getClock() / 1e9; }
22 DQMHistAnalysisSVDDoseModule::DQMHistAnalysisSVDDoseModule()
24 setDescription(
"Monitoring of SVD Dose with events from Poisson trigger w/o inj. veto. See also SVDDQMDoseModule.");
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"));
36 DQMHistAnalysisSVDDoseModule::~DQMHistAnalysisSVDDoseModule()
39 if (getUseEpics() && ca_current_context()) ca_context_destroy();
43 void DQMHistAnalysisSVDDoseModule::initialize()
45 B2DEBUG(18,
"DQMHistAnalysisSVDDose: initialize");
49 m_monObj = getMonitoringObject(
"svd");
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);
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);
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);
103 if (!ca_current_context())
104 SEVCHK(ca_context_create(ca_disable_preemptive_callback),
"ca_context_create");
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");
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");
116 SEVCHK(ca_pend_io(2.0),
"ca_pend_io");
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");
123 B2DEBUG(18,
"State PV failed to initialize, will retry in beginRun(), event() and endRun().");
126 m_lastPVUpdate = getClockSeconds();
131 void DQMHistAnalysisSVDDoseModule::beginRun()
136 B2DEBUG(19,
"beginRun: setting state PV to RUNNING");
137 m_stateCtrl.value = 1;
139 SEVCHK(ca_put(DBR_ENUM, m_stateChan, &m_stateCtrl.value),
"ca_put");
141 SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
142 NULL, NULL, 10, &m_stateChan),
"ca_create_channel (reconnection)");
144 SEVCHK(ca_pend_io(2.0),
"ca_pend_io");
146 m_lastPVUpdate = getClockSeconds();
151 void DQMHistAnalysisSVDDoseModule::event()
155 double timeSinceLastPVUpdate = getClockSeconds() - m_lastPVUpdate;
156 if (getUseEpics() && timeSinceLastPVUpdate >= m_epicsUpdateSeconds) {
159 SEVCHK(ca_get(DBR_CTRL_ENUM, m_stateChan, &m_stateCtrl),
"ca_get");
161 SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
162 NULL, NULL, 10, &m_stateChan),
"ca_create_channel (reconnection)");
164 SEVCHK(ca_pend_io(2.0),
"ca_pend_io");
167 if (m_timeSinceLastPVUpdateChan) {
168 SEVCHK(ca_put(DBR_DOUBLE, m_timeSinceLastPVUpdateChan, (
void*)&timeSinceLastPVUpdate),
"ca_put");
170 SEVCHK(ca_create_channel((m_pvPrefix + m_deltaTPVSuffix).data(), NULL, NULL, 10, &m_timeSinceLastPVUpdateChan),
171 "ca_create_channel (reconnection)");
173 m_stateCtrl.value = 1;
175 SEVCHK(ca_put(DBR_ENUM, m_stateChan, &m_stateCtrl.value),
"ca_put");
177 SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
178 NULL, NULL, 10, &m_stateChan),
"ca_create_channel (reconnection)");
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.");
192 nHits += hHits->GetEntries();
193 nEvts += hEvts->GetEntries();
196 B2DEBUG(19,
"DQMHistAnalysisSVDDose: PV write"
197 <<
LogVar(
"group", group.nameSuffix.Data())
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;
205 SEVCHK(ca_put(DBR_DOUBLE, pv.mychid, (
void*)&occ),
"ca_put");
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)");
210 pv.lastNEvts = nEvts;
211 pv.lastNHits = nHits;
215 SEVCHK(ca_pend_io(2.0),
"ca_pend_io");
216 m_lastPVUpdate = getClockSeconds();
223 void DQMHistAnalysisSVDDoseModule::endRun()
225 B2DEBUG(18,
"DQMHistAnalysisSVDDose: endRun");
230 B2DEBUG(19,
"endRun: setting state PV to NOT RUNNING");
231 m_stateCtrl.value = 0;
233 SEVCHK(ca_put(DBR_ENUM, m_stateChan, &m_stateCtrl.value),
"ca_put");
235 SEVCHK(ca_create_channel((m_pvPrefix + m_statePVSuffix).data(),
236 NULL, NULL, 10, &m_stateChan),
"ca_create_channel (reconnection)");
238 SEVCHK(ca_pend_io(2.0),
"ca_pend_io");
240 for (
auto& pv : m_myPVs)
241 pv.lastNEvts = pv.lastNHits = 0.0;
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.");
257 nHits += hHits->GetEntries();
258 nEvts += hEvts->GetEntries();
261 B2DEBUG(19,
"DQMHistAnalysisSVDDose: MonObj write"
262 <<
LogVar(
"group", group.nameSuffix.Data())
265 double occ = nEvts ? (nHits / nEvts * 100.0 / group.nStrips) : -1.0;
266 TString vName = group.nameSuffix +
"OccPoisAvg";
267 m_monObj->setVariable(vName.Data(), occ);
273 void DQMHistAnalysisSVDDoseModule::updateCanvases()
275 B2DEBUG(18,
"DQMHistAnalysisSVDDose: updating canvases");
277 for (
unsigned int g = 0; g < c_sensorGroups.size(); g++) {
278 const auto& group = c_sensorGroups[g];
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);
293 hNo->SetTitle(
"SVD instantaneous occu. " + group.titleSuffix +
" U-side Pois. trig.");
295 hLER->Draw(
"hist same");
296 hHER->Draw(
"hist same");
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);
306 hOccu->SetTitle(
"SVD Occupancy " + group.titleSuffix +
" - LER inj. Pois. trig."
307 ";Time since last injection [#mus];Time in beam cycle [#mus]"
309 hOccu->SetMinimum(1e-3);
310 hOccu->SetMaximum(10);
313 c->SetRightMargin(0.16);
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);
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);
329 hpOccu->SetMarkerStyle(7);
330 hpOccu->Draw(
"hist P");
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);
339 hOccu->SetTitle(
"SVD Occupancy " + group.titleSuffix +
" - HER inj. Pois. trig."
340 ";Time since last injection [#mus];Time in beam cycle [#mus]"
342 hOccu->SetMinimum(1e-3);
343 hOccu->SetMaximum(10);
346 c->SetRightMargin(0.16);
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);
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);
362 hpOccu->SetMarkerStyle(7);
363 hpOccu->Draw(
"hist P");
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);
381 hNo->SetTitle(
"SVD instantaneous occu. " + group.titleSuffix +
" U-side all events");
383 hLER->Draw(
"hist same");
384 hHER->Draw(
"hist same");
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);
394 hOccu->SetTitle(
"SVD Occupancy " + group.titleSuffix +
" - LER inj. all events"
395 ";Time since last injection [#mus];Time in beam cycle [#mus]"
397 hOccu->SetMinimum(1e-3);
398 hOccu->SetMaximum(10);
401 c->SetRightMargin(0.16);
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);
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);
417 hpOccu->SetMarkerStyle(7);
418 hpOccu->Draw(
"hist P");
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);
427 hOccu->SetTitle(
"SVD Occupancy " + group.titleSuffix +
" - HER inj. all events"
428 ";Time since last injection [#mus];Time in beam cycle [#mus]"
430 hOccu->SetMinimum(1e-3);
431 hOccu->SetMaximum(10);
434 c->SetRightMargin(0.16);
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);
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);
450 hpOccu->SetMarkerStyle(7);
451 hpOccu->Draw(
"hist P");
457 void DQMHistAnalysisSVDDoseModule::carryOverflowOver(TH1F* h)
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);
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}
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.
Abstract base class for different kinds of events.