Belle II Software development
DQMHistAnalysisKLMMonObj.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 <cstddef>
10#include <dqm/analysis/modules/DQMHistAnalysisKLMMonObj.h>
11#include <TH2.h>
12#include <iostream>
13using namespace Belle2;
14
15//-----------------------------------------------------------------
16// Register the Module
17//-----------------------------------------------------------------
18REG_MODULE(DQMHistAnalysisKLMMonObj);
19
20//-----------------------------------------------------------------
21// Implementation
22//-----------------------------------------------------------------
23
26 m_IsNullRun{false},
27 m_BklmElementNumbers{nullptr},
28 m_bklmGeoPar{nullptr}
29{
30 setDescription("Module to add Monitoring Variables for KLM on Mirabelle");
31
32 //Parameter definition
33 addParam("histogramDirectoryName", m_histogramDirectoryName, "Name of Histogram dir",
34 std::string("DetectorOccupancies_before_filter"));
35 addParam("lookbackWindow", m_lookbackWindow, "Lookback window in seconds for hit rate calculation (default: 10.4 microseconds)",
36 10.4e-6);
37}
38
43
54
56{
57 // Get run flags for PVs
58 m_IsPhysicsRun = (getRunType() == "physics");
59 m_IsNullRun = (getRunType() == "null");
60}
61
63{
64 B2DEBUG(20, "DQMHistAnalysisKLMMonObj: event called.");
65}
66
67void DQMHistAnalysisKLMMonObjModule::CalculateKLMHitRate(auto* hist, int layer, Double_t totalEvents,
68 Double_t layerArea, Double_t& hitRate, Double_t& hitRateErr)
69{
70 if (!hist || hist->GetDimension() != 2 || layer <= 0 || layerArea <= 0 || totalEvents <= 0) {
71 B2ERROR("CalculateKLMHitRate: Invalid input parameters.");
72 hitRate = 0.0;
73 hitRateErr = 0.0;
74 return;
75 }
76
77 // Sum entries for the specific layer across all time bins (Y-axis)
78 // Layer number is on X-axis, so we sum over all Y bins for a given X bin (layer)
79 Double_t numDigits = 0.0;
80
81 int nBinsX = hist->GetNbinsX();
82 int nBinsY = hist->GetNbinsY();
83
84 // Layer corresponds to X-axis bins
85 if (layer > 0 && layer <= nBinsX) {
86 for (int binY = 1; binY <= nBinsY; binY++) {
87 Double_t binContent = hist->GetBinContent(layer, binY);
88 numDigits += binContent;
89 }
90 } else {
91 B2ERROR("CalculateKLMHitRate: Layer number out of range.");
92 hitRate = 0.0;
93 hitRateErr = 0.0;
94 return;
95 }
96
97 // Calculate hit rate in Hz/cm²: numDigits / (numEvents(delayed Physics == 1) * lookbackWindow * layerArea)
98 Double_t denominator = totalEvents * m_lookbackWindow * layerArea;
99
100 if (denominator > 0 && numDigits > 0) {
101 hitRate = numDigits / denominator; // Hit rate in Hz/cm²
102
103 // Calculate relative error:
104 Double_t relErr = sqrt(1.0 / numDigits + 1.0 / totalEvents);
105
106 // Absolute error: hitRate * relErr
107 hitRateErr = hitRate * relErr;
108 } else {
109 hitRate = 0.0;
110 hitRateErr = 0.0;
111 }
112}
113
115{
116 // Calculate hit rates for each layer from 2D histograms
117 // BKLM layer types:
118 // - Layers 1-2: Scintillator
119 // - Layers 3-15: RPC
120
121 std::string histPrefix = "/bklm_plane_trg_occupancy";
122 TH2F* bklm_trg[2];
123 for (size_t i = 0; i < 2; i++) {
124 bklm_trg[i] = (TH2F*)findHist(m_histogramDirectoryName + histPrefix + "_" + m_tag[i]);
125 }
126
127 auto* background_trigger_count = findHist("KLM/event_background_trigger_summary");
128 if (not background_trigger_count) {
129 B2ERROR("Cannot find histogram: KLM/event_background_trigger_summary");
130 return;
131 }
132
133 Double_t totalEventsTrg = background_trigger_count->GetBinContent(1); // TTYP_DPHY == 1
134 std::string prefix = "KLM_";
135 std::string suffix = "hitRate";
136
137 for (size_t i = 0; i < 2; i++) {
138 if (not bklm_trg[i]) {
139 B2ERROR("Cannot find histogram: " << m_histogramDirectoryName + histPrefix + "_" + m_tag[i]);
140 continue;
141 }
142 for (int layerGlobal = 0; layerGlobal < 240; layerGlobal++) {
143 int section, sector, layer;
144 m_BklmElementNumbers->layerGlobalNumberToElementNumbers(
145 layerGlobal, &section, &sector, &layer);
146 Double_t layerAreaTrg = m_bklmGeoPar->getBKLMLayerArea(section, sector, layer); // in cm^2
147 Double_t hitRate, hitRateErr;
148 CalculateKLMHitRate(bklm_trg[i], layer, totalEventsTrg, layerAreaTrg, hitRate, hitRateErr);
149 // Naming consistent with KLM2: B/F for section, 0-based sector, 1-based layer
150 std::string varName = prefix + "B";
151 varName += (section == 0) ? "B" : "F";
152 varName += std::to_string((sector - 1) % BKLMElementNumbers::getMaximalSectorNumber());
153 varName += "_layer" + std::to_string(layer) + "_trg_" + suffix + "_" + m_tag[i];
154 m_klmMonObj->setVariable(varName, hitRate, hitRateErr);
155 }
156 }
157}
158
static constexpr int getMaximalSectorNumber()
Get maximal sector number (1-based).
void initialize() override final
Initializer.
const bklm::GeometryPar * m_bklmGeoPar
BKLM Geometry data.
Double_t m_lookbackWindow
Lookback window in seconds for hit rate calculation (default: 10.4 microseconds)
bool m_IsPhysicsRun
Run type flag for physics runs.
const BKLMElementNumbers * m_BklmElementNumbers
BKLM element numbers.
void event() override final
This method is called for each event.
std::string m_histogramDirectoryName
Name of histogram directory.
void CalculateKLMHitRate(auto *hist, int layer, Double_t totalEvents, Double_t layerArea, Double_t &hitRate, Double_t &hitRateErr)
Calculate KLM hit rate for a specific layer from 2D histogram.
void endRun() override final
This method is called if the current run ends.
void beginRun() override final
Called when entering a new run.
bool m_IsNullRun
Run type flag for null runs.
const std::string m_tag[2]
Tag suffix based on injection veto.
MonitoringObject * m_klmMonObj
KLM Monitoring object.
static MonitoringObject * getMonitoringObject(const std::string &name)
Get MonitoringObject with given name (new object is created if non-existing)
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
static const std::string & getRunType(void)
Get the list of the reference histograms.
DQMHistAnalysisModule()
Constructor / Destructor.
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
static GeometryPar * instance(void)
Static method to get a reference to the singleton GeometryPar instance.
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
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
Abstract base class for different kinds of events.