ATLAS Offline Software
Loading...
Searching...
No Matches
TileCellMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "PairBuilder.h"
10
12
15#include "AthenaKernel/Units.h"
17#include <stdexcept>
18
19using Athena::Units::GeV;
20using Athena::Units::ns;
21
23
24 ATH_MSG_INFO("in initialize()");
25
26 ATH_CHECK( detStore()->retrieve(m_tileID) );
27 ATH_CHECK( detStore()->retrieve(m_tileHWID) );
28
29 ATH_CHECK( m_cablingSvc.retrieve() );
30 m_cabling = m_cablingSvc->cablingService();
31
32 ATH_CHECK( m_DQstatusKey.initialize() );
33 ATH_CHECK( m_badChannelsKey.initialize() );
34 ATH_CHECK( m_caloCellContainerKey.initialize() );
35
36 using Tile = TileCalibUtils;
37 using namespace Monitored;
38
39 int nL1Triggers = getNumberOfL1Triggers();
40
41 m_cellSynchGroups = buildToolMap<int>(m_tools, "TileCellSynch", nL1Triggers);
42 m_energyBalModPartGroups = buildToolMap<int>(m_tools, "TileCellEneBalModPart", nL1Triggers);
43 m_timeBalModPartGroups = buildToolMap<int>(m_tools, "TileCellTimeBalModPart", nL1Triggers);
44 m_maskedOnFlyGroups = buildToolMap<int>(m_tools, "TileCellStatusOnFly", Tile::MAX_ROS - 1);
45 m_maskedDueDQGroups = buildToolMap<int>(m_tools, "TileMaskChannelDueDQvsLB", MAX_PART);
46 m_maskedCellsDueDQGroups = buildToolMap<int>(m_tools, "TileMaskedCellDueDQvsLB", MAX_PART);
47
48 m_maskedOnFlyLBGroups = buildToolMap<int>(m_tools, "TileMaskChannelOnFlyLB", MAX_PART);
50
52 Tile::MAX_ROS - 1, Tile::MAX_GAIN);
53
54 m_energySampEGroups = buildToolMap<std::vector<int>>(m_tools, "TileCellEventEnergy_SampE",
55 Tile::MAX_ROS, nL1Triggers);
56
57 m_moduleCorrGroups = buildToolMap<std::vector<int>>(m_tools, "TileCellModuleCorrelation",
58 Tile::MAX_ROS, nL1Triggers);
59
61 Tile::MAX_ROS - 1, nL1Triggers);
62
64 Tile::MAX_ROS - 1, nL1Triggers);
65
67 Tile::MAX_ROS - 1, nL1Triggers);
68
69 m_overThrOccupGroups = buildToolMap<std::vector<int>>(m_tools, "TileCellDetailOccMapOvThr",
70 Tile::MAX_ROS - 1, nL1Triggers);
71
72 m_overThr30GeVOccupGroups = buildToolMap<std::vector<int>>(m_tools, "TileCellDetailOccMapOvThr30GeV",
73 Tile::MAX_ROS - 1, nL1Triggers);
74
75 m_overThr300GeVOccupGroups = buildToolMap<std::vector<int>>(m_tools, "TileCellDetailOccMapOvThr300GeV",
76 Tile::MAX_ROS - 1, nL1Triggers);
77
79 Tile::MAX_ROS - 1, nL1Triggers);
80
82 Tile::MAX_ROS - 1, Tile::MAX_GAIN, nL1Triggers);
83
85 Tile::MAX_ROS - 1, Tile::MAX_GAIN, nL1Triggers);
86
88 m_energyGapScintGroups = buildToolMap<std::vector<std::vector<int>>>(m_tools, "TileGapScintilatorEnergy", 2 /* EBA and EBC */,
89 Tile::MAX_DRAWER, 4 /* E1-E4 */);
90 }
91
93 Tile::MAX_ROS, nL1Triggers);
94
96 Tile::MAX_ROS, nL1Triggers);
97
99 MAX_SAMP, nL1Triggers);
100
102 MAX_SAMP, nL1Triggers);
103
106 Tile::MAX_ROS - 1, MAX_SAMP, nL1Triggers);
107 }
108
110 Tile::MAX_ROS - 1, MAX_SAMP, nL1Triggers);
111
113 Tile::MAX_ROS - 1, MAX_SAMP, nL1Triggers);
114
115 m_negOccupGroups = buildToolMap<int>(m_tools, "TileCellDetailNegOccMap", Tile::MAX_ROS - 1);
116 m_timeBalGroups = buildToolMap<int>(m_tools, "TileCellTimeBalance", Tile::MAX_ROS - 1);
117 m_energyBalGroups = buildToolMap<int>(m_tools, "TileCellEnergyBalance", Tile::MAX_ROS - 1);
118
119
121}
122
123
124StatusCode TileCellMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
125
126 using Tile = TileCalibUtils;
127
128 // In case you want to measure the execution time
129 auto timer = Monitored::Timer("TIME_execute");
130
131 const xAOD::EventInfo* eventInfo = GetEventInfo(ctx).get();
132
133 const TileDQstatus* dqStatus = SG::makeHandle(m_DQstatusKey, ctx).get();
134 auto lumiBlock = Monitored::Scalar<int>("lumiBlock", eventInfo->lumiBlock());
135
136
137 if (msgLvl(MSG::DEBUG)) {
138 msg(MSG::DEBUG) << "Run = " << eventInfo->runNumber()
139 << " LB = " << eventInfo->lumiBlock()
140 << " Evt = " << eventInfo->eventNumber()
141 << " BCID = " << eventInfo->bcid()
142 << " lvl1 = 0x" << std::hex << eventInfo->level1TriggerType() << std::dec;
143
144 const std::vector<xAOD::EventInfo::StreamTag>& eventStreamTags = eventInfo->streamTags();
145 if (!eventStreamTags.empty()) {
146 msg(MSG::DEBUG) << " stream name/type:";
147 for (const auto& eventStreamTag : eventStreamTags) {
148 msg(MSG::DEBUG) << " " << eventStreamTag.name() << "/" << eventStreamTag.type();
149 }
150 }
151
152 msg(MSG::DEBUG) << endmsg;
153 }
154
155 // Weights for E-cells, only towers 10..15
156 static const float energyWeight[6] = {1.f/3.f, 1.f/6.f, 1.f/11.f, 1.f/11.f, 1.f/28.f, 1.f/28.f};
157 static const int gapScintIndex[6] = {0, 1, 2, 2, 3, 3};
158
159 std::vector<const CaloCell*> muonCells;
160
161 std::vector<int> energyBalModPartModule;
162 std::vector<int> energyBalModPartPartition;
163
164 std::vector<int> timeBalModPartModule;
165 std::vector<int> timeBalModPartPartition;
166
167 double energySample[MAX_PART][MAX_SAMP]{};
168 int nCells[MAX_PART]{};
169 int nBadCells[MAX_PART]{};
170
171 // Arrays for BCID plots
172 int nCellsOverThreshold[MAX_PART]{};
173
174 // Number of channels masked on the fly
175 int nBadChannelsOnFly[MAX_PART]{};
176
177 // Number of channels masked on the fly due to bad DQ status
178 unsigned int nMaskedChannelsDueDQ[MAX_PART]{};
179
180 // Number of cells masked on the fly due to bad DQ status
181 unsigned int nMaskedCellsDueDQ[MAX_PART]{};
182
183 std::vector<int> negOccupModule[Tile::MAX_ROS - 1];
184 std::vector<int> negOccupChannel[Tile::MAX_ROS - 1];
185
186 std::vector<float> timeBal[Tile::MAX_ROS - 1];
187 std::vector<int> timeBalModule[Tile::MAX_ROS - 1];
188
189 std::vector<float> energyBal[Tile::MAX_ROS - 1];
190 std::vector<int> energyBalModule[Tile::MAX_ROS - 1];
191
192 std::vector<int> detailOccupModule[Tile::MAX_ROS - 1];
193 std::vector<int> detailOccupChannel[Tile::MAX_ROS - 1];
194 std::vector<float> detailOccupEnergies[Tile::MAX_ROS - 1];
195
196 std::vector<int> detailOccupGainModule[Tile::MAX_ROS - 1][Tile::MAX_GAIN];
197 std::vector<int> detailOccupGainChannel[Tile::MAX_ROS - 1][Tile::MAX_GAIN];
198 std::vector<float> detailOccupGainEnergies[Tile::MAX_ROS - 1][Tile::MAX_GAIN];
199
200 std::vector<int> overThrOccupModule[Tile::MAX_ROS - 1];
201 std::vector<int> overThrOccupChannel[Tile::MAX_ROS - 1];
202 std::vector<float> overThrOccupWeight[Tile::MAX_ROS - 1];
203
204 std::vector<int> overThrOccupGainModule[Tile::MAX_ROS - 1][Tile::MAX_GAIN];
205 std::vector<int> overThrOccupGainChannel[Tile::MAX_ROS - 1][Tile::MAX_GAIN];
206 std::vector<float> overThrOccupGainWeight[Tile::MAX_ROS - 1][Tile::MAX_GAIN];
207
208 std::vector<int> overThr30GeVOccupModule[Tile::MAX_ROS - 1];
209 std::vector<int> overThr30GeVOccupChannel[Tile::MAX_ROS - 1];
210
211 std::vector<int> overThr300GeVOccupModule[Tile::MAX_ROS - 1];
212 std::vector<int> overThr300GeVOccupChannel[Tile::MAX_ROS - 1];
213
214 std::vector<int> eneDiff[Tile::MAX_ROS - 1];
215 std::vector<int> eneDiffChannel[Tile::MAX_ROS - 1];
216 std::vector<int> eneDiffModule[Tile::MAX_ROS - 1];
217
218 std::vector<int> maskedOnFlyDrawers[Tile::MAX_ROS - 1];
219 std::vector<int> maskedOnFlyChannel[Tile::MAX_ROS - 1];
220
221 std::vector<int> chanTime[Tile::MAX_ROS - 1];
222 std::vector<int> chanTimeDrawer[Tile::MAX_ROS - 1];
223 std::vector<int> chanTimeChannel[Tile::MAX_ROS - 1];
224 std::vector<int> chanTimeDigitizer[Tile::MAX_ROS - 1];
225
226 int nChannelsInPartition = 2880; // LB
227 for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
228 if (partition > 1) nChannelsInPartition = 2048; // EB
229 detailOccupModule[partition].reserve(nChannelsInPartition);
230 detailOccupChannel[partition].reserve(nChannelsInPartition);
231 detailOccupEnergies[partition].reserve(nChannelsInPartition);
232 }
233
234 std::vector<float> occupEta[SAMP_ALL];
235 std::vector<float> occupPhi[SAMP_ALL];
236 std::vector<float> occupEnergy[SAMP_ALL];
237
238 std::vector<float> overThrOccupEta[SAMP_ALL];
239 std::vector<float> overThrOccupPhi[SAMP_ALL];
240
241 std::vector<float> sampChanTime[Tile::MAX_ROS - 1][SAMP_ALL];
242 std::vector<float> sampEnergyDiff[Tile::MAX_ROS - 1][SAMP_ALL];
243 std::vector<float> sampTimeDiff[Tile::MAX_ROS - 1][SAMP_ALL];
244
245 PairBuilder moduleCorr[MAX_PART];
246
247 // Indices of L1 trigger histograms to be filled in the current event
248 std::vector<int> l1TriggersIndices = getL1TriggerIndices(eventInfo->level1TriggerType());
249
251 const TileBadChannels* badChannels(badChannelsHandle.cptr());
252
253 fillMaskedInDB(badChannels);
254
255 bool isCollision = true;
256
258 ATH_CHECK( caloCellContainer.isValid() );
259
260
261 for (const CaloCell* cell : *caloCellContainer) {
262 // Tell clang to optimize assuming that FP operations may trap.
263 // Prevents spurious FPEs from the division by energy.
265 Identifier id = cell->ID();
266 if (m_tileID->is_tile(id)) {
267
268 const TileCell* tile_cell = dynamic_cast<const TileCell*>(cell);
269 if (tile_cell == 0) continue;
270
271 int drawer = 0; // Drawer number, range 0-63, the same for both channels
272 int channel1 = -1; // Channel number, range 0-47 or -1 for unknown
273 int channel2 = -1; // Channel number, range 0-47 or -1 for unknown
274
275 int ros1 = -1;
276 int ros2 = -1;
277
278 int partition1 = -1;
279 int partition2 = -1;
280
281 bool isMaskedChannel1 = false;
282 bool isMaskedAdc1 = false;
283 bool isMaskedAdc2 = false;
284
285 int gain1 = tile_cell->gain1(); // Gain of first PMT
286 int gain2 = tile_cell->gain2(); // Gain of second PMT
287
288 const CaloDetDescrElement* caloDDE = tile_cell->caloDDE();
289
290 IdentifierHash hash1 = caloDDE->onl1();
291 if (hash1 != TileHWID::NOT_VALID_HASH) {
292 HWIdentifier channel1_id = m_tileHWID->channel_id(hash1);
293 channel1 = m_tileHWID->channel(channel1_id);
294 drawer = m_tileHWID->drawer(channel1_id);
295 ros1 = m_tileHWID->ros(channel1_id);
296 partition1 = ros1 - 1;
297 }
298
299 IdentifierHash hash2 = caloDDE->onl2();
300 if (hash2 != TileHWID::NOT_VALID_HASH) {
301 HWIdentifier channel2_id = m_tileHWID->channel_id(hash2);
302 channel2 = m_tileHWID->channel(channel2_id);
303 drawer = m_tileHWID->drawer(channel2_id);
304 ros2 = m_tileHWID->ros(channel2_id);
305 partition2 = ros2 - 1;
306 }
307
308 // Note that drawer from HWID and module from ID are different for E3 cells near MBTS
309 int module = m_tileID->module(id); // Range from 0-63
310
311 int sample = m_tileID->sample(id);
312 // Skip special-purpose samplings used for Cs calibration.
313 if (sample >= SAMP_ALL) continue;
314
315 bool single_PMT_scin = (sample == TileID::SAMP_E);
316 bool single_PMT_C10 = (m_tileID->section(id) == TileID::GAPDET
317 && sample == TileID::SAMP_C
318 && (!m_cabling->C10_connected(module)));
319
320 // Distinguish cells with one or two PMTs
321 bool single_PMT = single_PMT_C10 || single_PMT_scin;
322
323 // Distinguish normal cells and phantoms (e.g. non-existing D4 in EBA15, EBC18
324 // or non-existing E3/E4 - they might appear in CaloCellContainer)
325 bool realCell = single_PMT_C10 || m_cabling->TileGap_connected(id);
326
327 // Note that in single PMT cell both badch1() and badch2() are changed together
328 bool isBadChannel1 = tile_cell->badch1();
329 bool isBadChannel2 = tile_cell->badch2();
330
331 int isCellGood = !tile_cell->badcell();
332
333 bool isOkChannel1 = (channel1 > -1 && gain1 != CaloGain::INVALIDGAIN);
334 bool isOkChannel2 = (channel2 > -1 && gain2 != CaloGain::INVALIDGAIN);
335
336 // Get the cell energy, time and position info
337 double energy = cell->energy();
338 double time = cell->time();
339 double eta = cell->eta();
340 double phi = cell->phi();
341 double energy1 = tile_cell->ene1();
342 double energy2 = tile_cell->ene2();
343 double energyDiff = (single_PMT) ? 0.0 : tile_cell->eneDiff();
344 double energyRatio = (energy != 0.0) ? energyDiff/energy : 0.0;
345 double time1 = tile_cell->time1();
346 double time2 = tile_cell->time2();
347 double timeDiff = (single_PMT) ? 0.0 : 2. * tile_cell->timeDiff(); // Attention! factor of 2 is needed here
348
349 double weight = 1.;
350 if (single_PMT_scin) {
351 int tower = m_tileID->tower(id);
352 if (tower > 9 && tower < 16) {
353 weight = energyWeight[tower - 10];
354 }
356 if (energy > m_energyThresholdForGapScint) {
357 int idx = tower - 10;
358 if (idx >= 0 && idx < static_cast<int>(std::size(gapScintIndex))) {
359 int gapScintIdx = gapScintIndex[idx];
360 unsigned int partition = (ros1 > 0) ? ros1 - 3 : ros2 - 3;
361 auto monEnergy = Monitored::Scalar<float>("energy", energy);
362 fill(m_tools[m_energyGapScintGroups[partition][drawer][gapScintIdx]], monEnergy);
363 }
364 }
365 }
366 }
367
368 if (msgLvl(MSG::VERBOSE)) {
369
370 msg(MSG::VERBOSE) << "Identifier: " << id << " " << m_tileID->to_string(id,-2) << endmsg;
371 msg(MSG::VERBOSE) << " region: " << m_tileID->region(id)
372 << " system: " << m_tileID->system(id)
373 << " section: "<< m_tileID->section(id)
374 << " side: " << m_tileID->side(id)
375 << " module: " << m_tileID->module(id)
376 << " tower: " << m_tileID->tower(id)
377 << " sample: " << m_tileID->sample(id) << endmsg;
378
379 msg(MSG::VERBOSE) << "1st PMT ROS: " << ros1
380 << " drawer: " << drawer
381 << " ch1: " << channel1
382 << " gain1: " << gain1
383 << " qual1: " << (int)tile_cell->qual1()
384 << " qbit1: " << (int)tile_cell->qbit1()
385 << ((drawer != module) ? " drawer != module":" ") << endmsg;
386
387 msg(MSG::VERBOSE) << "2nd PMT ROS: " << ros2
388 << " drawer: " << drawer
389 << " ch2: " << channel2
390 << " gain2: " << gain2
391 << " qual2: " << (int)tile_cell->qual2()
392 << " qbit2: " << (int)tile_cell->qbit2()
393 << ((ros1 != ros2) ? " ros1 != ros2" : " ") << endmsg;
394
395 msg(MSG::VERBOSE) << "Bad status: " << !isCellGood
396 << " bad1: " << isBadChannel1
397 << " bad2: " << isBadChannel2
398 << ((single_PMT_scin && isBadChannel1 && !isMaskedChannel1)
399 ? " NEW BAD E-cell" : " ") << endmsg ;
400
401 msg(MSG::VERBOSE) << " real_cell: " << ((realCell) ? "true" : "false")
402 << " E-cell: " << ((single_PMT_scin) ? "true" : "false")
403 << " specC10: " << ((single_PMT_C10) ? "true" : "false") << endmsg;
404
405 msg(MSG::VERBOSE) << "Energy= " << energy << " = " << energy1 << " + " << energy2
406 << " ediff= " << energyDiff
407 << " eratio= " << energyRatio
408 << "\t Energy[GeV]= " << energy/GeV << endmsg ;
409
410 msg(MSG::VERBOSE) << "Time= " << time << " = (" << time1 << " + " << time2 << ")/2 "
411 << "tdiff= " << timeDiff
412 << "\t time[ns]= " << time/ns << endmsg ;
413 }
414
415
416 if (realCell) {
417
418 int dbGain1 = gain1;
419 int dbGain2 = gain2;
420 // When only one channel is bad, it might be that gain of masked channel is not correct
421 // If two qualities are not identical, then gains are not the same (new feature introduced in rel 17.2)
422 int quality1 = (int)tile_cell->qual1();
423 int quality2 = (int)tile_cell->qual2();
424 if (isBadChannel1 != isBadChannel2 && quality1 != quality2
425 && quality1 < 255 && quality2 < 255) {
426 if (isBadChannel1 && isOkChannel1) dbGain1 = 1 - gain1;
427 if (isBadChannel2 && isOkChannel2) dbGain2 = 1 - gain2;
428 }
429
430 if (hash1 != TileHWID::NOT_VALID_HASH) {
431 HWIdentifier adc1_id = m_tileHWID->adc_id(hash1, dbGain1);
432 isMaskedAdc1 = badChannels->getAdcStatus(adc1_id).isBad();
433 }
434
435 if (hash2 != TileHWID::NOT_VALID_HASH) {
436 HWIdentifier adc2_id = m_tileHWID->adc_id(hash2, dbGain2);
437 isMaskedAdc2 = badChannels->getAdcStatus(adc2_id).isBad();
438 }
439
440 bool channel1MaskedDueDQ(false);
441 if (isBadChannel1 && isOkChannel1 && !(single_PMT_C10 && channel1 == 4)) {
442 if (!isMaskedAdc1) {
443 ++nBadChannelsOnFly[partition1];
444 maskedOnFlyDrawers[partition1].push_back(drawer);
445 maskedOnFlyChannel[partition1].push_back(channel1);
446
447 if (!dqStatus->isAdcDQgood(ros1, drawer, channel1, gain1)) {
448 channel1MaskedDueDQ = true;
449 ++nMaskedChannelsDueDQ[partition1];
450 }
451 }
452 }
453
454 bool channel2MaskedDueDQ(false);
455 if (isBadChannel2 && isOkChannel2 && !(single_PMT_C10 && channel2 == 4)) {
456 if (!isMaskedAdc2) {
457 ++nBadChannelsOnFly[partition2];
458 maskedOnFlyDrawers[partition2].push_back(drawer);
459 maskedOnFlyChannel[partition2].push_back(channel2);
460
461 if (!dqStatus->isAdcDQgood(ros2, drawer, channel2, gain2)) {
462 channel2MaskedDueDQ = true;
463 ++nMaskedChannelsDueDQ[partition2];
464 }
465 }
466 }
467
468 if (isCellGood) {
469
470 if ((energy > m_energyRangeForMuon[0]) && (energy < m_energyRangeForMuon[1])
471 && (time > m_timeRangeForMuon[0]) && (time < m_timeRangeForMuon[1])
472 && (time != 0)) { // Cell has reconstructed time
473 muonCells.push_back(cell);
474 }
475 occupEta[sample].push_back(eta);
476 occupPhi[sample].push_back(phi);
477 occupEnergy[sample].push_back(energy);
478
479 if (isOkChannel1) {
480 detailOccupModule[partition1].push_back(module);
481 detailOccupChannel[partition1].push_back(channel1);
482 detailOccupEnergies[partition1].push_back(energy1 * weight);
483
484 detailOccupGainModule[partition1][gain1].push_back(module);
485 detailOccupGainChannel[partition1][gain1].push_back(channel1);
486 detailOccupGainEnergies[partition1][gain1].push_back(energy1 * weight);
487 }
488
489 if (isOkChannel2) {
490 detailOccupModule[partition2].push_back(module);
491 detailOccupChannel[partition2].push_back(channel2);
492 detailOccupEnergies[partition2].push_back(energy2);
493
494 detailOccupGainModule[partition2][gain2].push_back(module);
495 detailOccupGainChannel[partition2][gain2].push_back(channel2);
496 detailOccupGainEnergies[partition2][gain2].push_back(energy2);
497 }
498
499 } else {
500 ++nBadCells[partition1];
501 if (channel1MaskedDueDQ || channel2MaskedDueDQ) {
502 ++nMaskedCellsDueDQ[partition1];
503 }
504 }
505
506 // Check if energy is below negative threshold
507 if (isOkChannel1 && energy1 < m_negativeEnergyThreshold && (!isMaskedAdc1)) {
508 negOccupModule[partition1].push_back(module);
509 negOccupChannel[partition1].push_back(channel1);
510 }
511
512 if (isOkChannel2 && energy2 < m_negativeEnergyThreshold && (!isMaskedAdc2)) {
513 negOccupModule[partition2].push_back(module);
514 negOccupChannel[partition2].push_back(channel2);
515 }
516
517 if (energy > m_energyThreshold) {
518
519 // Fill channel timing histograms.
520 if (isCollision || m_fillTimeHistograms) {
521 if (isOkChannel1 && energy1 > m_energyThresholdForTime && energy1 < m_energyLimitForTime) {
522 if ((gain1 == 0) && (energy1 < 1000.)) {
523 ATH_MSG_DEBUG("Low energy in LG for time monitoring: " << Tile::getDrawerString(ros1, drawer)
524 << ", channel = " << channel1 << ", energy = " << energy1 << ", time = " << time1);
525 } else {
526 chanTime[partition1].push_back(time1);
527 chanTimeDrawer[partition1].push_back(drawer);
528 chanTimeChannel[partition1].push_back(channel1);
529 chanTimeDigitizer[partition1].push_back(getDigitizer(channel1));
531 sampChanTime[partition1][sample].push_back(time1);
532 }
533 }
534 }
535
536 if (isOkChannel2 && energy2 > m_energyThresholdForTime && energy2 < m_energyLimitForTime) {
537 if ((gain2 == 0) && (energy2 < 1000.)) {
538 ATH_MSG_DEBUG("Low energy in LG for time monitoring: " << Tile::getDrawerString(ros2, drawer)
539 << ", channel = " << channel2 << ", energy = " << energy2 << ", time = " << time2);
540 } else {
541 chanTime[partition2].push_back(time2);
542 chanTimeDrawer[partition2].push_back(drawer);
543 chanTimeChannel[partition2].push_back(channel2);
544 chanTimeDigitizer[partition2].push_back(getDigitizer(channel2));
546 sampChanTime[partition2][sample].push_back(time2);
547 }
548 }
549 }
550 }
551
552 overThrOccupEta[sample].push_back(eta);
553 overThrOccupPhi[sample].push_back(phi);
554
555 if (isOkChannel1 && energy1 > m_energyThreshold && (!isBadChannel1)) {
556 overThrOccupModule[partition1].push_back(module);
557 overThrOccupChannel[partition1].push_back(channel1);
558 overThrOccupWeight[partition1].push_back(weight);
559
560 if (energy1 > m_energyThresholdForGain[gain1]) {
561 overThrOccupGainModule[partition1][gain1].push_back(module);
562 overThrOccupGainChannel[partition1][gain1].push_back(channel1);
563 overThrOccupGainWeight[partition1][gain1].push_back(weight);
564 }
565
566 if (energy1 > 30000.) {
567 overThr30GeVOccupModule[partition1].push_back(module);
568 overThr30GeVOccupChannel[partition1].push_back(channel1);
569
570 if (energy1 > 300000.) {
571 overThr300GeVOccupModule[partition1].push_back(module);
572 overThr300GeVOccupChannel[partition1].push_back(channel1);
573 }
574 }
575 }
576
577 if (isOkChannel2 && energy2 > m_energyThreshold && (!isBadChannel2)) {
578 overThrOccupModule[partition2].push_back(module);
579 overThrOccupChannel[partition2].push_back(channel2);
580 overThrOccupWeight[partition2].push_back(1.0F);
581
582 if (energy2 > m_energyThresholdForGain[gain2]) {
583 overThrOccupGainModule[partition2][gain2].push_back(module);
584 overThrOccupGainChannel[partition2][gain2].push_back(channel2);
585 overThrOccupGainWeight[partition2][gain2].push_back(1.0F);
586 }
587
588 if (energy2 > 30000.) {
589 overThr30GeVOccupModule[partition2].push_back(module);
590 overThr30GeVOccupChannel[partition2].push_back(channel2);
591
592 if (energy2 > 300000.) {
593 overThr300GeVOccupModule[partition2].push_back(module);
594 overThr300GeVOccupChannel[partition2].push_back(channel2);
595 }
596 }
597 }
598
599 bool fillEneAndTimeDiff(m_fillTimeAndEnergyDiffHistograms);
600
601 // avoid double peak structure in energy and time balance histograms
602 if ((gain1 == 0 && gain2 == 1 && (energy1 < 2000 || energy2 < 10 || std::abs(energy1 / energy2) > 5))
603 || (gain1 == 1 && gain2 == 0 && (energy2 < 2000 || energy1 < 10 || std::abs(energy2 / energy1) > 5))) {
604
605 fillEneAndTimeDiff = false;
606 }
607
608 // Fill these histograms only if the both PMTs are good
609 if (!(isBadChannel1 || isBadChannel2 || single_PMT)) {
610
611 if (std::abs(energyRatio) > m_energyBalanceThreshold) {
612 energyBalModPartModule.push_back(module);
613 energyBalModPartPartition.push_back(partition1);
614 }
615
616 if (std::abs(timeDiff) > m_timeBalanceThreshold
617 && (energy1 > m_energyThresholdForTime || energy2 > m_energyThresholdForTime)
618 && (isCollision || m_fillTimeHistograms)) {
619 timeBalModPartModule.push_back(module);
620 timeBalModPartPartition.push_back(partition1);
621 }
622
623 energyBal[partition1].push_back(energyRatio);
624 energyBalModule[partition1].push_back(module);
625
626 eneDiff[partition1].push_back(energyDiff);
627 eneDiffChannel[partition1].push_back(channel1);
628 eneDiffModule[partition1].push_back(module);
629
630 eneDiff[partition2].push_back(-1.0 * energyDiff);
631 eneDiffChannel[partition2].push_back(channel2);
632 eneDiffModule[partition2].push_back(module);
633
634 if (fillEneAndTimeDiff) {
635 sampEnergyDiff[partition1][sample].push_back(energyDiff);
636 }
637
638 if ((energy1 > m_energyThresholdForTime || energy2 > m_energyThresholdForTime)
639 && (isCollision || m_fillTimeHistograms)) {
640
641 timeBal[partition1].push_back(timeDiff);
642 timeBalModule[partition1].push_back(module);
643
644 if (fillEneAndTimeDiff) {
645 sampTimeDiff[partition1][sample].push_back(timeDiff);
646 }
647 }
648
649 moduleCorr[partition1].inputxy(module);
650 moduleCorr[PART_ALL].inputxy(module);
651 }
652
653 if (partition1 >= 0) {
654 // Store info for BCID plots.
655 // Count the number of cells over threshold per partition
656 ++nCellsOverThreshold[partition1];
657 }
658 }
659 }
660
661 if (partition1 >= 0) {
662 // Count total number of cells in a partition
663 ++nCells[partition1];
664
665 // Accumulate total energy per sample per partition
666 energySample[partition1][sample] += energy;
667 }
668 }
669 }
670
671 // Calculate totals for all samples and all partitions
672 for (int partition = 0; partition < PART_ALL; ++partition) {
673
674 nCells[PART_ALL] += nCells[partition];
675 nBadCells[PART_ALL] += nBadCells[partition];
676
677 nBadChannelsOnFly[PART_ALL] += nBadChannelsOnFly[partition];
678 nCellsOverThreshold[PART_ALL] += nCellsOverThreshold[partition];
679
680 nMaskedChannelsDueDQ[PART_ALL] += nMaskedChannelsDueDQ[partition];
681 nMaskedCellsDueDQ[PART_ALL] += nMaskedCellsDueDQ[partition];
682
683 for (int sample = 0; sample < SAMP_ALL; ++sample) {
684 energySample[partition][SAMP_ALL] += energySample[partition][sample];
685 energySample[PART_ALL][sample] += energySample[partition][sample];
686 }
687
688 energySample[PART_ALL][SAMP_ALL] += energySample[partition][SAMP_ALL];
689 }
690
691 if (msgLvl(MSG::DEBUG)) {
692
693 msg(MSG::DEBUG) << "N Cells: "
694 << " " << nCells[PART_LBA]
695 << " " << nCells[PART_LBC]
696 << " " << nCells[PART_EBA]
697 << " " << nCells[PART_EBC]
698 << " " << nCells[PART_ALL] << endmsg;
699
700 if (nCells[PART_ALL] > 0) {
701
702 msg(MSG::DEBUG) << "AboveThr: "
703 << " " << nCellsOverThreshold[PART_LBA]
704 << " " << nCellsOverThreshold[PART_LBC]
705 << " " << nCellsOverThreshold[PART_EBA]
706 << " " << nCellsOverThreshold[PART_EBC]
707 << " " << nCellsOverThreshold[PART_ALL] << endmsg;
708
709 msg(MSG::DEBUG) << "MaskOnFly:"
710 << " " << nBadChannelsOnFly[PART_LBA]
711 << " " << nBadChannelsOnFly[PART_LBC]
712 << " " << nBadChannelsOnFly[PART_EBA]
713 << " " << nBadChannelsOnFly[PART_EBC]
714 << " " << nBadChannelsOnFly[PART_ALL] << endmsg;
715
716 msg(MSG::DEBUG) << "EneSampA:"
717 << " " << energySample[PART_LBA][TileID::SAMP_A]
718 << " " << energySample[PART_LBC][TileID::SAMP_A]
719 << " " << energySample[PART_EBA][TileID::SAMP_A]
720 << " " << energySample[PART_EBC][TileID::SAMP_A]
721 << " " << energySample[PART_ALL][TileID::SAMP_A] << endmsg;
722
723 msg(MSG::DEBUG) << "EneSampB:"
724 << " " << energySample[PART_LBA][TileID::SAMP_B]
725 << " " << energySample[PART_LBC][TileID::SAMP_B]
726 << " " << energySample[PART_EBA][TileID::SAMP_B]
727 << " " << energySample[PART_EBC][TileID::SAMP_B]
728 << " " << energySample[PART_ALL][TileID::SAMP_B] << endmsg;
729
730 msg(MSG::DEBUG) << "EneSampD:"
731 << " " << energySample[PART_LBA][TileID::SAMP_D]
732 << " " << energySample[PART_LBC][TileID::SAMP_D]
733 << " " << energySample[PART_EBA][TileID::SAMP_D]
734 << " " << energySample[PART_EBC][TileID::SAMP_D]
735 << " " << energySample[PART_ALL][TileID::SAMP_D] << endmsg;
736
737 msg(MSG::DEBUG) << "EneSampE:"
738 << " " << energySample[PART_LBA][TileID::SAMP_E]
739 << " " << energySample[PART_LBC][TileID::SAMP_E]
740 << " " << energySample[PART_EBA][TileID::SAMP_E]
741 << " " << energySample[PART_EBC][TileID::SAMP_E]
742 << " " << energySample[PART_ALL][TileID::SAMP_E] << endmsg;
743
744 msg(MSG::DEBUG) << "EneTotal:"
745 << " " << energySample[PART_LBA][SAMP_ALL]
746 << " " << energySample[PART_LBC][SAMP_ALL]
747 << " " << energySample[PART_EBA][SAMP_ALL]
748 << " " << energySample[PART_EBC][SAMP_ALL]
749 << " " << energySample[PART_ALL][SAMP_ALL] << endmsg;
750
751 }
752 }
753
754 std::vector<int> partitions(Tile::MAX_ROS);
755 std::iota(partitions.begin(), partitions.end(), 0);
756
757 auto monPartition = Monitored::Collection("Partition", partitions);
758 auto monBadCells = Monitored::Collection("nBadCells", nBadCells);
759 fill("TileBadCell", monPartition, monBadCells);
760
761 fillSynchronization(muonCells, l1TriggersIndices);
762
763 if (!energyBalModPartPartition.empty()) {
764 for (int l1TriggerIdx : l1TriggersIndices) {
765 auto monModule = Monitored::Collection("module", energyBalModPartModule);
766 auto monPartion = Monitored::Collection("partition", energyBalModPartPartition);
767 fill(m_tools[m_energyBalModPartGroups[l1TriggerIdx]], monModule, monPartion);
768 }
769 }
770
771 if (!timeBalModPartPartition.empty()) {
772 for (int l1TriggerIdx : l1TriggersIndices) {
773 auto monModule = Monitored::Collection("module", timeBalModPartModule);
774 auto monPartion = Monitored::Collection("partition", timeBalModPartPartition);
775 fill(m_tools[m_timeBalModPartGroups[l1TriggerIdx]], monModule, monPartion);
776 }
777 }
778
779 unsigned int bcid = eventInfo->bcid();
780
781 for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
782
783 if (!maskedOnFlyDrawers[partition].empty()) {
784 auto monModule = Monitored::Collection("module", maskedOnFlyDrawers[partition]);
785 auto monChannel = Monitored::Collection("channel", maskedOnFlyChannel[partition]);
786 fill(m_tools[m_maskedOnFlyGroups[partition]], monModule, monChannel);
787 }
788
789 if (!negOccupModule[partition].empty()) {
790 auto monModule = Monitored::Collection("module", negOccupModule[partition]);
791 auto monChannel = Monitored::Collection("channel", negOccupChannel[partition]);
792 fill(m_tools[m_negOccupGroups[partition]], monModule, monChannel);
793 }
794
795 if (!energyBalModule[partition].empty()) {
796 auto monModule = Monitored::Collection("module", energyBalModule[partition]);
797 auto monEnergyBal = Monitored::Collection("energyBalance", energyBal[partition]);
798 fill(m_tools[m_energyBalGroups[partition]], monModule, monEnergyBal);
799 }
800
801 if (!timeBalModule[partition].empty()) {
802 auto monModule = Monitored::Collection("module", timeBalModule[partition]);
803 auto monTimeBal = Monitored::Collection("timeBalance", timeBal[partition]);
804 fill(m_tools[m_timeBalGroups[partition]], monModule, monTimeBal);
805 }
806
807 if (!chanTimeDrawer[partition].empty()) {
808 auto monTime = Monitored::Collection("time", chanTime[partition]);
809 auto monModule = Monitored::Collection("module", chanTimeDrawer[partition]);
810 auto monChannel = Monitored::Collection("channel", chanTimeChannel[partition]);
811 auto monDigitizer = Monitored::Collection("digitizer", chanTimeDigitizer[partition]);
812 for (int l1TriggerIdx : l1TriggersIndices) {
813 fill(m_tools[m_chanTimeGroups[partition][l1TriggerIdx]], monModule, monChannel, monTime);
814 fill(m_tools[m_digiTimeGroups[partition][l1TriggerIdx]], monModule, monDigitizer, monTime);
815 }
816 }
817
818 if (!detailOccupModule[partition].empty()) {
819 auto monModule = Monitored::Collection("module", detailOccupModule[partition]);
820 auto monChannel = Monitored::Collection("channel", detailOccupChannel[partition]);
821 auto monEnergies = Monitored::Collection("energy", detailOccupEnergies[partition]);
822 for (int l1TriggerIdx : l1TriggersIndices) {
823 fill(m_tools[m_detailOccupGroups[partition][l1TriggerIdx]], monModule, monChannel, monEnergies);
824 }
825 }
826
827 if (!overThrOccupModule[partition].empty()) {
828 auto monModule = Monitored::Collection("module", overThrOccupModule[partition]);
829 auto monChannel = Monitored::Collection("channel", overThrOccupChannel[partition]);
830 auto monWeight = Monitored::Collection("weight", overThrOccupWeight[partition]);
831 for (int l1TriggerIdx : l1TriggersIndices) {
832 fill(m_tools[m_overThrOccupGroups[partition][l1TriggerIdx]], monModule, monChannel, monWeight);
833 }
834 }
835
836 if (!overThr30GeVOccupModule[partition].empty()) {
837 auto monModule = Monitored::Collection("module", overThr30GeVOccupModule[partition]);
838 auto monChannel = Monitored::Collection("channel", overThr30GeVOccupChannel[partition]);
839 for (int l1TriggerIdx : l1TriggersIndices) {
840 fill(m_tools[m_overThr30GeVOccupGroups[partition][l1TriggerIdx]], monModule, monChannel);
841 }
842 }
843
844 if (!overThr300GeVOccupModule[partition].empty()) {
845 auto monModule = Monitored::Collection("module", overThr300GeVOccupModule[partition]);
846 auto monChannel = Monitored::Collection("channel", overThr300GeVOccupChannel[partition]);
847 for (int l1TriggerIdx : l1TriggersIndices) {
848 fill(m_tools[m_overThr300GeVOccupGroups[partition][l1TriggerIdx]], monModule, monChannel);
849 }
850 }
851
852 if (!eneDiff[partition].empty()) {
853 auto monEnergyDiff = Monitored::Collection("energyDiff", eneDiff[partition]);
854 auto monModule = Monitored::Collection("module", eneDiffModule[partition]);
855 auto monChannel = Monitored::Collection("channel", eneDiffChannel[partition]);
856 for (int l1TriggerIdx : l1TriggersIndices) {
857 fill(m_tools[m_eneDiffChanModGroups[partition][l1TriggerIdx]], monModule, monChannel, monEnergyDiff);
858 }
859 }
860
861 for (unsigned int gain = 0; gain < Tile::MAX_GAIN; ++gain) {
862 if (!overThrOccupGainModule[partition][gain].empty()) {
863 auto monModule = Monitored::Collection("module", overThrOccupGainModule[partition][gain]);
864 auto monChannel = Monitored::Collection("channel", overThrOccupGainChannel[partition][gain]);
865 auto monWeight = Monitored::Collection("weight", overThrOccupGainWeight[partition][gain]);
866 for (int l1TriggerIdx : l1TriggersIndices) {
867 fill(m_tools[m_overThrOccupGainGroups[partition][gain][l1TriggerIdx]], monModule, monChannel, monWeight);
868 }
869 }
870
871 if (!detailOccupGainModule[partition][gain].empty()) {
872 auto monModule = Monitored::Collection("module", detailOccupGainModule[partition][gain]);
873 auto monChannel = Monitored::Collection("channel", detailOccupGainChannel[partition][gain]);
874 auto monEnergies = Monitored::Collection("energy", detailOccupGainEnergies[partition][gain]);
875 for (int l1TriggerIdx : l1TriggersIndices) {
876 fill(m_tools[m_detailOccupGainGroups[partition][gain][l1TriggerIdx]], monModule, monChannel, monEnergies);
877 }
878 }
879 }
880
882 for (unsigned int sample = 0; sample < SAMP_ALL; ++sample) {
883 if (!sampChanTime[partition][sample].empty()) {
884 auto monChanTime = Monitored::Collection("time", sampChanTime[partition][sample]);
885 for (int l1TriggerIdx : l1TriggersIndices) {
886 fill(m_tools[m_chanTimeSampGroups[partition][sample][l1TriggerIdx]], monChanTime);
887 fill(m_tools[m_chanTimeSampGroups[partition][SAMP_ALL][l1TriggerIdx]], monChanTime);
888 }
889 }
890 }
891 }
892
894 for (unsigned int sample = 0; sample < SAMP_ALL; ++sample) {
895 if (!sampEnergyDiff[partition][sample].empty()) {
896 auto monEneDiff = Monitored::Collection("energyDiff", sampEnergyDiff[partition][sample]);
897 for (int l1TriggerIdx : l1TriggersIndices) {
898 fill(m_tools[m_eneDiffSampGroups[partition][sample][l1TriggerIdx]], monEneDiff);
899 fill(m_tools[m_eneDiffSampGroups[partition][SAMP_ALL][l1TriggerIdx]], monEneDiff);
900 }
901 }
902
903 if (!sampTimeDiff[partition][sample].empty()) {
904 auto monTimeDiff = Monitored::Collection("timeDiff", sampTimeDiff[partition][sample]);
905 for (int l1TriggerIdx : l1TriggersIndices) {
906 fill(m_tools[m_timeDiffSampGroups[partition][sample][l1TriggerIdx]], monTimeDiff);
907 fill(m_tools[m_timeDiffSampGroups[partition][SAMP_ALL][l1TriggerIdx]], monTimeDiff);
908 }
909 }
910 }
911 }
912
913 }
914
915 for (int partition = 0; partition < MAX_PART; ++partition) {
916 auto monMaskedDueDQ = Monitored::Scalar<int>("nMaskedChannelsDueDQ", nMaskedChannelsDueDQ[partition]);
917 fill(m_tools[m_maskedDueDQGroups[partition]], lumiBlock, monMaskedDueDQ);
918
919 auto monMaskedCellsDueDQ = Monitored::Scalar<int>("nMaskedCellsDueDQ", nMaskedCellsDueDQ[partition]);
920 fill(m_tools[m_maskedCellsDueDQGroups[partition]], lumiBlock, monMaskedCellsDueDQ);
921
922 auto monMaskedOnFly = Monitored::Scalar<int>("nMaskedChannelsOnFly", nBadChannelsOnFly[partition]);
923 fill(m_tools[m_maskedOnFlyLBGroups[partition]], lumiBlock, monMaskedOnFly);
924
925 auto monMaskedCellsOnFly = Monitored::Scalar<int>("nMaskedCells", nBadCells[partition]);
926 fill(m_tools[m_maskedCellsLBGroups[partition]], lumiBlock, monMaskedCellsOnFly);
927
928
929 if (moduleCorr[partition].numberOfPairs() > 0) {
930 const PairBuilder::PairVector pairs = moduleCorr[partition].pairs();
931 auto monModule1 = Monitored::Collection("firstModule", pairs, [] (const PairBuilder::XYPair& p) {return (double) p.first;});
932 auto monModule2 = Monitored::Collection("secondModule", pairs, [] (const PairBuilder::XYPair& p) {return (double) p.second;});
933 std::vector<float> weight(moduleCorr[partition].numberOfPairs(), moduleCorr[partition].weight());
934 auto monWeight = Monitored::Collection("weight", weight);
935 for (int l1TriggerIdx : l1TriggersIndices) {
936 fill(m_tools[m_moduleCorrGroups[partition][l1TriggerIdx]], monModule1, monModule2, monWeight);
937 }
938 }
939
940 for (int l1TriggerIdx : l1TriggersIndices) {
941 auto monCellsNumber = Monitored::Scalar<float>("nCells", nCells[partition]);
942 fill(m_tools[m_nCellsGroups[partition][l1TriggerIdx]], lumiBlock, monCellsNumber);
943
944 auto monBCID = Monitored::Scalar<unsigned int>("BCID", bcid);
945 auto monCellsNumberOvThr = Monitored::Scalar<float>("nCells", nCellsOverThreshold[partition]);
946 fill(m_tools[m_nCellsOverThrGroups[partition][l1TriggerIdx]], monBCID, monCellsNumberOvThr);
947 }
948
949 if (partition > 1) { // Fill SampE energy for EB
950 for (int l1TriggerIdx : l1TriggersIndices) {
951 auto monEnergy = Monitored::Scalar<float>("energy", energySample[partition][TileID::SAMP_E]);
952 fill(m_tools[m_energySampEGroups[partition][l1TriggerIdx]], monEnergy);
953 }
954 }
955 }
956
957 for (unsigned int sample = 0; sample < SAMP_ALL; ++sample) {
958 if (!occupEnergy[sample].empty()) {
959 auto monEta = Monitored::Collection("eta", occupEta[sample]);
960 auto monPhi = Monitored::Collection("phi", occupPhi[sample]);
961 auto monEnergy = Monitored::Collection("energy", occupEnergy[sample]);
962 for (int l1TriggerIdx : l1TriggersIndices) {
963 fill(m_tools[m_eneEtaPhiGroups[sample][l1TriggerIdx]], monEta, monPhi, monEnergy);
964 fill(m_tools[m_eneEtaPhiGroups[SAMP_ALL][l1TriggerIdx]], monEta, monPhi, monEnergy);
965 }
966 }
967
968 if (!overThrOccupEta[sample].empty()) {
969 auto monEta = Monitored::Collection("eta", overThrOccupEta[sample]);
970 auto monPhi = Monitored::Collection("phi", overThrOccupPhi[sample]);
971 for (int l1TriggerIdx : l1TriggersIndices) {
972 fill(m_tools[m_overThrEtaPhiGroups[sample][l1TriggerIdx]], monEta, monPhi);
973 fill(m_tools[m_overThrEtaPhiGroups[SAMP_ALL][l1TriggerIdx]], monEta, monPhi);
974 }
975 }
976 }
977
978
979
980 fill("TileCellMonExecuteTime", timer);
981
982 return StatusCode::SUCCESS;
983}
984
985
987
988 using Tile = TileCalibUtils;
989
990 std::vector<HWIdentifier>::const_iterator adc_it = m_tileHWID->adc_begin();
991 std::vector<HWIdentifier>::const_iterator adc_end = m_tileHWID->adc_end();
992
993 std::vector<int> drawers[Tile::MAX_ROS - 1][Tile::MAX_GAIN];
994 std::vector<int> channels[Tile::MAX_ROS - 1][Tile::MAX_GAIN];
995
996 for (; adc_it != adc_end; ++adc_it) {
997 HWIdentifier adc_id(*adc_it);
998
999 if (badChannels->getAdcStatus(adc_id).isBad()) {
1000
1001 unsigned int partition = m_tileHWID->ros(adc_id);
1002 if (partition > 0) {
1003 partition -= 1; // ROS - 1
1004 unsigned int drawer = m_tileHWID->drawer(adc_id);
1005 unsigned int channel = m_tileHWID->channel(adc_id);
1006 unsigned int adc = m_tileHWID->adc(adc_id);
1007
1008 drawers[partition][adc].push_back(drawer);
1009 channels[partition][adc].push_back(channel);
1010 }
1011
1012 }
1013 }
1014
1015 for (unsigned int partition = 0; partition < Tile::MAX_ROS - 1; ++partition) {
1016 for (unsigned int gain = 0; gain < Tile::MAX_GAIN; ++gain) {
1017 if (!drawers[partition][gain].empty()) {
1018
1019 auto monModule = Monitored::Collection("module", drawers[partition][gain]);
1020 auto monChannel = Monitored::Collection("channel", channels[partition][gain]);
1021 fill(m_tools[m_maskedGroups[partition][gain]], monModule, monChannel);
1022
1023 }
1024 }
1025 }
1026}
1027
1028
1029void TileCellMonitorAlgorithm::fillSynchronization(const std::vector<const CaloCell*>& cells,
1030 const std::vector<int>& l1TriggersIndices) const {
1031
1032 std::vector<float> timeDifference;
1033
1034 int size = cells.size();
1035 if (size > 1) {
1036 for (int i = 1; i < size; ++i) {
1037 float x1 = cells[i]->x();
1038 float y1 = cells[i]->y();
1039 float z1 = cells[i]->z();
1040 float time1 = cells[i]->time();
1041
1042 for (int j = 0; j < i; ++j) {
1043 float x2 = cells[j]->x();
1044 float y2 = cells[j]->y();
1045 float z2 = cells[j]->z();
1046 float time2 = cells[j]->time();
1047
1048 float timeMeasured = (y2 > y1) ? time1 - time2 : time2 - time1;
1049
1050 float distance = sqrt( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
1051 float timeExpected = distance / 300.;
1052
1053 timeDifference.push_back(timeExpected - timeMeasured);
1054 }
1055 }
1056
1057 auto monTimeDifference = Monitored::Collection("timeDifference", timeDifference);
1058 for (int l1TriggerIdx : l1TriggersIndices) {
1059 fill(m_tools[m_cellSynchGroups[l1TriggerIdx]], monTimeDifference);
1060 }
1061 }
1062}
1063
1065
1066 // Conversion from channel number to digitizer number
1067 static const int channel2digitizer[48] = {8, 8, 8, 8, 8, 8,
1068 7, 7, 7, 7, 7, 7,
1069 6, 6, 6, 6, 6, 6,
1070 5, 5, 5, 5, 5, 5,
1071 4, 4, 4, 4, 4, 4,
1072 3, 3, 3, 3, 3, 3,
1073 2, 2, 2, 2, 2, 2,
1074 1, 1, 1, 1, 1, 1};
1075
1076 return channel2digitizer[channel];
1077}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
Contains class declaration for PairBuilder, and overloaded "operator <<" for output of same.
Handle class for reading from StoreGate.
Wrapper to avoid constant divisions when using units.
static const Attributes_t empty
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
This class groups all DetDescr information related to a CaloCell.
IdentifierHash onl2() const
cell online identifier 2
IdentifierHash onl1() const
cell online identifier 1
This is a "hash" representation of an Identifier.
Declare a monitored scalar variable.
A monitored timer.
Class to build pairs of XY values.
Definition PairBuilder.h:30
const PairVector & pairs() const
Return the pairs as a vector of pairs of integers.
std::vector< XYPair > PairVector
Definition PairBuilder.h:36
void inputxy(const int ystrip)
Input a new y value.
std::pair< int, int > XYPair
Definition PairBuilder.h:35
const_pointer_type cptr()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Condition object to keep Tile channel and ADC status.
const TileBchStatus & getAdcStatus(const HWIdentifier adc_id) const
Return Tile ADC status.
bool isBad() const
Static class providing several utility functions and constants.
SG::ReadCondHandleKey< TileBadChannels > m_badChannelsKey
Name of TileBadChannels in condition store.
std::vector< std::vector< int > > m_moduleCorrGroups
Gaudi::Property< bool > m_fillChannelTimeHistograms
std::vector< std::vector< int > > m_overThr30GeVOccupGroups
void fillMaskedInDB(const TileBadChannels *badChannels) const
SG::ReadHandleKey< CaloCellContainer > m_caloCellContainerKey
std::vector< std::vector< int > > m_detailOccupGroups
std::vector< std::vector< std::vector< int > > > m_energyGapScintGroups
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
std::vector< std::vector< std::vector< int > > > m_overThrOccupGainGroups
Gaudi::Property< float > m_energyThreshold
Gaudi::Property< std::vector< float > > m_energyRangeForMuon
Gaudi::Property< float > m_energyLimitForTime
Gaudi::Property< std::vector< float > > m_timeRangeForMuon
std::vector< std::vector< std::vector< int > > > m_eneDiffSampGroups
std::vector< int > m_timeBalModPartGroups
std::vector< std::vector< std::vector< int > > > m_chanTimeSampGroups
std::vector< std::vector< int > > m_nCellsOverThrGroups
SG::ReadHandleKey< TileDQstatus > m_DQstatusKey
const TileCablingService * m_cabling
Gaudi::Property< float > m_timeBalanceThreshold
std::vector< std::vector< int > > m_nCellsGroups
std::vector< std::vector< std::vector< int > > > m_detailOccupGainGroups
virtual StatusCode initialize() override
initialize
Gaudi::Property< float > m_energyThresholdForTime
std::vector< std::vector< int > > m_overThrOccupGroups
Gaudi::Property< float > m_negativeEnergyThreshold
Gaudi::Property< bool > m_fillTimeHistograms
std::vector< std::vector< int > > m_overThrEtaPhiGroups
std::vector< std::vector< int > > m_chanTimeGroups
std::vector< std::vector< int > > m_eneEtaPhiGroups
Gaudi::Property< float > m_energyThresholdForGapScint
std::vector< std::vector< int > > m_eneDiffChanModGroups
Gaudi::Property< std::vector< float > > m_energyThresholdForGain
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
std::vector< int > m_maskedCellsDueDQGroups
std::vector< int > m_energyBalModPartGroups
std::vector< std::vector< int > > m_digiTimeGroups
Gaudi::Property< float > m_energyBalanceThreshold
Gaudi::Property< bool > m_fillTimeAndEnergyDiffHistograms
std::vector< std::vector< int > > m_maskedGroups
void fillSynchronization(const std::vector< const CaloCell * > &cells, const std::vector< int > &l1TriggersIndices) const
std::vector< std::vector< int > > m_overThr300GeVOccupGroups
std::vector< std::vector< std::vector< int > > > m_timeDiffSampGroups
std::vector< std::vector< int > > m_energySampEGroups
Gaudi::Property< bool > m_fillGapScintHistograms
uint8_t qual1(void) const
get quality of first PMT (data member)
Definition TileCell.h:197
float time1(void) const
get time of first PMT
Definition TileCell.h:192
virtual bool badcell(void) const override final
check if whole cell is bad (i.e.
Definition TileCell.h:214
float eneDiff(void) const
all get methods
Definition TileCell.h:182
int gain2(void) const
get gain of second PMT
Definition TileCell.cxx:175
bool badch1(void) const
check if first PMT is in bad channel list and masked
Definition TileCell.h:209
uint8_t qbit2(void) const
get quality bits of second PMT (data member)
Definition TileCell.h:206
int gain1(void) const
get gain of first PMT
Definition TileCell.cxx:168
uint8_t qual2(void) const
get quality of second PMT (data member)
Definition TileCell.h:200
float ene1(void) const
get energy of first PMT
Definition TileCell.h:187
bool badch2(void) const
check if second PMT is in bad channel list and masked
Definition TileCell.h:212
float timeDiff(void) const
get time diff for two PMTs (data member)
Definition TileCell.h:184
float time2(void) const
get time of second PMT
Definition TileCell.h:194
uint8_t qbit1(void) const
get quality bits of first PMT (data member)
Definition TileCell.h:203
float ene2(void) const
get energy of second PMT
Definition TileCell.h:189
Class that holds Data Quality fragment information and provides functions to extract the data quality...
bool isAdcDQgood(int partition, int drawer, int ch, int gain) const
returns status of single ADC returns False if there are any errors
@ NOT_VALID_HASH
Definition TileHWID.h:314
int getNumberOfL1Triggers(void) const
Return number of L1 triggers for which histograms should be filled.
virtual StatusCode initialize() override
initialize
std::vector< int > getL1TriggerIndices(uint32_t lvl1TriggerType) const
Return indices of histograms to be filled according fired L1 trigger type.
uint32_t lumiBlock() const
The current event's luminosity block number.
uint32_t bcid() const
The bunch crossing ID of the event.
uint16_t level1TriggerType() const
The Level-1 trigger type.
const std::vector< StreamTag > & streamTags() const
Get the streams that the event was put in.
uint32_t runNumber() const
The current event's run number.
uint64_t eventNumber() const
The current event's event number.
@ INVALIDGAIN
Definition CaloGain.h:18
Generic monitoring tool for athena components.
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case)
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
EventInfo_v1 EventInfo
Definition of the latest event info version.
void fill(H5::Group &out_file, size_t iterations)
MsgStream & msg
Definition testRead.cxx:32
Tell the compiler to optimize assuming that FP may trap.
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24