ATLAS Offline Software
Loading...
Searching...
No Matches
PixelAthHitMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
9#include "PixelAthHitMonAlg.h"
10#include <stdexcept>
11
12PixelAthHitMonAlg::PixelAthHitMonAlg(const std::string& name, ISvcLocator* pSvcLocator) :
13 AthMonitorAlgorithm(name, pSvcLocator)
14{
15 //jo flags
16 declareProperty("doOnline", m_doOnline = false);
17 declareProperty("doLumiBlock", m_doLumiBlock = false);
18 declareProperty("doLowOccupancy", m_doLowOccupancy = false);
19 declareProperty("doHighOccupancy", m_doHighOccupancy = false);
20 declareProperty("doHeavyIonMon", m_doHeavyIonMon = false);
21 declareProperty("doFEPlots", m_doFEPlots = false);
22}
23
26 ATH_CHECK(m_pixelRDOName.initialize());
27
28 return StatusCode::SUCCESS;
29}
30
31StatusCode PixelAthHitMonAlg::fillHistograms(const EventContext& ctx) const {
32 using namespace Monitored;
33
34 int lb = GetEventInfo(ctx)->lumiBlock();
35 auto lbval = Monitored::Scalar<int>("pixhitsmontool_lb", lb);
36 auto hitGroup = getGroup("Hit");
37
38 unsigned int bcid = GetEventInfo(ctx)->bcid();
39 auto bcidval = Monitored::Scalar<unsigned int>("pixhitsmontool_bcid", bcid);
40 auto rdocontainer = SG::makeHandle(m_pixelRDOName, ctx);
41 if (!(rdocontainer.isValid())) {
42 ATH_MSG_ERROR("Pixel Monitoring: Pixel RDO container " << m_pixelRDOName << " could not be found.");
43 auto dataread_err = Monitored::Scalar<int>("hitdataread_err", DataReadErrors::ContainerInvalid);
44 fill(hitGroup, dataread_err);
45 return StatusCode::RECOVERABLE;
46 } else {
47 ATH_MSG_DEBUG("Pixel Monitoring: Pixel RDO container " << rdocontainer.name() << " is found.");
48 }
49
50 int nhits = 0;
51 float nhits_layer[PixLayers::COUNT] = {
52 0
53 };
54
55 int phiMod(-99);
56 int etaMod(-99);
57 bool copyFEval(false);
58
59 AccumulatorArrays hitsPerEventArray = {{{0}}, {{0}}, {{0}}, {{0}}, {{0}}, {{0}}};
62 // for inactive or bad modules init corresponding arrays entries to -1
63 for (auto idIt = m_pixelid->wafer_begin(); idIt != m_pixelid->wafer_end(); ++idIt) {
64 Identifier waferID = *idIt;
65 IdentifierHash id_hash = m_pixelid->wafer_hash(waferID);
66 int pixlayer = getPixLayersID(m_pixelid->barrel_ec(waferID), m_pixelid->layer_disk(waferID));
67 if (pixlayer == 99) continue;
68 if (isActive( !m_pixelDetElStatusActiveOnly.empty() ? pixel_active.cptr() : nullptr, id_hash) == false) {
69 getPhiEtaMod(waferID, phiMod, etaMod, copyFEval);
70 switch (pixlayer) {
71 case PixLayers::kECA:
72 hitsPerEventArray.DA[phiMod][etaMod] = -1;
73 break;
74
75 case PixLayers::kECC:
76 hitsPerEventArray.DC[phiMod][etaMod] = -1;
77 break;
78
80 hitsPerEventArray.B0[phiMod][etaMod] = -1;
81 break;
82
84 hitsPerEventArray.B1[phiMod][etaMod] = -1;
85 break;
86
88 hitsPerEventArray.B2[phiMod][etaMod] = -1;
89 break;
90
91 case PixLayers::kIBL:
92 hitsPerEventArray.IBL[phiMod][etaMod] = -1;
93 if (copyFEval) hitsPerEventArray.IBL[phiMod][++etaMod] = -1;
94 break;
95 }
96 }
97 }
98
99 int nGood_layer[PixLayers::COUNT] = {
100 0
101 };
102 int nActive_layer[PixLayers::COUNT] = {
103 0
104 };
105 float avgocc_active_layer[PixLayers::COUNT] = {
106 0
107 };
108 float avgocc_good_layer[PixLayers::COUNT] = {
109 0
110 };
111 float avgocc_ratio_toIBL_layer[PixLayers::COUNT] = {
112 0
113 };
114
115 PixelID::const_id_iterator idIt = m_pixelid->wafer_begin();
116 PixelID::const_id_iterator idItEnd = m_pixelid->wafer_end();
117 for (; idIt != idItEnd; ++idIt) {
118 Identifier waferID = *idIt;
119 IdentifierHash modHash = m_pixelid->wafer_hash(waferID);
120 int pixlayer = getPixLayersID(m_pixelid->barrel_ec(waferID), m_pixelid->layer_disk(waferID));
121 if (pixlayer == 99) continue;
122
123 if (pixlayer == PixLayers::kIBL)
124 {
125 // normalization per FE for IBL
126 //
127 int nFE = getNumberOfFEs(pixlayer, m_pixelid->eta_module(waferID));
128 int iblsublayer = (m_pixelid->eta_module(waferID) > -7 && m_pixelid->eta_module(waferID) < 6) ? PixLayers::kIBL2D : PixLayers::kIBL3D;
129 for (int iFE=0; iFE<nFE; iFE++) {
130 Identifier pixID = m_pixelReadout->getPixelIdfromHash(modHash, iFE, 1, 1);
131 if (not pixID.is_valid()) continue;
132 auto [is_active,is_good] = isChipGood( !m_pixelDetElStatusActiveOnly.empty() ? pixel_active.cptr() : nullptr,
133 !m_pixelDetElStatus.empty() ? pixel_status.cptr() : nullptr,
134 modHash, iFE);
135 if (not is_active) continue;
136 nActive_layer[iblsublayer]++;
137 if (is_good) nGood_layer[iblsublayer]++;
138 }
139 }
140 else
141 {
142 // normalization per module for the old pixel layers
143 //
144 bool is_active = isActive( !m_pixelDetElStatusActiveOnly.empty() ? pixel_active.cptr() : nullptr, modHash);
145 bool is_good = isGood( !m_pixelDetElStatus.empty() ? pixel_status.cptr() : nullptr, modHash);
146 if (is_active) {
147 nActive_layer[pixlayer]++;
148 if (is_good) nGood_layer[pixlayer]++;
149 }
150 }
151 }
152
153 const int nChannels_mod[PixLayers::COUNT] = {
154 46080, 46080, 46080, 46080, 46080, 26880, 26880
155 };
156 float nGoodChannels_layer[PixLayers::COUNT];
157 float nActiveChannels_layer[PixLayers::COUNT];
158 for (int i = 0; i < PixLayers::COUNT; i++) {
159 nGoodChannels_layer[i] = 1.0 * nChannels_mod[i] * nGood_layer[i];
160 nActiveChannels_layer[i] = 1.0 * nChannels_mod[i] * nActive_layer[i];
161 }
162
163 //*******************************************************************************
164 //************************** Begin of filling Hit Histograms ********************
165 //*******************************************************************************
166
167 ATH_MSG_DEBUG("Filling Raw Hit (RDO) Monitoring Histograms");
168
169
170 VecAccumulator2DMap HitMap(*this, "HitMap");
171 VecAccumulator2DMap HitFEMap(*this, "HitFEMap");
172 std::vector<int> hitLvl1a;
173 std::unordered_map<int, std::vector<int> > hitLvl1aLayer;
174 std::unordered_map<int, std::vector<int> > hitToTLayer;
175
176 Identifier rdoID;
177
178 for (auto colNext: *rdocontainer) {
179 const InDetRawDataCollection<PixelRDORawData>* HitCollection(colNext);
180 if (!HitCollection) {
181 ATH_MSG_DEBUG("Pixel Monitoring: Pixel Hit container is empty.");
182 auto dataread_err = Monitored::Scalar<int>("hitdataread_err", DataReadErrors::CollectionInvalid);
183 fill(hitGroup, dataread_err);
184 continue;
185 }
186
187 for (auto p_rdo: *HitCollection) {
188 rdoID = p_rdo->identify();
189 int pixlayer = getPixLayersID(m_pixelid->barrel_ec(rdoID), m_pixelid->layer_disk(rdoID));
190 if (pixlayer == 99) continue;
191
192 HitMap.add(pixlayer, rdoID, 1.0);
193 if (m_doFEPlots) HitFEMap.add(pixlayer, rdoID, m_pixelReadout->getFE(rdoID, rdoID), 1.0);
194
195 nhits++;
196 hitLvl1a.push_back(p_rdo->getLVL1A());
197 getPhiEtaMod(rdoID, phiMod, etaMod, copyFEval);
198 switch (pixlayer) {
199 case PixLayers::kECA:
200 hitsPerEventArray.DA[phiMod][etaMod]++;
201 break;
202
203 case PixLayers::kECC:
204 hitsPerEventArray.DC[phiMod][etaMod]++;
205 break;
206
208 hitsPerEventArray.B0[phiMod][etaMod]++;
209 break;
210
212 hitsPerEventArray.B1[phiMod][etaMod]++;
213 break;
214
216 hitsPerEventArray.B2[phiMod][etaMod]++;
217 break;
218
219 case PixLayers::kIBL:
220 hitsPerEventArray.IBL[phiMod][etaMod]++;
221 break;
222 }
223 if (pixlayer == PixLayers::kIBL)
224 {
225 pixlayer = (m_pixelid->eta_module(rdoID) > -7 && m_pixelid->eta_module(rdoID) < 6) ? PixLayers::kIBL2D : PixLayers::kIBL3D;
226 }
227 nhits_layer[pixlayer]++;
228 hitLvl1aLayer[pixlayer].push_back(p_rdo->getLVL1A());
229 hitToTLayer[pixlayer].push_back(p_rdo->getToT());
230 }
231 }
232
233 fill2DProfLayerAccum(HitMap);
234 if (m_doFEPlots) fill2DProfLayerAccum(HitFEMap);
235
236 auto vals = Monitored::Collection("Hit_LVL1A_pixel", hitLvl1a);
237 fill(hitGroup, vals);
238 for (const auto& itr : hitLvl1aLayer) {
239 int layer = itr.first;
240 try {
241 //cppcheck-suppress containerOutOfBounds
242 auto vals = Monitored::Collection("Hit_LVL1A_layer", hitLvl1aLayer.at(layer));
243 fill(pixLayersLabel[layer], vals);
244 } catch (std::out_of_range& e) {
245 ATH_MSG_ERROR("Out of range access in PixelAthHitMonAlg::fillHistograms");
246 }
247 }
248 for (const auto& itr : hitToTLayer) {
249 int layer = itr.first;
250 try {
251 //cppcheck-suppress containerOutOfBounds
252 auto vals = Monitored::Collection("HitToT_val", hitToTLayer.at(layer));
253 fill(pixLayersLabel[layer], vals);
254 } catch (std::out_of_range& e) {
255 ATH_MSG_ERROR("Out of range access in PixelAthHitMonAlg::fillHistograms");
256 }
257 }
258
259
260 auto nhitsval = Monitored::Scalar<int>("nhits_per_event", nhits);
261 fill(hitGroup, lbval, nhitsval);
262 fill1DProfLumiLayers("HitsPerLumi", lb, nhits_layer);
263
264 fillFromArrays("HitOccupancyPP0", hitsPerEventArray, "OccupancyPerPixelEvent");
265
266 for (int i = 0; i < PixLayers::COUNT; i++) {
267 if (nGoodChannels_layer[i] > 0) avgocc_good_layer[i] = nhits_layer[i] / nGoodChannels_layer[i];
268 auto val = Monitored::Scalar<float>("AvgOccPerBCID_val", avgocc_good_layer[i]);
269 fill(pixLayersLabel[i], bcidval, val);
270 if (nActiveChannels_layer[i] > 0) avgocc_active_layer[i] = nhits_layer[i] / nActiveChannels_layer[i];
271 }
272 fill1DProfLumiLayers("AvgOccActivePerLumi", lb, avgocc_active_layer);
273 fill1DProfLumiLayers("AvgOccGoodPerLumi", lb, avgocc_good_layer);
274
275
276 float nGoodChannels_ibl = nGoodChannels_layer[PixLayers::kIBL2D] + nGoodChannels_layer[PixLayers::kIBL3D];
277 float avgocc_good_ibl(0);
278 if (nGoodChannels_ibl>0) avgocc_good_ibl = (nhits_layer[PixLayers::kIBL2D] + nhits_layer[PixLayers::kIBL3D])/nGoodChannels_ibl;
279 if (avgocc_good_ibl > 0) {
280 for (int i = 0; i < PixLayers::COUNT; i++) {
281 avgocc_ratio_toIBL_layer[i] = avgocc_good_layer[i] / avgocc_good_ibl;
282 }
283 fill1DProfLumiLayers("AvgOccRatioToIBLPerLumi", lb, avgocc_ratio_toIBL_layer);
284 }
285
286 if (nhits == 0) {
287 auto dataread_err = Monitored::Scalar<int>("hitdataread_err", DataReadErrors::EmptyContainer);
288 fill(hitGroup, dataread_err);
289 }
290 //*******************************************************************************
291 //************************** End of filling Hit Histograms **********************
292 //*******************************************************************************
293
294 return StatusCode::SUCCESS;
295}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_DEBUG(x)
const std::string pixLayersLabel[PixLayers::COUNT]
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
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.
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
Declare a monitored scalar variable.
PixelAthHitMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< PixelRDO_Container > m_pixelRDOName
virtual StatusCode initialize() override
initialize
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
void fill2DProfLayerAccum(const VecAccumulator2DMap &accumulator) const
take VecAccumulator2DMap and fill the corresponding group
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_pixelDetElStatusActiveOnly
Optional read handle to get status data to test whether a pixel detector element is active.
int getNumberOfFEs(int pixlayer, int etaMod) const
helper function to get number of FEs per module
void getPhiEtaMod(Identifier &id, int &phiMod, int &etaMod, bool &copyFE) const
helper function to get eta phi coordinates of per-layer arrays
ServiceHandle< InDetDD::IPixelReadoutManager > m_pixelReadout
bool isGood(const InDet::SiDetectorElementStatus *element_status, const IdentifierHash &module_hash) const
void fill1DProfLumiLayers(const std::string &prof1Dname, int lb, float *weights, int nlayers=PixLayers::COUNT) const
filling 1DProf per-lumi per-layer histograms ["ECA","ECC","BLayer","Layer1","Layer2",...
int getPixLayersID(int ec, int ld) const
helper function to get layers ID
std::tuple< bool, bool > isChipGood(const IdentifierHash &module_hash, unsigned int chip_i) const
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_pixelDetElStatus
Optional read handle to get status data to test whether a pixel detector element is good.
bool isActive(const InDet::SiDetectorElementStatus *element_status, const IdentifierHash &module_hash) const
void fillFromArrays(const std::string &namePP0, AccumulatorArrays &pixarrays, const std::string &name2DMap="") const
filling 1DProfile per-pp0(ROD) histograms for ["ECA","ECC","BLayer","Layer1","Layer2",...
SG::ReadHandle< InDet::SiDetectorElementStatus > getPixelDetElStatus(const SG::ReadHandleKey< InDet::SiDetectorElementStatus > &key, const EventContext &ctx) const
virtual StatusCode initialize() override
initialize
std::vector< Identifier >::const_iterator const_id_iterator
Definition PixelID.h:72
const_pointer_type cptr()
Dereference the pointer.
int lb
Definition globals.cxx:23
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable > > &&variables) const
Fills a vector of variables to a group by reference.
Generic monitoring tool for athena components.
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())