ATLAS Offline Software
Loading...
Searching...
No Matches
PprMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// L1 objects
11// xAOD
13// =============================================
14
15#include "PprMonitorAlgorithm.h"
16
17
18PprMonitorAlgorithm::PprMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
19 : AthMonitorAlgorithm(name,pSvcLocator)
20{
21}
22
24
25 ATH_MSG_DEBUG("PprMonitorAlgorithm::initialize");
26 ATH_MSG_DEBUG("Package Name "<< m_packageName);
27 ATH_MSG_DEBUG("m_xAODTriggerTowerContainerName "<< m_xAODTriggerTowerContainerName);
28 ATH_MSG_DEBUG("m_TT_ADC_HitMap_Thresh " << m_TT_ADC_HitMap_Thresh);
29
30 // We initialise all the containers that we need
33 ATH_CHECK(m_errorLocation.initialize());
34
35 // Initialize the groups for GenericMonitoringArrays
36 std::vector<std::string> partitionsEM = {"LArFCAL1C", "LArEMECC", "LArOverlapC", "LArEMBC", "LArEMBA", "LArOverlapA", "LArEMECA", "LArFCAL1A"};
37 m_groupTimeslice_EM = Monitored::buildToolMap<int>(m_tools, "groupTimeslice_EM", partitionsEM);
38
39 std::vector<std::string> partitionsHAD = {"LArFCAL23C", "LArHECC", "TileEBC", "TileLBC", "TileLBA", "TileEBA", "LArHECA", "LArFCAL23A"};
40 m_groupTimeslice_HAD = Monitored::buildToolMap<int>(m_tools, "groupTimeslice_HAD", partitionsHAD);
41
42 return StatusCode::SUCCESS;
43}
44
45StatusCode PprMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
46
47 ATH_MSG_DEBUG("PprMonitorAlgorithm::fillHistograms");
48
49 // Retrieve event info from SG
50
51 uint32_t bunchCrossing = 0;
52 bunchCrossing = ctx.eventID().bunch_crossing_id();
53 ATH_MSG_DEBUG("BCID: " << bunchCrossing);
54 const long long eventNumber = ctx.eventID().event_number();
55 ATH_MSG_DEBUG("Event Number" << eventNumber);
56
57
58 // Retrieve Trigger Towers from SG
60 if(!triggerTowerTES.isValid()){
61 ATH_MSG_ERROR("No Trigger Tower container found in TES "<< m_xAODTriggerTowerContainerName);
62 return StatusCode::FAILURE;
63 }
64
65 // Create a vector of trigger towers with quantities to be monitored
66 std::vector<MonitorTT> vecMonTT; // All towers
67
68 // Loop over trigger tower container
69 // Create the trigger tower objects and calculate scaled phi
70 for (const xAOD::TriggerTower* tt : *triggerTowerTES) {
71 ATH_CHECK( makePPMTower(tt, vecMonTT) );
72 }
73
74 // Error vector for global overview
75 ErrorVector overview(8);
76 // Trigger tower error flag
77 bool triggerTowerHasMcmError = false;
78 bool triggerTowerHasSubstatusError = false;
79
80 // Loop over the trigger tower objects and fill the histograms
81
82 for (auto& myTower : vecMonTT) {
83 ATH_MSG_DEBUG("PprMonitorAlgorithm looping over TTs");
84 // -------- LUT --------
85 int cpET = (myTower.tower)->cpET();
86 int jepET = myTower.jepET;
87 int layer = (myTower.tower)->layer();
88 bool isEM = (layer == 0);
89 bool isHAD = (layer == 1);
90 std::string layerName = (layer == 0) ? "EM" : "HAD";
91
92 ATH_MSG_DEBUG("isEM " << isEM << " isHAD " << isHAD << " layerName " << layerName);
93 ATH_MSG_DEBUG("cpET: " << cpET << " jepET: " << jepET);
94
95 // The variables to plot
96 auto eta_TT = Monitored::Scalar<double>("eta_TT", myTower.tower->eta());
97 auto cpET_TT = Monitored::Scalar<int>("cpET_TT", cpET);
98 auto jepET_TT = Monitored::Scalar<int>("jepET_TT", jepET);
99 auto BCID = Monitored::Scalar<uint32_t>("BCID", bunchCrossing);
100
101 // The cutmasks
102 auto mask_EM = Monitored::Scalar<bool>("mask_EM", isEM);
103 auto mask_HAD = Monitored::Scalar<bool>("mask_HAD", isHAD);
104 auto mask_cpET_0 = Monitored::Scalar<bool>("mask_cpET_0", cpET > 0 );
105 auto mask_jepET_0 = Monitored::Scalar<bool>("mask_jepET_0", jepET > 0 );
106 auto mask_cpET_5 = Monitored::Scalar<bool>("mask_cpET_5", cpET > 5);
107 auto mask_jepET_5 = Monitored::Scalar<bool>("mask_jepET_5", jepET > 5);
108
109 // Fill LUT histograms (layer-independent)
110 std::string groupName = "groupLUTCP";
111 fill(groupName, BCID, mask_cpET_5); // ppm_1d_tt_lutcp_LutPerBCN
112
113 groupName = "groupLUTJEP";
114 fill(groupName, BCID, mask_jepET_5); // ppm_1d_tt_lutjep_LutPerBCN
115
116 // Layer-dependent LUT-CP plots (EM or HAD)
117 groupName = "groupLUTCP_";
118 groupName.append(layerName);
119
120 // Fill LUT-CP eta and ET distributions
121 // ppm_em_1d_tt_lutcp_Eta, ppm_had_1d_tt_lutcp_Eta
122 // ppm_em_1d_tt_lutcp_Et, ppm_had_1d_tt_lutcp_Et
123 fill(groupName, eta_TT, cpET_TT, mask_cpET_0);
124
125 // Fill LUT-CP phi distributions
126 // ppm_em_1d_tt_lutcp_Phi, ppm_had_1d_tt_lutcp_Phi
127 if (cpET > 0) {
128 ATH_CHECK( fillPPMPhi(myTower, groupName) );
129
130 // Fill LUT-CP eta-phi maps
131 // ppm_em_2d_etaPhi_tt_lutcp_AverageEt, ppm_had_2d_etaPhi_tt_lutcp_AverageEt
132 if (cpET > 5) {
133 ATH_CHECK( fillPPMEtaPhi(myTower, groupName, "cpET_TT_2D", cpET) );
134 }
135 }
136
137 // LUT hitmaps per threshold
138 // ppm_em_2d_etaPhi_tt_lutcp_Threshold, ppm_had_2d_etaPhi_tt_lutcp_Threshold
139
140 for (int th : m_TT_HitMap_ThreshVec) {
141 groupName = "groupLUTCP_"+layerName+"_"+std::to_string(th);
142 ATH_MSG_DEBUG("Filling group " << groupName);
143 ATH_MSG_DEBUG("cpET > " << th << " ? " << (cpET > th));
144 if (cpET > th) {
145 ATH_CHECK( fillPPMEtaPhi(myTower, groupName, "", 1.) );
146 }
147 }
148
149 // LUT-JEP
150 groupName = "groupLUTJEP_";
151 groupName.append(layerName);
152
153 // Fill LUT-JEP eta and ET distributions
154 // ppm_em_1d_tt_lutjep_Eta, ppm_had_1d_tt_lutjep_Eta
155 // ppm_em_1d_tt_lutjep_Et, ppm_had_1d_tt_lutjep_Et
156 fill(groupName, eta_TT, jepET_TT, mask_jepET_0); // LUT-JEP eta and ET distributions
157
158 // Fill LUT-JEP phi distributions
159 // ppm_em_1d_tt_lutjep_Phi, ppm_had_1d_tt_lutjep_Phi
160 if (jepET > 0) {
161 ATH_CHECK( fillPPMPhi(myTower, groupName) );
162
163 // Fill LUT-JEP eta-phi maps
164 // ppm_em_2d_etaPhi_tt_lutjep_AverageEt, ppm_had_2d_etaPhi_tt_lutjep_AverageEt
165 if (jepET > 5) {
166 ATH_CHECK( fillPPMEtaPhi(myTower, groupName, "jepET_TT_2D", jepET) );
167 }
168 }
169
170 // LUT hitmaps per threshold
171 // ppm_em_2d_etaPhi_tt_lutjep_Threshold, ppm_had_2d_etaPhi_tt_lutcp_Threshold
172
173 for (int th : m_TT_HitMap_ThreshVec) {
174 groupName = "groupLUTJEP_"+layerName+"_"+std::to_string(th);
175 ATH_MSG_DEBUG("Filling group " << groupName);
176 ATH_MSG_DEBUG("jepET > " << th << " ? " << (jepET > th));
177 if (jepET > th) {
178 ATH_CHECK( fillPPMEtaPhi(myTower, groupName, "", 1.) );
179 }
180
181 }
182
183 // -------- ADC hitmaps per timeslice --------
184 unsigned int tslice = (myTower.tower)->adcPeak();
185 unsigned int adcSize = ((myTower.tower)->adc()).size();
186
187 // Number of triggered timeslice
188 groupName = "groupTimeslice_";
189 groupName.append(layerName);
190
191 auto adcPeak = Monitored::Scalar<unsigned int>("adcPeak", tslice);
192 fill(groupName, adcPeak);
193
194 if (tslice < adcSize) {
195 groupName = "groupADC_";
196 groupName.append(layerName);
197 const int ADC = ((myTower.tower)->adc())[tslice];
199 // Fills both ppm_em_2d_etaPhi_tt_adc_HitMap (unweighted) and ppm_em_2d_etaPhi_tt_adc_ProfileHitMap (weighted) at the same time
200 ATH_CHECK(fillPPMEtaPhi(myTower, groupName, "adcTT", ADC));
201 }
202 }
203
204 // -------- Timing of FADC signal --------
205
206 int max = myTower.maxADC;
207 int maxADCPlus1 = max + 1;
208 auto maxADC = Monitored::Scalar<unsigned int>("maxADC", max);
209
210 groupName = "groupTimeslice_";
211 groupName.append(layerName);
212
213 if (max >= 0.) {
214 fill(groupName, maxADC);
215 ATH_CHECK(fillPPMEtaPhi(myTower, groupName, "maxADCPlus1", maxADCPlus1));
216 }
217
218 // -------- Bits of BCID logic word --------
219
220 // ppm_2d_tt_adc_BcidBits
221 groupName = "groupTimeslice";
222
223 auto bcidBits = Monitored::Scalar<int>("bcidBits", 0);
224 auto adcBCID = Monitored::Scalar<int>("adcBCID", 0);
225
226 short unsigned int peak = (myTower.tower)->peak();
227
228 if (cpET > 0 && tslice < adcSize) { // Defined above in ADC hitmaps per timeslice block
229
230 adcBCID = ((myTower.tower)->adc())[tslice];
231 uint8_t bcidWord = (myTower.tower)->bcidVec()[peak];
232
233 if (bcidWord == char(0) || bcidWord == char(1)) { // None (40 MHz)
234 bcidBits = 0;
235 fill(groupName, bcidBits, adcBCID);
236 }
237 else if (bcidWord == char(2) || bcidWord == char(3)) { // satBC only
238 bcidBits = 1;
239 fill(groupName, bcidBits, adcBCID);
240 }
241 else if (bcidWord == char(4) || bcidWord == char(5)) { // PF only
242 bcidBits = 2;
243 fill(groupName, bcidBits, adcBCID);
244 }
245 else if (bcidWord == char(6) || bcidWord == char(7)) { // satBC & PF
246 bcidBits = 3;
247 fill(groupName, bcidBits, adcBCID);
248 }
249 if (bcidWord == char(5) || bcidWord == char(7)) { // sat80BC & PF
250 bcidBits = 4;
251 fill(groupName, bcidBits, adcBCID);
252 }
253 if (bcidWord == char(3) || bcidWord == char(7)) { // sat80BC & sat40BC
254 bcidBits = 5;
255 fill(groupName, bcidBits, adcBCID);
256 }
257 if (bcidWord == char(1)) { // sat80BC only
258 bcidBits = 6;
259 fill(groupName, bcidBits, adcBCID);
260 }
261 }
262
263
264 // -------- High/low threshold pass cases (Sat80) --------
265 // ppm_1d_tt_adc_HLCase
266
267 if (cpET > 0 && tslice < adcSize && peak < (myTower.tower)->sat80Vec().size()) {
268 auto sat80Word = Monitored::Scalar<int>("sat80Word", (myTower.tower)->sat80Vec()[peak]);
269 for(unsigned int i = 0; i < 8; i++) {
270 if (sat80Word == char(i)) fill(groupName, sat80Word);
271 }
272 }
273
274
275 // -------- Signal shape profile --------
276 // ppm_1d_tt_adc_SignalProfile
277
278 const std::vector<short unsigned int> &vADC((myTower.tower)->adc());
279
280 if (cpET > 0) {
281
282 const std::string part = getPartition(layer, myTower.tower->eta());
283 std::vector<short unsigned int>::const_iterator it = vADC.begin();
284 std::vector<short unsigned int>::const_iterator itE = vADC.end();
285
286 for (int s = 0; it!= itE && s < m_SliceNo; ++it, ++s) {
287 auto slice = Monitored::Scalar<int>("slice", s);
288 auto wADC = Monitored::Scalar<int>("wADC", *it);
289 if (isEM) fill(m_tools[m_groupTimeslice_EM.at(part)], slice, wADC);
290 else fill(m_tools[m_groupTimeslice_HAD.at(part)], slice, wADC);
291 }
292 } // End if cpeT > 0 (signal shape block)
293
294
295
296 // -------- Pedestal correction over-/underflow --------
297
298 // ppm_em_1d_pedOverflow_Eta, ppm_had_1d_pedOverflow_Eta
299 // ppm_em_1d_pedUnderflow_Eta, ppm_had_1d_pedUnderflow_Eta
300
301 groupName = "groupErrors_";
302 groupName.append(layerName);
303
304 bool isPedCorrOverflow = false;
305 bool isPedCorrUnderflow = false;
306
307 for (auto pedCorr : (myTower.tower)->correction()) {
308 if ( pedCorr >= 511 ) isPedCorrOverflow = true;
309 else if ( pedCorr <= -512 ) isPedCorrUnderflow = true;
310 }
311
312 auto mask_PedCorrOverflow = Monitored::Scalar<bool>("mask_PedCorrOverflow", isPedCorrOverflow);
313 auto mask_PedCorrUnderflow = Monitored::Scalar<bool>("mask_PedCorrUnderflow", isPedCorrUnderflow);
314
315 fill(groupName, eta_TT, mask_PedCorrOverflow, mask_PedCorrUnderflow);
316
317
318 //------------ SubStatus Word errors and MCM errors ----------------
319
320 // set maximum number of error events per lumiblock(per type) to avoid histograms with many x-bins
321 // Inspired by https://gitlab.cern.ch/atlas/athena/-/blob/22.0/Trigger/TrigT1/TrigT1CaloMonitoring/src/CpmSimMonitorAlgorithm.cxx#L267
322 const int maxErrorsPerLB = 10;
323 auto currentLumiblock = GetEventInfo(ctx)->lumiBlock();
324
325 using LVL1::DataError;
326 if ( (myTower.tower)->errorWord()) {
327 const LVL1::DataError err((myTower.tower)->errorWord());
328 const L1CaloCoolChannelId coolId((myTower.tower)->coolId());
329 const int crate = coolId.crate();
330 const int module = coolId.module();
331 const int ypos = (crate < 4) ? module + crate * 16 : module + (crate - 4) * 16;
332
333 auto eventMonitor= Monitored::Scalar<std::string>("eventMonitor", std::to_string(eventNumber));
334 auto y_2D = Monitored::Scalar<int>("y_2D", ypos);
335
336 std::lock_guard<std::mutex> lock(m_mutex);
337
338 for (int bit = 0; bit < 8; ++bit) {
339 auto bit_2D = Monitored::Scalar<int>("bit_2D", bit);
340
341 // MCM Error Field histograms: Here checking these PP specific error bits:
342 // ChannelDisabled = 4, MCMAbsent = 5, Timeout = 6,
343 // ASICFull = 7, EventMismatch = 8, BunchMismatch = 9,
344 // FIFOCorrupt = 10, PinParity = 11,
345 if (err.get(bit + DataError::ChannelDisabled)) {
346 fill("group1DMCMErrorSummary", bit_2D);
347
348 if (crate < 4) fill("groupErrorMCMField03", bit_2D, y_2D );
349 else fill("groupMCMErrorField47", bit_2D, y_2D );
350
351 if ((m_errorLB_tt_counter[currentLumiblock]<maxErrorsPerLB) && (!triggerTowerHasMcmError)) {
352 fill("groupMCMErrorEventNumbers", eventMonitor, bit_2D );
353 }
354 triggerTowerHasMcmError = true;
355 }
356
357 // And here checking for these Sub-status word error bits and failing BCN:
358 // GLinkParity = 16, GLinkProtocol = 17, BCNMismatch = 18,
359 // FIFOOverflow = 19, ModuleError = 20, GLinkDown = 22,
360 // GLinkTimeout = 23, FailingBCN = 24,
361 if (err.get(bit + DataError::GLinkParity)) {
362 fill("group1DSubStatErrorSummary", bit_2D);
363
364 if (crate < 4) fill("groupSubStatError03", bit_2D, y_2D );
365 else fill("groupSubStatError47", bit_2D, y_2D );
366
367 if ((m_errorLB_tt_counter[currentLumiblock]<maxErrorsPerLB) && (!triggerTowerHasSubstatusError)) {
368 fill("groupSubStatErrorEventNumbers", eventMonitor, bit_2D );
369 }
370 triggerTowerHasSubstatusError = true;
371 }
372 } // end loop over 8 error bits
373
374 if (triggerTowerHasMcmError || triggerTowerHasSubstatusError) {
375 m_errorLB_tt_counter[currentLumiblock]+=1;
376 }
377
378 if (err.get(DataError::ChannelDisabled) ||
379 err.get(DataError::MCMAbsent))
380 overview[crate] |= 1;
381
382 if (err.get(DataError::Timeout) || err.get(DataError::ASICFull) ||
383 err.get(DataError::EventMismatch) ||
384 err.get(DataError::BunchMismatch) ||
385 err.get(DataError::FIFOCorrupt) || err.get(DataError::PinParity))
386 overview[crate] |= (1 << 1);
387
388 if (err.get(DataError::GLinkParity) ||
389 err.get(DataError::GLinkProtocol) ||
390 err.get(DataError::FIFOOverflow) ||
391 err.get(DataError::ModuleError) || err.get(DataError::GLinkDown) ||
392 err.get(DataError::GLinkTimeout) || err.get(DataError::BCNMismatch))
393 overview[crate] |= (1 << 2);
394
395 } // end if-statement for existence of error word
396
397 } // End loop over tower objects
398
399 // Save error vector for global summary
400 auto save = std::make_unique<ErrorVector>(overview);
401 auto* result = SG::makeHandle(m_errorLocation, ctx).put(std::move(save));
402 if (!result) {
403 ATH_MSG_ERROR("Error recording PPM vector in TES");
404 return StatusCode::FAILURE;
405 }
406
407 return StatusCode::SUCCESS;
408}
409
411 std::vector<MonitorTT> &vecMonTT) const
412{
413 // Geometry
414 const double phi = tt->phi();
415 double phiMod = phi * m_phiScaleTT;
416
417 // LUT JEP
418 int jepET = 0;
419 const std::vector<uint_least8_t>& jepETvec = tt->lut_jep();
420 if (jepETvec.size() > 0) jepET = tt->jepET();
421
422 // ADC timeslice
423 const std::vector<short unsigned int> &ADC( tt->adc() );
424 double max = recTime(ADC, m_EMFADCCut);
425
426 // Fill TT quantities
427 MonitorTT monTT;
428 monTT.tower = tt;
429 monTT.phiScaled = phiMod;
430 monTT.jepET = jepET;
431 monTT.maxADC = max;
432 vecMonTT.push_back(monTT);
433
434 return StatusCode::SUCCESS;
435}
436
437
438double PprMonitorAlgorithm::recTime(const std::vector<short unsigned int> &vFADC, int cut) const {
439
440 int max = -1;
441 const int slices = vFADC.size();
442 if (slices > 0) {
443 max = 0.;
444 int maxAdc = vFADC[0];
445 for (int sl = 1; sl < slices; ++sl) {
446 if (vFADC[sl] > maxAdc) {
447 maxAdc = vFADC[sl];
448 max = sl;
449 } else if (vFADC[sl] == maxAdc)
450 max = -1;
451 }
452 if (maxAdc == 0)
453 max = -1;
454 }
455 if (max >= 0) {
456 int slbeg = max - 2;
457 if (slbeg < 0)
458 slbeg = 0;
459 int slend = max + 3;
460 if (slend > slices)
461 slend = slices;
462 int sum = 0;
463 int min = 999999;
464 for (int sl = slbeg; sl < slend; ++sl) {
465 int val = vFADC[sl];
466 if (val < m_TT_ADC_Pedestal)
467 val = m_TT_ADC_Pedestal;
468 sum += val;
469 if (val < min)
470 min = val;
471 }
472 sum -= (slend - slbeg) * min;
473 if (sum <= cut)
474 max = -1;
475 }
476
477 return double(max);
478}
479
480
481std::string PprMonitorAlgorithm::getPartition(int layer, double eta) const {
482
483 std::string part = "";
484 if (layer == 0) { // EM layer
485 if (eta < -3.2)
486 part = "LArFCAL1C";
487 else if (eta < -1.5)
488 part = "LArEMECC";
489 else if (eta < -1.4)
490 part = "LArOverlapC";
491 else if (eta < 0.0)
492 part = "LArEMBC";
493 else if (eta < 1.4)
494 part = "LArEMBA";
495 else if (eta < 1.5)
496 part = "LArOverlapA";
497 else if (eta < 3.2)
498 part = "LArEMECA";
499 else
500 part = "LArFCAL1A";
501 } else { // HAD layer
502 if (eta < -3.2)
503 part = "LArFCAL23C";
504 else if (eta < -1.5)
505 part = "LArHECC";
506 else if (eta < -0.9)
507 part = "TileEBC";
508 else if (eta < 0.0)
509 part = "TileLBC";
510 else if (eta < 0.9)
511 part = "TileLBA";
512 else if (eta < 1.5)
513 part = "TileEBA";
514 else if (eta < 3.2)
515 part = "LArHECA";
516 else
517 part = "LArFCAL23A";
518 }
519 return part;
520}
521
522
523StatusCode PprMonitorAlgorithm::fillPPMEtaPhi( MonitorTT &monTT,
524 const std::string& groupName,
525 const std::string& weightName,
526 double weight/*=1.*/) const {
527
528 // Number of bins filled in phi depends on eta due to electronics coverage
529
530 // KW to do: fill in shrinkEtaBins part
531 double phiMod = monTT.phiScaled; // Integer binning for 2D plots
532 double etaMod = monTT.tower->eta();
533 const double absEta = std::abs(etaMod);
534
535 const std::vector<double> offset32 = {1.5, 0.5, -0.5, -1.5};
536 const std::vector<double> offset25 = {0.5, -0.5};
537 std::vector<double> offset = {};
538
539 if (absEta > 3.2) {
540 // Fill four bins in phi
541 phiMod = std::floor(phiMod/4)*4. + 2.;
542 offset = std::move(offset32);
543 }
544 else if (absEta > 2.5) {
545 // Fill two bins in phi
546 phiMod = std::floor(phiMod/2)*2. + 1.;
547 offset = std::move(offset25);
548 }
549 else {
550 offset = {0.};
551 }
552
553 // Fill the histograms
554 for (auto phiOffset : offset) {
555
556 auto etaTT_2D = Monitored::Scalar<double>("etaTT_2D", etaMod);
557 auto phiTT_2D = Monitored::Scalar<double>("phiTT_2D", phiMod + phiOffset);
558 auto weight_2D = Monitored::Scalar<double>(weightName, weight); // Weight for filling 2D profile histograms; name must be included in python histogram definition
559 ATH_MSG_DEBUG("etaTT_2D: " << etaTT_2D << " phiTT_2D: " << phiTT_2D << " weight_2D: " << weight_2D);
560 ATH_MSG_DEBUG("groupName: " << groupName);
561 fill(groupName, etaTT_2D, phiTT_2D, weight_2D);
562
563 }
564
565 return StatusCode::SUCCESS;
566}
567
568StatusCode PprMonitorAlgorithm::fillPPMPhi( MonitorTT &monTT,
569 const std::string& groupName) const {
570
571 // Number of bins filled in phi depends on eta due to electronics coverage
572
573 const double phi = monTT.tower->phi(); // Using the actual phi value for 1D plots
574 const double absEta = std::abs(monTT.tower->eta());
575
576 const std::vector<double> offset32 = {1.5, 0.5, -0.5, -1.5};
577 const std::vector<double> offset25 = {0.5, -0.5};
578 std::vector<double> offset = {};
579
580 double phi1d = phi;
581
582 if (absEta > 3.2) {
583 // Fill four bins in phi
584 offset = std::move(offset32);
585 }
586 else if (absEta > 2.5) {
587 // Fill two bins in phi
588 offset = std::move(offset25);
589 }
590 else {
591 // Fill one phi bin
592 offset = {0.};
593 }
594
595 // Fill the histogram
596 for (auto phiOffset : offset) {
597 phi1d = phi + phiOffset/m_phiScaleTT;
598 auto phiTT_1D = Monitored::Scalar<double>("phiTT_1D", phi1d);
599 fill(groupName, phiTT_1D);
600 }
601
602 return StatusCode::SUCCESS;
603
604}
605
606
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
virtual StatusCode initialize() override
initialize
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
Encapsulates the ID of one channel of conditions data in COOL, ie the ID of a row in a table.
unsigned int module(bool logical=true) const
Convert a typeId to a L1CaloModuleType.
unsigned int crate() const
Error data.
Definition DataError.h:27
Declare a monitored scalar variable.
Gaudi::Property< std::vector< int > > m_TT_HitMap_ThreshVec
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
SG::ReadHandleKey< xAOD::TriggerTowerContainer > m_xAODTriggerTowerContainerName
container keys including steering parameter and description
std::vector< int > ErrorVector
StatusCode fillPPMPhi(MonitorTT &monTT, const std::string &groupName) const
std::map< std::string, int > m_groupTimeslice_HAD
virtual StatusCode initialize() override
initialize
Gaudi::Property< int > m_EMFADCCut
PprMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
StatusCode makePPMTower(const xAOD::TriggerTower_v2 *tt, std::vector< MonitorTT > &vecMonTT) const
Helper functions.
double recTime(const std::vector< short unsigned int > &vFADC, int cut) const
std::map< std::string, int > m_groupTimeslice_EM
Groups for GenericMonitoringArrays.
StringProperty m_packageName
Gaudi::Property< int > m_SliceNo
Gaudi::Property< int > m_TT_ADC_Pedestal
SG::WriteHandleKey< std::vector< int > > m_errorLocation
StatusCode fillPPMEtaPhi(MonitorTT &monTT, const std::string &groupName, const std::string &weightName, double weight=1.) const
Gaudi::Property< int > m_TT_ADC_HitMap_Thresh
Gaudi::Property< double > m_phiScaleTT
Properties.
std::string getPartition(int layer, double eta) const
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Description of TriggerTower_v2.
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case)
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
TriggerTower_v2 TriggerTower
Define the latest version of the TriggerTower class.
void fill(H5::Group &out_file, size_t iterations)