Skip to content

Commit 821e4dc

Browse files
committed
CheckETLstructure in MTDDigiGeometryAnalyzer.cc
1 parent 9cc3b68 commit 821e4dc

File tree

2 files changed

+232
-43
lines changed

2 files changed

+232
-43
lines changed

Geometry/MTDGeometryBuilder/test/MTDDigiGeometryAnalyzer.cc

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,22 @@ class MTDDigiGeometryAnalyzer : public edm::one::EDAnalyzer<> {
5656

5757
void checkRectangularMTDTopology(const RectangularMTDTopology&);
5858
void checkPixelsAcceptance(const GeomDetUnit& det);
59+
void CheckETLstructure(const MTDGeometry&);
5960

6061
std::stringstream sunitt_;
6162

6263
edm::ESGetToken<MTDGeometry, MTDDigiGeometryRecord> mtdgeoToken_;
64+
65+
// Constants to define the bins for Eta
66+
static constexpr int n_bin_Eta = 3;
67+
static constexpr double eta_bins_edges_neg[n_bin_Eta + 1] = {-3.0, -2.5, -2.1, -1.5};
68+
static constexpr double eta_bins_edges_pos[n_bin_Eta + 1] = {1.5, 2.1, 2.5, 3.0};
69+
70+
// LGAD counter per Disk
71+
uint32_t totalLGADsPerDisk_[4] = {0};
72+
73+
// Counter for total LGADs per disk per eta bin: [disk][eta_bin]
74+
uint32_t LGADsPerDiskperEtaBin_[4][n_bin_Eta] = {{0}};
6375
};
6476

6577
MTDDigiGeometryAnalyzer::MTDDigiGeometryAnalyzer(const edm::ParameterSet& iConfig) {
@@ -128,6 +140,8 @@ void MTDDigiGeometryAnalyzer::analyze(const edm::Event& iEvent, const edm::Event
128140
auto const& etldet = *(dynamic_cast<const MTDGeomDetUnit*>(pDD->detsETL().front()));
129141
checkPixelsAcceptance(etldet);
130142

143+
CheckETLstructure(*pDD);
144+
131145
edm::LogVerbatim("MTDUnitTest") << sunitt_.str();
132146
}
133147

@@ -178,5 +192,84 @@ void MTDDigiGeometryAnalyzer::checkPixelsAcceptance(const GeomDetUnit& det) {
178192
sunitt_ << " Acceptance: " << fround(acc, 3) << " +/- " << fround(accerr, 3);
179193
}
180194

195+
void MTDDigiGeometryAnalyzer::CheckETLstructure(const MTDGeometry& geom) {
196+
edm::LogVerbatim("MTDDigiGeometryAnalyzer") << "\n--- ETL Structure Validation ---";
197+
sunitt_ << "\n--- ETL Structure Validation ---";
198+
199+
// Reset counters
200+
for (int d = 0; d < 4; ++d) {
201+
totalLGADsPerDisk_[d] = 0;
202+
for (int eta = 0; eta < n_bin_Eta; ++eta) {
203+
LGADsPerDiskperEtaBin_[d][eta] = 0;
204+
}
205+
}
206+
207+
uint32_t totalETLdets = 0;
208+
for (const auto& det : geom.detsETL()) {
209+
const GeomDet* thedet = det;
210+
ETLDetId detId(thedet->geographicalId());
211+
212+
// Get the global position of the detector center
213+
const GlobalPoint& global_point = thedet->position();
214+
double eta = global_point.eta();
215+
216+
int idet = 999;
217+
if ((detId.zside() == -1) && (detId.nDisc() == 1)) {
218+
idet = 0;
219+
} else if ((detId.zside() == -1) && (detId.nDisc() == 2)) {
220+
idet = 1;
221+
} else if ((detId.zside() == 1) && (detId.nDisc() == 1)) {
222+
idet = 2;
223+
} else if ((detId.zside() == 1) && (detId.nDisc() == 2)) {
224+
idet = 3;
225+
} else {
226+
edm::LogWarning("EtlDigiHitsValidation") << "Unknown ETL DetId configuration: " << detId;
227+
continue;
228+
}
229+
230+
totalETLdets++;
231+
// Count total LGADs per disk
232+
totalLGADsPerDisk_[idet]++;
233+
234+
// Count LGADs per disk per eta bin
235+
const double* eta_edges = (idet < 2) ? eta_bins_edges_neg : eta_bins_edges_pos;
236+
237+
for (int j = 0; j < n_bin_Eta; j++) {
238+
double lower_edge = eta_edges[j];
239+
double upper_edge = eta_edges[j + 1];
240+
241+
// Check if the center of the LGAD is within the bin
242+
if ((eta >= lower_edge && eta < upper_edge) || (idet < 2 && j == n_bin_Eta - 1 && eta <= upper_edge)) {
243+
LGADsPerDiskperEtaBin_[idet][j]++;
244+
break; // Found the bin
245+
}
246+
}
247+
}
248+
249+
// --- Print Summary ---
250+
251+
sunitt_ << " Total ETL Detectors (LGADs): " << totalETLdets << "\n";
252+
const char* diskNames[4] = {"Disc 1 (-Z)", "Disc 2 (-Z)", "Disc 1 (+Z)", "Disc 2 (+Z)"};
253+
254+
sunitt_ << "\n--- LGADs per Disk and Eta Bin ---\n";
255+
for (int d = 0; d < 4; ++d) { // Physical Disk loop (0-3)
256+
std::string disk_name = diskNames[d];
257+
uint32_t total_disk = totalLGADsPerDisk_[d];
258+
259+
sunitt_ << "Region: " << disk_name << " | Total LGADs: " << total_disk << "\n";
260+
261+
// Print LGADs per Eta Bin
262+
sunitt_ << " - LGADs per Eta Bin (Center Eta):\n";
263+
const double* eta_edges = (d < 2) ? eta_bins_edges_neg : eta_bins_edges_pos;
264+
265+
for (int j = 0; j < n_bin_Eta; ++j) {
266+
sunitt_ << " Eta [" << std::setprecision(1) << std::fixed << eta_edges[j] << ", " << eta_edges[j + 1]
267+
<< "): " << LGADsPerDiskperEtaBin_[d][j] << "\n";
268+
}
269+
}
270+
271+
edm::LogVerbatim("MTDDigiGeometryAnalyzer") << sunitt_.str();
272+
}
273+
181274
//define this as a plug-in
182275
DEFINE_FWK_MODULE(MTDDigiGeometryAnalyzer);

Validation/MtdValidation/plugins/EtlDigiHitsValidation.cc

Lines changed: 139 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ void EtlDigiHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSe
212212
double bin_w_Q = (Q_Max - Q_Min) / n_bin_Q;
213213
// Initialize the Map Entry (if first hit for this LGAD)
214214
// The array must be initialized to all zeros.
215-
std::array<uint32_t, n_bin_Q> zero_counts_Q{}; // Array of N_bin_q zeros
215+
std::array<uint32_t, n_bin_Q> zero_counts_Q{}; // Array of N_bin_q zeros
216216
ndigiPerLGADoverQ_[idet].emplace(detId.rawId(), zero_counts_Q);
217217
// Increment the Appropriate Counters
218218
auto& threshold_counters = ndigiPerLGADoverQ_[idet].at(detId.rawId());
@@ -249,10 +249,10 @@ void EtlDigiHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSe
249249

250250
// --- Occupancy study for different thresholds on Q
251251
double bin_w_Q = (Q_Max - Q_Min) / n_bin_Q;
252-
for (int i = 0; i < 4; i++) { // Loop over the 4 ETL regions
252+
for (int i = 0; i < 4; i++) { // Loop over the 4 ETL regions
253253
// For each threshold bin (x-axis of the profile)
254254
for (int j = 0; j < n_bin_Q; j++) {
255-
double Q_value = Q_Min + j * bin_w_Q + (bin_w_Q / 2.); // Center of the threshold bin
255+
double Q_value = Q_Min + j * bin_w_Q + (bin_w_Q / 2.); // Center of the threshold bin
256256
double total_n_hits_for_this_threshold = 0.;
257257
// Variable to count LGADs with at least one hit above threshold j
258258
size_t n_lgads_with_hits_for_this_threshold = 0;
@@ -266,10 +266,6 @@ void EtlDigiHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSe
266266
}
267267
// Calculate the average number of hits per LGAD
268268
double average_n_hits = 0.;
269-
// const size_t n_lgads_hit = ndigiPerLGADoverQ_[i].size();
270-
// if (n_lgads_hit > 0) {
271-
// average_n_hits = total_n_hits_for_this_threshold / static_cast<double>(n_lgads_hit);
272-
// }
273269
if (n_lgads_with_hits_for_this_threshold > 0) {
274270
average_n_hits = total_n_hits_for_this_threshold / static_cast<double>(n_lgads_with_hits_for_this_threshold);
275271
}
@@ -280,11 +276,11 @@ void EtlDigiHitsValidation::analyze(const edm::Event& iEvent, const edm::EventSe
280276
}
281277
}
282278
// --- Occupancy study for different bins on Eta
283-
for (int i = 0; i < 4; i++) { // Loop over the 4 ETL regions
279+
for (int i = 0; i < 4; i++) { // Loop over the 4 ETL regions
284280
for (int j = 0; j < n_bin_Eta; j++) {
285281
double eta_low = ((i == 0) || (i == 1)) ? eta_bins_edges_neg[j] : eta_bins_edges_pos[j];
286282
double eta_high = ((i == 0) || (i == 1)) ? eta_bins_edges_neg[j + 1] : eta_bins_edges_pos[j + 1];
287-
double eta_value = (eta_low + eta_high) / 2.; // Center of the Eta bin
283+
double eta_value = (eta_low + eta_high) / 2.; // Center of the Eta bin
288284
double total_n_hits_for_this_eta_bin = 0.;
289285
size_t n_lgads_with_hits_for_this_eta_bin = 0;
290286
for (const auto& entry : ndigiPerLGADoverEta_[i]) {
@@ -341,50 +337,150 @@ void EtlDigiHitsValidation::bookHistograms(DQMStore::IBooker& ibook,
341337
meNhitsPerLGAD_[3] =
342338
ibook.book1D("EtlNhitsPerLGADZposD2", "Number of ETL DIGI hits (+Z, Second disk) per LGAD;N_{DIGI}", 50, 0., 50.);
343339

344-
meNLgadWithHits_[0] =
345-
ibook.book1D("EtlNLgadWithHitsZnegD1", "Number of ETL LGADs with at least 1 DIGI hit (-Z, D1);N_{LGAD with hit}", 100, 0., 4000.);
346-
meNLgadWithHits_[1] =
347-
ibook.book1D("EtlNLgadWithHitsZnegD2", "Number of ETL LGADs with at least 1 DIGI hit (-Z, D2);N_{LGAD with hit}", 100, 0., 4000.);
348-
meNLgadWithHits_[2] =
349-
ibook.book1D("EtlNLgadWithHitsZposD1", "Number of ETL LGADs with at least 1 DIGI hit (+Z, D1);N_{LGAD with hit}", 100, 0., 4000.);
350-
meNLgadWithHits_[3] =
351-
ibook.book1D("EtlNLgadWithHitsZposD2", "Number of ETL LGADs with at least 1 DIGI hit (+Z, D2);N_{LGAD with hit}", 100, 0., 4000.);
340+
meNLgadWithHits_[0] = ibook.book1D("EtlNLgadWithHitsZnegD1",
341+
"Number of ETL LGADs with at least 1 DIGI hit (-Z, D1);N_{LGAD with hit}",
342+
100,
343+
0.,
344+
4000.);
345+
meNLgadWithHits_[1] = ibook.book1D("EtlNLgadWithHitsZnegD2",
346+
"Number of ETL LGADs with at least 1 DIGI hit (-Z, D2);N_{LGAD with hit}",
347+
100,
348+
0.,
349+
4000.);
350+
meNLgadWithHits_[2] = ibook.book1D("EtlNLgadWithHitsZposD1",
351+
"Number of ETL LGADs with at least 1 DIGI hit (+Z, D1);N_{LGAD with hit}",
352+
100,
353+
0.,
354+
4000.);
355+
meNLgadWithHits_[3] = ibook.book1D("EtlNLgadWithHitsZposD2",
356+
"Number of ETL LGADs with at least 1 DIGI hit (+Z, D2);N_{LGAD with hit}",
357+
100,
358+
0.,
359+
4000.);
352360

353361
meNhitsPerLGADoverQ_[0] =
354-
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.);
362+
ibook.bookProfile("EtlNhitsPerLGADvsQThZnegD1",
363+
"ETL DIGI Hits per LGAD vs Q Threshold (-Z, D1);Q Threshold [ADC counts];<N_{DIGI} per LGAD>",
364+
n_bin_Q,
365+
Q_Min,
366+
Q_Max,
367+
0.,
368+
50.);
355369
meNhitsPerLGADoverQ_[1] =
356-
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.);
370+
ibook.bookProfile("EtlNhitsPerLGADvsQThZnegD2",
371+
"ETL DIGI Hits per LGAD vs Q Threshold (-Z, D2);Q Threshold [ADC counts];<N_{DIGI} per LGAD>",
372+
n_bin_Q,
373+
Q_Min,
374+
Q_Max,
375+
0.,
376+
50.);
357377
meNhitsPerLGADoverQ_[2] =
358-
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.);
378+
ibook.bookProfile("EtlNhitsPerLGADvsQThZposD1",
379+
"ETL DIGI Hits per LGAD vs Q Threshold (+Z, D1);Q Threshold [ADC counts];<N_{DIGI} per LGAD>",
380+
n_bin_Q,
381+
Q_Min,
382+
Q_Max,
383+
0.,
384+
50.);
359385
meNhitsPerLGADoverQ_[3] =
360-
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.);
361-
362-
meNLgadWithHitsoverQ_[0] =
363-
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.);
364-
meNLgadWithHitsoverQ_[1] =
365-
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.);
366-
meNLgadWithHitsoverQ_[2] =
367-
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.);
368-
meNLgadWithHitsoverQ_[3] =
369-
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.);
386+
ibook.bookProfile("EtlNhitsPerLGADvsQThZposD2",
387+
"ETL DIGI Hits per LGAD vs Q Threshold (+Z, D2);Q Threshold [ADC counts];<N_{DIGI} per LGAD>",
388+
n_bin_Q,
389+
Q_Min,
390+
Q_Max,
391+
0.,
392+
50.);
393+
394+
meNLgadWithHitsoverQ_[0] = ibook.bookProfile(
395+
"EtlNLgadWithHitsvsQThZnegD1",
396+
"Number of ETL LGADs with at least 1 DIGI hit vs Q Threshold (-Z, D1);Q Threshold [ADC counts];N_{LGAD with hit}",
397+
n_bin_Q,
398+
Q_Min,
399+
Q_Max,
400+
0.,
401+
4000.);
402+
meNLgadWithHitsoverQ_[1] = ibook.bookProfile(
403+
"EtlNLgadWithHitsvsQThZnegD2",
404+
"Number of ETL LGADs with at least 1 DIGI hit vs Q Threshold (-Z, D2);Q Threshold [ADC counts];N_{LGAD with hit}",
405+
n_bin_Q,
406+
Q_Min,
407+
Q_Max,
408+
0.,
409+
4000.);
410+
meNLgadWithHitsoverQ_[2] = ibook.bookProfile(
411+
"EtlNLgadWithHitsvsQThZposD1",
412+
"Number of ETL LGADs with at least 1 DIGI hit vs Q Threshold (+Z, D1);Q Threshold [ADC counts];N_{LGAD with hit}",
413+
n_bin_Q,
414+
Q_Min,
415+
Q_Max,
416+
0.,
417+
4000.);
418+
meNLgadWithHitsoverQ_[3] = ibook.bookProfile(
419+
"EtlNLgadWithHitsvsQThZposD2",
420+
"Number of ETL LGADs with at least 1 DIGI hit vs Q Threshold (+Z, D2);Q Threshold [ADC counts];N_{LGAD with hit}",
421+
n_bin_Q,
422+
Q_Min,
423+
Q_Max,
424+
0.,
425+
4000.);
370426

371427
meNhitsPerLGADoverEta_[0] =
372-
ibook.bookProfile("EtlNhitsPerLGADvsEtaZnegD1", "ETL DIGI Hits per LGAD vs Eta Bin (-Z, D1);#eta_{DIGI};<N_{DIGI} per LGAD>", n_bin_Eta, eta_bins_edges_neg, 0., 50.);
428+
ibook.bookProfile("EtlNhitsPerLGADvsEtaZnegD1",
429+
"ETL DIGI Hits per LGAD vs Eta Bin (-Z, D1);#eta_{DIGI};<N_{DIGI} per LGAD>",
430+
n_bin_Eta,
431+
eta_bins_edges_neg,
432+
0.,
433+
50.);
373434
meNhitsPerLGADoverEta_[1] =
374-
ibook.bookProfile("EtlNhitsPerLGADvsEtaZnegD2", "ETL DIGI Hits per LGAD vs Eta Bin (-Z, D2);#eta_{DIGI};<N_{DIGI} per LGAD>", n_bin_Eta, eta_bins_edges_neg, 0., 50.);
435+
ibook.bookProfile("EtlNhitsPerLGADvsEtaZnegD2",
436+
"ETL DIGI Hits per LGAD vs Eta Bin (-Z, D2);#eta_{DIGI};<N_{DIGI} per LGAD>",
437+
n_bin_Eta,
438+
eta_bins_edges_neg,
439+
0.,
440+
50.);
375441
meNhitsPerLGADoverEta_[2] =
376-
ibook.bookProfile("EtlNhitsPerLGADvsEtaZposD1", "ETL DIGI Hits per LGAD vs Eta Bin (+Z, D1);#eta_{DIGI};<N_{DIGI} per LGAD>", n_bin_Eta, eta_bins_edges_pos, 0., 50.);
442+
ibook.bookProfile("EtlNhitsPerLGADvsEtaZposD1",
443+
"ETL DIGI Hits per LGAD vs Eta Bin (+Z, D1);#eta_{DIGI};<N_{DIGI} per LGAD>",
444+
n_bin_Eta,
445+
eta_bins_edges_pos,
446+
0.,
447+
50.);
377448
meNhitsPerLGADoverEta_[3] =
378-
ibook.bookProfile("EtlNhitsPerLGADvsEtaZposD2", "ETL DIGI Hits per LGAD vs Eta Bin (+Z, D2);#eta_{DIGI};<N_{DIGI} per LGAD>", n_bin_Eta, eta_bins_edges_pos, 0., 50.);
379-
380-
meNLgadWithHitsoverEta_[0] =
381-
ibook.bookProfile("EtlNLgadWithHitsvsEtaZnegD1", "Number of ETL LGADs with at least 1 DIGI hit vs Eta Bin (-Z, D1);#eta_{DIGI};N_{LGAD with hit}", n_bin_Eta, eta_bins_edges_neg, 0., 4000.);
382-
meNLgadWithHitsoverEta_[1] =
383-
ibook.bookProfile("EtlNLgadWithHitsvsEtaZnegD2", "Number of ETL LGADs with at least 1 DIGI hit vs Eta Bin (-Z, D2);#eta_{DIGI};N_{LGAD with hit}", n_bin_Eta, eta_bins_edges_neg, 0., 4000.);
384-
meNLgadWithHitsoverEta_[2] =
385-
ibook.bookProfile("EtlNLgadWithHitsvsEtaZposD1", "Number of ETL LGADs with at least 1 DIGI hit vs Eta Bin (+Z, D1);#eta_{DIGI};N_{LGAD with hit}", n_bin_Eta, eta_bins_edges_pos, 0., 4000.);
386-
meNLgadWithHitsoverEta_[3] =
387-
ibook.bookProfile("EtlNLgadWithHitsvsEtaZposD2", "Number of ETL LGADs with at least 1 DIGI hit vs Eta Bin (+Z, D2);#eta_{DIGI};N_{LGAD with hit}", n_bin_Eta, eta_bins_edges_pos, 0., 4000.);
449+
ibook.bookProfile("EtlNhitsPerLGADvsEtaZposD2",
450+
"ETL DIGI Hits per LGAD vs Eta Bin (+Z, D2);#eta_{DIGI};<N_{DIGI} per LGAD>",
451+
n_bin_Eta,
452+
eta_bins_edges_pos,
453+
0.,
454+
50.);
455+
456+
meNLgadWithHitsoverEta_[0] = ibook.bookProfile(
457+
"EtlNLgadWithHitsvsEtaZnegD1",
458+
"Number of ETL LGADs with at least 1 DIGI hit vs Eta Bin (-Z, D1);#eta_{DIGI};N_{LGAD with hit}",
459+
n_bin_Eta,
460+
eta_bins_edges_neg,
461+
0.,
462+
4000.);
463+
meNLgadWithHitsoverEta_[1] = ibook.bookProfile(
464+
"EtlNLgadWithHitsvsEtaZnegD2",
465+
"Number of ETL LGADs with at least 1 DIGI hit vs Eta Bin (-Z, D2);#eta_{DIGI};N_{LGAD with hit}",
466+
n_bin_Eta,
467+
eta_bins_edges_neg,
468+
0.,
469+
4000.);
470+
meNLgadWithHitsoverEta_[2] = ibook.bookProfile(
471+
"EtlNLgadWithHitsvsEtaZposD1",
472+
"Number of ETL LGADs with at least 1 DIGI hit vs Eta Bin (+Z, D1);#eta_{DIGI};N_{LGAD with hit}",
473+
n_bin_Eta,
474+
eta_bins_edges_pos,
475+
0.,
476+
4000.);
477+
meNLgadWithHitsoverEta_[3] = ibook.bookProfile(
478+
"EtlNLgadWithHitsvsEtaZposD2",
479+
"Number of ETL LGADs with at least 1 DIGI hit vs Eta Bin (+Z, D2);#eta_{DIGI};N_{LGAD with hit}",
480+
n_bin_Eta,
481+
eta_bins_edges_pos,
482+
0.,
483+
4000.);
388484

389485
meHitCharge_[0] = ibook.book1D("EtlHitChargeZnegD1",
390486
"ETL DIGI hits charge (-Z, Single(topo1D)/First(topo2D) disk);Q_{DIGI} [ADC counts]",

0 commit comments

Comments
 (0)