ATLAS Offline Software
Loading...
Searching...
No Matches
TileJetMonitorAlgorithm.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
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
316 if (m_doEnergyDiffHistograms && (tilecell->energy() > m_energyDiffThreshold)) {
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 index_ch2 = findIndex(gain2, tilecell->ene2() * 2); // Using twice the channel energy to find the correct index
360 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));
361 auto cellTime_selCh2 = Monitored::Scalar<float>(std::move(name_selCh2), tilecell->time2());
362 fill("TileJetSelChanTime", cellTime_selCh2);
363 }
364
365 if (m_doEnergyProfiles) {
366 // TD adding energy profiles per partition and per radial sampling
367 std::string indexName1("index_" + partitionName[ros1] + "_" + sampleName(ros1, sample, tower) + "_" + gainName[gain1]);
368 auto energyIndex1 = Monitored::Scalar<float>(std::move(indexName1), index);
369
370 std::string energyName1("energy_" + partitionName[ros1] + "_" + sampleName(ros1, sample, tower) + "_" + gainName[gain1]);
371 auto cellEnergy1 = Monitored::Scalar<float>(std::move(energyName1), tilecell->energy());
372
373 fill("TileJetCellEnergyProfile", energyIndex1, cellEnergy1);
374
375 // Adding energy profiles per selected individual cell
377 {
378 std::string indexname_sel("index_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_" + gainName[gain1]);
379 auto energyIndex_sel = Monitored::Scalar<float>(std::move(indexname_sel), index);
380
381 std::string energyname_sel("energy_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_" + gainName[gain1]);
382 auto cellEnergy_sel = Monitored::Scalar<float>(std::move(energyname_sel), tilecell->energy());
383
384 fill("TileJetSelCellEnergyProfile", energyIndex_sel, cellEnergy_sel);
385
386 // Adding histograms per channels of selected individual cell
387 // First channel
388 std::string indexname_selCh1("index_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan1) + "_" + gainName[gain1]);
389 auto energyIndex_selCh1 = Monitored::Scalar<float>(std::move(indexname_selCh1), index_ch1);
390
391 std::string energyname_selCh1("energy_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan1) + "_" + gainName[gain1]);
392 auto cellEnergy_selCh1 = Monitored::Scalar<float>(std::move(energyname_selCh1), tilecell->ene1());
393
394 fill("TileJetSelChanEnergyProfile", energyIndex_selCh1, cellEnergy_selCh1);
395
396 // Second channel
397 std::string indexname_selCh2("index_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan2) + "_" + gainName[gain2]);
398 auto energyIndex_selCh2 = Monitored::Scalar<float>(std::move(indexname_selCh2), index_ch2);
399
400 std::string energyname_selCh2("energy_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_ch" + std::to_string(chan2) + "_" + gainName[gain2]);
401 auto cellEnergy_selCh2 = Monitored::Scalar<float>(std::move(energyname_selCh2), tilecell->ene2());
402
403 fill("TileJetSelChanEnergyProfile", energyIndex_selCh2, cellEnergy_selCh2);
404 }
405 } else {
406 // TD adding energy histograms per partition and per radial sampling
407 std::string name1("Cell_ene_" + partitionName[ros1] + "_" + sampleName(ros1, sample, tower) + "_" + gainName[gain1] + "_slice_" + std::to_string(index));
408 auto cellEnergy1 = Monitored::Scalar<float>(std::move(name1), tilecell->energy());
409 fill("TileJetCellEnergy", cellEnergy1);
410
411 // Adding energy histograms per selected individual cell
413 {
414 std::string name_sel("Cell_ene_" + TileCalibUtils::getDrawerString(ros1, module) + "_" + cellName(ros1, sample, tower, module) + "_" + gainName[gain1] + "_slice_" + std::to_string(index));
415 auto cellEnergy_sel = Monitored::Scalar<float>(std::move(name_sel), tilecell->energy());
416 fill("TileJetSelCellEnergy", cellEnergy_sel);
417
418 // Adding histograms per channels of selected individual cell
419 // First channel
420 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));
421 auto cellEnergy_selCh1 = Monitored::Scalar<float>(std::move(name_selCh1), tilecell->ene1());
422 fill("TileJetSelChanEnergy", cellEnergy_selCh1);
423
424 // Second channel
425 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));
426 auto cellEnergy_selCh2 = Monitored::Scalar<float>(std::move(name_selCh2), tilecell->ene2());
427 fill("TileJetSelChanEnergy", cellEnergy_selCh2);
428 }
429 }
430 }
431 }
432 } else {
433 ATH_MSG_DEBUG("Cell " << cellIndex << " is NOT Tilecal");
434 }
435 }
436 }
437 }
438 }
439
440 return StatusCode::SUCCESS;
441}
442
443/*---------------------------------------------------------*/
444std::string TileJetMonitorAlgorithm::sampleName(const int ros, const int sample, const int tower) const {
445/*---------------------------------------------------------*/
446 std::array<std::string, 3> sample_Name_LB{"A", "B", "D"};
447 std::array<std::string, 4> sample_Name_EB{"A", "B", "D", "E"};
448 std::string s_name;
449 if (ros < 3) { // LBA, LBC
450 s_name = sample_Name_LB[sample]; // default, standard cells
451 if ((sample == TileID::SAMP_BC) && (tower == 8)) { // cell B9
452 s_name = "B9";
453 }
454 } else { // EBA, EBC
455 s_name = sample_Name_EB[sample]; //default, standard cells
456 if ((sample == TileID::SAMP_C) && (tower == 9)) { // cell C10
457 s_name = "C10";
458 }
459 if ((sample == TileID::SAMP_D) && (tower == 8)) { // cell D4
460 s_name = "D4";
461 }
462 if ((sample == TileID::SAMP_E) && (tower == 10)) { // cell E1
463 s_name = "E1";
464 }
465 if ((sample == TileID::SAMP_E) && (tower == 11)) { // cell E2
466 s_name = "E2";
467 }
468 if ((sample == TileID::SAMP_E) && (tower == 13)) { // cell E3
469 s_name = "E3";
470 }
471 if ((sample == TileID::SAMP_E) && (tower == 15)) { // cell E4
472 s_name = "E4";
473 }
474 }
475 return s_name;
476}
477
478/*---------------------------------------------------------*/
479std::string TileJetMonitorAlgorithm::cellName(const int ros, const int sample, const int tower, const int module) const {
480/*---------------------------------------------------------*/
481 // names compatible with names in TileMonitoringCfgHelper.py
482 std::array<std::string, 3> sample_Name_LB{"A", "B", "D"};
483 std::array<std::string, 4> sample_Name_EB{"A", "B", "D", "E"};
484 std::string c_name;
485 if (ros < 3) { // LBA, LBC
486 c_name = sample_Name_LB[sample] + std::to_string(tower + 1); // default, standard cells
487 if ((sample == TileID::SAMP_BC) && (tower == 8)) { // cell B9
488 c_name = "B9";
489 }
490 if ((sample == TileID::SAMP_D) && (tower == 0)) { // cell D0
491 c_name = "D0";
492 }
493 if ((sample == TileID::SAMP_D) && (tower == 2)) { // cell D1
494 c_name = "D1";
495 }
496 if ((sample == TileID::SAMP_D) && (tower == 4)) { // cell D2
497 c_name = "D2";
498 }
499 if ((sample == TileID::SAMP_D) && (tower == 6)) { // cell D3
500 c_name = "D3";
501 }
502 } else { // EBA, EBC
503 c_name = sample_Name_EB[sample] + std::to_string(tower + 1); // default, standard cells
504 if ((sample == TileID::SAMP_C) && (tower == 9)) { // cell C10
505 c_name = "C10";
506 }
507 if ((sample == TileID::SAMP_D) && (tower == 8)) { // cell D4
508 c_name = "D4";
509 }
510 if ((sample == TileID::SAMP_D) && (tower == 10)) { // cell D5
511 c_name = "D5";
512 }
513 if ((sample == TileID::SAMP_D) && (tower == 12)) { // cell D6
514 c_name = "D6";
515 }
516 if ((sample == TileID::SAMP_E) && (tower == 10)) { // cell E1
517 c_name = "E1";
518 }
519 if ((sample == TileID::SAMP_E) && (tower == 11)) { // cell E2
520 c_name = "E2";
521 }
522 if ((sample == TileID::SAMP_E) && (tower == 13)) { // cell E3
523 if (((ros == 3) && ((module + 1) == 15)) || ((ros == 4) && ((module + 1) == 18))) { // special modules EBA15 & EBC18
524 c_name = "E3*";
525 } else {
526 c_name = "E3";
527 }
528 }
529 if ((sample == TileID::SAMP_E) && (tower == 15)) { // cell E4
530 if (((ros == 3) && ((module + 1) == 15)) || ((ros == 4) && ((module + 1) == 18))) { // special modules EBA15 & EBC18
531 c_name = "E4*";
532 } else {
533 c_name = "E4";
534 }
535 }
536 }
537 return c_name;
538}
539
540/*---------------------------------------------------------*/
541bool TileJetMonitorAlgorithm::matchesEnergyRange(const int sample, const int tower, const float energy, const int gain) const {
542/*---------------------------------------------------------*/
543 /* Want to separate E-cells, D4 and C10 from the rest:
544 ros: 1-2 LBA/LBC, 3-4 EBA/EBC
545 sample: 0 = A, 1 = B/BC/C, D = 2, E = 3
546 tower: 10 = E1, 11 = E2, 13 = E3, 14 = E4, 8 = D4, 9 = C10
547 Nevertheless, C10 and D4 have the same limits, since these are ordinary cells
548 */
549 if (sample != TileID::SAMP_E) {
550 return((energy > m_energyChanMin) && (energy < m_energyChanMax) && (gain == m_gain));
551 } else {
552 switch (tower) {
553 case 10:
554 return((energy > m_energyE1Min) && (energy < m_energyE1Max) && (gain == m_gainE1));
555 break;
556 case 11:
557 return((energy > m_energyE2Min) && (energy < m_energyE2Max) && (gain == m_gainE2));
558 break;
559 case 13:
560 return((energy > m_energyE3Min) && (energy < m_energyE3Max) && (gain == m_gainE3));
561 break;
562 case 15:
563 return((energy > m_energyE4Min) && (energy < m_energyE4Max) && (gain == m_gainE4));
564 break;
565 default:
566 return false;
567 }
568 }
569}
570
571bool TileJetMonitorAlgorithm::isGoodChannel(int ros, int module, int channel, uint32_t bad, unsigned int qbit, Identifier id) const {
572
573 if ((ros < 1) || (ros >= (int) TileCalibUtils::MAX_ROS)) return false; // invalid partition
574
575 if ((module < 0) || (module >= (int) TileCalibUtils::MAX_DRAWER)) return false; // invalid module number
576
577 if (m_cabling->isDisconnected(ros, module, channel)) {
578 return false; // non-existing PMT (empty hole)
579 }
580
581 if (((qbit & TileCell::MASK_BADCH) != 0) || // masked as bad
582 ((qbit & TileCell::MASK_TIME) != TileCell::MASK_TIME) || // flagged
583 ((qbit & TileCell::MASK_ALGO) == TileFragHash::OptFilterDsp)) // in DSP
584
585 return false;
586 /*
587 bad is the status in the DB (see http://alxr.usatlas.bnl.gov/lxr-stb6/source/atlas/TileCalorimeter/TileConditions/src/TileBadChanTool.cxx#390).
588 Meaning:
589 0 = good, 1 = noisy, 2 = affected, 3 = bad, 4 = otherwise
590 */
591 if (bad > 2) return false;
592
593 /*
594 Now check for special C10, merged E1, E4'
595 C10 spec is ok only if channel = 5 (i.e. pmt=6). The other is pmt=5
596 E1 merged and E4' should be dropped if channel = 12 (i.e. pmt=13)
597 */
598 return ((( channel != 4) && (channel != 12)) || m_cabling->TileGap_connected(id));
599}
600
601
602bool TileJetMonitorAlgorithm::isGoodEvent(const EventContext& ctx) const {
603 /* check for errors in LAr and Tile, see https://twiki.cern.ch/twiki/bin/viewauth/Atlas/DataPreparationCheckListForPhysicsAnalysis
604 */
605 if (! m_doEventCleaning) return true;
606
607 ATH_MSG_DEBUG("::isGoodEvent()....");
608
610
611 if (eventInfo->errorState(xAOD::EventInfo::LAr) == xAOD::EventInfo::Error) return false;
612 if (eventInfo->errorState(xAOD::EventInfo::Tile) == xAOD::EventInfo::Error) return false;
613
614 /* see https://twiki.cern.ch/twiki/bin/view/AtlasProtected/HowToCleanJets2017
615 */
616 if (! m_doJetCleaning) return true;
617
618 const xAOD::JetContainer* jetContainer = SG::get(m_jetContainerKey);
619 if (! jetContainer){
620 ATH_MSG_INFO("Cannot retrieve " << m_jetContainerKey << ". However, returning true.");
621 return true;
622 }
623
624 auto jetsSC = xAOD::shallowCopyContainer(*jetContainer);
625 std::unique_ptr< xAOD::JetContainer > jetsCopy(jetsSC.first);
626 std::unique_ptr< xAOD::ShallowAuxContainer > jetsCopyAux(jetsSC.second);
627
628 // We're attaching decorations here to a temporary object that
629 // is not recorded, so we shouldn't use a WriteDecorHandle.
630 static const SG::AuxElement::Decorator<char> passOR ("passOR");
631 static const SG::AuxElement::Decorator<char> passJvt ("passJvt");
632
633 int iJet = 0;
634 for (auto jet : *jetsCopy) {
635 ATH_MSG_DEBUG("Jet " << iJet << ", pT " << jet->pt()/1000.0 << " GeV, eta "
636 << jet->eta());
637 passJvt(*jet) = passesJvt(*jet);
638 passOR(*jet) = true;
639 ATH_MSG_DEBUG("... done with jet " << iJet);
640 ++iJet;
641 }
642
643 bool accept = m_eventCleaningTool->acceptEvent(&*jetsCopy);
644
645 return accept;
646}
647
648
650
651 if (jet.pt() > m_jetPtMin
652 && jet.pt() < m_jetPtMax
653 && fabs(jet.getAttribute<float>("DetectorEta")) < m_jetTrackingEtaLimit
654 && m_jvt->updateJvt(jet) < m_jvtThreshold) {
655
656 return false;
657
658 } else {
659 return true;
660 }
661
662}
663
665
666 if (m_doJetCleaning) {
667
668 if (jet.pt() >= m_jetPtMin && passesJvt(jet) && m_jetCleaningTool->keep(jet)) {
669 return true;
670 } else {
671 return false;
672 }
673
674 } else {
675 return true;
676 }
677
678}
679
680unsigned int TileJetMonitorAlgorithm::findIndex(const int gain, const float energy) const {
681
682 if (gain == 1) {
683 return (std::upper_bound(m_cellEnergyUpperLimitsHG.begin(), m_cellEnergyUpperLimitsHG.end(), energy)
684 - m_cellEnergyUpperLimitsHG.begin());
685 } else {
686 return (std::upper_bound(m_cellEnergyUpperLimitsLG.begin(), m_cellEnergyUpperLimitsLG.end(), energy)
687 - m_cellEnergyUpperLimitsLG.begin());
688 }
689
690}
#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.
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
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.
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, const EventContext &ctx)
Function making a shallow copy of a constant container.
JetContainer_v1 JetContainer
Definition of the current "jet container version".
void fill(H5::Group &out_file, size_t iterations)