Belle II Software development
DetectorOccupanciesDQMModule.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 "reconstruction/modules/detectorOccupanciesDQM/DetectorOccupanciesDQMModule.h"
10
11#include <framework/dataobjects/EventMetaData.h>
12#include <ecl/dataobjects/ECLCalDigit.h>
13#include <ecl/dataobjects/ECLElementNumbers.h>
14#include <klm/dataobjects/bklm/BKLMElementNumbers.h>
15#include <klm/dataobjects/KLMDigit.h>
16#include <arich/dataobjects/ARICHHit.h>
17#include <top/dataobjects/TOPDigit.h>
18
19#include <TDirectory.h>
20
21
22
23using namespace Belle2;
24
25//-----------------------------------------------------------------
26// Register the Module
27//-----------------------------------------------------------------
28REG_MODULE(DetectorOccupanciesDQM);
29
30
31//-----------------------------------------------------------------
32// Implementation
33//-----------------------------------------------------------------
34
36 , m_eklmElementNumbers{&(EKLMElementNumbers::Instance())}, m_klmTime{&(KLMTime::Instance())}
37{
38 setDescription("DQM Module to monitor basic detector quantities");
39
40 addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of the directory where histograms will be placed.",
41 std::string("DetectorOccupancies"));
42 addParam("eclEnergyThr", m_eclEnergyThr, "Energy threshold (in MeV) for ECL occupancy histogram", 5.0);
43 addParam("BKLMTimeMin", m_BKLMTimeMin,
44 "Min time for BKLM time histogram.", double(-6500));
45 addParam("BKLMTimeMax", m_BKLMTimeMax,
46 "Max time for BKLM time histogram.", double(5000));
47 addParam("EKLMTimeMin", m_EKLMTimeMin,
48 "Min time for EKLM time histogram.", double(-5100));
49 addParam("EKLMTimeMax", m_EKLMTimeMax,
50 "Max time for EKLM time histogram.", double(-4500));
51 addParam("BKLMScintOffset", m_BKLMScintOffset,
52 "Offset to center BKLM Scint. times at 0", double(-4705.));
53 addParam("BKLMRPCOffset", m_BKLMRPCOffset,
54 "Offset to center BKLM RPC times at 0", double(-4300.5));
56}
57
58
59DetectorOccupanciesDQMModule::~DetectorOccupanciesDQMModule()
60{
61}
62
63//------------------------------------------------------------------
64// Function to define histograms
65//-----------------------------------------------------------------
66
68{
69
70 // Create a separate histogram directories and cd into it.
71 TDirectory* oldDir = gDirectory;
72 if (m_histogramDirectoryName != "") {
73 oldDir->mkdir(m_histogramDirectoryName.c_str());
74 oldDir->cd(m_histogramDirectoryName.c_str());
75 }
76
77 //histogram index:
78 // 0 if the event is triggered OUTSIDE the active_veto window
79 const std::string tag[2] = {"OUT", "IN"};
80 const std::string title[2] = {"[Outside Active Veto Window]", "[Inside Active Veto Window]"};
81
82
83 //BKLM plane occupancy
84 //outside active_veto window:
85 std::string histoName = "bklm_plane_occupancy";
86 std::string histoTitle = "BKLM plane occupancy";
87 m_BKLM_Plane_Occupancy[0] = new TH2F((histoName + "_" + tag[0]).c_str(),
88 (histoTitle + " " + title[0]).c_str(),
89 240, 0.5, 240.5,
91 m_BKLM_Plane_Occupancy[0]->GetXaxis()->SetTitle("Layer number");
92 m_BKLM_Plane_Occupancy[0]->GetYaxis()->SetTitle("Shifted Time (ns)");
93
94 //inside active_veto window:
96 m_BKLM_Plane_Occupancy[1]->SetName((histoName + "_" + tag[1]).c_str());
97
98 m_BKLM_Plane_Occupancy[1]->SetTitle((histoTitle + " " + title[1]).c_str());
99
100
101 //BKLM plane occupancy (w/ random triggers)
102 //outside active_veto window:
103 histoName = "bklm_plane_trg_occupancy";
104 histoTitle = "BKLM plane occupancy (w/ trgs)";
105 m_BKLM_PlaneTrg_Occupancy[0] = new TH2F((histoName + "_" + tag[0]).c_str(),
106 (histoTitle + " " + title[0]).c_str(),
107 240, 0.5, 240.5,
109 m_BKLM_PlaneTrg_Occupancy[0]->GetXaxis()->SetTitle("Layer number");
110 m_BKLM_PlaneTrg_Occupancy[0]->GetYaxis()->SetTitle("Shifted Time (ns)");
111
112 //inside active_veto window:
114 m_BKLM_PlaneTrg_Occupancy[1]->SetName((histoName + "_" + tag[1]).c_str());
115 m_BKLM_PlaneTrg_Occupancy[1]->SetTitle((histoTitle + " " + title[1]).c_str());
116
117
118 //EKLM plane occupancy
119 //outside active_veto window:
120 histoName = "eklm_plane_occupancy";
121 histoTitle = "EKLM plane occupancy";
122 m_EKLM_Plane_Occupancy[0] = new TH2F((histoName + "_" + tag[0]).c_str(),
123 (histoTitle + " " + title[0]).c_str(),
124 208, 0.5, 208.5,
126 m_EKLM_Plane_Occupancy[0]->GetXaxis()->SetTitle("Plane number");
127 m_EKLM_Plane_Occupancy[0]->GetYaxis()->SetTitle("Time from L1Trigger (ns)");
128
129 //inside active_veto window:
131 m_EKLM_Plane_Occupancy[1]->SetName((histoName + "_" + tag[1]).c_str());
132 m_EKLM_Plane_Occupancy[1]->SetTitle((histoTitle + " " + title[1]).c_str());
133
134 //EKLM plane occupancy w/ random triggers
135 //outside active_veto window:
136 histoName = "eklm_plane_trg_occupancy";
137 histoTitle = "EKLM plane occupancy (w/ trgs)";
138 m_EKLM_PlaneTrg_Occupancy[0] = new TH2F((histoName + "_" + tag[0]).c_str(),
139 (histoTitle + " " + title[0]).c_str(),
140 208, 0.5, 208.5,
142 m_EKLM_PlaneTrg_Occupancy[0]->GetXaxis()->SetTitle("Plane number");
143 m_EKLM_PlaneTrg_Occupancy[0]->GetXaxis()->SetTitle("Time from L1Trigger (ns)");
144
145 //inside active_veto window:
147 m_EKLM_PlaneTrg_Occupancy[1]->SetName((histoName + "_" + tag[1]).c_str());
148 m_EKLM_PlaneTrg_Occupancy[1]->SetTitle((histoTitle + " " + title[1]).c_str());
149
150
151
152 //ARICH plane occupancy
153 //outside active_veto window:
154 histoName = "arich_occupancy";
155 histoTitle = "ARICH Occupancy";
156 m_ARICH_Occupancy[0] = new TH1F((histoName + "_" + tag[0]).c_str(),
157 (histoTitle + " " + title[0]).c_str(),
158 201, -0.5, 200.5);
159 m_ARICH_Occupancy[0]->GetXaxis()->SetTitle("hits per event");
160
161 //inside active_veto window:
162 m_ARICH_Occupancy[1] = new TH1F(*m_ARICH_Occupancy[0]);
163 m_ARICH_Occupancy[1]->SetName((histoName + "_" + tag[1]).c_str());
164 m_ARICH_Occupancy[1]->SetTitle((histoTitle + " " + title[1]).c_str());
165
166 //TOP occupancy
167 histoName = "top_occupancy";
168 histoTitle = "TOP Occupancy for good hits";
169 for (int i = 0; i < 2; i++) {
170 m_TOP_Occupancy[i] = new TH1F((histoName + "_" + tag[i]).c_str(),
171 (histoTitle + " " + title[i]).c_str(),
172 1000, 0, 10000);
173 m_TOP_Occupancy[i]->SetXTitle("hits per event");
174 m_TOP_Occupancy[i]->SetYTitle("entries per bin");
175 }
176
177 //ECL occupancy
178 histoName = "ecl_occupancy";
179 histoTitle = "ECL occupancy (for hits with E > " + std::to_string((int)m_eclEnergyThr) + " MeV)";
180 for (int i = 0; i < 2; i++) {
181 m_ECL_Occupancy[i] = new TProfile((histoName + "_" + tag[i]).c_str(),
182 (histoTitle + " " + title[i]).c_str(),
185 m_ECL_Occupancy[i]->SetXTitle("cell id");
186 m_ECL_Occupancy[i]->SetYTitle("Occupancy (hits / evt_count)");
187 }
188
189
190 oldDir->cd();
191}
192
194{
195 m_eventMetaData.isOptional();
196 m_trgSummary.isOptional();
197 m_KLMDigits.isOptional();
198 m_ARICHHits.isOptional();
199 m_topDigits.isOptional();
200 m_eclCalDigits.isOptional();
201
202 // Register histograms (calls back defineHisto)
203 REG_HISTOGRAM
204}
205
206
208{
209 m_klmTime->updateConstants(); //to get correct CTime
210 for (int i = 0; i < 2; i++) {
211 if (m_BKLM_Plane_Occupancy[i] != nullptr) m_BKLM_Plane_Occupancy[i]->Reset();
212 if (m_BKLM_PlaneTrg_Occupancy[i] != nullptr) m_BKLM_PlaneTrg_Occupancy[i]->Reset();
213 if (m_EKLM_Plane_Occupancy[i] != nullptr) m_EKLM_Plane_Occupancy[i]->Reset();
214 if (m_EKLM_PlaneTrg_Occupancy[i] != nullptr) m_EKLM_PlaneTrg_Occupancy[i]->Reset();
215 if (m_ARICH_Occupancy[i] != nullptr) m_ARICH_Occupancy[i]->Reset();
216 if (m_TOP_Occupancy[i] != nullptr) m_TOP_Occupancy[i]->Reset();
217 if (m_ECL_Occupancy[i] != nullptr) m_ECL_Occupancy[i]->Reset();
218
219 }
220}
221
222
224{
225
226 //skip events in which we do not have EventMetaData or TRGSummary
227 if (!m_eventMetaData.isValid()) return;
228 if (!m_trgSummary.isValid()) return;
229
230 //skip the empty events
232 return;
233
235 return;
236
238 return;
239
241 return;
242
243 //find out if we are in the passive veto (i=0) or in the active veto window (i=1)
244 int index = 0; //events accepted in the passive veto window but not in the active
245 try {
246 if (m_trgSummary->testInput("passive_veto") == 1 && m_trgSummary->testInput("cdcecl_veto") == 0) index = 1;
247 } catch (const std::exception&) {
248 }
249
250 // Check if any L1Triggers in the backTriggers list are hot
251 bool backBooleanFlag = std::any_of(
252 std::begin(m_klmBackTriggers),
253 std::end(m_klmBackTriggers),
254 [trg = m_trgSummary](TRGSummary::ETimingType trgBit) {
255 return trg->testInput(trgBit);
256 }
257 );
258
259
260 for (const KLMDigit& digit : m_KLMDigits) {
261 /*
262 * Reject digits that are below the threshold (such digits may appear
263 * for simulated events).
264 */
265 if (!digit.isGood())
266 continue;
267
268 if (digit.getSubdetector() == KLMElementNumbers::c_EKLM) {
269 int section = digit.getSection();
270 int layer = digit.getLayer();
271 int sector = digit.getSector();
272 int plane = digit.getPlane();
273 int planeGlobal = m_eklmElementNumbers->planeNumber(section, layer, sector, plane);
274 m_EKLM_Plane_Occupancy[index]->Fill(planeGlobal, digit.getTime());
275 if (backBooleanFlag) m_EKLM_PlaneTrg_Occupancy[index]->Fill(planeGlobal, digit.getTime());
276 } else if (digit.getSubdetector() == KLMElementNumbers::c_BKLM) {
277 int section = digit.getSection();
278 int layer = digit.getLayer();
279 int sector = digit.getSector();
281 section, sector, layer);
282 float offset = (digit.inRPC()) ? m_BKLMRPCOffset : m_BKLMScintOffset;
283 float rawTime = (digit.inRPC()) ? digit.getRevo9DCArrivalTime() * m_klmTime->getCTimePeriod() : digit.getTime();
284 float time = rawTime - offset; //shift is to align scintillator and RPC hits on one graph
285
286 bool goodHit = (rawTime > -11000 && rawTime < 0); //~11us from L1 trigger
287 if (!goodHit)
288 continue;
289 m_BKLM_Plane_Occupancy[index]->Fill(layerGlobal, time);
290 if (backBooleanFlag)
291 m_BKLM_PlaneTrg_Occupancy[index]->Fill(layerGlobal, time);
292 }
293 }
294
295 float xMax = m_ARICH_Occupancy[0]->GetXaxis()->GetBinCenter(m_ARICH_Occupancy[0]->GetNbinsX());
296 int arichNentr = m_ARICHHits.isValid() ? m_ARICHHits.getEntries() : 0;
297 m_ARICH_Occupancy[index] -> Fill(arichNentr > xMax ? xMax : arichNentr);
298
299
300 int topGoodHits = 0;
301 for (const auto& digit : m_topDigits) {
302 if (digit.getHitQuality() != TOPDigit::c_Junk) topGoodHits++;
303 }
304 m_TOP_Occupancy[index]->Fill(topGoodHits);
305
306 std::array<bool, ECLElementNumbers::c_NCrystals> crystal_hit;
307
308 for (const auto& digit : m_eclCalDigits) {
309 const double thresholdGeV = m_eclEnergyThr * 1e-3;
310 if (digit.getEnergy() > thresholdGeV)
311 crystal_hit.at(digit.getCellId() - 1) = true;
312 }
313 for (int cid0 = 0; cid0 < ECLElementNumbers::c_NCrystals; cid0++) {
314 m_ECL_Occupancy[index]->Fill(cid0 + 1, crystal_hit[cid0]);
315 }
316
317}
static int layerGlobalNumber(int section, int sector, int layer)
Get layer global number.
void initialize() override final
Module function initialize.
TH2F * m_EKLM_Plane_Occupancy[2]
EKLM plane integrated occupancy.
TH2F * m_BKLM_PlaneTrg_Occupancy[2]
BKLM plane integrated occupancy w/ trgs.
TH2F * m_EKLM_PlaneTrg_Occupancy[2]
EKLM plane integrated occupancy w/ trgs.
TH1F * m_TOP_Occupancy[2]
TOP occupancy (good hits only)
StoreArray< KLMDigit > m_KLMDigits
KLM digits.
const EKLMElementNumbers * m_eklmElementNumbers
EKLM Element numbers.
void defineHisto() override final
Defines Histograms.
StoreObjPtr< TRGSummary > m_trgSummary
trg summary
StoreObjPtr< EventMetaData > m_eventMetaData
event meta data
const TRGSummary::ETimingType m_klmBackTriggers[1]
Background Trigger bit(s) of interest.
void event() override final
Module function event.
std::string m_histogramDirectoryName
Name of the histogram directory in ROOT file.
double m_eclEnergyThr
Energy threshold (in MeV) for ECL occupancy histogram.
void beginRun() override final
Module function beginRun.
TH1F * m_ARICH_Occupancy[2]
ARICH Digit Occupancy.
StoreArray< ARICHHit > m_ARICHHits
ARICH hits.
TProfile * m_ECL_Occupancy[2]
ECL occupancy (hits above 5 MeV)
StoreArray< TOPDigit > m_topDigits
collection of TOP digits
StoreArray< ECLCalDigit > m_eclCalDigits
collection of ECL digits
TH2F * m_BKLM_Plane_Occupancy[2]
BKLM plane integrated occupancy.
@ c_B2LinkPacketCRCError
Belle2link CRC error is detected in the event.
@ c_HLTCrash
The HLT reconstruction crashed in this event or the event before.
@ c_ReconstructionAbort
The event was not reconstructed, e.g.
@ c_B2LinkEventCRCError
HSLB_COPPER CRC error is detected in the event.
HistoModule()
Constructor.
Definition HistoModule.h:32
KLM digit (class representing a digitized hit in RPCs or scintillators).
Definition KLMDigit.h:29
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
ETimingType
types of trigger timing source defined in b2tt firmware
Definition TRGSummary.h:43
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
const int c_NCrystals
Number of crystals.
Abstract base class for different kinds of events.