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