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