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
19using namespace Belle2;
20
21REG_MODULE(KLMDQM);
22
25 m_DAQInclusion{nullptr},
26 m_TimeRPC{nullptr},
29 m_PlaneBKLMPhi{nullptr},
30 m_PlaneBKLMZ{nullptr},
31 m_PlaneEKLM{nullptr},
33 m_DigitsKLM{nullptr},
34 m_DigitsRPC{nullptr},
39 m_TriggerBitsBKLM{nullptr},
40 m_TriggerBitsEKLM{nullptr},
42 m_DigitsAfterLERInj{nullptr},
43 m_TriggersLERInj{nullptr},
44 m_DigitsAfterHERInj{nullptr},
45 m_TriggersHERInj{nullptr},
46 m_FE_BKLM_Layer_0(nullptr),
47 m_FE_BKLM_Layer_1(nullptr),
48 m_FE_EKLM_Plane_0(nullptr),
49 m_FE_EKLM_Plane_1(nullptr),
52 m_ElementNumbers{&(KLMElementNumbers::Instance())},
54 m_klmTime{&(KLMTime::Instance())}
55{
56 setDescription("KLM data quality monitor.");
58 addParam("histogramDirectoryName", m_HistogramDirectoryName,
59 "Directory for KLM DQM histograms in ROOT file.",
60 std::string("KLM"));
61 addParam("RPCTimeMin", m_RPCTimeMin,
62 "Min time for RPC time histogram.", double(-1223.5));
63 addParam("RPCTimeMax", m_RPCTimeMax,
64 "Max time for RPC time histogram.", double(-199.5));
65 addParam("BKLMScintTimeMin", m_BKLMScintTimeMin,
66 "Min time for BKLM scintillator time histogram.", double(-5300));
67 addParam("BKLMScintTimeMax", m_BKLMScintTimeMax,
68 "Max time for BKLM scintillator time histogram.", double(-4300));
69 addParam("EKLMScintTimeMin", m_EKLMScintTimeMin,
70 "Min time for EKLM scintillator time histogram.", double(-5300));
71 addParam("EKLMScintTimeMax", m_EKLMScintTimeMax,
72 "Max time for EKLM scintillator time histogram.", double(-4300));
73 addParam("Revo9DCArrivalTimeMin", m_Revo9DCArrivalTimeMin,
74 "Min time for RPC hit revo9DCArrivalTime histogram.", double(-10000));
75 addParam("Revo9DCArrivalTimeMax", m_Revo9DCArrivalTimeMax,
76 "Max time for RPC hit revo9DCArrivalTime histogram.", double(3000));
77}
78
80{
82 for (KLMChannelIndex& klmSector : klmIndex) {
83 KLMSectorNumber sector = klmSector.getKLMSectorNumber();
84 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sector);
85 if (m_ChannelHits[sectorIndex] != nullptr)
86 delete[] m_ChannelHits[sectorIndex];
87 }
89 for (KLMChannelIndex& klmSection : klmIndex) {
90 KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
91 if (subdetector == KLMElementNumbers::c_EKLM) {
92 KLMSectionNumber section = klmSection.getSection();
93 if (m_Spatial2DHitsEKLM[section - 1] != nullptr)
94 delete[] m_Spatial2DHitsEKLM[section - 1];
95 }
96 }
97}
98
100{
101 TDirectory* oldDirectory, *newDirectory;
102 oldDirectory = gDirectory;
103 newDirectory = oldDirectory->mkdir(m_HistogramDirectoryName.c_str());
104 newDirectory->cd();
105 /* DAQ inclusion. */
106 m_DAQInclusion = new TH1F("daq_inclusion", "Is KLM included in DAQ?", 2, 0.0, 2.0);
107 m_DAQInclusion->GetXaxis()->SetBinLabel(1, "No");
108 m_DAQInclusion->GetXaxis()->SetBinLabel(2, "Yes");
109 /* Time histograms. */
110 m_TimeRPC = new TH1F("time_rpc", "RPC hit time", 128, m_RPCTimeMin, m_RPCTimeMax);
111 m_TimeRPC->GetXaxis()->SetTitle("Time, ns");
113 new TH1F("time_scintillator_bklm", "Scintillator hit time (BKLM)",
115 m_TimeScintillatorBKLM->GetXaxis()->SetTitle("Time, ns");
117 new TH1F("time_scintillator_eklm", "Scintillator hit time (EKLM)",
119 m_TimeScintillatorEKLM->GetXaxis()->SetTitle("Time, ns");
120 m_TimeRevo9DCArrivalTime = new TH1F("time_revo9dc_arrival_time", "DC arrival hit time (RPC)",
122 m_TimeRevo9DCArrivalTime->GetXaxis()->SetTitle("Time, ns");
123 /* Number of hits per plane. */
124 m_PlaneBKLMPhi = new TH1F("plane_bklm_phi",
125 "BKLM plane occupancy (#phi readout)",
126 240, 0.5, 240.5);
127 m_PlaneBKLMPhi->GetXaxis()->SetTitle("Layer number");
128 m_PlaneBKLMZ = new TH1F("plane_bklm_z",
129 "BKLM plane occupancy (z readout)",
130 240, 0.5, 240.5);
131 m_PlaneBKLMZ->GetXaxis()->SetTitle("Layer number");
132 m_PlaneEKLM = new TH1F("plane_eklm", "EKLM plane occupancy (both readouts)", 208, 0.5, 208.5);
133 m_PlaneEKLM->GetXaxis()->SetTitle("Plane number");
134 /* Number of hits per channel. */
135 int nChannelHistograms =
140 KLMChannelNumber* firstChannelNumbers =
141 new KLMChannelNumber[nChannelHistograms + 1];
142 int i = 0;
144 for (KLMChannelIndex& klmSector : klmIndex) {
145 KLMChannelIndex klmChannel(klmSector);
147 KLMChannelNumber channel = klmChannel.getKLMChannelNumber();
148 firstChannelNumbers[i] = m_ChannelArrayIndex->getIndex(channel);
149 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM) {
150 channel = m_ElementNumbers->channelNumberBKLM(
151 klmChannel.getSection(), klmChannel.getSector(), 8, 0, 1);
152 firstChannelNumbers[i + 1] = m_ChannelArrayIndex->getIndex(channel);
153 i += 2;
154 } else {
155 int layerIncrease = (klmSector.getSection() == 1) ? 4 : 5;
156 channel = m_ElementNumbers->channelNumberEKLM(
157 klmChannel.getSection(), klmChannel.getSector(),
158 1 + layerIncrease, 1, 1);
159 firstChannelNumbers[i + 1] = m_ChannelArrayIndex->getIndex(channel);
160 channel = m_ElementNumbers->channelNumberEKLM(
161 klmChannel.getSection(), klmChannel.getSector(),
162 1 + layerIncrease * 2, 1, 1);
163 firstChannelNumbers[i + 2] = m_ChannelArrayIndex->getIndex(channel);
164 i += 3;
165 }
166 }
167 firstChannelNumbers[nChannelHistograms] = m_ChannelArrayIndex->getNElements();
168 i = 0;
170 for (KLMChannelIndex& klmSector : klmIndex) {
171 int nHistograms;
172 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
173 nHistograms = m_ChannelHitHistogramsBKLM;
174 else
175 nHistograms = m_ChannelHitHistogramsEKLM;
176 KLMSectorNumber sector = klmSector.getKLMSectorNumber();
177 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sector);
178 m_ChannelHits[sectorIndex] = new TH1F*[nHistograms];
179 for (int j = 0; j < nHistograms; j++) {
180 std::string name =
181 "strip_hits_subdetector_" + std::to_string(klmSector.getSubdetector()) +
182 "_section_" + std::to_string(klmSector.getSection()) +
183 "_sector_" + std::to_string(klmSector.getSector()) +
184 "_" + std::to_string(j);
185 std::string title = "Sector " + std::to_string(klmSector.getSector()) + " -- " +
186 m_ElementNumbers->getSectorDAQName(klmSector.getSubdetector(), klmSector.getSection(), klmSector.getSector());
187 m_ChannelHits[sectorIndex][j] = new TH1F(
188 name.c_str(), title.c_str(),
189 firstChannelNumbers[i + 1] - firstChannelNumbers[i],
190 firstChannelNumbers[i] - 0.5, firstChannelNumbers[i + 1] - 0.5);
191 i++;
192 }
193 }
194 delete[] firstChannelNumbers;
195 /* Masked channels per sector:
196 * it is defined here, but filled by the analysis module. */
197 KLMSectorNumber totalSectors = m_SectorArrayIndex->getNElements();
198 m_MaskedChannelsPerSector = new TH1F("masked_channels", "Number of masked channels per sector",
199 totalSectors, -0.5, totalSectors - 0.5);
201 for (KLMChannelIndex& klmSector : klmIndex) {
202 std::string label = m_ElementNumbers->getSectorDAQName(klmSector.getSubdetector(), klmSector.getSection(), klmSector.getSector());
203 KLMSectorNumber sector = klmSector.getKLMSectorNumber();
204 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sector);
205 m_MaskedChannelsPerSector->GetXaxis()->SetBinLabel(sectorIndex + 1, label.c_str());
206 }
207 /* Number of digits. */
208 m_DigitsKLM = new TH1F("digits_klm", "Number of KLM digits",
209 250.0, 0.0, 250.0);
210 m_DigitsKLM->GetXaxis()->SetTitle("Number of digits");
211 m_DigitsRPC = new TH1F("digits_rpc", "Number of RPC digits",
212 250.0, 0.0, 250.0);
213 m_DigitsRPC->GetXaxis()->SetTitle("Number of digits");
214 m_DigitsScintillatorBKLM = new TH1F("digits_scintillator_bklm", "Number of scintillator digits (BKLM)",
215 250.0, 0.0, 250.0);
216 m_DigitsScintillatorBKLM->GetXaxis()->SetTitle("Number of digits");
217 m_DigitsScintillatorEKLM = new TH1F("digits_scintillator_eklm", "Number of scintillator digits (EKLM)",
218 250.0, 0.0, 250.0);
219 m_DigitsScintillatorEKLM->GetXaxis()->SetTitle("Number of digits");
220 m_DigitsMultiStripBKLM = new TH1F("digits_multi_bklm", "Number of multi-strip digits (BKLM)",
221 50.0, 0.0, 50.0);
222 m_DigitsMultiStripBKLM->GetXaxis()->SetTitle("Number of multi-strip digits");
223 m_DigitsMultiStripEKLM = new TH1F("digits_multi_eklm", "Number of multi-strip digits (EKLM)",
224 50.0, 0.0, 50.0);
225 m_DigitsMultiStripEKLM->GetXaxis()->SetTitle("Number of multi-strip digits");
226 /* Trigger bits. */
227 m_TriggerBitsBKLM = new TH1F("trigger_bits_bklm", "Trigger bits of multi-strip digits (BKLM)",
228 (double)c_0x1, (double)c_0x8, (double)c_0x1 + 1.0);
229 m_TriggerBitsBKLM->GetXaxis()->SetBinLabel(c_0x8, "0x8");
230 m_TriggerBitsBKLM->GetXaxis()->SetBinLabel(c_0x4, "0x4");
231 m_TriggerBitsBKLM->GetXaxis()->SetBinLabel(c_0x2, "0x2");
232 m_TriggerBitsBKLM->GetXaxis()->SetBinLabel(c_0x1, "0x1");
233 m_TriggerBitsEKLM = new TH1F("trigger_bits_eklm", "Trigger bits of multi-strip digits (EKLM)",
234 (double)c_0x1, (double)c_0x8, (double)c_0x1 + 1.0);
235 m_TriggerBitsEKLM->GetXaxis()->SetBinLabel(c_0x8, "0x8");
236 m_TriggerBitsEKLM->GetXaxis()->SetBinLabel(c_0x4, "0x4");
237 m_TriggerBitsEKLM->GetXaxis()->SetBinLabel(c_0x2, "0x2");
238 m_TriggerBitsEKLM->GetXaxis()->SetBinLabel(c_0x1, "0x1");
239
240 /* Event-level L1 trigger bits (TRGSummary). */
241 int nTimingBits = (int)c_KlmL1Triggers.size(); // TTYP_DPHY, TTYP_RAND, TTYP_POIS
242 int nL1Bins = nTimingBits + 1; // extra bin for bha_delay
243 m_EventBackgroundTriggerSummary = new TH1F("event_background_trigger_summary",
244 "Event background trigger summary;Trigger Decision;Events",
245 nL1Bins, 0.5, 0.5 + nL1Bins);
246 /* Keep labels explicit to match the actual trigger bits. */
247 m_EventBackgroundTriggerSummary->GetXaxis()->SetBinLabel(1, "TTYP_DPHY");
248 m_EventBackgroundTriggerSummary->GetXaxis()->SetBinLabel(2, "TTYP_RAND");
249 m_EventBackgroundTriggerSummary->GetXaxis()->SetBinLabel(3, "TTYP_POIS");
250 m_EventBackgroundTriggerSummary->GetXaxis()->SetBinLabel(4, "bha_delay");
251
252 /* Number of digits after injection */
253 /* For the histograms below, we use the same style as for other subdetectors. */
254 m_DigitsAfterLERInj = new TH1F("KLMOccInjLER", "KLM digits after LER injection / Time;Time [#mus];Number of KLM digits / (5 #mus)",
255 4000, 0, 20000);
256 m_TriggersLERInj = new TH1F("KLMTrigInjLER", "Triggers after KER injection / Time;Time [#mus];Number of triggers / (5 #mus)",
257 4000, 0, 20000);
258 m_DigitsAfterHERInj = new TH1F("KLMOccInjHER", "KLM digits after HER injection / Time;Time [#mus];Number of KLM digits / (5 #mus)",
259 4000, 0, 20000);
260 m_TriggersHERInj = new TH1F("KLMTrigInjHER", "Triggers after HER injection / Time;Time [#mus];Number of triggers / (5 #mus)",
261 4000, 0, 20000);
262 /* Spatial distribution of EKLM 2d hits per layer. */
264 for (KLMChannelIndex& klmSection : klmIndex) {
265 KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
266 if (subdetector == KLMElementNumbers::c_EKLM) {
267 KLMSectionNumber section = klmSection.getSection();
268 int maximalLayerNumber = m_eklmElementNumbers->getMaximalDetectorLayerNumber(section);
269 m_Spatial2DHitsEKLM[section - 1] = new TH2F*[maximalLayerNumber];
270 std::string sectionName = (section == EKLMElementNumbers::c_ForwardSection) ? "Forward" : "Backward";
271 for (int j = 1; j <= maximalLayerNumber; ++j) {
272 std::string name = "spatial_2d_hits_subdetector_" + std::to_string(subdetector) +
273 "_section_" + std::to_string(section) +
274 "_layer_" + std::to_string(j);
275 std::string title = "Endcap " + sectionName + " , Layer " + std::to_string(j);
276 /* Use bins with a size of 10 cm per side. */
277 m_Spatial2DHitsEKLM[section - 1][j - 1] = new TH2F(name.c_str(), title.c_str(),
278 340 * 2 / 10, -340, 340,
279 340 * 2 / 10, -340, 340);
280 m_Spatial2DHitsEKLM[section - 1][j - 1]->GetXaxis()->SetTitle("X coordinate [cm]");
281 m_Spatial2DHitsEKLM[section - 1][j - 1]->GetYaxis()->SetTitle("Y coordinate [cm]");
282 }
283 }
284 }
285 // Feature extraction status histogram for BKLM
286 int bklmSectors = BKLMElementNumbers::getMaximalSectorGlobalNumber(); // 16
287 int eklmPlanes = EKLMElementNumbers::getMaximalPlaneGlobalNumber(); // 208
288
289 m_FE_BKLM_Layer_0 = new TH1F("feStatus_bklm_scintillator_layers_0",
290 "BKLM Scintillator Standard Readout;FEE Card", bklmSectors * 2, 0.5, 0.5 + bklmSectors * 2);
291 m_FE_BKLM_Layer_1 = new TH1F("feStatus_bklm_scintillator_layers_1",
292 "BKLM Scintillator Feature Extraction;FEE Card", bklmSectors * 2, 0.5, 0.5 + bklmSectors * 2);
293 m_FE_EKLM_Plane_0 = new TH1F("feStatus_eklm_plane_0",
294 "EKLM Standard Readout;Plane number", eklmPlanes, 0.5, 0.5 + eklmPlanes);
295 m_FE_EKLM_Plane_1 = new TH1F("feStatus_eklm_plane_1",
296 "EKLM Feature Extraction;Plane number", eklmPlanes, 0.5, 0.5 + eklmPlanes);
297 oldDirectory->cd();
298}
299
301{
302 REG_HISTOGRAM;
303 m_RawFtsws.isOptional();
304 m_RawKlms.isOptional();
305 m_trgSummary.isOptional();
306 m_Digits.isOptional();
307 m_BklmHit1ds.isOptional();
308 m_Hit2ds.isOptional();
309}
310
312{
313 /* DAQ inclusion. */
314 m_DAQInclusion->Reset();
315 if (m_RawKlms.isValid())
316 m_DAQInclusion->Fill("Yes", 1);
317 else
318 m_DAQInclusion->Fill("No", 1);
319 /* Time. */
320 m_TimeRPC->Reset();
321 m_TimeScintillatorBKLM->Reset();
322 m_TimeScintillatorEKLM->Reset();
324 m_klmTime->updateConstants(); //to get correct CTime
325 /* Plane hits. */
326 m_PlaneEKLM->Reset();
327 m_PlaneBKLMPhi->Reset();
328 m_PlaneBKLMZ->Reset();
329 /* Channel hits. */
331 for (KLMChannelIndex& klmSector : klmIndex) {
332 int nHistograms;
333 if (klmSector.getSubdetector() == KLMElementNumbers::c_BKLM)
334 nHistograms = m_ChannelHitHistogramsBKLM;
335 else
336 nHistograms = m_ChannelHitHistogramsEKLM;
337 KLMSectorNumber sector = klmSector.getKLMSectorNumber();
338 KLMSectorNumber sectorIndex = m_SectorArrayIndex->getIndex(sector);
339 for (int j = 0; j < nHistograms; j++)
340 m_ChannelHits[sectorIndex][j]->Reset();
341 }
342 /* Digits. */
343 m_DigitsKLM->Reset();
344 m_DigitsRPC->Reset();
347 m_DigitsMultiStripBKLM->Reset();
348 m_DigitsMultiStripEKLM->Reset();
349 /* Trigger bits. */
350 m_TriggerBitsBKLM->Reset();
351 m_TriggerBitsEKLM->Reset();
352 /* Event-level background trigger summary. */
353 if (m_EventBackgroundTriggerSummary != nullptr)
355 /* Injection information. */
356 m_DigitsAfterLERInj->Reset();
357 m_TriggersLERInj->Reset();
358 m_DigitsAfterHERInj->Reset();
359 m_TriggersHERInj->Reset();
360 /* Spatial 2D hits distributions. */
362 for (KLMChannelIndex& klmSection : klmIndex) {
363 KLMSubdetectorNumber subdetector = klmSection.getSubdetector();
364 if (subdetector == KLMElementNumbers::c_EKLM) {
365 KLMSectionNumber section = klmSection.getSection();
366 int maximalLayerNumber =
367 m_eklmElementNumbers->getMaximalDetectorLayerNumber(section);
368 for (int j = 1; j <= maximalLayerNumber; ++j)
369 m_Spatial2DHitsEKLM[section - 1][j - 1]->Reset();
370 }
371 }
372 /* Feature extraction. */
373 m_FE_BKLM_Layer_0->Reset();
374 m_FE_BKLM_Layer_1->Reset();
375 m_FE_EKLM_Plane_0->Reset();
376 m_FE_EKLM_Plane_1->Reset();
377}
378
380{
381 /* Event-level background trigger summary, filled once per event. */
382 if (m_trgSummary.isValid() && m_EventBackgroundTriggerSummary != nullptr) {
383 const int nTimingBits = (int)c_KlmL1Triggers.size();
384 // GDL Background triggers: TTYP_DPHY, TTYP_RAND, TTYP_POIS
385 for (int i = 0; i < nTimingBits; ++i) {
386 if (m_trgSummary->testInput(c_KlmL1Triggers[i]))
387 m_EventBackgroundTriggerSummary->Fill((double)i + 1.0);
388 }
389 // L1 trigger bit: "bha_delay"
390 try {
391 if (m_trgSummary->testInput("bha_delay"))
392 m_EventBackgroundTriggerSummary->Fill((double)nTimingBits + 1.0);
393 } catch (const std::exception&) {
394 // Ignore if it is not available
395 }
396 }
397
398 int nDigits = m_Digits.getEntries();
399 int nDigitsRPC = 0, nDigitsScintillatorBKLM = 0, nDigitsScintillatorEKLM = 0;
400 int nDigitsMultiStripBKLM = 0, nDigitsMultiStripEKLM = 0;
401 for (const KLMDigit& digit : m_Digits) {
402 /*
403 * Reject digits that are below the threshold (such digits may appear
404 * for simulated events).
405 */
406
407 if (!digit.isGood())
408 continue;
409 KLMDigitRaw* digitRaw = digit.getRelated<KLMDigitRaw>();
410 if (digit.getSubdetector() == KLMElementNumbers::c_EKLM) {
411 nDigitsScintillatorEKLM++;
412 int section = digit.getSection();
413 int sector = digit.getSector();
414 int layer = digit.getLayer();
415 int plane = digit.getPlane();
416 int strip = digit.getStrip();
417 if (not digit.isMultiStrip()) {
418 KLMSectorNumber klmSector = m_ElementNumbers->sectorNumberEKLM(section, sector);
419 KLMSectorNumber klmSectorIndex = m_SectorArrayIndex->getIndex(klmSector);
420 KLMChannelNumber channel = m_ElementNumbers->channelNumberEKLM(section, sector, layer, plane, strip);
421 KLMChannelNumber channelIndex = m_ChannelArrayIndex->getIndex(channel);
422 for (int j = 0; j < m_ChannelHitHistogramsEKLM; j++) {
423 double xMin = m_ChannelHits[klmSectorIndex][j]->GetXaxis()->GetXmin();
424 double xMax = m_ChannelHits[klmSectorIndex][j]->GetXaxis()->GetXmax();
425 if ((xMin > channelIndex) || (xMax < channelIndex))
426 continue;
427 m_ChannelHits[klmSectorIndex][j]->Fill(channelIndex);
428 }
429 } else
430 nDigitsMultiStripEKLM++;
431 int planeGlobal = m_eklmElementNumbers->planeNumber(section, layer, sector, plane);
432 m_PlaneEKLM->Fill(planeGlobal);
433 m_TimeScintillatorEKLM->Fill(digit.getTime());
434 if (digit.isMultiStrip()) {
435 if (digitRaw) {
436 uint16_t triggerBits = digitRaw->getTriggerBits();
437 if ((triggerBits & 0x1) != 0)
439 if ((triggerBits & 0x2) != 0)
441 if ((triggerBits & 0x4) != 0)
443 if ((triggerBits & 0x8) != 0)
445 }
446 }
447 if (digitRaw) {
448 // Extract m_FE from m_word4
449 uint16_t feStatus = digitRaw->getFEStatus(); // Extract the most significant bit
450 if (feStatus != 0) {
451 m_FE_EKLM_Plane_1->Fill(planeGlobal);
452 } else {
453 m_FE_EKLM_Plane_0->Fill(planeGlobal);
454 }
455 }
456 } else if (digit.getSubdetector() == KLMElementNumbers::c_BKLM) {
457 int section = digit.getSection();
458 int sector = digit.getSector();
459 int layer = digit.getLayer();
460 int plane = digit.getPlane();
461 int strip = digit.getStrip();
462
463 KLMSectorNumber klmSector = m_ElementNumbers->sectorNumberBKLM(section, sector);
464 KLMSectorNumber klmSectorIndex = m_SectorArrayIndex->getIndex(klmSector);
465
466 if (not digit.isMultiStrip()) {
467 KLMChannelNumber channel = m_ElementNumbers->channelNumberBKLM(section, sector, layer, plane, strip);
468 KLMChannelNumber channelIndex = m_ChannelArrayIndex->getIndex(channel);
469 for (int j = 0; j < m_ChannelHitHistogramsBKLM; j++) {
470 double xMin = m_ChannelHits[klmSectorIndex][j]->GetXaxis()->GetXmin();
471 double xMax = m_ChannelHits[klmSectorIndex][j]->GetXaxis()->GetXmax();
472 if ((xMin > channelIndex) || (xMax < channelIndex))
473 continue;
474 m_ChannelHits[klmSectorIndex][j]->Fill(channelIndex);
475 }
476 } else
477 nDigitsMultiStripBKLM++;
478 if (digit.inRPC()) {
479 nDigitsRPC++;
480 m_TimeRPC->Fill(digit.getTime());
481 m_TimeRevo9DCArrivalTime->Fill(digit.getRevo9DCArrivalTime() * m_klmTime->getCTimePeriod());
482 } else {
483 nDigitsScintillatorBKLM++;
484 m_TimeScintillatorBKLM->Fill(digit.getTime());
485 if (digitRaw) {
486 uint16_t feStatus = digitRaw->getFEStatus(); // Extract the most significant bit
487 if (feStatus != 0) {
488 m_FE_BKLM_Layer_1->Fill((klmSectorIndex) * 2 + layer);
489 } else {
490 m_FE_BKLM_Layer_0->Fill((klmSectorIndex) * 2 + layer);
491 }
492 }
493 }
494 if (digit.isMultiStrip()) {
495 if (digitRaw) {
496 uint16_t triggerBits = digitRaw->getTriggerBits();
497 if ((triggerBits & 0x1) != 0)
499 if ((triggerBits & 0x2) != 0)
501 if ((triggerBits & 0x4) != 0)
503 if ((triggerBits & 0x8) != 0)
505 }
506 }
507 } else
508 B2FATAL("Not a BKLM or a EKLM digit, something went really wrong.");
509 }
510 for (const BKLMHit1d& hit1d : m_BklmHit1ds) {
511 int section = hit1d.getSection();
512 int sector = hit1d.getSector();
513 int layer = hit1d.getLayer();
515 section, sector, layer);
516 if (hit1d.isPhiReadout())
517 m_PlaneBKLMPhi->Fill(layerGlobal);
518 else
519 m_PlaneBKLMZ->Fill(layerGlobal);
520 }
521 /* Digits. */
522 m_DigitsKLM->Fill((double)nDigits);
523 m_DigitsRPC->Fill((double)nDigitsRPC);
524 m_DigitsScintillatorBKLM->Fill((double)nDigitsScintillatorBKLM);
525 m_DigitsScintillatorEKLM->Fill((double)nDigitsScintillatorEKLM);
526 if (nDigitsMultiStripBKLM > 0)
527 m_DigitsMultiStripBKLM->Fill((double)nDigitsMultiStripBKLM);
528 if (nDigitsMultiStripEKLM > 0)
529 m_DigitsMultiStripEKLM->Fill((double)nDigitsMultiStripEKLM);
530 /* Injection information. */
531 for (RawFTSW& rawFtsw : m_RawFtsws) {
532 unsigned int difference = rawFtsw.GetTimeSinceLastInjection(0);
533 if (difference != 0x7FFFFFFF) {
534 /* 127 MHz clock ticks to us, inexact rounding. */
535 float differenceInUs = difference / 127.;
536 if (rawFtsw.GetIsHER(0)) {
537 m_DigitsAfterHERInj->Fill(differenceInUs, nDigits);
538 m_TriggersHERInj->Fill(differenceInUs);
539 } else {
540 m_DigitsAfterLERInj->Fill(differenceInUs, nDigits);
541 m_TriggersLERInj->Fill(differenceInUs);
542 }
543 }
544 /*
545 * Usually, only one RawFTSW object is stored per event.
546 * If there are more, ignore the others.
547 */
548 break;
549 }
550 /* Spatial 2D hits distributions. */
551 for (const KLMHit2d& hit2d : m_Hit2ds) {
552 if (hit2d.getSubdetector() != KLMElementNumbers::c_EKLM)
553 continue;
554 int section = hit2d.getSection();
555 int layer = hit2d.getLayer();
556 m_Spatial2DHitsEKLM[section - 1][layer - 1]->Fill(hit2d.getPositionX(), hit2d.getPositionY());
557 }
558}
559
561{
562}
563
565{
566}
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.
double m_BKLMScintTimeMin
Min time for BKLM Scint.
TH1F * m_DigitsMultiStripEKLM
Number of multi-strip digits: EKLM scintillators.
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.
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.
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.
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_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_DigitsRPC
Number of digits: BKLM RPCs.
TH1F * m_TriggersHERInj
Histogram to be used for normalization of occupancy after HER injection.
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.
const KLMSectorArrayIndex * m_SectorArrayIndex
KLM sector array index.
StoreArray< BKLMHit1d > m_BklmHit1ds
BKLM 1d hits.
TH1F * m_DigitsAfterLERInj
Number of KLM Digits after LER injection.
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).
TH1F * m_MaskedChannelsPerSector
Masked channels per sector.
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
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
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
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.