ATLAS Offline Software
Loading...
Searching...
No Matches
LArSuperCellMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// NAME: LArSuperCellMonAlg.cxx
6// based on LArCellMonAlg:
7// L. Morvaj, P.Strizenec, D. Oliveira Damazio - develop for Digital Trigger monitoring (2021)
8// ********************************************************************
10
11#include "CaloDetDescr/CaloDetDescrElement.h"
13#include "Identifier/Identifier.h"
17
18//#include "AthenaMonitoring/DQBadLBFilterTool.h"
19//#include "AthenaMonitoring/DQAtlasReadyFilterTool.h"
20
22#include "AthenaKernel/Units.h"
23
25
26#include <cassert>
27#include <algorithm>
28
30LArSuperCellMonAlg::LArSuperCellMonAlg(const std::string& name, ISvcLocator* pSvcLocator)
31 :AthMonitorAlgorithm(name, pSvcLocator),
32 // m_badChannelMask("BadLArRawChannelMask",this),
33 m_calo_id(nullptr)
34{
35}
36
37
38
41
44
45 ATH_MSG_DEBUG("LArSuperCellMonAlg::initialize() start");
46
47
48 //Identfier-helpers
49 ATH_CHECK( detStore()->retrieve(m_calo_id) );
50
51 ATH_CHECK( m_superCellContainerKey.initialize() );
53 ATH_CHECK( m_noiseCDOKey.initialize() );
55
58
59 ATH_MSG_DEBUG("LArSuperCellMonAlg::initialize() is done!");
60
62}
63
64
65
67
68 return StatusCode::SUCCESS;
69}
70
71
73StatusCode LArSuperCellMonAlg::fillHistograms(const EventContext& ctx) const{
74
75 ATH_MSG_DEBUG("LArSuperCellMonAlg::fillHistograms() starts");
76
78 const CaloCellContainer* superCellCont = superCellHdl.cptr();
79 if(!superCellCont){
80 ATH_MSG_ERROR("The requested SC container key " << m_superCellContainerKey.key() << " could not be retrieved. !!!");
81 return StatusCode::SUCCESS;
82 }
83
85 const CaloCellContainer* superCellRefCont = superCellRefHdl.cptr();
86 if(!superCellRefCont){
87 ATH_MSG_ERROR("The requested SC ref container key " << m_superCellContainerRefKey.key() << " could not be retrieved. !!!");
88 return StatusCode::SUCCESS;
89 }
90
91 const CaloCellContainer *superCellRecoCont = nullptr;
92 if(m_doSCReco){
94 if (!hSCetRecoContainer.isValid()) {
95 ATH_MSG_ERROR("The requested SC ET reco container key could not be retrieved. !!!");
96 }else{
97 superCellRecoCont = hSCetRecoContainer.cptr();
98 ATH_MSG_DEBUG("SCetRecoContainer.size() " << hSCetRecoContainer->size());
99 }
100 }
101
102 if (ctx.evt()==0) {
104 const CaloNoise *noisep = *noiseHdl;
105 ATH_CHECK(createPerJobHistograms(superCellCont, noisep));
106 }
107
108 // FIXME: "lumiBlock" is not monitored
109 //auto lumiBlock = Monitored::Scalar<unsigned int>("lumiBlock",0);
110 //lumiBlock = ctx.eventID().lumi_block();
111 // FIXME: "bcid" is not monitored nor used, only bcidFFB is
112 //auto bcid = Monitored::Scalar<unsigned int>("bcid",0);
113 //bcid = ctx.eventID().bunch_crossing_id();
114 unsigned int bcid = ctx.eventID().bunch_crossing_id();
115 int bcidFFB = bcid;
116 if (!m_bcDataKey.empty()){
118 bcid=bccd->distanceFromFront(bcid,BunchCrossingCondData::BunchCrossings);
119 }
120
121 // create local variables to speed up things
122 // per layer
123 std::vector<std::vector<std::string> > nameHistos;
124 for (const auto& layerName : m_layerNames){
125 nameHistos.insert(nameHistos.end(),
126 {"superCellEt_"+layerName,
127 "superCelltime_"+layerName,
128 "superCellprovenance_"+layerName,
129 "superCellEta_"+layerName,
130 "superCellPhi_"+layerName,
131 "resolution_"+layerName,
132 "resolutionPass_"+layerName,
133 "resolutionHET_"+layerName,
134 "superCellEtRef_"+layerName,
135 "superCelltimeRef_"+layerName,
136 "superCellprovenanceRef_"+layerName,
137 "superCellEtDiff_"+layerName});
138 }
139
140
142
143 CaloCellContainer::const_iterator SCit = superCellCont->begin();
144 CaloCellContainer::const_iterator SCit_e = superCellCont->end();
145
146 std::vector<std::reference_wrapper<Monitored::IMonitoredVariable>> variables;
147
148 for ( ; SCit!=SCit_e;++SCit) {
149
150 const CaloCell* superCell = *SCit;
151 variables.clear();
152 // Discard masked cells from monitoring
153 int SCprov = superCell->provenance()&0xFFF;
154 if (m_removeMasked && ((SCprov&0x80)==0x80)) continue;
155 float SCet = superCell->et();
156 const CaloDetDescrElement* SCcaloDDE = superCell->caloDDE();
157 float SCeta,SCphi;
158 unsigned iLyr, iLyrNS;
159 float SCt = superCell->time();
160
161 getHistoCoordinates(SCcaloDDE, SCeta, SCphi, iLyr, iLyrNS);
162
163
164 bool SCpassTime = LArProv::test(SCprov,LArProv::SCTIMEPASS);//SCprov & 0x200;
165 bool SCpassPF = LArProv::test(SCprov,LArProv::SCPASSBCIDMAX);// SCprov & 0x40;
166
167 const CaloCell* superCellRef = superCellRefCont->findCell( SCcaloDDE->identifyHash() );
168 if (not superCellRef){
169 ATH_MSG_WARNING("cell not found in LArSuperCellMonAlg::fillHistograms");
170 continue;
171 }
172 float SCetRef = superCellRef->et();
173 float SCetDiff = SCet - SCetRef;
174 float resolution = -1000;
175 float resolutionPass = -1000;
176 float resolutionHET = -1000;
177 if ( SCetRef > m_thresholdsForResolution) resolution = 100.0*(SCet-SCetRef)/SCetRef;
178 if ( SCpassTime || SCpassPF ) resolutionPass = resolution;
179 if ( SCet > 4e3 ) resolutionHET=resolution;
180
181 // real monitoring business
182 auto MSCet = Monitored::Scalar<float>("superCellEt",SCet);
183 auto MSCt = Monitored::Scalar<float>("superCelltime",SCt);
184 auto MSCprov = Monitored::Scalar<int>("superCellprovenance",SCprov);
185 auto MSCeta = Monitored::Scalar<float>("superCellEta",SCeta);
186 auto MSCphi = Monitored::Scalar<float>("superCellPhi",SCphi);
187 auto MSCres = Monitored::Scalar<float>("resolution",resolution);
188 auto MSCresPass = Monitored::Scalar<float>("resolutionPass",resolutionPass);
189 auto MSCresHET = Monitored::Scalar<float>("resolutionHET",resolutionHET);
190 auto MSCetRef = Monitored::Scalar<float>("superCellEtRef",SCetRef);
191 auto MSCtRef = Monitored::Scalar<float>("superCelltimeRef",superCellRef->time());
192 auto MSCprovRef = Monitored::Scalar<int>("superCellprovenanceRef",(superCellRef->provenance()&0xFFF));
193 auto MSCetDiff = Monitored::Scalar<float>("superCellEtDiff",SCetDiff);
194 // 'push_back' conditional variables one at a time, and 'insert' all other variables in one go
195 if ( SCetRef > m_thresholdsForResolution ) variables.push_back(MSCres);
196 if ( (SCetRef > m_thresholdsForResolution ) && (SCpassTime || SCpassPF ) ) variables.push_back(MSCresPass);
197 if ( (SCetRef > m_thresholdsForResolution ) && (SCet > 4e3 ) ) variables.push_back(MSCresHET);
198
199 // let us put conditional to force building the linearity plot
200 // only when the new signal passes BCID
201
202 // per layer
203 const auto & layerName=m_layerNames[iLyr];
204 auto LMSCet = Monitored::Scalar<float>(nameHistos[iLyr][0],SCet);
205 auto LMSCt = Monitored::Scalar<float>(nameHistos[iLyr][1],SCt);
206 auto LMSCprov = Monitored::Scalar<int>(nameHistos[iLyr][2],SCprov);
207 auto LMSCeta = Monitored::Scalar<float>(nameHistos[iLyr][3],SCeta);
208 auto LMSCphi = Monitored::Scalar<float>(nameHistos[iLyr][4],SCphi);
209 auto LMSCres = Monitored::Scalar<float>(nameHistos[iLyr][5],resolution);
210 auto LMSCresPass = Monitored::Scalar<float>(nameHistos[iLyr][6],resolutionPass);
211 auto LMSCresHET = Monitored::Scalar<float>(nameHistos[iLyr][7],resolutionHET);
212 auto LMSCetRef = Monitored::Scalar<float>(nameHistos[iLyr][8],SCetRef);
213 auto LMSCtRef = Monitored::Scalar<float>(nameHistos[iLyr][9],superCellRef->time());
214 auto LMSCprovRef = Monitored::Scalar<int>(nameHistos[iLyr][10],(superCellRef->provenance()&0xFFF));
215
216 auto MBCIDFFB = Monitored::Scalar<int>("BCID",bcidFFB);
217 auto LMSCetDiff = Monitored::Scalar<float>(nameHistos[iLyr][11],SCetDiff);
218 if ( SCetRef > m_thresholdsForResolution ) variables.push_back(LMSCres);
219 if ( (SCetRef > m_thresholdsForResolution ) && (SCpassTime || SCpassPF ) ) variables.push_back(LMSCresPass);
220 if ( (SCetRef > m_thresholdsForResolution ) && (SCet > 4e3 ) ) variables.push_back(LMSCresHET);
221 if ( SCpassTime || SCpassPF ) variables.push_back(LMSCtRef);
222
223 variables.insert(variables.end(),
224 {MSCet,
225 MSCt,
226 MSCprov,
227 MSCeta,
228 MSCphi,
229 MSCetRef,
230 MSCtRef,
231 MSCprovRef,
232 MSCetDiff,
233 LMSCet,
234 LMSCt,
235 LMSCprov,
236 LMSCeta,
237 LMSCphi,
238 LMSCetRef,
239 LMSCprovRef,
240 MBCIDFFB,
241 LMSCetDiff});
242
243
244 if(m_doSCReco){
245 auto MSCtReco = Monitored::Scalar<float>("superCelltimeReco",0.);
246 auto MSCetReco = Monitored::Scalar<float>("superCellEtReco",0.);
247 auto LMSCtReco = Monitored::Scalar<float>("superCelltimeReco_"+layerName,0.);
248 const CaloCell* superCellReco = superCellRecoCont->findCell( SCcaloDDE->identifyHash() );
249 if(superCellReco) {
250 float SCetReco = superCellReco->et();
251 float SCtimeReco = superCellReco->time();
252 MSCtReco = SCtimeReco;
253 MSCetReco = SCetReco;
254 LMSCtReco = SCtimeReco;
255
256 variables.insert(variables.end(),
257 {MSCtReco,
258 LMSCtReco,
259 MSCetReco});
260 }
261 }
262 fill(m_MonGroupName,variables);
263
264 } // end loop over SC
265
266
267
268 ATH_MSG_DEBUG("LArSuperCellMonAlg::fillLarHists() is done");
269 return StatusCode::SUCCESS;
270}
271
272
273StatusCode LArSuperCellMonAlg::createPerJobHistograms(const CaloCellContainer* cellCont, const CaloNoise *noisep ) const {
274
275 ATH_MSG_INFO("Creating the once-per-job histograms");
276
277 if(!noisep){
278 ATH_MSG_ERROR("Do not have DB noise, doing nothing !!!");
279 return StatusCode::SUCCESS;
280 }
281
282 //The following histograms can be considered constants for one job
283 //(in fact, they are constant for an entire run or even run-periode)
284 //ActiveCells in eta/phi (to normalize 1D occupancy plots)
285 //BadChannel word
286 //Database noise
287
288 auto doDatabaseNoisePlot = Monitored::Scalar<bool>("doDatabaseNoisePlot",m_doDatabaseNoiseVsEtaPhi);
289
290 // if(!doDatabaseNoisePlot && !doCellsActiveEtaPlot && !doCellsActivePhiPlot) {
291 if(!doDatabaseNoisePlot) {
292 ATH_MSG_INFO("No once-per-job histogram requested");
293 return StatusCode::SUCCESS;
294 }
295
296
297 //filling:
298
300 CaloCellContainer::const_iterator it_e = cellCont->end();
301 for ( ; it!=it_e;++it) {
302 const CaloCell* cell = *it;
303 Identifier id = cell->ID();
304 bool is_lar=m_calo_id->is_lar(id);
305 if(!is_lar) continue;
306 const CaloDetDescrElement* caloDDEl=cell->caloDDE();
307 float celleta, cellphi;
308 unsigned iLyr, iLyrNS;
309
310
311 getHistoCoordinates(caloDDEl, celleta, cellphi, iLyr, iLyrNS);
312
313 auto mon_eta = Monitored::Scalar<float>("celleta_"+m_layerNames[iLyr],celleta);
314 auto mon_phi = Monitored::Scalar<float>("cellphi_"+m_layerNames[iLyr],cellphi);
315 auto cellnoisedb = Monitored::Scalar<float>("cellnoisedb_"+m_layerNames[iLyr],noisep->getNoise(id,cell->gain()));
316
317 fill(m_MonGroupName,cellnoisedb,mon_eta,mon_phi);
318
319
320 }//end loop over cells
321
322 return StatusCode::SUCCESS;
323}
324
325
326
327std::string LArSuperCellMonAlg::strToLower(const std::string& input) const {
328 std::string output;
329 for (const auto& c : input) {
330 output.push_back(std::tolower(c));
331 }
332 return output;
333}
334
335
336
337void LArSuperCellMonAlg::getHistoCoordinates(const CaloDetDescrElement* dde, float& celleta, float& cellphi, unsigned& iLyr, unsigned& iLyrNS) const {
338
339 celleta=dde->eta_raw();
340 cellphi=dde->phi_raw();
341
342 int calosample=dde->getSampling();
343 if (dde->is_lar_em_endcap_inner()) calosample-=1; //Here, we consider the two layers of the EMEC IW as EME1 and EME2 instad of layer 2 and 3
344 iLyrNS=m_caloSamplingToLyrNS.at(calosample); //will throw if out of bounds
345 if ((iLyrNS==EMB1NS || iLyrNS==EMB2NS) && m_calo_id->region(dde->identify())==1) {
346 //We are in the awkward region 1 of the EM Barrel
347 //Looking at the image at http://atlas.web.cern.ch/Atlas/GROUPS/LIQARGEXT/TDR/figures6/figure6-17.eps
348 //may be useful to understand what's going on here.
349
350 //In brief: Region 1, layer 1 is closer related ot the middle compartment (aka layer 2)
351 // and region 1, layer 2 closer related to the back compartment (aka layer 3)
352 iLyrNS+=1;
353
354 //Layer 2: 0<eta<1.4 + 1.4<eta<1.475, deta = 0.025. 3 rows of cells from region 1
355 //Layer 3: 0<eta<1.35 (deta=0.050) + 1.4<eta<1.475 (deta = 0.075). 1 row of cell from region 1 with different dEta
356 }
357
358 const unsigned side=(celleta>0) ? 0 : 1; //Value >0 means A-side
359 iLyr=iLyrNS*2+side; //Getting LayerEnum value. This logic works because of the way the enums LayerEnum and LayerEnumNoSides are set up.
360 return;
361}
#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.
Wrapper to avoid constant divisions when using units.
const ServiceHandle< StoreGateSvc > & detStore() const
virtual StatusCode initialize() override
initialize
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
@ BunchCrossings
Distance in units of 25 nanoseconds.
Container class for CaloCell.
const CaloCell * findCell(const IdentifierHash theHash) const
fast find method given identifier hash.
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
float time() const
get time (data member)
Definition CaloCell.h:368
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
uint16_t provenance() const
get provenance (data member)
Definition CaloCell.h:354
virtual double et() const override final
get et
Definition CaloCell.h:423
This class groups all DetDescr information related to a CaloCell.
IdentifierHash identifyHash() const override final
cell subcalo hash same as subcalo_hash(), but kept for backward compatibility
CaloCell_ID::CaloSample getSampling() const
cell sampling
Identifier identify() const override final
cell identifier
bool is_lar_em_endcap_inner() const
cell belongs to the inner wheel of EM end cap
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.
BooleanProperty m_removeMasked
BooleanProperty m_doSCReco
LArSuperCellMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode initialize() override final
initialize
Gaudi::Property< std::string > m_MonGroupName
SG::ReadHandleKey< CaloCellContainer > m_superCellContainerKey
FloatProperty m_thresholdsForResolution
StatusCode createPerJobHistograms(const CaloCellContainer *cellcont, const CaloNoise *noisep) const
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
SG::ReadHandleKey< CaloCellContainer > m_superCellContainerRefKey
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
void getHistoCoordinates(const CaloDetDescrElement *dde, float &celleta, float &cellphi, unsigned &iLyr, unsigned &iLyrNS) const
const std::map< unsigned, LayerEnumNoSides > m_caloSamplingToLyrNS
const CaloCell_ID * m_calo_id
StringArrayProperty m_layerNames
std::string strToLower(const std::string &input) const
SG::ReadHandleKey< CaloCellContainer > m_superCellContainerRecoKey
SG::ReadCondHandleKey< BunchCrossingCondData > m_bcDataKey
Property: Bunch crossing data (MC only) (conditions input).
BooleanProperty m_doDatabaseNoiseVsEtaPhi
Declare a monitored scalar variable.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
bool test(const uint16_t prov, const LArProvenance check)
void fill(H5::Group &out_file, size_t iterations)