Belle II Software development
KLMDQMModule.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/* Own header. */
10#include <klm/modules/KLMDQM/KLMDQMModule.h>
11
12/* KLM headers. */
13#include <klm/dataobjects/KLMChannelIndex.h>
14#include <klm/dataobjects/KLMDigitRaw.h>
15
16/* ROOT headers. */
17#include <TDirectory.h>
18
19#include <set>
20
21using namespace Belle2;
22
23REG_MODULE(KLMDQM);
24
27 m_DAQInclusion{nullptr},
28 m_TimeRPC{nullptr},
37 m_ChargeClusterBKLM{nullptr},
38 m_ChargeClusterEKLM{nullptr},
41 m_PlaneBKLMPhi{nullptr},
42 m_PlaneBKLMZ{nullptr},
43 m_PlaneEKLM{nullptr},
44 m_DigitsKLM{nullptr},
45 m_DigitsRPC{nullptr},
50 m_TriggerBitsBKLM{nullptr},
51 m_TriggerBitsEKLM{nullptr},
53 m_DigitsAfterLERInj{nullptr},
54 m_TriggersLERInj{nullptr},
55 m_DigitsAfterHERInj{nullptr},
56 m_TriggersHERInj{nullptr},
57 m_FE_BKLM_Layer_0(nullptr),
58 m_FE_BKLM_Layer_1(nullptr),
59 m_FE_EKLM_Plane_0(nullptr),
60 m_FE_EKLM_Plane_1(nullptr),
63 m_ElementNumbers{&(KLMElementNumbers::Instance())},
65 m_klmTime{&(KLMTime::Instance())}
66{
67 setDescription("KLM data quality monitor.");
69 addParam("histogramDirectoryName", m_HistogramDirectoryName,
70 "Directory for KLM DQM histograms in ROOT file.",
71 std::string("KLM"));
72 addParam("RPCTimeMin", m_RPCTimeMin,
73 "Min time for RPC time histogram.", double(-1223.5));
74 addParam("RPCTimeMax", m_RPCTimeMax,
75 "Max time for RPC time histogram.", double(-199.5));
76 addParam("BKLMScintTimeMin", m_BKLMScintTimeMin,
77 "Min time for BKLM scintillator time histogram.", double(-5300));
78 addParam("BKLMScintTimeMax", m_BKLMScintTimeMax,
79 "Max time for BKLM scintillator time histogram.", double(-4300));
80 addParam("EKLMScintTimeMin", m_EKLMScintTimeMin,
81 "Min time for EKLM scintillator time histogram.", double(-5300));
82 addParam("EKLMScintTimeMax", m_EKLMScintTimeMax,
83 "Max time for EKLM scintillator time histogram.", double(-4300));
84 addParam("Revo9DCArrivalTimeMin", m_Revo9DCArrivalTimeMin,
85 "Min time for RPC hit revo9DCArrivalTime histogram.", double(-10000));
86 addParam("Revo9DCArrivalTimeMax", m_Revo9DCArrivalTimeMax,
87 "Max time for RPC hit revo9DCArrivalTime histogram.", double(3000));
88}
89
91{
93 for (KLMChannelIndex& klmSector : klmIndex) {
94 KLMSectorNumber sector = klmSector.getKLMSectorNumber();
95 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sector);
96 if (m_ChannelHits[sectorIndex] != nullptr)
97 delete[] m_ChannelHits[sectorIndex];
98 }
100 for (KLMChannelIndex& klmSection : klmIndex) {
101 KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
102 if (subdetector == KLMElementNumbers::c_EKLM) {
103 KLMSectionNumber section = klmSection.getSection();
104 if (m_Spatial2DHitsEKLM[section - 1] != nullptr)
105 delete[] m_Spatial2DHitsEKLM[section - 1];
106 }
107 }
108}
109
111{
112 TDirectory* oldDirectory, *newDirectory;
113 oldDirectory = gDirectory;
114 newDirectory = oldDirectory->mkdir(m_HistogramDirectoryName.c_str());
115 newDirectory->cd();
116 /* DAQ inclusion. */
117 m_DAQInclusion = new TH1F("daq_inclusion", "Is KLM included in DAQ?", 2, 0.0, 2.0);
118 m_DAQInclusion->GetXaxis()->SetBinLabel(1, "No");
119 m_DAQInclusion->GetXaxis()->SetBinLabel(2, "Yes");
120 /* Time histograms. */
121 m_TimeRPC = new TH1F("time_rpc", "RPC hit time", 128, m_RPCTimeMin, m_RPCTimeMax);
122 m_TimeRPC->GetXaxis()->SetTitle("Time, ns");
124 new TH1F("time_scintillator_bklm", "Scintillator hit time (BKLM)",
126 m_TimeScintillatorBKLM->GetXaxis()->SetTitle("Time, ns");
128 new TH1F("time_scintillator_eklm", "Scintillator hit time (EKLM)",
130 m_TimeScintillatorEKLM->GetXaxis()->SetTitle("Time, ns");
132 new TH1F("charge_scintillator_bklm", "Scintillator charge (BKLM)",
133 256, 0., 512.);
134 m_ChargeScintillatorBKLM->GetXaxis()->SetTitle("Charge");
136 new TH1F("charge_scintillator_eklm", "Scintillator charge (EKLM)",
137 256, 0., 512.);
138 m_ChargeScintillatorEKLM->GetXaxis()->SetTitle("Charge");
140 new TH1F("charge_scintillator_bklm_single_strip", "Scintillator charge (BKLM) single strip",
141 256, 0., 512.);
142 m_ChargeScintillatorBKLM_SingleStrip->GetXaxis()->SetTitle("Charge");
144 new TH1F("charge_scintillator_eklm_single_strip", "Scintillator charge (EKLM) single strip",
145 256, 0., 512.);
146 m_ChargeScintillatorEKLM_SingleStrip->GetXaxis()->SetTitle("Charge");
148 new TH1F("charge_scintillator_bklm_multi_strip", "Scintillator charge (BKLM) multi strip",
149 256, 0., 512.);
150 m_ChargeScintillatorBKLM_MultiStrip->GetXaxis()->SetTitle("Charge");
152 new TH1F("charge_scintillator_eklm_multi_strip", "Scintillator charge (EKLM) multi strip",
153 256, 0., 512.);
154 m_ChargeScintillatorEKLM_MultiStrip->GetXaxis()->SetTitle("Charge");
156 new TH1F("charge_cluster_bklm", "BKLM Scintillator Clusters",
157 500, 0., 10000.);
158 m_ChargeClusterBKLM->GetXaxis()->SetTitle("Cluster Charge");
160 new TH1F("charge_cluster_eklm", "EKLM Clusters",
161 500, 0., 10000.);
162 m_ChargeClusterEKLM->GetXaxis()->SetTitle("Cluster Charge");
164 new TH1F("avg_charge_cluster_bklm", "Mean Cluster Charge (BKLM)",
165 256, 0., 512.);
166 m_AverageChargeClusterBKLM->GetXaxis()->SetTitle("Cluster Charge / Number of Digits in Cluster");
168 new TH1F("avg_charge_cluster_eklm", "Mean Cluster Charge (EKLM)",
169 256, 0., 512.);
170 m_AverageChargeClusterEKLM->GetXaxis()->SetTitle("Cluster Charge / Number of Digits in Cluster");
171 m_TimeRevo9DCArrivalTime = new TH1F("time_revo9dc_arrival_time", "DC arrival hit time (RPC)",
173 m_TimeRevo9DCArrivalTime->GetXaxis()->SetTitle("Time, ns");
174 /* Number of hits per plane. */
175 m_PlaneBKLMPhi = new TH1F("plane_bklm_phi",
176 "BKLM plane occupancy (#phi readout)",
177 240, 0.5, 240.5);
178 m_PlaneBKLMPhi->GetXaxis()->SetTitle("Layer number");
179 m_PlaneBKLMZ = new TH1F("plane_bklm_z",
180 "BKLM plane occupancy (z readout)",
181 240, 0.5, 240.5);
182 m_PlaneBKLMZ->GetXaxis()->SetTitle("Layer number");
183 m_PlaneEKLM = new TH1F("plane_eklm", "EKLM plane occupancy (both readouts)", 208, 0.5, 208.5);
184 m_PlaneEKLM->GetXaxis()->SetTitle("Plane number");
185 /* Number of hits per channel. */
186 int nChannelHistograms =
191 KLMChannelNumber* firstChannelNumbers =
192 new KLMChannelNumber[nChannelHistograms + 1];
193 int i = 0;
195 for (KLMChannelIndex& klmSector : klmIndex) {
196 KLMChannelIndex klmChannel(klmSector);
198 KLMChannelNumber channel = klmChannel.getKLMChannelNumber();
199 firstChannelNumbers[i] = m_ChannelArrayIndex->getIndex(channel);
200 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM) {
201 channel = m_ElementNumbers->channelNumberBKLM(
202 klmChannel.getSection(), klmChannel.getSector(), 8, 0, 1);
203 firstChannelNumbers[i + 1] = m_ChannelArrayIndex->getIndex(channel);
204 i += 2;
205 } else {
206 int layerIncrease = (klmSector.getSection() == 1) ? 4 : 5;
207 channel = m_ElementNumbers->channelNumberEKLM(
208 klmChannel.getSection(), klmChannel.getSector(),
209 1 + layerIncrease, 1, 1);
210 firstChannelNumbers[i + 1] = m_ChannelArrayIndex->getIndex(channel);
211 channel = m_ElementNumbers->channelNumberEKLM(
212 klmChannel.getSection(), klmChannel.getSector(),
213 1 + layerIncrease * 2, 1, 1);
214 firstChannelNumbers[i + 2] = m_ChannelArrayIndex->getIndex(channel);
215 i += 3;
216 }
217 }
218 firstChannelNumbers[nChannelHistograms] = m_ChannelArrayIndex->getNElements();
219 i = 0;
221 for (KLMChannelIndex& klmSector : klmIndex) {
222 int nHistograms;
223 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
224 nHistograms = m_ChannelHitHistogramsBKLM;
225 else
226 nHistograms = m_ChannelHitHistogramsEKLM;
227 KLMSectorNumber sector = klmSector.getKLMSectorNumber();
228 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sector);
229 m_ChannelHits[sectorIndex] = new TH1F*[nHistograms];
230 for (int j = 0; j < nHistograms; j++) {
231 std::string name =
232 "strip_hits_subdetector_" + std::to_string(klmSector.getSubdetector()) +
233 "_section_" + std::to_string(klmSector.getSection()) +
234 "_sector_" + std::to_string(klmSector.getSector()) +
235 "_" + std::to_string(j);
236 std::string title = "Sector " + std::to_string(klmSector.getSector()) + " -- " +
237 m_ElementNumbers->getSectorDAQName(klmSector.getSubdetector(), klmSector.getSection(), klmSector.getSector());
238 m_ChannelHits[sectorIndex][j] = new TH1F(
239 name.c_str(), title.c_str(),
240 firstChannelNumbers[i + 1] - firstChannelNumbers[i],
241 firstChannelNumbers[i] - 0.5, firstChannelNumbers[i + 1] - 0.5);
242 i++;
243 }
244 }
245 delete[] firstChannelNumbers;
246 /* Number of digits. */
247 m_DigitsKLM = new TH1F("digits_klm", "Number of KLM digits",
248 250.0, 0.0, 250.0);
249 m_DigitsKLM->GetXaxis()->SetTitle("Number of digits");
250 m_DigitsRPC = new TH1F("digits_rpc", "Number of RPC digits",
251 250.0, 0.0, 250.0);
252 m_DigitsRPC->GetXaxis()->SetTitle("Number of digits");
253 m_DigitsScintillatorBKLM = new TH1F("digits_scintillator_bklm", "Number of scintillator digits (BKLM)",
254 250.0, 0.0, 250.0);
255 m_DigitsScintillatorBKLM->GetXaxis()->SetTitle("Number of digits");
256 m_DigitsScintillatorEKLM = new TH1F("digits_scintillator_eklm", "Number of scintillator digits (EKLM)",
257 250.0, 0.0, 250.0);
258 m_DigitsScintillatorEKLM->GetXaxis()->SetTitle("Number of digits");
259 m_DigitsMultiStripBKLM = new TH1F("digits_multi_bklm", "Number of multi-strip digits (BKLM)",
260 50.0, 0.0, 50.0);
261 m_DigitsMultiStripBKLM->GetXaxis()->SetTitle("Number of multi-strip digits");
262 m_DigitsMultiStripEKLM = new TH1F("digits_multi_eklm", "Number of multi-strip digits (EKLM)",
263 50.0, 0.0, 50.0);
264 m_DigitsMultiStripEKLM->GetXaxis()->SetTitle("Number of multi-strip digits");
265 /* Trigger bits. */
266 m_TriggerBitsBKLM = new TH1F("trigger_bits_bklm", "Trigger bits of multi-strip digits (BKLM)",
267 (double)c_0x1, (double)c_0x8, (double)c_0x1 + 1.0);
268 m_TriggerBitsBKLM->GetXaxis()->SetBinLabel(c_0x8, "0x8");
269 m_TriggerBitsBKLM->GetXaxis()->SetBinLabel(c_0x4, "0x4");
270 m_TriggerBitsBKLM->GetXaxis()->SetBinLabel(c_0x2, "0x2");
271 m_TriggerBitsBKLM->GetXaxis()->SetBinLabel(c_0x1, "0x1");
272 m_TriggerBitsEKLM = new TH1F("trigger_bits_eklm", "Trigger bits of multi-strip digits (EKLM)",
273 (double)c_0x1, (double)c_0x8, (double)c_0x1 + 1.0);
274 m_TriggerBitsEKLM->GetXaxis()->SetBinLabel(c_0x8, "0x8");
275 m_TriggerBitsEKLM->GetXaxis()->SetBinLabel(c_0x4, "0x4");
276 m_TriggerBitsEKLM->GetXaxis()->SetBinLabel(c_0x2, "0x2");
277 m_TriggerBitsEKLM->GetXaxis()->SetBinLabel(c_0x1, "0x1");
278
279 /* Event-level L1 trigger bits (TRGSummary). */
280 int nTimingBits = (int)c_KlmL1Triggers.size(); // TTYP_DPHY, TTYP_RAND, TTYP_POIS
281 m_EventBackgroundTriggerSummary = new TH1F("event_background_trigger_summary",
282 "Event background trigger summary;Trigger Decision;Events",
283 nTimingBits, 0.5, 0.5 + nTimingBits);
284 /* Keep labels explicit to match the actual trigger bits. */
285 m_EventBackgroundTriggerSummary->GetXaxis()->SetBinLabel(1, "TTYP_DPHY");
286 m_EventBackgroundTriggerSummary->GetXaxis()->SetBinLabel(2, "TTYP_RAND");
287 m_EventBackgroundTriggerSummary->GetXaxis()->SetBinLabel(3, "TTYP_POIS");
288
289 /* Number of digits after injection */
290 /* For the histograms below, we use the same style as for other subdetectors. */
291 m_DigitsAfterLERInj = new TH1F("KLMOccInjLER", "KLM digits after LER injection / Time;Time [#mus];Number of KLM digits / (5 #mus)",
292 4000, 0, 20000);
293 m_TriggersLERInj = new TH1F("KLMTrigInjLER", "Triggers after KER injection / Time;Time [#mus];Number of triggers / (5 #mus)",
294 4000, 0, 20000);
295 m_DigitsAfterHERInj = new TH1F("KLMOccInjHER", "KLM digits after HER injection / Time;Time [#mus];Number of KLM digits / (5 #mus)",
296 4000, 0, 20000);
297 m_TriggersHERInj = new TH1F("KLMTrigInjHER", "Triggers after HER injection / Time;Time [#mus];Number of triggers / (5 #mus)",
298 4000, 0, 20000);
299 /* Spatial distribution of EKLM 2d hits per layer. */
301 for (KLMChannelIndex& klmSection : klmIndex) {
302 KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
303 if (subdetector == KLMElementNumbers::c_EKLM) {
304 KLMSectionNumber section = klmSection.getSection();
305 int maximalLayerNumber = m_eklmElementNumbers->getMaximalDetectorLayerNumber(section);
306 m_Spatial2DHitsEKLM[section - 1] = new TH2F*[maximalLayerNumber];
307 std::string sectionName = (section == EKLMElementNumbers::c_ForwardSection) ? "Forward" : "Backward";
308 for (int j = 1; j <= maximalLayerNumber; ++j) {
309 std::string name = "spatial_2d_hits_subdetector_" + std::to_string(subdetector) +
310 "_section_" + std::to_string(section) +
311 "_layer_" + std::to_string(j);
312 std::string title = "Endcap " + sectionName + " , Layer " + std::to_string(j);
313 /* Use bins with a size of 10 cm per side. */
314 m_Spatial2DHitsEKLM[section - 1][j - 1] = new TH2F(name.c_str(), title.c_str(),
315 340 * 2 / 10, -340, 340,
316 340 * 2 / 10, -340, 340);
317 m_Spatial2DHitsEKLM[section - 1][j - 1]->GetXaxis()->SetTitle("X coordinate [cm]");
318 m_Spatial2DHitsEKLM[section - 1][j - 1]->GetYaxis()->SetTitle("Y coordinate [cm]");
319 }
320 }
321 }
322 // Feature extraction status histogram for BKLM
323 int bklmSectors = BKLMElementNumbers::getMaximalSectorGlobalNumber(); // 16
324 int eklmPlanes = EKLMElementNumbers::getMaximalPlaneGlobalNumber(); // 208
325
326 m_FE_BKLM_Layer_0 = new TH1F("feStatus_bklm_scintillator_layers_0",
327 "BKLM Scintillator Standard Readout;FEE Card", bklmSectors * 2, 0.5, 0.5 + bklmSectors * 2);
328 m_FE_BKLM_Layer_1 = new TH1F("feStatus_bklm_scintillator_layers_1",
329 "BKLM Scintillator Feature Extraction;FEE Card", bklmSectors * 2, 0.5, 0.5 + bklmSectors * 2);
330 m_FE_EKLM_Plane_0 = new TH1F("feStatus_eklm_plane_0",
331 "EKLM Standard Readout;Plane number", eklmPlanes, 0.5, 0.5 + eklmPlanes);
332 m_FE_EKLM_Plane_1 = new TH1F("feStatus_eklm_plane_1",
333 "EKLM Feature Extraction;Plane number", eklmPlanes, 0.5, 0.5 + eklmPlanes);
334 oldDirectory->cd();
335}
336
338{
339 REG_HISTOGRAM;
340 m_RawFtsws.isOptional();
341 m_RawKlms.isOptional();
342 m_trgSummary.isOptional();
343 m_Digits.isOptional();
344 m_BklmHit1ds.isOptional();
345 m_Hit2ds.isOptional();
346 m_KLMClusters.isOptional();
347}
348
350{
351 /* DAQ inclusion. */
352 m_DAQInclusion->Reset();
353 if (m_RawKlms.isValid())
354 m_DAQInclusion->Fill("Yes", 1);
355 else
356 m_DAQInclusion->Fill("No", 1);
357 /* Time. */
358 m_TimeRPC->Reset();
359 m_TimeScintillatorBKLM->Reset();
360 m_TimeScintillatorEKLM->Reset();
367 m_ChargeClusterBKLM->Reset();
368 m_ChargeClusterEKLM->Reset();
372 m_klmTime->updateConstants(); //to get correct CTime
373 /* Plane hits. */
374 m_PlaneEKLM->Reset();
375 m_PlaneBKLMPhi->Reset();
376 m_PlaneBKLMZ->Reset();
377 /* Channel hits. */
379 for (KLMChannelIndex& klmSector : klmIndex) {
380 int nHistograms;
381 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
382 nHistograms = m_ChannelHitHistogramsBKLM;
383 else
384 nHistograms = m_ChannelHitHistogramsEKLM;
385 KLMSectorNumber sector = klmSector.getKLMSectorNumber();
386 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sector);
387 for (int j = 0; j < nHistograms; j++)
388 m_ChannelHits[sectorIndex][j]->Reset();
389 }
390 /* Digits. */
391 m_DigitsKLM->Reset();
392 m_DigitsRPC->Reset();
395 m_DigitsMultiStripBKLM->Reset();
396 m_DigitsMultiStripEKLM->Reset();
397 /* Trigger bits. */
398 m_TriggerBitsBKLM->Reset();
399 m_TriggerBitsEKLM->Reset();
400 /* Event-level background trigger summary. */
401 if (m_EventBackgroundTriggerSummary != nullptr)
403 /* Injection information. */
404 m_DigitsAfterLERInj->Reset();
405 m_TriggersLERInj->Reset();
406 m_DigitsAfterHERInj->Reset();
407 m_TriggersHERInj->Reset();
408 /* Spatial 2D hits distributions. */
410 for (KLMChannelIndex& klmSection : klmIndex) {
411 KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
412 if (subdetector == KLMElementNumbers::c_EKLM) {
413 KLMSectionNumber section = klmSection.getSection();
414 int maximalLayerNumber =
415 m_eklmElementNumbers->getMaximalDetectorLayerNumber(section);
416 for (int j = 1; j <= maximalLayerNumber; ++j)
417 m_Spatial2DHitsEKLM[section - 1][j - 1]->Reset();
418 }
419 }
420 /* Feature extraction. */
421 m_FE_BKLM_Layer_0->Reset();
422 m_FE_BKLM_Layer_1->Reset();
423 m_FE_EKLM_Plane_0->Reset();
424 m_FE_EKLM_Plane_1->Reset();
425}
426
428{
429 /* Event-level background trigger summary, filled once per event. */
430 if (m_trgSummary.isValid() && m_EventBackgroundTriggerSummary != nullptr) {
431 const int nTimingBits = (int)c_KlmL1Triggers.size();
432 // GDL Background triggers: TTYP_DPHY, TTYP_RAND, TTYP_POIS (event-level timing source)
433 for (int i = 0; i < nTimingBits; ++i) {
434 if (m_trgSummary->getTimType() == c_KlmL1Triggers[i])
435 m_EventBackgroundTriggerSummary->Fill((double)i + 1.0);
436 }
437 }
438
439 int nDigits = m_Digits.getEntries();
440 int nDigitsRPC = 0, nDigitsScintillatorBKLM = 0, nDigitsScintillatorEKLM = 0;
441 int nDigitsMultiStripBKLM = 0, nDigitsMultiStripEKLM = 0;
442 for (const KLMDigit& digit : m_Digits) {
443 /*
444 * Reject digits that are below the threshold (such digits may appear
445 * for simulated events).
446 */
447
448 if (!digit.isGood())
449 continue;
450 KLMDigitRaw* digitRaw = digit.getRelated<KLMDigitRaw>();
451 if (digit.getSubdetector() == KLMElementNumbers::c_EKLM) {
452 nDigitsScintillatorEKLM++;
453 int section = digit.getSection();
454 int sector = digit.getSector();
455 int layer = digit.getLayer();
456 int plane = digit.getPlane();
457 int strip = digit.getStrip();
458 if (not digit.isMultiStrip()) {
459 KLMSectorNumber klmSector = m_ElementNumbers->sectorNumberEKLM(section, sector);
460 KLMSectorNumber klmSectorIndex = m_SectorArrayIndex->getIndex(klmSector);
461 KLMChannelNumber channel = m_ElementNumbers->channelNumberEKLM(section, sector, layer, plane, strip);
462 KLMChannelNumber channelIndex = m_ChannelArrayIndex->getIndex(channel);
463 for (int j = 0; j < m_ChannelHitHistogramsEKLM; j++) {
464 double xMin = m_ChannelHits[klmSectorIndex][j]->GetXaxis()->GetXmin();
465 double xMax = m_ChannelHits[klmSectorIndex][j]->GetXaxis()->GetXmax();
466 if ((xMin > channelIndex) || (xMax < channelIndex))
467 continue;
468 m_ChannelHits[klmSectorIndex][j]->Fill(channelIndex);
469 }
470 } else
471 nDigitsMultiStripEKLM++;
472 int planeGlobal = m_eklmElementNumbers->planeNumber(section, layer, sector, plane);
473 m_PlaneEKLM->Fill(planeGlobal);
474 m_TimeScintillatorEKLM->Fill(digit.getTime());
475 if (digit.isMultiStrip()) {
476 if (digitRaw) {
477 uint16_t triggerBits = digitRaw->getTriggerBits();
478 if ((triggerBits & 0x1) != 0)
480 if ((triggerBits & 0x2) != 0)
482 if ((triggerBits & 0x4) != 0)
484 if ((triggerBits & 0x8) != 0)
486 }
487 }
488 if (digitRaw) {
489 // Extract m_FE from m_word4
490 uint16_t feStatus = digitRaw->getFEStatus(); // Extract the most significant bit
491 if (feStatus != 0) {
492 m_FE_EKLM_Plane_1->Fill(planeGlobal);
493 m_ChargeScintillatorEKLM->Fill(digit.getCharge());
494 uint16_t triggerBits = digitRaw->getTriggerBits();
495 if ((triggerBits & 0x10) != 0) {
496 m_ChargeScintillatorEKLM_MultiStrip->Fill(digit.getCharge());
497 } else if ((triggerBits & 0x10) == 0) {
498 m_ChargeScintillatorEKLM_SingleStrip->Fill(digit.getCharge());
499 }
500 } else {
501 m_FE_EKLM_Plane_0->Fill(planeGlobal);
502 }
503 }
504 } else if (digit.getSubdetector() == KLMElementNumbers::c_BKLM) {
505 int section = digit.getSection();
506 int sector = digit.getSector();
507 int layer = digit.getLayer();
508 int plane = digit.getPlane();
509 int strip = digit.getStrip();
510
511 KLMSectorNumber klmSector = m_ElementNumbers->sectorNumberBKLM(section, sector);
512 KLMSectorNumber klmSectorIndex = m_SectorArrayIndex->getIndex(klmSector);
513
514 if (not digit.isMultiStrip()) {
515 KLMChannelNumber channel = m_ElementNumbers->channelNumberBKLM(section, sector, layer, plane, strip);
516 KLMChannelNumber channelIndex = m_ChannelArrayIndex->getIndex(channel);
517 for (int j = 0; j < m_ChannelHitHistogramsBKLM; j++) {
518 double xMin = m_ChannelHits[klmSectorIndex][j]->GetXaxis()->GetXmin();
519 double xMax = m_ChannelHits[klmSectorIndex][j]->GetXaxis()->GetXmax();
520 if ((xMin > channelIndex) || (xMax < channelIndex))
521 continue;
522 m_ChannelHits[klmSectorIndex][j]->Fill(channelIndex);
523 }
524 } else
525 nDigitsMultiStripBKLM++;
526 if (digit.inRPC()) {
527 nDigitsRPC++;
528 m_TimeRPC->Fill(digit.getTime());
529 m_TimeRevo9DCArrivalTime->Fill(digit.getRevo9DCArrivalTime() * m_klmTime->getCTimePeriod());
530 } else {
531 nDigitsScintillatorBKLM++;
532 m_TimeScintillatorBKLM->Fill(digit.getTime());
533 if (digitRaw) {
534 uint16_t feStatus = digitRaw->getFEStatus(); // Extract the most significant bit
535 if (feStatus != 0) {
536 m_FE_BKLM_Layer_1->Fill((klmSectorIndex) * 2 + layer);
537 m_ChargeScintillatorBKLM->Fill(digit.getCharge());
538 uint16_t triggerBits = digitRaw->getTriggerBits();
539 if ((triggerBits & 0x10) != 0) {
540 m_ChargeScintillatorBKLM_MultiStrip->Fill(digit.getCharge());
541 } else if ((triggerBits & 0x10) == 0) {
542 m_ChargeScintillatorBKLM_SingleStrip->Fill(digit.getCharge());
543 }
544 } else {
545 m_FE_BKLM_Layer_0->Fill((klmSectorIndex) * 2 + layer);
546 }
547 }
548 }
549 if (digit.isMultiStrip()) {
550 if (digitRaw) {
551 uint16_t triggerBits = digitRaw->getTriggerBits();
552 if ((triggerBits & 0x1) != 0)
554 if ((triggerBits & 0x2) != 0)
556 if ((triggerBits & 0x4) != 0)
558 if ((triggerBits & 0x8) != 0)
560 }
561 }
562 } else
563 B2FATAL("Not a BKLM or a EKLM digit, something went really wrong.");
564 }
565 for (const BKLMHit1d& hit1d : m_BklmHit1ds) {
566 int section = hit1d.getSection();
567 int sector = hit1d.getSector();
568 int layer = hit1d.getLayer();
570 section, sector, layer);
571 if (hit1d.isPhiReadout())
572 m_PlaneBKLMPhi->Fill(layerGlobal);
573 else
574 m_PlaneBKLMZ->Fill(layerGlobal);
575 }
576 /* Digits. */
577 m_DigitsKLM->Fill((double)nDigits);
578 m_DigitsRPC->Fill((double)nDigitsRPC);
579 m_DigitsScintillatorBKLM->Fill((double)nDigitsScintillatorBKLM);
580 m_DigitsScintillatorEKLM->Fill((double)nDigitsScintillatorEKLM);
581 if (nDigitsMultiStripBKLM > 0)
582 m_DigitsMultiStripBKLM->Fill((double)nDigitsMultiStripBKLM);
583 if (nDigitsMultiStripEKLM > 0)
584 m_DigitsMultiStripEKLM->Fill((double)nDigitsMultiStripEKLM);
585 /* Injection information. */
586 for (RawFTSW& rawFtsw : m_RawFtsws) {
587 unsigned int difference = rawFtsw.GetTimeSinceLastInjection(0);
588 if (difference != 0x7FFFFFFF) {
589 /* 127 MHz clock ticks to us, inexact rounding. */
590 float differenceInUs = difference / 127.;
591 if (rawFtsw.GetIsHER(0)) {
592 m_DigitsAfterHERInj->Fill(differenceInUs, nDigits);
593 m_TriggersHERInj->Fill(differenceInUs);
594 } else {
595 m_DigitsAfterLERInj->Fill(differenceInUs, nDigits);
596 m_TriggersLERInj->Fill(differenceInUs);
597 }
598 }
599 /*
600 * Usually, only one RawFTSW object is stored per event.
601 * If there are more, ignore the others.
602 */
603 break;
604 }
605 /* Spatial 2D hits distributions. */
606 for (const KLMHit2d& hit2d : m_Hit2ds) {
607 if (hit2d.getSubdetector() != KLMElementNumbers::c_EKLM)
608 continue;
609 int section = hit2d.getSection();
610 int layer = hit2d.getLayer();
611 m_Spatial2DHitsEKLM[section - 1][layer - 1]->Fill(hit2d.getPositionX(), hit2d.getPositionY());
612 }
613 /* Cluster charge from related scintillator digits (unique per cluster). */
614 if (m_KLMClusters.isValid()) {
615 for (KLMCluster& cluster : m_KLMClusters) {
616 std::set<const KLMDigit*> digitsSeen;
617 double sumChargeBKLM = 0.;
618 double sumChargeEKLM = 0.;
619 int nDigitsClusterBKLM = 0;
620 int nDigitsClusterEKLM = 0;
621 auto addDigits = [&](const RelationVector<KLMDigit>& digits) {
622 for (unsigned id = 0; id < digits.size(); ++id) {
623 const KLMDigit* digit = digits[id];
624 if (!digit->isGood())
625 continue;
626 if (!digitsSeen.insert(digit).second)
627 continue;
628 if (digit->getSubdetector() == KLMElementNumbers::c_EKLM && digit->getCharge() > 35.) {
629 sumChargeEKLM += digit->getCharge();
630 ++nDigitsClusterEKLM;
631 } else if (digit->getSubdetector() == KLMElementNumbers::c_BKLM && !digit->inRPC() && digit->getCharge() > 35.) {
632 sumChargeBKLM += digit->getCharge();
633 ++nDigitsClusterBKLM;
634 }
635 }
636 };
637 RelationVector<KLMHit2d> clusterHits = cluster.getRelationsTo<KLMHit2d>();
638 for (unsigned ih = 0; ih < clusterHits.size(); ++ih) {
639 KLMHit2d* hit2d = clusterHits[ih];
640 addDigits(hit2d->getRelationsTo<KLMDigit>());
642 for (unsigned i1 = 0; i1 < hit1ds.size(); ++i1)
643 addDigits(hit1ds[i1]->getRelationsTo<KLMDigit>());
644 }
645 if (clusterHits.size() > 1 && sumChargeBKLM > 0.) {
646 m_ChargeClusterBKLM->Fill(sumChargeBKLM);
647 m_AverageChargeClusterBKLM->Fill(sumChargeBKLM /
648 static_cast<double>(nDigitsClusterBKLM));
649 }
650 if (clusterHits.size() > 1 && sumChargeEKLM > 0.) {
651 m_ChargeClusterEKLM->Fill(sumChargeEKLM);
652 m_AverageChargeClusterEKLM->Fill(sumChargeEKLM /
653 static_cast<double>(nDigitsClusterEKLM));
654 }
655 }
656 }
657}
658
660{
661}
662
664{
665}
static constexpr int getMaximalSectorGlobalNumber()
Get maximal sector global number.
static int layerGlobalNumber(int section, int sector, int layer)
Get layer global number.
Store one reconstructed BKLM 1D hit as a ROOT object.
Definition BKLMHit1d.h:30
static constexpr int getMaximalPlaneGlobalNumber()
Get maximal plane global number.
static constexpr int getMaximalSectorGlobalNumberKLMOrder()
Get maximal sector global number with KLM ordering (section, sector).
HistoModule()
Constructor.
Definition HistoModule.h:32
KLM channel index.
int getSection() const
Get section.
int getSector() const
Get sector.
KLMChannelNumber getKLMChannelNumber() const
Get KLM channel number.
void setIndexLevel(enum IndexLevel indexLevel)
Set index level.
KLM cluster data.
Definition KLMCluster.h:29
double m_BKLMScintTimeMin
Min time for BKLM Scint.
TH1F * m_DigitsMultiStripEKLM
Number of multi-strip digits: EKLM scintillators.
TH1F * m_ChargeScintillatorEKLM
Charge: EKLM scintillators when FE != 0.
StoreArray< RawFTSW > m_RawFtsws
Raw FTSW.
const int m_ChannelHitHistogramsEKLM
Number of channel hit histograms per sector for EKLM.
TH1F * m_FE_EKLM_Plane_1
feature extraction status for EKLM
TH1F * m_PlaneBKLMPhi
Plane occupancy: BKLM, phi readout.
TH1F * m_TriggerBitsBKLM
Trigger bits: BKLM scintillators.
~KLMDQMModule()
Destructor.
TH1F * m_TimeScintillatorEKLM
Time: EKLM scintillators.
double m_RPCTimeMax
Max time for RPC.
StoreArray< KLMDigit > m_Digits
KLM digits.
double m_RPCTimeMin
Min time for RPC.
TH1F * m_ChargeScintillatorEKLM_SingleStrip
Charge: EKLM scintillators when FE != 0 & trigger bits 0x10 == 0.
void initialize() override
Initializer.
TH1F * m_DigitsScintillatorEKLM
Number of digits: EKLM scintillators.
TH1F ** m_ChannelHits[EKLMElementNumbers::getMaximalSectorGlobalNumberKLMOrder()+BKLMElementNumbers::getMaximalSectorGlobalNumber()]
Number of hits per channel.
TH1F * m_TimeRPC
Time: BKLM RPCs.
TH1F * m_DigitsKLM
Number of digits: whole KLM.
double m_Revo9DCArrivalTimeMax
Max time for revo9DCArrivalTime for RPC.
void event() override
This method is called for each event.
const KLMElementNumbers * m_ElementNumbers
KLM element numbers.
KLMDQMModule()
Constructor.
double m_Revo9DCArrivalTimeMin
Min time for revo9DCArrivalTime for RPC.
double m_EKLMScintTimeMax
Max time for EKLM Scint.
TH1F * m_ChargeScintillatorEKLM_MultiStrip
Charge: EKLM scintillators when FE != 0 & trigger bits 0x10 != 0.
const int m_ChannelHitHistogramsBKLM
Number of channel hit histograms per sector for BKLM.
TH1F * m_TriggerBitsEKLM
Trigger bits: EKLM scintillators.
void endRun() override
This method is called if the current run ends.
TH1F * m_ChargeClusterBKLM
Cluster charge (sum of scintillator digit charges), BKLM part.
const EKLMElementNumbers * m_eklmElementNumbers
Element numbers.
double m_BKLMScintTimeMax
Max time for BKLM Scint.
StoreObjPtr< TRGSummary > m_trgSummary
Trigger summary (event-level L1 bits).
void terminate() override
This method is called at the end of the event processing.
TH1F * m_ChargeScintillatorBKLM
Charge: BKLM scintillators when FE != 0.
TH1F * m_TimeRevo9DCArrivalTime
Time: revo9DCArrivalTime for RPC.
TH1F * m_PlaneBKLMZ
Plane occupancy: BKLM, z readout.
TH1F * m_TimeScintillatorBKLM
Time: BKLM scintillators.
TH1F * m_FE_BKLM_Layer_1
feature extraction status for BKLM Scintillator
TH1F * m_ChargeScintillatorBKLM_MultiStrip
Charge: BKLM scintillators when FE != 0 & trigger bits 0x10 != 0.
TH1F * m_AverageChargeClusterEKLM
Mean scintillator digit charge per cluster (EKLM contributors only).
TH1F * m_DigitsRPC
Number of digits: BKLM RPCs.
TH1F * m_TriggersHERInj
Histogram to be used for normalization of occupancy after HER injection.
TH1F * m_ChargeScintillatorBKLM_SingleStrip
Charge: BKLM scintillators when FE != 0 & trigger bits 0x10 == 0.
void beginRun() override
Called when entering a new run.
TH1F * m_DigitsAfterHERInj
Number of KLM Digits after LER injection.
TH1F * m_DigitsScintillatorBKLM
Number of digits: BKLM scintillators.
TH1F * m_TriggersLERInj
Histogram to be used for normalization of occupancy after LER injection.
TH1F * m_DigitsMultiStripBKLM
Number of multi-strip digits: BKLM scintillators.
TH1F * m_ChargeClusterEKLM
Cluster charge (sum of scintillator digit charges), EKLM part.
const KLMSectorArrayIndex * m_SectorArrayIndex
KLM sector array index.
TH1F * m_AverageChargeClusterBKLM
Mean scintillator digit charge per cluster (BKLM contributors only).
StoreArray< BKLMHit1d > m_BklmHit1ds
BKLM 1d hits.
TH1F * m_DigitsAfterLERInj
Number of KLM Digits after LER injection.
StoreArray< KLMCluster > m_KLMClusters
KLM clusters.
TH1F * m_DAQInclusion
KLM DAQ inclusion.
TH1F * m_FE_EKLM_Plane_0
Standard Readout status for EKLM.
StoreArray< RawKLM > m_RawKlms
Raw KLM.
KLMTime * m_klmTime
KLM time conversion (for revo9DCArrivalTime).
TH1F * m_PlaneEKLM
Plane occupancy: EKLM.
TH2F ** m_Spatial2DHitsEKLM[EKLMElementNumbers::getMaximalSectionNumber()]
Spatial distribution of EKLM 2d hits per layer.
TH1F * m_EventBackgroundTriggerSummary
Event-level background trigger summary (from TRGSummary).
double m_EKLMScintTimeMin
Min time for EKLM Scint.
const KLMChannelArrayIndex * m_ChannelArrayIndex
KLM channel array index.
static constexpr std::array< TRGSummary::ETimingType, 3 > c_KlmL1Triggers
L1 timing trigger bits of interest for KLM DQM (event-level).
std::string m_HistogramDirectoryName
Directory for KLM DQM histograms in ROOT file.
TH1F * m_FE_BKLM_Layer_0
Standard Readout status for BKLM Scintillator.
void defineHisto() override
Definition of the histograms.
StoreArray< KLMHit2d > m_Hit2ds
KLM 2d hits.
Class to store the raw words from the unpacker, digit-by-digit.
Definition KLMDigitRaw.h:29
uint16_t getTriggerBits()
Get trigger bits.
uint16_t getFEStatus()
Get FE.
KLM digit (class representing a digitized hit in RPCs or scintillators).
Definition KLMDigit.h:29
bool inRPC() const
Determine whether the hit is in RPC or scintillator.
Definition KLMDigit.h:206
int getSubdetector() const
Get subdetector number.
Definition KLMDigit.h:72
bool isGood() const
Whether hit could be used late (if it passed discriminator threshold)
Definition KLMDigit.h:387
uint16_t getCharge() const
Get charge.
Definition KLMDigit.h:224
KLM 2d hit.
Definition KLMHit2d.h:33
KLM sector array index.
KLM time conversion.
Definition KLMTime.h:27
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
The Raw FTSW class.
Definition RawFTSW.h:30
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of relations.
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
uint16_t KLMSectorNumber
Sector number.
uint16_t KLMChannelNumber
Channel number.
uint16_t KLMSubdetectorNumber
Subdetector number.
uint16_t KLMSectionNumber
Section number.
Abstract base class for different kinds of events.