ATLAS Offline Software
Loading...
Searching...
No Matches
LArCellMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// NAME: LArCellMonAlg.cxx
6// based on LArCellMonTool:
7// W.Lampl - Spring 2017: Major re-design
8// M. Spalla, P.Strizenec - Migration to AthenaMT (2020)
9// ********************************************************************
10#include "LArCellMonAlg.h"
11
14
15#include "CaloDetDescr/CaloDetDescrElement.h"
17#include "Identifier/Identifier.h"
21
24
26#include "AthenaKernel/Units.h"
27
28#include <cassert>
29#include <algorithm>
30
32LArCellMonAlg::LArCellMonAlg(const std::string& name, ISvcLocator* pSvcLocator)
33 :CaloMonAlgBase(name, pSvcLocator),
34 m_LArOnlineIDHelper(nullptr)
35{
36}
37
38LArCellMonAlg::~LArCellMonAlg() = default;
39
42
43 ATH_MSG_DEBUG("LArCellMonAlg::initialize() start");
44
45 // Initialize superclass
47
48 //Identfier-helpers
49 ATH_CHECK( detStore()->retrieve(m_LArOnlineIDHelper, "LArOnlineID") );
50
51 // Bad channel masker tool
53 ATH_CHECK(m_bcMask.buildBitMask(m_problemsToMask,msg()));
54
55 ATH_CHECK( m_cellContainerKey.initialize() );
56 ATH_CHECK( m_cablingKey.initialize() );
57 ATH_CHECK( m_noiseCDOKey.initialize() );
58
59 //JobO consistency check:
60 if (m_useTrigger && std::all_of(std::begin(m_triggerNames),std::end(m_triggerNames),[](const std::string& trigName){return trigName.empty();})) {
61 ATH_MSG_WARNING("UseTrigger set to true but no trigger names given! Forcing useTrigger to false");
62 m_useTrigger=false;
63 }
64
65 // FIXME check consistency between layer and partitions from jO to enums
66
67 // Check that sizes of layer names and ncells is the same
68 if (m_layerNames.size() != m_layerNcells.size()) {
69 ATH_MSG_ERROR("LayerNames and LayerNcells not of the same length, aborting.....");
70 return StatusCode::FAILURE;
71 }
72
73
74 // Sets the threshold value arrays
76
77 //Fill the LArCellBinning for each layer
78 //setLArCellBinning();
79
81
82 ATH_MSG_DEBUG("LArCellMonAlg::initialize() is done!");
83
84 return StatusCode::SUCCESS;
85}
86
87
88
90
91 //Interpret the jobO defining the per-threshold histograms
92 //and initialize vector<threshold_t> m_thresholds;
93
94 const size_t nThr=m_thresholdNameProp.value().size();
95
96 //Check uniqueness of threshold-type by filling a set
97 std::set<std::string> uniqunesCheck;
98 for (const std::string& s : m_thresholdNameProp.value()) {
99 auto r=uniqunesCheck.insert(s);
100 if (!r.second) {
101 ATH_MSG_ERROR( "Configuration error: Threshold type " << s << " appears more than once" );
102 return StatusCode::FAILURE;
103 }
104 }
105 uniqunesCheck.clear();
106
107
108 const std::map<const std::string, const Direction> stringToDirection {{"over",OVER},{"under",UNDER},{"both",BOTH},{"none",NONE}};
109 const std::map<const std::string, const TriggerType> stringToTrigType {{"nota",NOTA},{"rndm",RNDM},{"calo",CALO},{"minbias",MINBIAS},
110 {"met",MET},{"misc",MISC},{"none",NOTA},{"all",NOTA}};
111
112 m_thresholds.resize(nThr);
113 for (size_t iThr=0;iThr<nThr;++iThr) {
114 threshold_t& threshold=m_thresholds[iThr];
115 threshold.m_threshName=m_thresholdNameProp.value()[iThr];
116 threshold.m_thrIndex=iThr;
117 threshold.m_threshTitleTemplate= m_thresholdTitleTemplates.value()[iThr];
118 std::fill(threshold.m_threshValue.begin(),threshold.m_threshValue.end(),m_defaultThresholds.value()[iThr]);
119 threshold.m_inSigNoise=m_inSigNoise.value()[iThr];
120
121 auto itD=stringToDirection.find(strToLower(m_thresholdDirectionProp.value()[iThr]));
122 if (itD!=stringToDirection.end()) {
123 threshold.m_threshDirection=itD->second;
124 }
125 else {
126 ATH_MSG_ERROR( "Configuration problem. Unknown threshold direction '"
127 << m_thresholdDirectionProp.value()[iThr]
128 << "'given" );
129 return StatusCode::FAILURE;
130 }
131
132 auto itT=stringToTrigType.find(strToLower(m_triggersToExcludeProp.value()[iThr]));
133 if (itT!=stringToTrigType.end()) {
134 threshold.m_triggersToExclude.set(itT->second);
135 if (itT->first=="all") {ATH_MSG_WARNING( "Setting TriggersToExclude to 'all' has no effect!" );}
136 }
137 else {
138 ATH_MSG_ERROR( "Configuration problem. Unknown trigger type '"
139 << m_triggersToExcludeProp.value()[iThr]
140 << "' given in propety 'TriggersToExlude'" );
141 return StatusCode::FAILURE;
142 }
143
144 itT=stringToTrigType.find(strToLower(m_triggersToIncludeProp.value()[iThr]));
145 if (itT!=stringToTrigType.end()) {
146 threshold.m_triggersToInclude.set(itT->second);
147 if (itT->first=="none") {ATH_MSG_WARNING( "Setting TriggersToInclude to 'none' has no effect!" );}
148 }
149 else {
150 ATH_MSG_ERROR( "Configuration problem. Unknown trigger type '"
151 << m_triggersToIncludeProp.value()[iThr]
152 << "' given in propety 'TriggersToInclude'" );
153 return StatusCode::FAILURE;
154 }
155
156 threshold.m_doPercentageOccupancy=isThrListed(m_doEtaPhiPercentageOccupancyNames.value(),threshold.m_threshName);
157 threshold.m_doEtaPhiOccupancy=isThrListed(m_doEtaPhiTotalOccupancyNames.value(),threshold.m_threshName);
158 threshold.m_doEtaOccupancy=isThrListed(m_doEtaOccupancyNames.value(),threshold.m_threshName);
159 threshold.m_doPhiOccupancy=isThrListed(m_doPhiOccupancyNames.value(),threshold.m_threshName);
160 threshold.m_doEtaPhiTotalEnergy=isThrListed(m_doEtaPhiTotEnergyNames.value(),threshold.m_threshName);
161 threshold.m_doEtaPhiAverageQuality=isThrListed(m_doEtaPhiAvgQualityNames.value(),threshold.m_threshName);
162 threshold.m_doEtaPhiFractionOverQth=isThrListed(m_doEtaPhiFractionOverQthNames.value(),threshold.m_threshName);
163 threshold.m_qualityFactorThreshold=m_qualityFactorThresholdProp.value()[iThr];
164 threshold.m_doEtaPhiAverageTime=isThrListed(m_doEtaPhiAvgTimeNames.value(),threshold.m_threshName);
165 threshold.m_doEtaPhiFractionPastTth=isThrListed(m_doEtaPhiFractionPastTthNames.value(),threshold.m_threshName);
166 threshold.m_timeThreshold=m_timeThresholdProp.value()[iThr];
167 threshold.m_doBeamBackgroundRemoval=m_doBeamBackgroundRemovalProp.value()[iThr];
168 }//end loop over threshold names
169
170
171 //Overwrite per-layer thresholds:
172 for (size_t iThrOvr=0;iThrOvr!= m_thresholdColumnType.value().size();++iThrOvr) {
173 const std::string& nameToOverwrite=m_thresholdColumnType.value()[iThrOvr];
174 auto it=std::find_if(m_thresholds.begin(),m_thresholds.end(),
175 [&](const threshold_t& x) {return (x.m_threshName==nameToOverwrite);}
176 );
177
178 if (it==m_thresholds.end()) {
179 ATH_MSG_ERROR( "Configuration error reading 'ThresholdColumnType': Threshold type '" << nameToOverwrite << "' is not defined in 'ThresholdType'" );
180 return StatusCode::FAILURE;
181 }
182
183 for (unsigned iLyr=0;iLyr<MAXLYRNS;++iLyr) {
184 if (m_thresholdsProp[iLyr].value().size()<iThrOvr) {
185 ATH_MSG_ERROR( "Configuration error: Not enough values in threshold vector for layer " << iLyr );
186 return StatusCode::FAILURE;
187 }
188
189 it->m_threshValue[iLyr]=m_thresholdsProp[iLyr].value()[iThrOvr];
190 }
191 }//end loop over threshold types with per-layer thresholds
192
193
194 //Clean out thresholds with no histogram requested:
195 auto thrIt=m_thresholds.begin();
196 while (thrIt!=m_thresholds.end()) {
197 const threshold_t& thr=*thrIt;
198 if (!(thr.m_doEtaPhiOccupancy || thr.m_doPercentageOccupancy || thr.m_doEtaOccupancy || thr.m_doPhiOccupancy || thr.m_doEtaPhiTotalEnergy ||
199 thr.m_doEtaPhiAverageQuality || thr.m_doEtaPhiFractionOverQth || thr.m_doEtaPhiAverageTime || thr.m_doEtaPhiFractionPastTth)) {
200 ATH_MSG_INFO( "Config issue: Threshold type '" << thr.m_threshName << "' defined but no histograms requested. Deleting." );
201 thrIt=m_thresholds.erase(thrIt);
202 }
203 else {
204 ATH_MSG_INFO("Threshold histograms requested for threshold '" << thrIt->m_threshName << "'");
205 thrIt++;
206 }
207 }
208
209
210 //Fix up histogram titles
211 for (threshold_t& thr : m_thresholds) {
212 if (thr.m_threshDirection!=NONE &&
213 std::count(thr.m_threshTitleTemplate.begin(),thr.m_threshTitleTemplate.end(),'%')==1) {
214 const size_t maxTitleLenght=thr.m_threshTitleTemplate.size()+32;
215 std::unique_ptr<char[]> toBeFilled(new char[maxTitleLenght]);
216
217 for (unsigned iLyrns=0;iLyrns<MAXLYRNS;++iLyrns) {
218 //Attempt to fill in theshold value
219 snprintf(toBeFilled.get(),maxTitleLenght,thr.m_threshTitleTemplate.c_str(),thr.m_threshValue[iLyrns]);
220 toBeFilled[maxTitleLenght-1]='\0'; //To be absolutely sure...
221 thr.m_threshTitles[iLyrns]=toBeFilled.get();
222 //std::cout << "Fixup result:" << thr.m_threshTitles[iLyrns] << std::endl;
223 } //end loop over thresholds
224 } //and if somthing to fix up
225 else {
226 //No threshold value to be set, keep as is
227 for (unsigned iLyrns=0;iLyrns<MAXLYRNS;++iLyrns) {
228 thr.m_threshTitles[iLyrns]=thr.m_threshTitleTemplate;
229 }
230 }
231 }
232
233 return StatusCode::SUCCESS;
234}
235
236
238/*
239StatusCode LArCellMonAlg::bookHistograms() {
240
241 ATH_MSG_INFO("BookHistogram called");
242
243 resetInternals();
244
245
246 ATH_CHECK(bookLarMultThreHists());
247
248
249 ATH_CHECK(bookLarNonThreHists());
250
251 return StatusCode::SUCCESS;
252}
253
254
255
256
257*/
258
259void LArCellMonAlg::checkTriggerAndBeamBackground(bool passBeamBackgroundRemoval, std::vector<threshold_t> &thresholds) const {
260
261 auto mon_trig = Monitored::Scalar<float>("trigType",-1);
262 mon_trig=0.5;
263 fill(m_MonGroupName,mon_trig);
264
265 const ToolHandle<Trig::TrigDecisionTool>& trigTool = getTrigDecisionTool();
266 if (m_useTrigger && !trigTool.empty()) {
267 std::bitset<MAXTRIGTYPE> triggersPassed(0x1<<NOTA); //Last bit: NOTA, always passes
268 constexpr std::bitset<MAXTRIGTYPE> NOTAmask=~(0x1<<NOTA);
269
270 for (unsigned i=0;i<NOTA;++i) {
271 const std::string& chainName=m_triggerNames[i];
272 if(!chainName.empty()) {
273 const Trig::ChainGroup* cg = trigTool->getChainGroup(chainName);
274 if(cg->isPassed()) {
275 triggersPassed.set(i);
276 mon_trig=0.5+i;
277 fill(m_MonGroupName,mon_trig);
278 }
279 }
280 }//end of loop over trigger types
281
282 for (threshold_t& thr : thresholds) { //Loop over thresholds
283 thr.m_threshTriggerDecision=(thr.m_triggersToInclude & triggersPassed).any() && (thr.m_triggersToExclude & triggersPassed & NOTAmask).none();
284 }// end loop over thresholds
285
286 } //end if trigger used
287 else {
288 mon_trig=6.5;
289 fill(m_MonGroupName,mon_trig);
290 }
291 //Note that thr.m_threshTriggerDecision remains in it's default state 'true' if trigger wasn't used
292
293 //Check beam-background removal
294 for (const threshold_t& thr : thresholds) { //Loop over thresholds
295 if (thr.m_threshTriggerDecision && (passBeamBackgroundRemoval || !thr.m_doBeamBackgroundRemoval)) {
296 //The counter of events passing. Will be incremented even if neither trigger nor background removal is requested for this threshold
297 auto eventCounter = Monitored::Scalar<size_t>("eventCounter",thr.m_thrIndex);
298 fill(m_MonGroupName,eventCounter);
299 }
300 }//end loop over thresholds
301 }
302
303/*
304void LArCellMonAlg::sporadicNoiseCandidate(const CaloCell* cell, const LArCellMonAlg::LayerEnum iLyr, const float threshold, const LArOnOffIdMapping* cabling) const {
305
306 const Identifier id=cell->ID();
307 const PartitionEnum part=m_layerEnumtoPartitionEnum[iLyr];
308 ATH_MSG_INFO( "Found sporadic noise candidate cell with id 0x" << std::hex << id.get_identifier32().get_compact() << std::dec << " in " << m_partitionNames[part] );
309
310 SporadicNoiseCell_t& snc=m_sporadicNoiseCells[id];
311 snc.m_counter++;
312 //Note wrt AthenaMP: Counting noisy event is obviously flawed, even for
313 //serial processing as events are scattered over many files
314 //The sporadic-noise histograms here are only an indication, not reproducible
315
316 if (snc.m_counter==m_minSporadicNoiseEventsPerCell && m_counter_sporadic_protc<m_sporadic_protc && m_sporadicPerPartCounter[part] < m_sporadicPlotLimit) {
317 ++m_sporadicPerPartCounter[part];
318 ++m_counter_sporadic_protc;
319 m_h_sporadicHists[part]->Fill(1.0); //FIXME Sounds like nonsense but used in webdisplay config
320 bookNoisyCellHistos(snc,cell->caloDDE(),part,threshold, cabling);
321 }// end if reached m_minSporadicNoiseEventsPerCell and < m_sporadic_protection
322
323 if (snc.m_h_energy) {
324 const float energy=cell->energy();
325 const float quality=cell->quality();
326 snc.m_h_energy->Fill(energy);
327 snc.m_h_quality->Fill(quality);
328 snc.m_h_energyVsLB->Fill(m_lb,energy);
329 }
330
331 return;
332}
333*/
334
335/*
336void LArCellMonAlg::bookNoisyCellHistos(SporadicNoiseCell_t& result, const CaloDetDescrElement* dde,
337 const PartitionEnum part, const float threshold,
338 const LArOnOffIdMapping* cabling) {
339
340 const HWIdentifier onlID=cabling->createSignalChannelID(dde->identify());
341 const int ft = m_LArOnlineIDHelper->feedthrough(onlID);
342 const int slot = m_LArOnlineIDHelper->slot(onlID);
343 const int channel = m_LArOnlineIDHelper->channel(onlID);
344
345
346 std::stringstream hName;
347 hName.precision(2);
348 hName << m_partitionNames[part] << "_FT"<<ft<<"Sl"<<slot<<"Ch"<<channel<<"_(Phi"<<dde->phi()<<"_Eta"<<dde->eta()<<"_sampling" << dde->getLayer() << ")";
349
350 std::stringstream titleSuffix;
351 titleSuffix.precision(0);
352 titleSuffix << "::" << threshold*1e-3 <<"GeV with CSC veto";
353
354 const std::string dir=m_sporadicDir+"/"+m_partitionNames[part];
355
356 //Energy Histogram
357 result.m_h_energy=new TH1F((hName.str()+"_EN").c_str(),
358 (hName.str()+"_EN"+titleSuffix.str()).c_str(),
359 75,-10000,140000); //bins of 2GeV
360 result.m_h_energy->GetXaxis()->SetTitle("MeV");
361 result.m_h_energy->GetYaxis()->SetTitle("Number of Events");
362
363 regHist(result.m_h_energy,dir,run).ignore();
364
365
366 //Quality Histogram (Q: is this actually needed?
367 result.m_h_quality=new TH1F((hName.str()+"_Quality").c_str(),
368 (hName.str()+"_Quality"+titleSuffix.str()).c_str(),
369 75,-10000,140000); //bins of 2GeV
370 result.m_h_quality->GetXaxis()->SetTitle("Quality Factor");
371 result.m_h_quality->GetYaxis()->SetTitle("Number of Events");
372
373 regHist(result.m_h_quality,dir,run).ignore();
374
375 //E vs LB
376 result.m_h_energyVsLB=new TProfile((hName.str()+"_ENLB").c_str(),
377 (hName.str()+"_LB"+titleSuffix.str()).c_str(),
378 1400,0.5,1400.5);
379 result.m_h_energyVsLB->GetXaxis()->SetTitle("LumiBlocks");
380 result.m_h_energyVsLB->GetYaxis()->SetTitle("MeV");
381
382 regHist(result.m_h_energyVsLB,dir,run,ATTRIB_X_VS_LB,"","merge").ignore();
383
384 return;
385}
386*/
387
389 float mon_eta;
390 float mon_phi;
391 float en;
392 float time;
393 uint16_t mon_qual;
397};
398
400StatusCode LArCellMonAlg::fillHistograms(const EventContext& ctx) const{
401
402 ATH_MSG_DEBUG("LArCellMonAlg::fillHistograms() starts");
403
405 const LArOnOffIdMapping* cabling{*cablingHdl};
406 if(!cabling) {
407 ATH_MSG_ERROR( "Do not have cabling");
408 return StatusCode::FAILURE;
409 }
410
411 const LArBadChannelCont* bcCont=nullptr;
414 bcCont=(*bcContHdl);
415 }
416
418 const CaloCellContainer* cellCont = cellHdl.cptr();
419
421 const CaloNoise *noisep = *noiseHdl;
422
423 if (ctx.evt()==0) {
424 ATH_CHECK(createPerJobHistograms(cellCont, noisep));
425 }
426
427 bool ifPass = true;
428 bool passBeamBackgroundRemoval = true;
429 ATH_CHECK(checkFilters(ifPass,passBeamBackgroundRemoval,m_MonGroupName,ctx)); //Check ATLAS-Ready, beam-background, etc from base class
430 //Continue if 'ifpass' set but also if we identified a background event (for the control plot)
431 if(!ifPass and not passBeamBackgroundRemoval==false) {
432 ATH_MSG_DEBUG("Event rejected by filters");
433 return StatusCode::SUCCESS;
434 }
435
436 std::vector<threshold_t> thresholds = m_thresholds;
437
438 checkTriggerAndBeamBackground(passBeamBackgroundRemoval, thresholds);
439
440 //get LB
441 auto lumiBlock = Monitored::Scalar<unsigned int>("lumiBlock",0);
442 lumiBlock = GetEventInfo(ctx)->lumiBlock();
443
445 CaloCellContainer::const_iterator it_e = cellCont->end();
446 // loop over cells -------------
447
448 std::vector<std::vector<std::vector<LArMonValues>>> monValueVec;
449 monValueVec.reserve(m_layerNames.size());
450 for (size_t ilayer = 0; ilayer < m_layerNames.size(); ++ilayer) {
451 monValueVec.emplace_back();
452 monValueVec[ilayer].reserve(thresholds.size());
453 for (size_t ithreshold = 0; ithreshold < thresholds.size(); ++ithreshold) {
454 monValueVec[ilayer].emplace_back();
455 // this could be more intelligent (this is the worst case for #cells in a layer, most are much less)
456 monValueVec[ilayer][ithreshold].reserve(m_layerNcells[ilayer]);
457 }
458 }
459
460 std::vector<std::vector<float>> energies_nocut;
461 energies_nocut.reserve(m_layerNames.size());
462 for (size_t ilayer = 0; ilayer < m_layerNames.size(); ++ilayer) {
463 energies_nocut.emplace_back();
464 energies_nocut[ilayer].reserve(m_layerNcells[ilayer]);
465 }
466
467 for ( ; it!=it_e;++it) {
468 // cell info
469 const CaloCell* cell = *it;
470 Identifier id = cell->ID();
471 bool is_lar=m_calo_id->is_lar(id);
472 const ULong64_t monCellID = id.get_compact();
473
474 if(!is_lar) continue;
475
476 const CaloDetDescrElement* caloDDEl=cell->caloDDE();
477 const IdentifierHash cellHash=caloDDEl->calo_hash();
478
479 const CaloGain::CaloGain gain= cell->gain();
480 const float cellen = cell->energy();
481 const float celltime = cell->time();
482 const uint16_t cellquality = cell->quality();
483 const uint16_t cellprovenance = cell->provenance();
484 const bool celltqavailable = ( cellprovenance & 0x2000 );
485
486 // No more filling if we encounter a bad channel ....
487 if (m_ignoreKnownBadChannels && m_bcMask.cellShouldBeMasked(bcCont,id)) continue;
488
489 // ...or a channel w/o conditions
490 if (m_maskNoCondChannels && (cellprovenance & 0x00FF) != 0x00A5) continue; //FIXME, I think that cut is wrong
491
492 float celleta,cellphi;
493 unsigned iLyr, iLyrNS;
494 getHistoCoordinates(caloDDEl, celleta, cellphi, iLyr, iLyrNS);
495
496 //Start filling per-threshold histograms:
497 auto& lvaluemap = monValueVec[iLyr];
498 for (size_t ithr = 0; ithr < thresholds.size(); ++ithr) {
499 const auto& thr = thresholds[ithr];
500 // for (auto& thr : thresholds) {
501 //std::cout << "Threshold name " << thr.m_threshName << std::endl;
502 //Any of the conditons below means we do not fill the histogram:
503
504 //Trigger passed?
505 if (m_useTrigger && !thr.m_threshTriggerDecision) continue;
506 //std::cout << " Trigger passed" << std::endl;
507
508 //Beam background event?
509 if (thr.m_doBeamBackgroundRemoval && !passBeamBackgroundRemoval) continue;
510
511 //std::cout << " Beam background passed" << std::endl;
512
513 float thresholdVal=thr.m_threshValue[iLyrNS];
514 if (thresholdVal==0) {
515 ATH_MSG_WARNING("Got threshold 0 for type '" << thr.m_threshName << "'for cell in layer " << m_layerNames[iLyr]);
516 }
517
518 if (thr.m_inSigNoise) thresholdVal*=noisep->getNoise(cellHash, gain);
519
520
521 bool passThrCut(true);
522 if (thr.m_threshDirection==OVER && cellen <= thresholdVal) passThrCut=false;
523 if (thr.m_threshDirection==UNDER && cellen > thresholdVal) passThrCut=false;
524 if (thr.m_threshDirection==BOTH && (cellen > -thresholdVal && cellen <= thresholdVal)) passThrCut=false;
525
526
527 bool pass_qual = (cellquality > thr.m_qualityFactorThreshold);
528 bool pass_time = (fabs(celltime) > thr.m_timeThreshold);
529
530 lvaluemap[ithr].push_back({celleta, cellphi, cellen, celltime, cellquality, pass_qual, pass_time, passThrCut});
531
532 if(!passThrCut) continue;
533
534 }//end loop over thresholds
535
536 //some additional monitored objects
537 auto en = Monitored::Scalar<float>("cellEnergy_"+m_layerNames[iLyr],cellen);
538 auto tim = Monitored::Scalar<float>("cellTime_"+m_layerNames[iLyr],celltime);
539 if(passBeamBackgroundRemoval) {
540 // 1D Energy distribution:
541 energies_nocut[iLyr].push_back(cellen);
542 //if (m_h_energy[iLyr]) m_h_energy[iLyr]->Fill(cellen);
543
544 // Time vs Energy:
545 if (m_doEnergyVsTime && celltqavailable && cellquality<4000) {
546 bool passecut = (cellen>m_eCutForTiming[iLyrNS]);
547 auto eGTcut = Monitored::Scalar<float>("enGreaterThanCut_"+m_layerNames[iLyr],passecut);
548 fill(m_MonGroupName,en,tim,eGTcut);
549
550 }
551
552 //Checking for signs of sporadic noise
554 float energyThreshold;
555 //We have two energy thresholds for sporadic noise, one for EM samling 1 and 2 and one for the rest
556 if(iLyrNS==EMB1NS || iLyrNS==EMB2NS || iLyrNS==EMEC1NS || iLyrNS==EMEC2NS) {
557 energyThreshold=m_threshold_em_S0S1;
558 }
559 else {
560 energyThreshold = m_threshold_HECFCALEMS2S3;
561 }
562 if (cellen > energyThreshold) {
563 ATH_MSG_INFO( "Found sporadic noise candidate cell with id 0x" << std::hex << id.get_identifier32().get_compact() << std::dec << " in " << m_partitionNames[m_layerEnumtoPartitionEnum[iLyr]] );
564 auto sporadicCellE = Monitored::Scalar<float>("sporadicCellE",cellen);
565 auto sporadicCellTime = Monitored::Scalar<float>("sporadicCellTime",celltime);
566 auto sporadicCellQuality = Monitored::Scalar<uint16_t>("sporadicCellQuality",cellquality);
567 auto sporadicCellID = Monitored::Scalar<ULong64_t>("sporadicCellID",monCellID);
568 fill(m_MonGroupName,sporadicCellE,sporadicCellTime,sporadicCellQuality,sporadicCellID,lumiBlock);
569 }
570 }//end if m_sporadic_switch
571 } // end if m_passBeamBackgroundRemoval
572 }//end loop over cells
573
574 for (size_t ilayer = 0; ilayer < energies_nocut.size(); ++ilayer) {
575 auto en0 = Monitored::Collection("cellEnergy_nocuts_"+m_layerNames[ilayer],
576 energies_nocut[ilayer]);
577 fill(m_MonGroupName, en0);
578 }
579
580 // fill, for every layer/threshold
581 for (size_t ilayer = 0; ilayer < monValueVec.size(); ++ilayer) {
582 for (size_t ithreshold = 0; ithreshold < monValueVec[ilayer].size(); ++ithreshold) {
583 const auto& tool = monValueVec[ilayer][ithreshold];
584 auto mon_eta = Monitored::Collection("celleta",tool,[](const auto& v){return v.mon_eta;});
585 auto mon_phi = Monitored::Collection("cellphi",tool,[](const auto& v){return v.mon_phi;});
586 auto en = Monitored::Collection("cellEnergy",tool,[](const auto& v){return v.en;});
587 auto mon_qual = Monitored::Collection("cellQuality",tool,[](const auto& v){return v.mon_qual;});
588 auto pass_qual = Monitored::Collection("isPoorQuality",tool,[](const auto& v){return v.pass_qual;});
589 auto tim = Monitored::Collection("cellTime",tool,[](const auto& v){return v.time;});
590 auto pass_time = Monitored::Collection("isLateTime",tool,[](const auto& v){return v.pass_time;});
591 auto passThrCut = Monitored::Collection("passThrCut",tool,[](const auto& v){return v.passThrCut;});
592 fill(m_tools[m_toolmapAll.at(m_layerNames[ilayer]).at(thresholds[ithreshold].m_threshName)],
593 passThrCut, mon_eta, mon_phi, en, mon_qual,
594 pass_qual, tim, pass_time);
595 }
596 }
597
598 ATH_MSG_DEBUG("LArCellMonAlg::fillLarHists() is done");
599 return StatusCode::SUCCESS;
600}
601
602
603StatusCode LArCellMonAlg::createPerJobHistograms(const CaloCellContainer* cellCont, const CaloNoise *noisep ) const {
604
605 ATH_MSG_INFO("Creating the once-per-job histograms");
606 //The following histograms can be considered constants for one job
607 //(in fact, they are constant for an entire run or even run-periode)
608 //ActiveCells in eta/phi (to normalize 1D occupancy plots)
609 //BadChannel word
610 //Database noise
611
612 auto doDatabaseNoisePlot = Monitored::Scalar<bool>("doDatabaseNoisePlot",m_doDatabaseNoiseVsEtaPhi);
613 auto doCellsActiveEtaPlot = Monitored::Scalar<bool>("doCellsActiveEtaPlot",m_doEtaOccupancyNames.size()>0);
614 auto doCellsActivePhiPlot = Monitored::Scalar<bool>("doCellsActivePhiPlot",m_doPhiOccupancyNames.size()>0);
615
616 if(!m_doKnownBadChannelsVsEtaPhi && !doDatabaseNoisePlot && !doCellsActiveEtaPlot && !doCellsActivePhiPlot) {
617 ATH_MSG_INFO("No once-per-job histogram requested");
618 return StatusCode::SUCCESS;
619 }
620
622 const LArBadChannelCont *bcCont {*readHandle};
623 if(m_doKnownBadChannelsVsEtaPhi && !bcCont) {
624 ATH_MSG_WARNING( "Do not have Bad chan container !!!" );
625 return StatusCode::FAILURE;
626 }
627
628 //filling:
629
631 CaloCellContainer::const_iterator it_e = cellCont->end();
632 for ( ; it!=it_e;++it) {
633 const CaloCell* cell = *it;
634 Identifier id = cell->ID();
635 bool is_lar=m_calo_id->is_lar(id);
636 if(!is_lar) continue;
637 const CaloDetDescrElement* caloDDEl=cell->caloDDE();
638 float celleta, cellphi;
639 unsigned iLyr, iLyrNS;
640 getHistoCoordinates(caloDDEl, celleta, cellphi, iLyr, iLyrNS);
641
642 auto mon_eta = Monitored::Scalar<float>("celleta_"+m_layerNames[iLyr],celleta);
643 auto mon_phi = Monitored::Scalar<float>("cellphi_"+m_layerNames[iLyr],cellphi);
644
645 const LArBadChannel larBadChannel = bcCont->offlineStatus(id);
646 auto fillBadChannelPlot = Monitored::Scalar<bool>("fillBadChannelPlot",(m_doKnownBadChannelsVsEtaPhi && (!larBadChannel.good())));
647 auto badCellWord = Monitored::Scalar<uint32_t>("badCellWord_"+m_layerNames[iLyr],larBadChannel.packedData());
648
649 auto cellnoisedb = Monitored::Scalar<float>("cellnoisedb_"+m_layerNames[iLyr],noisep->getNoise(id,cell->gain()));
650
651 fill(m_MonGroupNamePerJob,badCellWord,cellnoisedb,mon_eta,mon_phi,fillBadChannelPlot,doDatabaseNoisePlot,doCellsActiveEtaPlot,doCellsActivePhiPlot);
652 }//end loop over cells
653
654 return StatusCode::SUCCESS;
655}
656
657
658
659std::string LArCellMonAlg::strToLower(const std::string& input) {
660 std::string output;
661 for (const auto& c : input) {
662 output.push_back(std::tolower(c));
663 }
664 return output;
665}
666
667 bool LArCellMonAlg::isThrListed(const std::vector<std::string>& vec, const std::string& s) {
668 return (std::find(vec.begin(),vec.end(),s)!=vec.end());
669 }
670
671
672
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Definition of CaloDetDescrManager.
std::vector< size_t > vec
LArBadXCont< LArBadChannel > LArBadChannelCont
size_t size() const
Number of registered mappings.
Wrapper to avoid constant divisions when using units.
#define x
const ServiceHandle< StoreGateSvc > & detStore() const
const ToolHandle< Trig::TrigDecisionTool > & getTrigDecisionTool() const
Get the trigger decision tool member.
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.
Container class for CaloCell.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
This class groups all DetDescr information related to a CaloCell.
StatusCode checkFilters(bool &ifPass, bool &passBeamBackgroundRemoval, const std::string &MonGroupName, const EventContext &ctx) const
void getHistoCoordinates(const CaloDetDescrElement *dde, float &celleta, float &cellphi, unsigned &iLyr, unsigned &iLyrNS) const
virtual StatusCode initialize() override
initialize
const CaloCell_ID * m_calo_id
float getNoise(const IdentifierHash h, const int gain) const
Accessor by IdentifierHash and gain.
Definition CaloNoise.h:35
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
This is a "hash" representation of an Identifier.
BitWord packedData() const
bool good() const
Returns true if no problems at all (all bits at zero).
LArBC_t offlineStatus(const Identifier id) const
Query the status of a particular channel by offline ID This is the main client access method.
StatusCode createPerJobHistograms(const CaloCellContainer *cellcont, const CaloNoise *noisep) const
std::map< std::string, std::map< std::string, int > > m_toolmapAll
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
BooleanProperty m_doEnergyVsTime
StringArrayProperty m_thresholdNameProp
Gaudi::Property< std::vector< std::string > > m_problemsToMask
BooleanProperty m_useTrigger
const std::array< PartitionEnum, MAXLAYER > m_layerEnumtoPartitionEnum
StatusCode initThresh()
FloatArrayProperty m_timeThresholdProp
BooleanProperty m_doDatabaseNoiseVsEtaPhi
StringArrayProperty m_doEtaOccupancyNames
std::vector< threshold_t > m_thresholds
std::array< FloatArrayProperty, MAXLYRNS > m_thresholdsProp
StringArrayProperty m_doEtaPhiAvgTimeNames
BooleanProperty m_ignoreKnownBadChannels
StringArrayProperty m_doEtaPhiTotalOccupancyNames
BooleanProperty m_doKnownBadChannelsVsEtaPhi
FloatArrayProperty m_eCutForTiming
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
Gaudi::Property< std::string > m_MonGroupNamePerJob
FloatProperty m_threshold_em_S0S1
BooleanArrayProperty m_inSigNoise
StringArrayProperty m_thresholdColumnType
StringArrayProperty m_doEtaPhiAvgQualityNames
virtual StatusCode initialize() override final
initialize
BooleanProperty m_maskNoCondChannels
StringArrayProperty m_doEtaPhiTotEnergyNames
StringArrayProperty m_doEtaPhiFractionPastTthNames
static std::string strToLower(const std::string &input)
LArCellMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
BooleanProperty m_sporadic_switch
StringArrayProperty m_thresholdTitleTemplates
LArBadChannelMask m_bcMask
FloatArrayProperty m_defaultThresholds
StringArrayProperty m_thresholdDirectionProp
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
StringArrayProperty m_triggersToIncludeProp
StringArrayProperty m_doEtaPhiFractionOverQthNames
std::array< StringProperty, NOTA > m_triggerNames
BooleanArrayProperty m_doBeamBackgroundRemovalProp
StringArrayProperty m_layerNames
FloatArrayProperty m_qualityFactorThresholdProp
static bool isThrListed(const std::vector< std::string > &vec, const std::string &s)
SG::ReadCondHandleKey< LArBadChannelCont > m_BCKey
Gaudi::Property< std::string > m_MonGroupName
IntegerArrayProperty m_layerNcells
void checkTriggerAndBeamBackground(bool passBeamBackgroundRemoval, std::vector< threshold_t > &thresholds) const
StringArrayProperty m_partitionNames
SG::ReadHandleKey< CaloCellContainer > m_cellContainerKey
const LArOnlineID * m_LArOnlineIDHelper
StringArrayProperty m_doEtaPhiPercentageOccupancyNames
FloatProperty m_threshold_HECFCALEMS2S3
StringArrayProperty m_doPhiOccupancyNames
StringArrayProperty m_triggersToExcludeProp
Declare a monitored scalar variable.
const_pointer_type cptr()
Dereference the pointer.
bool isPassed(unsigned int condition=TrigDefs::Physics) const
tells if chain group passed
int r
Definition globals.cxx:22
Definition MET.py:1
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.
void fill(H5::Group &out_file, size_t iterations)
MsgStream & msg
Definition testRead.cxx:32