ATLAS Offline Software
Loading...
Searching...
No Matches
TileJetMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
13
15#include "CaloEvent/CaloCell.h"
16
20
21
22TileJetMonitorAlgorithm::TileJetMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
23 : AthMonitorAlgorithm(name, pSvcLocator)
24 , m_tileID{nullptr}
25 , m_tileHWID{nullptr}
26 , m_cabling{nullptr}
27{}
28
29
31
32
34
36
37 ATH_MSG_INFO("in initialize()");
38
39 ATH_CHECK( detStore()->retrieve(m_tileID) );
40 ATH_CHECK( detStore()->retrieve(m_tileHWID) );
41
42 //=== get TileCablingSvc
43 ServiceHandle<TileCablingSvc> cablingSvc("TileCablingSvc", name());
44 ATH_CHECK( cablingSvc.retrieve() );
45
46 //=== cache pointers to cabling helpers
47 m_cabling = cablingSvc->cablingService();
48
49 if (!m_cabling) {
50 ATH_MSG_ERROR( "Pointer to TileCablingService is zero: " << m_cabling);
51 return StatusCode::FAILURE;
52 }
53
54 ATH_MSG_INFO("value of m_doJetCleaning: " << m_doJetCleaning);
55
56 //=== get TileBadChanTool
57 ATH_MSG_DEBUG("::Retrieving tile bad channel tool");
58 ATH_CHECK(m_tileBadChanTool.retrieve());
59 ATH_MSG_DEBUG("::Retrieved tile bad channel tool");
60
61 if (m_doJetCleaning) {
62 ATH_MSG_DEBUG("::initializing JVT updater");
63 ATH_CHECK(m_jvt.retrieve());
64 ATH_MSG_DEBUG("::initialized JVT updater");
65
66 ATH_MSG_DEBUG("::initializing JetCleaningTool");
67 ATH_CHECK(m_jetCleaningTool.retrieve());
69 ATH_MSG_DEBUG("::initialized JetCleaningTool");
70 } else {
71 m_jvt.disable();
72 m_jetCleaningTool.disable();
73 m_eventCleaningTool.disable();
74 }
75
76 ATH_CHECK( m_jetContainerKey.initialize() );
77 ATH_CHECK( m_caloCellContainerKey.initialize() );
78
79 /* Initialize Gain and Min/Max cell energies for E-cells:
80 if they are not explicitly given, set them as for the ordinary cells
81 */
84 if (m_gainE1 < 0) m_gainE1 = m_gain;
87 if (m_gainE2 < 0) m_gainE2 = m_gainE1;
90 if (m_gainE3 < 0) m_gainE3 = m_gainE2;
93 if (m_gainE4 < 0) m_gainE4 = m_gainE3;
94
95 return StatusCode::SUCCESS;
96}
97
98
99StatusCode TileJetMonitorAlgorithm::fillHistograms( const EventContext& ctx ) const {
100
101 // In case you want to measure the execution time
102 auto timer = Monitored::Timer("TIME_execute");
103
104 if (!isGoodEvent(ctx)) {
105 ATH_MSG_DEBUG("::fillHistograms(), event skipped ");
106 return StatusCode::SUCCESS;
107 } else {
108 ATH_MSG_DEBUG("::fillHistograms(), event accepted ");
109 }
110
112 if (!jetContainer.isValid()) {
113 ATH_MSG_WARNING("Can't retrieve Jet Container: " << m_jetContainerKey.key());
114 return StatusCode::SUCCESS;
115 }
116
117 uint32_t lumiBlock = GetEventInfo(ctx)->lumiBlock();
118
119 ATH_MSG_VERBOSE("::fillHistograms(), lumiblock " << lumiBlock);
120
121 std::set<Identifier> usedCells; // cells already used in the given event
122
123 int iJet = 0;
124 for (const xAOD::Jet* jet : *jetContainer) {
125 if ((jet->pt() > m_jetPtMin) && (fabs(jet->eta()) < m_jetEtaMax)) {
126 if (isGoodJet(*jet)) {
127 ATH_MSG_DEBUG("::fillHistograms, jet " << iJet
128 << ", eta " << jet->eta()
129 << ", phi " << jet->phi()
130 << ", constituents " << jet->numConstituents());
131 CHECK(fillTimeHistograms(*jet, lumiBlock, usedCells));
132 } else {
133 ATH_MSG_DEBUG("::fillHistogram, BAD jet " << iJet
134 << ", eta " << jet->eta()
135 << ", phi " << jet->phi()
136 << ", constituents " << jet->numConstituents());
137 }
138 }
139 ++iJet;
140 }
141
142
143 fill("TileJetMonExecuteTime", timer);
144
145 ATH_MSG_VERBOSE("::fillHistograms(), end-of-loops ");
146
147 return StatusCode::SUCCESS;
148}
149
150
151/*---------------------------------------------------------*/
152StatusCode TileJetMonitorAlgorithm::fillTimeHistograms(const xAOD::Jet& jet, uint32_t lumiBlock, std::set<Identifier>& usedCells) const {
153/*---------------------------------------------------------*/
154
155 ATH_MSG_VERBOSE( "in fillTimeHistograms()" );
156
157 if( jet.numConstituents() == 0 || !jet.getConstituents().isValid()) return StatusCode::SUCCESS;
158
159 int cellIndex(-1);
160
161 ToolHandle<GenericMonitoringTool> tileJetChannTimeDQTool = getGroup("TileJetChanTimeDQ");
162
163 std::array<std::string, 2> gainName{"LG", "HG"};
164 std::array<std::string, 5> partitionName{"AUX", "LBA", "LBC", "EBA", "EBC"};
165
166 for (const xAOD::JetConstituent* jet_constituent : jet.getConstituents()) {
167 if( jet_constituent->type() == xAOD::Type::CaloCluster ){
168 const xAOD::CaloCluster* calo_cluster = static_cast<const xAOD::CaloCluster*>(jet_constituent->rawConstituent());
169 if (calo_cluster && calo_cluster->getCellLinks()) {
170 for (const CaloCell* cell : *calo_cluster) {
171 cellIndex++;
172 if (cell->caloDDE()->getSubCalo() == CaloCell_ID::TILE) { // a Tile Cell
173 ATH_MSG_DEBUG("Cell " << cellIndex << " IS TILECAL !!");
174 const TileCell *tilecell = static_cast<const TileCell*> (cell);
175 Identifier id = tilecell->ID();
176 if (usedCells.find(id) == usedCells.end()) {
177 usedCells.insert(id);
178 } else {
179 continue;
180 }
181 // int section= m_tileID->section(id);
182 // int module = m_tileID->module(id); // ranges 0..63
183 auto module = Monitored::Scalar<int>("module", m_tileID->module(id));
184 int sample = m_tileID->sample(id); // ranges 0..3 (A, BC, D, E)
185 int tower = m_tileID->tower(id);
186 int ros1 = 0;
187 int ros2 = 0;
188 int chan1 = -1;
189 int chan2 = -1;
190 uint32_t bad1 = 0;
191 uint32_t bad2 = 0;
192 int gain1 = tilecell->gain1();
193 int gain2 = tilecell->gain2();
194 unsigned int qbit1 = tilecell->qbit1();
195 unsigned int qbit2 = tilecell->qbit2();
196
197 const CaloDetDescrElement * caloDDE = tilecell->caloDDE();
198 IdentifierHash hash1 = caloDDE->onl1();
199 if (hash1 != TileHWID::NOT_VALID_HASH) {
200 HWIdentifier adc_id = m_tileHWID->adc_id(hash1, gain1);
201 ros1 = m_tileHWID->ros(adc_id);
202 chan1 = m_tileHWID->channel(adc_id);
203 bad1 = m_tileBadChanTool->encodeStatus(m_tileBadChanTool->getAdcStatus(adc_id));
204 }
205
206 // How is it here with partition? D0 spans two partitions....
207 // It should be ok to treat it in this way:
208 IdentifierHash hash2 = caloDDE->onl2();
209 if (hash2 != TileHWID::NOT_VALID_HASH) {
210 HWIdentifier adc_id = m_tileHWID->adc_id(hash2, gain2);
211 ros2 = m_tileHWID->ros(adc_id);
212 chan2 = m_tileHWID->channel(adc_id);
213 bad2 = m_tileBadChanTool->encodeStatus(m_tileBadChanTool->getAdcStatus(adc_id));
214 }
215
216 bool is_good1 = isGoodChannel(ros1, module, chan1, bad1, qbit1, id);
217 bool is_good2 = isGoodChannel(ros2, module, chan2, bad2, qbit2, id);
218 float ene1 = is_good1 ? tilecell->ene1() : -1;
219 float ene2 = is_good2 ? tilecell->ene2() : -1;
220
221 ATH_MSG_DEBUG(".... " << TileCalibUtils::getDrawerString(ros1, module)
222 << ", ch1 " << chan1
223 << ", ch2 " << chan2
224 << ", qbit " << qbit1 << "/" << qbit2
225 << ", is_bad " << bad1 << "/" << bad2
226 << ", isGood " << is_good1
227 << "/" << is_good2
228 << ", ene " << tilecell->energy());
229 /*
230 Now really fill the histograms time vs lumiblock and 1dim time
231 */
232
233 // first channel
234 if (is_good1 && matchesEnergyRange(sample, tower, ene1, gain1)) {
235 if (m_do1DHistograms) {
236 std::string name = TileCalibUtils::getDrawerString(ros1, module) + "_ch_" + std::to_string(chan1) + "_1d";
237 auto channelTime = Monitored::Scalar<float>(std::move(name), tilecell->time1());
238 fill("TileJetChanTime1D", channelTime);
239 }
240
241 if (m_do2DHistograms) {
242 ATH_MSG_WARNING("These histograms are not implemented yet!");
243 }
244
245 // info for DQ histograms
246 auto moduleDQ = Monitored::Scalar<int>("module" + partitionName[ros1], module + 1);
247 auto channelDQ = Monitored::Scalar<int>("channel" + partitionName[ros1], chan1);
248 auto timeDQ = Monitored::Scalar<float>("time" + partitionName[ros1], tilecell->time1());
249 Monitored::fill(tileJetChannTimeDQTool, moduleDQ, channelDQ, timeDQ);
250
251 // general histograms, only require non-affected channels
252 if (bad1 < 2) {
253 ATH_MSG_DEBUG( "Filling in time1 for " << TileCalibUtils::getDrawerString(ros1, module)
254 << ", ch " << chan1
255 << ", ene " << ene1
256 << ", LB " << lumiBlock
257 << ", time: " << tilecell->time1());
258
259 auto channelTime = Monitored::Scalar<float>("channelTime" + partitionName[ros1], tilecell->time1());
260 fill("TileJetChanTime", channelTime);
261
262 if ((ros1 > 2) && (sample < TileID::SAMP_E)) {
263 std::string nameNoScint("channelTime" + partitionName[ros1] + "_NoScint");
264 auto channelTimeNoScint = Monitored::Scalar<float>(std::move(nameNoScint), tilecell->time1());
265 fill("TileJetChanTime", channelTimeNoScint);
266 }
267 }
268 }
269
270 // second channel
271 if (is_good2 && matchesEnergyRange(sample, tower, ene2, gain2)) {
272 if (m_do1DHistograms) {
273 std::string name = TileCalibUtils::getDrawerString(ros2, module) + "_ch_" + std::to_string(chan2) + "_1d";
274 auto channelTime = Monitored::Scalar<float>(std::move(name), tilecell->time2());
275 fill("TileJetChanTime1D", channelTime);
276 }
277
278 if (m_do2DHistograms) {
279 ATH_MSG_WARNING("This histograms are not implemented yet!");
280 }
281
282 // info for DQ histograms
283 auto moduleDQ = Monitored::Scalar<int>("module" + partitionName[ros2], module + 1);
284 auto channelDQ = Monitored::Scalar<int>("channel" + partitionName[ros2], chan2);
285 auto timeDQ = Monitored::Scalar<float>("time" + partitionName[ros2], tilecell->time2());
286 Monitored::fill(tileJetChannTimeDQTool, moduleDQ, channelDQ, timeDQ);
287
288 // general histograms, only require non-affected channels
289 if (bad2 < 2) {
290 ATH_MSG_DEBUG( "Filling in time2 for " << TileCalibUtils::getDrawerString(ros2, module)
291 << ", ch " << chan2
292 << ", ene " << ene2
293 << ", LB " << lumiBlock
294 << ", time: " << tilecell->time2()
295 <<" (qbit2 " << qbit2 << ", ch1 " << chan1 << ", ene1 " << ene1 << ", bad1 " << bad1 << ", qbit1 " << qbit1 << ")" );
296
297 auto channelTime = Monitored::Scalar<float>("channelTime" + partitionName[ros2], tilecell->time2());
298 fill("TileJetChanTime", channelTime);
299
300 if ((ros2 > 2) && (sample < TileID::SAMP_E)) {
301 std::string nameNoScint("channelTime" + partitionName[ros2] + "_NoScint");
302 auto channelTimeNoScint = Monitored::Scalar<float>(std::move(nameNoScint), tilecell->time2());
303 fill("TileJetChanTime", channelTimeNoScint);
304 }
305 }
306 }
307
308 /*
309 Now filling the cell-based histograms,
310 HG-HG and LG-LG combinations only for normal cells,
311 also include E-cells
312 */
313 if ((is_good1) && (((is_good2) && (gain1 == gain2)) || (sample == TileID::SAMP_E))) {
314 // E-cells are read-out by one channel only, so is_good2 = false for E-cells
315
317 // EneDiff histograms
318
319 int evenChannnel = (chan1 % 2 == 0) ? chan1 : chan2;
320 std::string name = TileCalibUtils::getDrawerString(ros1, module) + "_enediff_"
321 + gainName[gain1] + "_ch1_" + std::to_string(evenChannnel);
322 auto energyDifference = Monitored::Scalar<float>(std::move(name), tilecell->eneDiff() / tilecell->energy());
323 fill("TileJetEnergyDiff", energyDifference);
324 }
325
326 if ((bad1 < 2) && (bad2 < 2)) {
327
328 // cell-time histograms, only overall, require not affected channels
329 int index = findIndex(gain1, tilecell->energy());
330 ATH_MSG_DEBUG( "Filling in cell-time for " << TileCalibUtils::getDrawerString(ros1, module)
331 << ", ch1 " << chan1
332 << ", ch2 " << chan2
333 << ", ene " << tilecell->energy()
334 << ", index " << index
335 << ", time: " << tilecell->time());
336
337 // TD adding histograms per partition and per radial sampling
338 std::string name1("Cell_time_" + partitionName[ros1] + "_" + sampleName(ros1, sample, tower) + "_" + gainName[gain1] + "_slice_" + std::to_string(index));
339 auto cellTime1 = Monitored::Scalar<float>(std::move(name1), tilecell->time());
340 fill("TileJetCellTime", cellTime1);
341
342 // Adding histograms per selected individual cell
343 int index_ch1 = -1;
344 int index_ch2 = -1;
346 {
347 std::string name_sel("Cell_time_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_" + gainName[gain1] + "_slice_" + std::to_string(index));
348 auto cellTime_sel = Monitored::Scalar<float>(std::move(name_sel), tilecell->time());
349 fill("TileJetSelCellTime", cellTime_sel);
350
351 // Adding histograms per channels of selected individual cell
352 // First channel
353 index_ch1 = findIndex(gain1, tilecell->ene1() * 2); // Using twice the channel energy to find the correct index
354 std::string name_selCh1("Cell_time_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan1) + "_" + gainName[gain1] + "_slice_" + std::to_string(index_ch1));
355 auto cellTime_selCh1 = Monitored::Scalar<float>(std::move(name_selCh1), tilecell->time1());
356 fill("TileJetSelChanTime", cellTime_selCh1);
357
358 // Second channel
359 if (is_good2) {
360 index_ch2 = findIndex(gain2, tilecell->ene2() * 2); // Using twice the channel energy to find the correct index
361 std::string name_selCh2("Cell_time_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan2) + "_" + gainName[gain2] + "_slice_" + std::to_string(index_ch2));
362 auto cellTime_selCh2 = Monitored::Scalar<float>(std::move(name_selCh2), tilecell->time2());
363 fill("TileJetSelChanTime", cellTime_selCh2);
364 }
365 }
366
367 if (m_doEnergyProfiles) {
368 // TD adding energy profiles per partition and per radial sampling
369 std::string indexName1("index_" + partitionName[ros1] + "_" + sampleName(ros1, sample, tower) + "_" + gainName[gain1]);
370 auto energyIndex1 = Monitored::Scalar<float>(std::move(indexName1), index);
371
372 std::string energyName1("energy_" + partitionName[ros1] + "_" + sampleName(ros1, sample, tower) + "_" + gainName[gain1]);
373 auto cellEnergy1 = Monitored::Scalar<float>(std::move(energyName1), tilecell->energy());
374
375 fill("TileJetCellEnergyProfile", energyIndex1, cellEnergy1);
376
377 // Adding energy profiles per selected individual cell
379 {
380 std::string indexname_sel("index_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_" + gainName[gain1]);
381 auto energyIndex_sel = Monitored::Scalar<float>(std::move(indexname_sel), index);
382
383 std::string energyname_sel("energy_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_" + gainName[gain1]);
384 auto cellEnergy_sel = Monitored::Scalar<float>(std::move(energyname_sel), tilecell->energy());
385
386 fill("TileJetSelCellEnergyProfile", energyIndex_sel, cellEnergy_sel);
387
388 // Adding histograms per channels of selected individual cell
389 // First channel
390 std::string indexname_selCh1("index_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan1) + "_" + gainName[gain1]);
391 auto energyIndex_selCh1 = Monitored::Scalar<float>(std::move(indexname_selCh1), index_ch1);
392
393 std::string energyname_selCh1("energy_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan1) + "_" + gainName[gain1]);
394 auto cellEnergy_selCh1 = Monitored::Scalar<float>(std::move(energyname_selCh1), tilecell->ene1());
395
396 fill("TileJetSelChanEnergyProfile", energyIndex_selCh1, cellEnergy_selCh1);
397
398 // Second channel
399 if (is_good2) {
400 std::string indexname_selCh2("index_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan2) + "_" + gainName[gain2]);
401 auto energyIndex_selCh2 = Monitored::Scalar<float>(std::move(indexname_selCh2), index_ch2);
402
403 std::string energyname_selCh2("energy_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan2) + "_" + gainName[gain2]);
404 auto cellEnergy_selCh2 = Monitored::Scalar<float>(std::move(energyname_selCh2), tilecell->ene2());
405
406 fill("TileJetSelChanEnergyProfile", energyIndex_selCh2, cellEnergy_selCh2);
407 }
408 }
409 } else {
410 // TD adding energy histograms per partition and per radial sampling
411 std::string name1("Cell_ene_" + partitionName[ros1] + "_" + sampleName(ros1, sample, tower) + "_" + gainName[gain1] + "_slice_" + std::to_string(index));
412 auto cellEnergy1 = Monitored::Scalar<float>(std::move(name1), tilecell->energy());
413 fill("TileJetCellEnergy", cellEnergy1);
414
415 // Adding energy histograms per selected individual cell
417 {
418 std::string name_sel("Cell_ene_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_" + gainName[gain1] + "_slice_" + std::to_string(index));
419 auto cellEnergy_sel = Monitored::Scalar<float>(std::move(name_sel), tilecell->energy());
420 fill("TileJetSelCellEnergy", cellEnergy_sel);
421
422 // Adding histograms per channels of selected individual cell
423 // First channel
424 std::string name_selCh1("Cell_ene_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan1) + "_" + gainName[gain1] + "_slice_" + std::to_string(index_ch1));
425 auto cellEnergy_selCh1 = Monitored::Scalar<float>(std::move(name_selCh1), tilecell->ene1());
426 fill("TileJetSelChanEnergy", cellEnergy_selCh1);
427
428 // Second channel
429 if (is_good2) {
430 std::string name_selCh2("Cell_ene_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan2) + "_" + gainName[gain2] + "_slice_" + std::to_string(index_ch2));
431 auto cellEnergy_selCh2 = Monitored::Scalar<float>(std::move(name_selCh2), tilecell->ene2());
432 fill("TileJetSelChanEnergy", cellEnergy_selCh2);
433 }
434 }
435 }
436 }
437 }
438 } else {
439 ATH_MSG_DEBUG("Cell " << cellIndex << " is NOT Tilecal");
440 }
441 }
442 }
443 }
444 }
445
446 return StatusCode::SUCCESS;
447}
448
449/*---------------------------------------------------------*/
450std::string TileJetMonitorAlgorithm::sampleName(const int ros, const int sample, const int tower) const {
451/*---------------------------------------------------------*/
452 std::array<std::string, 3> sample_Name_LB{"A", "B", "D"};
453 std::array<std::string, 4> sample_Name_EB{"A", "B", "D", "E"};
454 std::string s_name;
455 if (ros < 3) { // LBA, LBC
456 s_name = sample_Name_LB[sample]; // default, standard cells
457 if ((sample == TileID::SAMP_BC) && (tower == 8)) { // cell B9
458 s_name = "B9";
459 }
460 } else { // EBA, EBC
461 s_name = sample_Name_EB[sample]; //default, standard cells
462 if ((sample == TileID::SAMP_C) && (tower == 9)) { // cell C10
463 s_name = "C10";
464 }
465 if ((sample == TileID::SAMP_D) && (tower == 8)) { // cell D4
466 s_name = "D4";
467 }
468 if ((sample == TileID::SAMP_E) && (tower == 10)) { // cell E1
469 s_name = "E1";
470 }
471 if ((sample == TileID::SAMP_E) && (tower == 11)) { // cell E2
472 s_name = "E2";
473 }
474 if ((sample == TileID::SAMP_E) && (tower == 13)) { // cell E3
475 s_name = "E3";
476 }
477 if ((sample == TileID::SAMP_E) && (tower == 15)) { // cell E4
478 s_name = "E4";
479 }
480 }
481 return s_name;
482}
483
484/*---------------------------------------------------------*/
485std::string TileJetMonitorAlgorithm::cellName(const int ros, const int sample, const int tower, const int module) const {
486/*---------------------------------------------------------*/
487 // names compatible with names in TileMonitoringCfgHelper.py
488 std::array<std::string, 3> sample_Name_LB{"A", "B", "D"};
489 std::array<std::string, 4> sample_Name_EB{"A", "B", "D", "E"};
490 std::string c_name;
491 if (ros < 3) { // LBA, LBC
492 c_name = sample_Name_LB[sample] + std::to_string(tower + 1); // default, standard cells
493 if ((sample == TileID::SAMP_BC) && (tower == 8)) { // cell B9
494 c_name = "B9";
495 }
496 if ((sample == TileID::SAMP_D) && (tower == 0)) { // cell D0
497 c_name = "D0";
498 }
499 if ((sample == TileID::SAMP_D) && (tower == 2)) { // cell D1
500 c_name = "D1";
501 }
502 if ((sample == TileID::SAMP_D) && (tower == 4)) { // cell D2
503 c_name = "D2";
504 }
505 if ((sample == TileID::SAMP_D) && (tower == 6)) { // cell D3
506 c_name = "D3";
507 }
508 } else { // EBA, EBC
509 c_name = sample_Name_EB[sample] + std::to_string(tower + 1); // default, standard cells
510 if ((sample == TileID::SAMP_C) && (tower == 9)) { // cell C10
511 c_name = "C10";
512 }
513 if ((sample == TileID::SAMP_D) && (tower == 8)) { // cell D4
514 c_name = "D4";
515 }
516 if ((sample == TileID::SAMP_D) && (tower == 10)) { // cell D5
517 c_name = "D5";
518 }
519 if ((sample == TileID::SAMP_D) && (tower == 12)) { // cell D6
520 c_name = "D6";
521 }
522 if ((sample == TileID::SAMP_E) && (tower == 10)) { // cell E1
523 c_name = "E1";
524 }
525 if ((sample == TileID::SAMP_E) && (tower == 11)) { // cell E2
526 c_name = "E2";
527 }
528 if ((sample == TileID::SAMP_E) && (tower == 13)) { // cell E3
529 if (((ros == 3) && ((module + 1) == 15)) || ((ros == 4) && ((module + 1) == 18))) { // special modules EBA15 & EBC18
530 c_name = "E3*";
531 } else {
532 c_name = "E3";
533 }
534 }
535 if ((sample == TileID::SAMP_E) && (tower == 15)) { // cell E4
536 if (((ros == 3) && ((module + 1) == 15)) || ((ros == 4) && ((module + 1) == 18))) { // special modules EBA15 & EBC18
537 c_name = "E4*";
538 } else {
539 c_name = "E4";
540 }
541 }
542 }
543 return c_name;
544}
545
546/*---------------------------------------------------------*/
547bool TileJetMonitorAlgorithm::matchesEnergyRange(const int sample, const int tower, const float energy, const int gain) const {
548/*---------------------------------------------------------*/
549 /* Want to separate E-cells, D4 and C10 from the rest:
550 ros: 1-2 LBA/LBC, 3-4 EBA/EBC
551 sample: 0 = A, 1 = B/BC/C, D = 2, E = 3
552 tower: 10 = E1, 11 = E2, 13 = E3, 14 = E4, 8 = D4, 9 = C10
553 Nevertheless, C10 and D4 have the same limits, since these are ordinary cells
554 */
555 if (sample != TileID::SAMP_E) {
556 return((energy > m_energyChanMin) && (energy < m_energyChanMax) && (gain == m_gain));
557 } else {
558 switch (tower) {
559 case 10:
560 return((energy > m_energyE1Min) && (energy < m_energyE1Max) && (gain == m_gainE1));
561 break;
562 case 11:
563 return((energy > m_energyE2Min) && (energy < m_energyE2Max) && (gain == m_gainE2));
564 break;
565 case 13:
566 return((energy > m_energyE3Min) && (energy < m_energyE3Max) && (gain == m_gainE3));
567 break;
568 case 15:
569 return((energy > m_energyE4Min) && (energy < m_energyE4Max) && (gain == m_gainE4));
570 break;
571 default:
572 return false;
573 }
574 }
575}
576
577bool TileJetMonitorAlgorithm::isGoodChannel(int ros, int module, int channel, uint32_t bad, unsigned int qbit, Identifier id) const {
578
579 if ((ros < 1) || (ros >= (int) TileCalibUtils::MAX_ROS)) return false; // invalid partition
580
581 if ((module < 0) || (module >= (int) TileCalibUtils::MAX_DRAWER)) return false; // invalid module number
582
583 if (m_cabling->isDisconnected(ros, module, channel)) {
584 return false; // non-existing PMT (empty hole)
585 }
586
587 if (((qbit & TileCell::MASK_BADCH) != 0) || // masked as bad
588 ((qbit & TileCell::MASK_TIME) != TileCell::MASK_TIME) || // flagged
589 ((qbit & TileCell::MASK_ALGO) == TileFragHash::OptFilterDsp)) // in DSP
590
591 return false;
592 /*
593 bad is the status in the DB (see http://alxr.usatlas.bnl.gov/lxr-stb6/source/atlas/TileCalorimeter/TileConditions/src/TileBadChanTool.cxx#390).
594 Meaning:
595 0 = good, 1 = noisy, 2 = affected, 3 = bad, 4 = otherwise
596 */
597 if (bad > 2) return false;
598
599 /*
600 Now check for special C10, merged E1, E4'
601 C10 spec is ok only if channel = 5 (i.e. pmt=6). The other is pmt=5
602 E1 merged and E4' should be dropped if channel = 12 (i.e. pmt=13)
603 */
604 return ((( channel != 4) && (channel != 12)) || m_cabling->TileGap_connected(id));
605}
606
607
608bool TileJetMonitorAlgorithm::isGoodEvent(const EventContext& ctx) const {
609 /* check for errors in LAr and Tile, see https://twiki.cern.ch/twiki/bin/viewauth/Atlas/DataPreparationCheckListForPhysicsAnalysis
610 */
611 if (! m_doEventCleaning) return true;
612
613 ATH_MSG_DEBUG("::isGoodEvent()....");
614
616
617 if (eventInfo->errorState(xAOD::EventInfo::LAr) == xAOD::EventInfo::Error) return false;
618 if (eventInfo->errorState(xAOD::EventInfo::Tile) == xAOD::EventInfo::Error) return false;
619
620 /* see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/HowToCleanJets2017
621 */
622 if (! m_doJetCleaning) return true;
623
624 const xAOD::JetContainer* jetContainer = SG::get(m_jetContainerKey);
625 if (! jetContainer){
626 ATH_MSG_INFO("Cannot retrieve " << m_jetContainerKey << ". However, returning true.");
627 return true;
628 }
629
630 auto [jetsCopy, jetsCopyAux] = xAOD::shallowCopy(*jetContainer,ctx);
631 //std::unique_ptr< xAOD::JetContainer > jetsCopy(jetsSC.first);
632 //std::unique_ptr< xAOD::ShallowAuxContainer > jetsCopyAux(jetsSC.second);
633
634 // We're attaching decorations here to a temporary object that
635 // is not recorded, so we shouldn't use a WriteDecorHandle.
636 static const SG::AuxElement::Decorator<char> passOR ("passOR");
637 static const SG::AuxElement::Decorator<char> passJvt ("passJvt");
638
639 int iJet = 0;
640 for (auto jet : *jetsCopy) {
641 ATH_MSG_DEBUG("Jet " << iJet << ", pT " << jet->pt()/1000.0 << " GeV, eta "
642 << jet->eta());
643 passJvt(*jet) = passesJvt(*jet);
644 passOR(*jet) = true;
645 ATH_MSG_DEBUG("... done with jet " << iJet);
646 ++iJet;
647 }
648
649 bool accept = m_eventCleaningTool->acceptEvent(&*jetsCopy);
650
651 return accept;
652}
653
654
656
657 if (jet.pt() > m_jetPtMin
658 && jet.pt() < m_jetPtMax
659 && fabs(jet.getAttribute<float>("DetectorEta")) < m_jetTrackingEtaLimit
660 && m_jvt->updateJvt(jet) < m_jvtThreshold) {
661
662 return false;
663
664 } else {
665 return true;
666 }
667
668}
669
671
672 if (m_doJetCleaning) {
673
674 if (jet.pt() >= m_jetPtMin && passesJvt(jet) && m_jetCleaningTool->keep(jet)) {
675 return true;
676 } else {
677 return false;
678 }
679
680 } else {
681 return true;
682 }
683
684}
685
686unsigned int TileJetMonitorAlgorithm::findIndex(const int gain, const float energy) const {
687
688 if (gain == 1) {
689 return (std::upper_bound(m_cellEnergyUpperLimitsHG.begin(), m_cellEnergyUpperLimitsHG.end(), energy)
690 - m_cellEnergyUpperLimitsHG.begin());
691 } else {
692 return (std::upper_bound(m_cellEnergyUpperLimitsLG.begin(), m_cellEnergyUpperLimitsLG.end(), energy)
693 - m_cellEnergyUpperLimitsLG.begin());
694 }
695
696}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
Handle class for reading from StoreGate.
std::atomic< const char * > ClassID_traits< ViewVector< DV > >::s_name
Definition ViewVector.h:339
const ServiceHandle< StoreGateSvc > & detStore() const
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
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.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
float time() const
get time (data member)
Definition CaloCell.h:368
double energy() const
get energy (data member)
Definition CaloCell.h:327
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition CaloCell.h:295
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.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
static const unsigned int MAX_ROS
Number of ROSs.
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
static const unsigned int MAX_DRAWER
Number of drawers in ROS 1-4.
float time1(void) const
get time of first PMT
Definition TileCell.h:192
float eneDiff(void) const
all get methods
Definition TileCell.h:182
int gain2(void) const
get gain of second PMT
Definition TileCell.cxx:175
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
float ene1(void) const
get energy of first PMT
Definition TileCell.h:187
float time2(void) const
get time of second PMT
Definition TileCell.h:194
@ MASK_TIME
Definition TileCell.h:67
@ MASK_ALGO
Definition TileCell.h:62
@ MASK_BADCH
Definition TileCell.h:63
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
@ NOT_VALID_HASH
Definition TileHWID.h:314
Gaudi::Property< bool > m_do1DHistograms
StatusCode fillTimeHistograms(const xAOD::Jet &jet, uint32_t lumiBlock, std::set< Identifier > &usedCells) const
Gaudi::Property< float > m_gainE2
std::string cellName(const int ros, const int sample, const int tower, const int module) const
Gaudi::Property< float > m_gainE4
ToolHandle< ITileBadChanTool > m_tileBadChanTool
const TileCablingService * m_cabling
TileCabling instance.
SG::ReadHandleKey< xAOD::JetContainer > m_jetContainerKey
Gaudi::Property< float > m_energyDiffThreshold
Gaudi::Property< bool > m_doCellHistograms
Gaudi::Property< bool > m_doJetCleaning
virtual StatusCode initialize() override
initialize
Gaudi::Property< float > m_gainE1
Gaudi::Property< float > m_energyE3Min
Gaudi::Property< float > m_jetEtaMax
Gaudi::Property< bool > m_doEnergyProfiles
Gaudi::Property< bool > m_doEnergyDiffHistograms
Gaudi::Property< float > m_energyE2Min
SG::ReadHandleKey< CaloCellContainer > m_caloCellContainerKey
Gaudi::Property< float > m_energyE4Max
Gaudi::Property< bool > m_doEventCleaning
Gaudi::Property< std::vector< float > > m_cellEnergyUpperLimitsLG
Gaudi::Property< float > m_energyE1Min
bool matchesEnergyRange(const int sample, const int tower, const float energy, const int gain) const
Gaudi::Property< float > m_jetPtMin
ToolHandle< IJetSelector > m_jetCleaningTool
Gaudi::Property< std::vector< float > > m_cellEnergyUpperLimitsHG
Gaudi::Property< bool > m_do2DHistograms
bool isGoodChannel(int part, int module, int channel, uint32_t bad, unsigned int qbit, Identifier id) const
ToolHandle< IJetUpdateJvt > m_jvt
Gaudi::Property< float > m_energyE2Max
Gaudi::Property< float > m_gainE3
bool isGoodJet(const xAOD::Jet &jet) const
Gaudi::Property< float > m_energyChanMax
std::string sampleName(const int ros, const int sample, const int tower) const
Gaudi::Property< float > m_jetTrackingEtaLimit
Gaudi::Property< float > m_energyE3Max
Gaudi::Property< float > m_gain
Gaudi::Property< float > m_energyE1Max
ToolHandle< ECUtils::IEventCleaningTool > m_eventCleaningTool
TileJetMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
Gaudi::Property< float > m_energyChanMin
unsigned int findIndex(const int gain, const float energy) const
bool isGoodEvent(const EventContext &ctx) const
Gaudi::Property< float > m_jetPtMax
Gaudi::Property< float > m_energyE4Min
Gaudi::Property< float > m_jvtThreshold
bool passesJvt(const xAOD::Jet &jet) const
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version).
@ Tile
The Tile calorimeter.
@ LAr
The LAr calorimeter.
@ Error
The sub-detector issued an error.
4-vector of jet constituent at the scale used during jet finding.
void fill(const ToolHandle< GenericMonitoringTool > &tool, T &&... variables)
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition index.py:1
@ CaloCluster
The object is a calorimeter cluster.
Definition ObjectType.h:39
Jet_v1 Jet
Definition of the current "jet version".
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
ShallowCopyResult_t< T > shallowCopy(const T &cont, const EventContext &ctx)
Create a shallow copy of an existing container.
JetContainer_v1 JetContainer
Definition of the current "jet container version".
void fill(H5::Group &out_file, size_t iterations)