Skip to content

Commit a08da3e

Browse files
committed
Occupancy plots for LGAD added in ETL DigiHits Validation
1 parent 05248a5 commit a08da3e

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

Validation/MtdValidation/plugins/EtlDigiHitsValidation.cc

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class EtlDigiHitsValidation : public DQMEDAnalyzer {
5858

5959
MonitorElement* meNhits_[4];
6060
MonitorElement* meNhitsPerLGAD_[4];
61+
MonitorElement* meNLgadWithHits_[4];
62+
MonitorElement* meNhitsPerLGADoverQ_[4];
63+
MonitorElement* meNLgadWithHitsoverQ_[4];
6164

6265
MonitorElement* meHitCharge_[4];
6366
MonitorElement* meHitTime_[4];
@@ -83,6 +86,13 @@ class EtlDigiHitsValidation : public DQMEDAnalyzer {
8386
MonitorElement* meHitTvsEta_[4];
8487

8588
std::array<std::unordered_map<uint32_t, uint32_t>, 4> ndigiPerLGAD_;
89+
90+
// Constants to define the threshold bins for Q in occupancy studies
91+
static constexpr int n_bin_Q = 32;
92+
static constexpr double Q_Min = 0.;
93+
static constexpr double Q_Max = 256.;
94+
95+
std::array<std::unordered_map<uint32_t, std::array<uint32_t, n_bin_Q>>, 4> ndigiPerLGADoverQ_;
8696
};
8797

8898
// ------------ constructor and destructor --------------
@@ -110,6 +120,7 @@ void EtlDigiHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSe
110120
unsigned int n_digi_etl[4] = {0, 0, 0, 0};
111121
for (size_t i = 0; i < 4; i++) {
112122
ndigiPerLGAD_[i].clear();
123+
ndigiPerLGADoverQ_[i].clear();
113124
}
114125

115126
size_t index(0);
@@ -189,13 +200,65 @@ void EtlDigiHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSe
189200
ndigiPerLGAD_[idet].emplace(detId.rawId(), ncount);
190201
ndigiPerLGAD_[idet].at(detId.rawId())++;
191202

203+
// --- Occupancy study for different thresholds on Q
204+
double bin_w_Q = (Q_Max - Q_Min) / n_bin_Q;
205+
// Initialize the Map Entry (if first hit for this LGAD)
206+
// The array must be initialized to all zeros.
207+
std::array<uint32_t, n_bin_Q> zero_counts{}; // Array of N_bin_q zeros
208+
ndigiPerLGADoverQ_[idet].emplace(detId.rawId(), zero_counts);
209+
// Increment the Appropriate Counters
210+
auto& threshold_counters = ndigiPerLGADoverQ_[idet].at(detId.rawId());
211+
for (int i = 0; i < n_bin_Q; i++) {
212+
// Calculate the lower bound of the charge bin, which acts as the threshold
213+
double th_Q = Q_Min + i * bin_w_Q;
214+
// If the hit charge is greater than this threshold, increment the counter for this bin
215+
if (sample.data() > th_Q) {
216+
threshold_counters[i]++;
217+
}
218+
}
219+
192220
} // dataFrame loop
193221

194222
for (int i = 0; i < 4; i++) {
195223
meNhits_[i]->Fill(log10(n_digi_etl[i]));
196224
for (const auto& thisNdigi : ndigiPerLGAD_[i]) {
197225
meNhitsPerLGAD_[i]->Fill(thisNdigi.second);
198226
}
227+
// Number of LGADs with at least one hit.
228+
meNLgadWithHits_[i]->Fill(ndigiPerLGAD_[i].size());
229+
}
230+
231+
// --- Occupancy study for different thresholds on Q
232+
double bin_w_Q = (Q_Max - Q_Min) / n_bin_Q;
233+
for (int i = 0; i < 4; i++) { // Loop over the 4 ETL regions
234+
// For each threshold bin (x-axis of the profile)
235+
for (int j = 0; j < n_bin_Q; j++) {
236+
double Q_value = Q_Min + j * bin_w_Q + (bin_w_Q / 2.); // Center of the threshold bin
237+
double total_n_hits_for_this_threshold = 0.;
238+
// Variable to count LGADs with at least one hit above threshold j
239+
size_t n_lgads_with_hits_for_this_threshold = 0;
240+
// Sum the counts from all LGADs for the current threshold 'j'
241+
for (const auto& entry : ndigiPerLGADoverQ_[i]) {
242+
total_n_hits_for_this_threshold += entry.second[j];
243+
// Check if the total hits for this LGAD at this specific threshold is > 0
244+
if (entry.second[j] > 0) {
245+
n_lgads_with_hits_for_this_threshold++;
246+
}
247+
}
248+
// Calculate the average number of hits per LGAD
249+
double average_n_hits = 0.;
250+
const size_t n_lgads_hit = ndigiPerLGADoverQ_[i].size();
251+
// if (n_lgads_hit > 0) {
252+
// average_n_hits = total_n_hits_for_this_threshold / static_cast<double>(n_lgads_hit);
253+
// }
254+
if (n_lgads_with_hits_for_this_threshold > 0) {
255+
average_n_hits = total_n_hits_for_this_threshold / static_cast<double>(n_lgads_with_hits_for_this_threshold);
256+
}
257+
// Fill the profile with the AVERAGE N_hits found at this threshold
258+
meNhitsPerLGADoverQ_[i]->Fill(Q_value, average_n_hits);
259+
// Fill the profile with average Number of LGADs with Hits per Event vs Q Threshold
260+
meNLgadWithHitsoverQ_[i]->Fill(Q_value, n_lgads_with_hits_for_this_threshold);
261+
}
199262
}
200263
}
201264

@@ -237,6 +300,33 @@ void EtlDigiHitsValidation::bookHistograms(DQMStore::IBooker& ibook,
237300
meNhitsPerLGAD_[3] =
238301
ibook.book1D("EtlNhitsPerLGADZposD2", "Number of ETL DIGI hits (+Z, Second disk) per LGAD;N_{DIGI}", 50, 0., 50.);
239302

303+
meNLgadWithHits_[0] =
304+
ibook.book1D("EtlNLgadWithHitsZnegD1", "Number of ETL LGADs with at least 1 DIGI hit (-Z, D1);N_{LGAD with hit}", 100, 0., 4000.);
305+
meNLgadWithHits_[1] =
306+
ibook.book1D("EtlNLgadWithHitsZnegD2", "Number of ETL LGADs with at least 1 DIGI hit (-Z, D2);N_{LGAD with hit}", 100, 0., 4000.);
307+
meNLgadWithHits_[2] =
308+
ibook.book1D("EtlNLgadWithHitsZposD1", "Number of ETL LGADs with at least 1 DIGI hit (+Z, D1);N_{LGAD with hit}", 100, 0., 4000.);
309+
meNLgadWithHits_[3] =
310+
ibook.book1D("EtlNLgadWithHitsZposD2", "Number of ETL LGADs with at least 1 DIGI hit (+Z, D2);N_{LGAD with hit}", 100, 0., 4000.);
311+
312+
meNhitsPerLGADoverQ_[0] =
313+
ibook.bookProfile("EtlNhitsPerLGADvsQThZnegD1", "ETL DIGI Hits per LGAD vs Q Threshold (-Z, D1);Q Threshold [ADC counts];<N_{DIGI} per LGAD>", n_bin_Q, Q_Min, Q_Max, 0., 50.);
314+
meNhitsPerLGADoverQ_[1] =
315+
ibook.bookProfile("EtlNhitsPerLGADvsQThZnegD2", "ETL DIGI Hits per LGAD vs Q Threshold (-Z, D2);Q Threshold [ADC counts];<N_{DIGI} per LGAD>", n_bin_Q, Q_Min, Q_Max, 0., 50.);
316+
meNhitsPerLGADoverQ_[2] =
317+
ibook.bookProfile("EtlNhitsPerLGADvsQThZposD1", "ETL DIGI Hits per LGAD vs Q Threshold (+Z, D1);Q Threshold [ADC counts];<N_{DIGI} per LGAD>", n_bin_Q, Q_Min, Q_Max, 0., 50.);
318+
meNhitsPerLGADoverQ_[3] =
319+
ibook.bookProfile("EtlNhitsPerLGADvsQThZposD2", "ETL DIGI Hits per LGAD vs Q Threshold (+Z, D2);Q Threshold [ADC counts];<N_{DIGI} per LGAD>", n_bin_Q, Q_Min, Q_Max, 0., 50.);
320+
321+
meNLgadWithHitsoverQ_[0] =
322+
ibook.bookProfile("EtlNLgadWithHitsvsQThZnegD1", "Number of ETL LGADs with at least 1 DIGI hit vs Q Threshold (-Z, D1);Q Threshold [ADC counts];N_{LGAD with hit}", n_bin_Q, Q_Min, Q_Max, 0., 4000.);
323+
meNLgadWithHitsoverQ_[1] =
324+
ibook.bookProfile("EtlNLgadWithHitsvsQThZnegD2", "Number of ETL LGADs with at least 1 DIGI hit vs Q Threshold (-Z, D2);Q Threshold [ADC counts];N_{LGAD with hit}", n_bin_Q, Q_Min, Q_Max, 0., 4000.);
325+
meNLgadWithHitsoverQ_[2] =
326+
ibook.bookProfile("EtlNLgadWithHitsvsQThZposD1", "Number of ETL LGADs with at least 1 DIGI hit vs Q Threshold (+Z, D1);Q Threshold [ADC counts];N_{LGAD with hit}", n_bin_Q, Q_Min, Q_Max, 0., 4000.);
327+
meNLgadWithHitsoverQ_[3] =
328+
ibook.bookProfile("EtlNLgadWithHitsvsQThZposD2", "Number of ETL LGADs with at least 1 DIGI hit vs Q Threshold (+Z, D2);Q Threshold [ADC counts];N_{LGAD with hit}", n_bin_Q, Q_Min, Q_Max, 0., 4000.);
329+
240330
meHitCharge_[0] = ibook.book1D("EtlHitChargeZnegD1",
241331
"ETL DIGI hits charge (-Z, Single(topo1D)/First(topo2D) disk);Q_{DIGI} [ADC counts]",
242332
100,

0 commit comments

Comments
 (0)