ATLAS Offline Software
Loading...
Searching...
No Matches
SCTErrMonAlg.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#include "SCTErrMonAlg.h"
6
11
12using namespace SCT_Monitoring;
13
14SCTErrMonAlg::SCTErrMonAlg(const std::string& name, ISvcLocator* pSvcLocator)
15 :AthMonitorAlgorithm(name,pSvcLocator){
16 for (int reg{0}; reg<N_REGIONS_INC_GENERAL; reg++) {
17 m_nMaskedLinks[reg] = 0;
18 }
19}
20
22 ATH_CHECK(detStore()->retrieve(m_pSCTHelper, "SCT_ID"));
25 if (m_useDCS) ATH_CHECK(m_dcsTool.retrieve());
26 else m_dcsTool.disable();
27 ATH_CHECK(m_pSummaryTool.retrieve());
28 ATH_CHECK(m_flaggedTool.retrieve());
29 ATH_CHECK(m_atlasReadyFilter.retrieve());
30 // Retrieve geometrical information
31 const InDetDD::SCT_DetectorManager* sctManager{nullptr};
32 ATH_CHECK(detStore()->retrieve(sctManager, "SCT"));
33 const unsigned int maxHash{static_cast<unsigned int>(m_pSCTHelper->wafer_hash_max())}; // 8176
34 moduleGeo_t moduleGeo; // dummy value
35 m_geo.resize(maxHash, moduleGeo);
36 double rz{0.};
37 const double deltaZ{0.};
38 for (unsigned int i{0}; i<maxHash; i++) {
39 IdentifierHash hash{i};
40 const InDetDD::SiDetectorElement* newElement{sctManager->getDetectorElement(hash)};
41 newElement->getEtaPhiRegion(deltaZ,
42 moduleGeo.first.first, moduleGeo.first.second,
43 moduleGeo.second.first, moduleGeo.second.second,
44 rz);
45 m_geo[i] = moduleGeo;
46 }
47
49}
50
51StatusCode SCTErrMonAlg::fillHistograms(const EventContext& ctx) const {
53 if (not pEvent.isValid()) {
54 ATH_MSG_WARNING("Could not retrieve event info!");
55 return StatusCode::SUCCESS;
56 }
57
58 bool sctFlag{false};
59 if (pEvent->errorState(xAOD::EventInfo::SCT) == xAOD::EventInfo::Error) {
60 sctFlag = true;
61 }
64 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
65 auto is1DAcc{Monitored::Scalar<bool>("is1D", true)};
66 auto sctFlagAcc{Monitored::Scalar<bool>("sctFlag", sctFlag)};
67 fill("SCTErrMonitor", lumiBlockAcc, is1DAcc, sctFlagAcc);
68
69 // Check wafers with many fired strips (event dependent) using SCT_FlaggedConditionTool.
70 std::array<int, N_REGIONS_INC_GENERAL> flaggedWafersIndices
72 std::array<int, N_REGIONS_INC_GENERAL> nFlaggedWafers{};
73 nFlaggedWafers.fill(0);
74 const unsigned int wafer_hash_max{static_cast<unsigned int>(m_pSCTHelper->wafer_hash_max())};
75 for (unsigned int iHash{0}; iHash<wafer_hash_max; iHash++) {
76 const IdentifierHash hash{iHash};
77 if (not m_flaggedTool->isGood(hash, ctx)) {
78 const Identifier wafer_id{m_pSCTHelper->wafer_id(hash)};
79 const unsigned barrel_ec{bec2Index(m_pSCTHelper->barrel_ec(wafer_id))};
80 nFlaggedWafers[barrel_ec]++;
81 nFlaggedWafers[GENERAL_INDEX]++;
82 }
83 }
84 auto flaggedWwafersIndicesAcc{Monitored::Collection("flaggedWafersIndices", flaggedWafersIndices)};
85 auto nFlaggedWafersAcc{Monitored::Collection("nFlaggedWafers", nFlaggedWafers)};
86 fill("SCTErrMonitor", flaggedWwafersIndicesAcc, nFlaggedWafersAcc);
87
88 if (sctFlag) {
89 return StatusCode::SUCCESS;
90 }
91
92 // The numbers of disabled modules, links, strips do not change during a run.
93 { //scope for lock
94 std::lock_guard<std::mutex> glock{m_mutex};
98 }
99 }
100
102
104 // TODO: fill only at the end of a LB
105 if (m_makeConfHisto) {
106 int moduleOut{0};
107 SCT_ID::const_id_iterator waferIterator{m_pSCTHelper->wafer_begin()};
108 SCT_ID::const_id_iterator waferEnd{m_pSCTHelper->wafer_end()};
109 const std::string errMonName{"SCTErrMonitor"};
110 for (; waferIterator not_eq waferEnd; ++waferIterator) {
111 Identifier waferId{*waferIterator};
112 int layer{m_pSCTHelper->layer_disk(waferId)};
113 int side{m_pSCTHelper->side(waferId)};
114 int eta{m_pSCTHelper->eta_module(waferId)};
115 int phi{m_pSCTHelper->phi_module(waferId)};
116 int barrel_ec{m_pSCTHelper->barrel_ec(waferId)};
117
118 int reg{BARREL_INDEX};
119 if (barrel_ec == ENDCAP_A) reg = ENDCAP_A_INDEX;
120 if (barrel_ec == ENDCAP_C) reg = ENDCAP_C_INDEX;
121
122 int IN{m_configurationTool->isGood(waferId, ctx, InDetConditions::SCT_SIDE) ? 0 : 1};
123 if (m_pSCTHelper->side(waferId) == 0) { // Use only side 0 to check module level
124 if (IN == 1) {
125 moduleOut++;
126 auto mEtaAcc{Monitored::Scalar<int>("eta_out", eta)};
127 auto mPhiAcc{Monitored::Scalar<int>("phi_out", phi)};
128 auto mOutAcc{Monitored::Scalar<int>(std::string("modulemap")+subDetNameShort[reg].Data()+std::to_string(layer)+"_"+std::to_string(side), IN)};
129 fill(errMonName, mEtaAcc, mPhiAcc, mOutAcc);
130 }
131 }
132 }
133 auto moduleOutBinAcc{Monitored::Scalar<int>("moduleOutBin", 0)};
134 auto moduleOutAcc{Monitored::Scalar<int>("moduleOut", moduleOut)};
135 fill(errMonName, moduleOutBinAcc, moduleOutAcc);
136 }
137
138 return StatusCode::SUCCESS;
139}
140
141StatusCode
144 std::array<int, N_REGIONS_INC_GENERAL> maskedLinksBin{ENDCAP_C_INDEX, BARREL_INDEX, ENDCAP_A_INDEX, GENERAL_INDEX};
145 auto maskedLinksBinAcc{Monitored::Collection("maskedLinksBin", maskedLinksBin)};
146 auto maskedLinksAcc{Monitored::Collection("maskedLinks", m_nMaskedLinks)};
147 fill("SCTErrMonitor", maskedLinksBinAcc, maskedLinksAcc);
148
149 return StatusCode::SUCCESS;
150}
151
152StatusCode
153SCTErrMonAlg::fillConfigurationDetails(const EventContext& ctx) const {
154 ATH_MSG_DEBUG("Inside fillConfigurationDetails()");
155 unsigned int nBadMods{static_cast<unsigned int>(m_configurationTool->badModules(ctx)->size())}; // bad modules
156 const std::map<IdentifierHash, std::pair<bool, bool>>* badLinks{m_configurationTool->badLinks(ctx)}; // bad links
157 unsigned int nBadLink0{0}, nBadLink1{0}, nBadLinkBoth{0};
158 for (const std::pair<const IdentifierHash, std::pair<bool, bool>>& link: *badLinks) {
159 std::pair<bool, bool> status{link.second};
160 if ((status.first == false) and (status.second == true)) {
161 ++nBadLink0;
162 }
163 if ((status.first == true) and (status.second == false)) {
164 ++nBadLink1;
165 }
166 if ((status.first == false) and (status.second == false)) {
167 ++nBadLinkBoth;
168 }
169 }
170
171 const std::map<Identifier, unsigned int>* badChips{m_configurationTool->badChips(ctx)}; // bad chips
172 unsigned int nBadChips{0};
173 for (const std::pair<const Identifier, unsigned int>& chip : *badChips) {
174 unsigned int status{chip.second};
175 for (unsigned int i{0}; i < CHIPS_PER_MODULE; i++) {
176 nBadChips += ((status & (1 << i)) == 0 ? 0 : 1);
177 }
178 }
179
180 std::set<Identifier> badStripsAll; // bad strips
181 m_configurationTool->badStrips(badStripsAll, ctx);
182 unsigned int nBadStrips{static_cast<unsigned int>(badStripsAll.size())};
183
184 std::set<Identifier> badStripsExclusive; // bad strips w/o bad modules and chips
185 m_configurationTool->badStrips(badStripsExclusive, ctx, true, true);
186 int nBadStripsExclusive{static_cast<int>(badStripsExclusive.size())};
187 int nBadStripsExclusiveBEC[N_REGIONS] = {
188 0, 0, 0
189 };
190 for (const Identifier& strip: badStripsExclusive) {
191 int bec{m_pSCTHelper->barrel_ec(strip)};
192 nBadStripsExclusiveBEC[bec2Index(bec)] += 1;
193 }
194
196 std::vector<int> vDetailedConfBin(ConfbinsDetailed);
197 std::vector<double> vNBad(ConfbinsDetailed);
198 for (unsigned int i{0}; i<ConfbinsDetailed; i++) {
199 vDetailedConfBin[i] = i;
200 if (i==0) vNBad[i] = nBadMods;
201 else if (i==1) vNBad[i] = nBadLink0;
202 else if (i==2) vNBad[i] = nBadLink1;
203 else if (i==3) vNBad[i] = nBadChips;
204 else if (i==4) vNBad[i] = static_cast<double>(nBadStripsExclusive) / 100.;
205 }
206 auto detailedConfBinAcc{Monitored::Collection("detailedConfBin", vDetailedConfBin)};
207 auto nBadAcc{Monitored::Collection("nBad", vNBad)};
208 fill("SCTErrMonitor", detailedConfBinAcc, nBadAcc);
209
210 ATH_MSG_DEBUG("-----------------------------------------------------------------------");
211 ATH_MSG_DEBUG("Number of bad modules = " << nBadMods);
212 ATH_MSG_DEBUG("Number of bad link 0 = " << nBadLink0);
213 ATH_MSG_DEBUG("Number of bad link 1 = " << nBadLink1);
214 ATH_MSG_DEBUG("Number of bad link both = " << nBadLinkBoth);
215 ATH_MSG_DEBUG("Number of bad chips = " << nBadChips);
216 ATH_MSG_DEBUG("Number of bad strips = " << nBadStrips);
217 ATH_MSG_DEBUG("Number of bad strips exclusive = " << nBadStripsExclusive);
218 ATH_MSG_DEBUG("Number of bad strips exclusive (ECC, B, ECA) = "
219 << nBadStripsExclusiveBEC[ENDCAP_C_INDEX] << ", "
220 << nBadStripsExclusiveBEC[BARREL_INDEX] << ", "
221 << nBadStripsExclusiveBEC[ENDCAP_A_INDEX] << ", ");
222 ATH_MSG_DEBUG("-----------------------------------------------------------------------");
223
224 return StatusCode::SUCCESS;
225}
226
227StatusCode
228SCTErrMonAlg::fillByteStreamErrors(const EventContext& ctx) const {
230 if (not pEvent.isValid()) {
231 ATH_MSG_WARNING("Could not retrieve event info!");
232 return StatusCode::SUCCESS;
233 }
234
235 //--- Fill 1D histograms (vs LumiBlock) for each BS
236 for (int errType{0}; errType < SCT_ByteStreamErrors::NUM_ERROR_TYPES; ++errType) {
237 int nBSErrors{0};
238 // get number of BS errors
239 numByteStreamErrors(m_byteStreamErrTool->getErrorSet(errType, ctx), nBSErrors);
241 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
242 auto nBSErrorsAcc{Monitored::Scalar<int>("n_"+SCT_ByteStreamErrors::ErrorTypeDescription[errType], nBSErrors)};
243 fill("SCTErrMonitor", lumiBlockAcc, nBSErrorsAcc);
244 }
245 //Total stack use for this function is 1'623'676 bytes.
246 //coverity[STACK_USE]
247 categoryErrorMap_t categoryErrorMap;
248 std::array<int, N_REGIONS_INC_GENERAL> nMaskedLinks{};
249 nMaskedLinks.fill(0);
250 for (int errType{0}; errType < SCT_ByteStreamErrors::NUM_ERROR_TYPES; ++errType) {
251 fillByteStreamErrorsHelper(m_byteStreamErrTool->getErrorSet(errType, ctx), errType, categoryErrorMap, nMaskedLinks);
252 }
253 for (int reg{0}; reg<N_REGIONS_INC_GENERAL; reg++) {
254 m_nMaskedLinks[reg] = nMaskedLinks[reg];
255 }
257 std::vector<int> vEta;
258 std::vector<int> vPhi;
259 std::vector<bool> vHasError;
260 for (int errCate{0}; errCate < CategoryErrors::N_ERRCATEGORY; ++errCate) {
261 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
262 auto nCategoryErrorsAcc{Monitored::Scalar<int>("n_"+CategoryErrorsNames[errCate],
263 categoryErrorMap.count(errCate))};
264 fill("SCTErrMonitor", lumiBlockAcc, nCategoryErrorsAcc);
265
266 for (int iReg{0}; iReg<N_REGIONS; iReg++) {
267 const int maxLayer{iReg==BARREL_INDEX ? N_BARRELSx2 : N_ENDCAPSx2};
268 const int firstEta{iReg==BARREL_INDEX ? FIRST_ETA_BIN : FIRST_ETA_BIN_EC};
269 const int lastEta{iReg==BARREL_INDEX ? LAST_ETA_BIN : LAST_ETA_BIN_EC};
270 const int firstPhi{iReg==BARREL_INDEX ? FIRST_PHI_BIN : FIRST_PHI_BIN_EC};
271 const int lastPhi{iReg==BARREL_INDEX ? LAST_PHI_BIN : LAST_PHI_BIN_EC};
272 const size_t size{static_cast<size_t>((lastEta-firstEta+1)*(lastPhi-firstPhi+1))};
273 for (int iLay{0}; iLay<maxLayer; iLay++) {
274 vEta.resize(size);
275 vPhi.resize(size);
276 vHasError.resize(size);
277 for (int eta{firstEta}; eta<=lastEta; eta++) {
278 const int iEta{eta-firstEta};
279 for (int phi{firstPhi}; phi<=lastPhi; phi++) {
280 const int iPhi{phi-firstPhi};
281 size_t index{static_cast<size_t>(iEta*(lastPhi-firstPhi+1)+iPhi)};
282 vEta[index] = eta;
283 vPhi[index] = phi;
284 vHasError[index] = categoryErrorMap[errCate][iReg][iLay][iEta][iPhi];
285 }
286 }
287 auto etaAcc{Monitored::Collection("eta", vEta)};
288 auto phiAcc{Monitored::Collection("phi", vPhi)};
289 auto hasErrorAcc{Monitored::Collection("hasError_"+CategoryErrorsNames[errCate]+"_"+subDetNameShort[iReg].Data()+"_"+std::to_string(iLay/2)+"_"+std::to_string(iLay%2),
290 vHasError)};
291 fill("SCTErrMonitor", etaAcc, phiAcc, hasErrorAcc);
292
293 if (m_doOnline and CategoryErrorsNames[errCate] == "Errors"){
294 auto hasErrorRecentAcc{Monitored::Collection("hasError_"+CategoryErrorsNames[errCate]+"_recent_"+subDetNameShort[iReg].Data()+"_"+std::to_string(iLay/2)+"_"+std::to_string(iLay%2),vHasError)};
295 fill("SCTErrMonitor", etaAcc, phiAcc, hasErrorRecentAcc);
296 }
297 }
298 }
299 }
300
301 //coverity[DEADCODE]
302 bool doCoverage = false;
303 {
304 std::lock_guard<std::mutex> lock(m_mutex);
305 if (not (m_procLB.find(pEvent->lumiBlock()) != m_procLB.end() and m_coverageCheckOnlyFirtsEventOfLB) ) {
306 m_procLB.insert(pEvent->lumiBlock());
307 doCoverage = m_coverageCheck;
308 }
309 }
310
311 // Coverage check is time consuming and run at the first event of each lumi block.
312 if (doCoverage) {
313 ATH_MSG_DEBUG("Detector Coverage calculation starts" );
314
315 static const std::string names[numberOfProblemForCoverage] = {
316 "SCT_AllRegion", // All
317 "SCT_MapOfDisabledLinks", // Disabled
318 "SCT_MapOfLinksWithBadLinkLevelErrors", // BadLinkLevelError
319 "SCT_MapOfLinksWithBadRODLevelErrors", // BadRODLevelError
320 "SCT_MapOfLinksWithBadErrors", // BadError
321 "SCT_MapOfLinksWithPSTrip", // PSTrip (DCS)
322 "SCT_MapOfLinksWithAnyProbelm" // Summary
323 };
324 static const std::string titles[numberOfProblemForCoverage] = {
325 "Map of All Region", // All
326 "Map of Disabled Links", // Disabled
327 "Map of Links with bad LinkLevelErrors", // BadLinkLevelError
328 "Map of Links with Bad RODLevelErrors", // BadRODLevelError
329 "Map of Links with Bad Errors", // BadError
330 "Map of Links Affected by PS Trip", // PSTrip (DCS)
331 "Map of Links with Any Bad Problem" // Summary
332 };
333
334 std::lock_guard<std::mutex> lock{m_mutex};
335 CacheEntry* ent{m_cache.get(ctx)};
336 if (ent->m_evt!=ctx.evt()) { // New event in this slot
337 if (ent->m_mapSCT.empty()) { // First event
338 for (int iProblem{0}; iProblem<numberOfProblemForCoverage; iProblem++) {
339 ent->m_mapSCT.emplace_back(names[iProblem].c_str(), titles[iProblem].c_str(),
341 ent->m_mapSCT[iProblem].GetXaxis()->SetTitle("#eta");
342 ent->m_mapSCT[iProblem].GetYaxis()->SetTitle("#phi");
343 }
344 } else {
345 for (int iProblem{0}; iProblem<numberOfProblemForCoverage; iProblem++) {
346 ent->m_mapSCT[iProblem].Reset(); // Initialize histograms every event
347 }
348 }
349 ent->m_evt = ctx.evt();
350 }
351
352 std::set<IdentifierHash> sctHash[numberOfProblemForCoverage]{{}};
353 disabledSCT(ctx, sctHash[disabled]);
354 errorSCT(sctHash[badLinkError], sctHash[badRODError], sctHash[badError]);
355 summarySCT(sctHash[allRegion], sctHash[summary]);
356 float psTripModules{0.};
357 psTripDCSSCT(ctx, sctHash[psTripDCS], psTripModules);
358
359 sctHash[summary].clear();
360 sctHash[summary].insert(sctHash[disabled].begin(),sctHash[disabled].end()); // disabled
361 sctHash[summary].insert(sctHash[badError].begin(),sctHash[badError].end()); // bad error = bad link error + bad rod error
362 sctHash[summary].insert(sctHash[psTripDCS].begin(),sctHash[psTripDCS].end()); // pstrip
363
364 for (int iProblem{0}; iProblem<numberOfProblemForCoverage; iProblem++) {
365 for (const IdentifierHash& hash: sctHash[iProblem]) {
366 fillWafer(m_geo[hash], ent->m_mapSCT[iProblem]);
367 }
368
369 if (iProblem==allRegion) continue;
370
371 double detector_coverage{calculateDetectorCoverage(ent->m_mapSCT[iProblem], ent->m_mapSCT[allRegion])};
373 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
374 auto detectorCoverageAcc{Monitored::Scalar<double>("detectorCoverage"+coverageVarNames[iProblem], detector_coverage)};
375 fill("SCTErrMonitor", lumiBlockAcc, detectorCoverageAcc);
376
377 if (iProblem==summary) {
378 auto detectorCoverageR4PAcc{Monitored::Scalar<double>("detectorCoverage"+coverageVarNames[iProblem]+"InR4P", detector_coverage)};
379 bool atlasReady = m_atlasReadyFilter->accept(ctx);
380 if(atlasReady) {
381 fill("SCTErrMonitor", lumiBlockAcc, detectorCoverageR4PAcc);
382 }
383 }
384 }
385
387 // Modules affected by PS Tirp
388 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
389 auto psTripModulesAcc{Monitored::Scalar<int>("psTripModules", psTripModules)};
390 fill("SCTErrMonitor", lumiBlockAcc, psTripModulesAcc);
391
392 }
393
394 return StatusCode::SUCCESS;
395}
396
397int
398SCTErrMonAlg::fillByteStreamErrorsHelper(const std::set<IdentifierHash>& errors,
399 int err_type,
400 categoryErrorMap_t& categoryErrorMap,
401 std::array<int, N_REGIONS_INC_GENERAL>& nMaskedLinks) const {
402 //--- Check categories of the BS error
403 std::array<bool, CategoryErrors::N_ERRCATEGORY> b_category{};
404 b_category.fill(false);
405
406 // Error summaries
408 (err_type == SCT_ByteStreamErrors::MaskedLink) or (err_type == SCT_ByteStreamErrors::MaskedROD);
409
410 b_category[CategoryErrors::SUMMARY] = true;
411
412 b_category[CategoryErrors::BADERR] = false;
414 if (err_type == tmpBadError) {
415 b_category[CategoryErrors::BADERR] = true;
416 break;
417 }
418 }
419
420 b_category[CategoryErrors::LINKLEVEL] = false;
422 if (err_type == linkLevelError) {
423 b_category[CategoryErrors::LINKLEVEL] = true;
424 break;
425 }
426 }
427
428 b_category[CategoryErrors::RODLEVEL] = false;
430 if (err_type == rodLevelError) {
431 b_category[CategoryErrors::RODLEVEL] = true;
432 break;
433 }
434 }
435
436 b_category[CategoryErrors::MASKEDCHIP] =
437 (err_type == SCT_ByteStreamErrors::TempMaskedChip0) or (err_type == SCT_ByteStreamErrors::TempMaskedChip1) or
438 (err_type == SCT_ByteStreamErrors::TempMaskedChip2) or (err_type == SCT_ByteStreamErrors::TempMaskedChip3) or
439 (err_type == SCT_ByteStreamErrors::TempMaskedChip4) or (err_type == SCT_ByteStreamErrors::TempMaskedChip5);
440
441 // Each error
442 b_category[CategoryErrors::BYTESTREAMPARSEERROR] = (err_type == SCT_ByteStreamErrors::ByteStreamParseError);
443 b_category[CategoryErrors::TIMEOUTERROR] = (err_type == SCT_ByteStreamErrors::TimeOutError);
444 b_category[CategoryErrors::BCIDERROR] = (err_type == SCT_ByteStreamErrors::BCIDError);
445 b_category[CategoryErrors::LVL1IDERROR] = (err_type == SCT_ByteStreamErrors::LVL1IDError);
446 b_category[CategoryErrors::PREAMBLEERROR] = (err_type == SCT_ByteStreamErrors::PreambleError);
447 b_category[CategoryErrors::FORMATTERERROR] = (err_type == SCT_ByteStreamErrors::FormatterError);
448 b_category[CategoryErrors::TRAILERERROR] = (err_type == SCT_ByteStreamErrors::TrailerError);
449 b_category[CategoryErrors::TRAILEROVERFLOWERROR] = (err_type == SCT_ByteStreamErrors::TrailerOverflowError);
450 b_category[CategoryErrors::HEADERTRAILERLIMITERROR] = (err_type == SCT_ByteStreamErrors::HeaderTrailerLimitError);
451 b_category[CategoryErrors::ABCDERROR] = (err_type == SCT_ByteStreamErrors::ABCDError);
452 b_category[CategoryErrors::RAWERROR] = (err_type == SCT_ByteStreamErrors::RawError);
453 b_category[CategoryErrors::MASKEDLINK] = (err_type == SCT_ByteStreamErrors::MaskedLink);
454 b_category[CategoryErrors::RODCLOCKERROR] = (err_type == SCT_ByteStreamErrors::RODClockError);
455 b_category[CategoryErrors::TRUNCATEDROD] = (err_type == SCT_ByteStreamErrors::TruncatedROD);
456 b_category[CategoryErrors::ROBFRAGMENTERROR] = (err_type == SCT_ByteStreamErrors::ROBFragmentError);
457 b_category[CategoryErrors::MISSINGLINKHEADERERROR] = (err_type == SCT_ByteStreamErrors::MissingLinkHeaderError);
458 b_category[CategoryErrors::MASKEDROD] = (err_type == SCT_ByteStreamErrors::MaskedROD);
459 b_category[CategoryErrors::ABCDERROR_CHIP0] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip0);
460 b_category[CategoryErrors::ABCDERROR_CHIP1] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip1);
461 b_category[CategoryErrors::ABCDERROR_CHIP2] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip2);
462 b_category[CategoryErrors::ABCDERROR_CHIP3] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip3);
463 b_category[CategoryErrors::ABCDERROR_CHIP4] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip4);
464 b_category[CategoryErrors::ABCDERROR_CHIP5] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip5);
465 b_category[CategoryErrors::ABCDERROR_ERROR1] = (err_type == SCT_ByteStreamErrors::ABCDError_Error1);
466 b_category[CategoryErrors::ABCDERROR_ERROR2] = (err_type == SCT_ByteStreamErrors::ABCDError_Error2);
467 b_category[CategoryErrors::ABCDERROR_ERROR4] = (err_type == SCT_ByteStreamErrors::ABCDError_Error4);
468 b_category[CategoryErrors::TEMPMASKEDCHIP0] = (err_type == SCT_ByteStreamErrors::TempMaskedChip0);
469 b_category[CategoryErrors::TEMPMASKEDCHIP1] = (err_type == SCT_ByteStreamErrors::TempMaskedChip1);
470 b_category[CategoryErrors::TEMPMASKEDCHIP2] = (err_type == SCT_ByteStreamErrors::TempMaskedChip2);
471 b_category[CategoryErrors::TEMPMASKEDCHIP3] = (err_type == SCT_ByteStreamErrors::TempMaskedChip3);
472 b_category[CategoryErrors::TEMPMASKEDCHIP4] = (err_type == SCT_ByteStreamErrors::TempMaskedChip4);
473 b_category[CategoryErrors::TEMPMASKEDCHIP5] = (err_type == SCT_ByteStreamErrors::TempMaskedChip5);
474 b_category[CategoryErrors::ABCDERROR_ERROR7] = (err_type == SCT_ByteStreamErrors::ABCDError_Error7);
475 b_category[CategoryErrors::ABCDERROR_INVALID] = (err_type == SCT_ByteStreamErrors::ABCDError_Invalid);
476 b_category[CategoryErrors::RODSIMULATEDDATA] = (err_type == SCT_ByteStreamErrors::RODSimulatedData);
477
478 std::array<std::vector<int>,N_REGIONS> numErrorsPerLumi;
479 if (m_doPerLumiErrors) {
480 for (int reg{0}; reg<N_REGIONS; reg++) {
481 const int nLayers{n_layers[reg]*2};
482 numErrorsPerLumi[reg].resize(nLayers, 0);
483 }
484 }
485
486 //--- Count BS errors
487 int nerrors{0};
488 for (const auto& hash: errors) {
489 nerrors++;
490 if (not hash.is_valid()) continue;
491
492 //--- FIll module information with BS error
493 const Identifier fitId{m_pSCTHelper->wafer_id(hash)};
494 int layer{m_pSCTHelper->layer_disk(fitId)};
495 int side{m_pSCTHelper->side(fitId)};
496 int barrel_ec{m_pSCTHelper->barrel_ec(fitId)};
497 int ieta{m_pSCTHelper->eta_module(fitId)};
498 int iphi{m_pSCTHelper->phi_module(fitId)};
499 layer = layer * 2 + side;
500 // barrel_ec = {ENDCAP_C=-2, BARREL=0, ENDCAP_A=2}
501 // -> regionIndex = {ENDCAP_C_INDEX=0, BARREL_INDEX=1, ENDCAP_A_INDEX=2, GENERAL_INDEX=3}
502 int regionIndex{GENERAL_INDEX};
503 if ((barrel_ec == BARREL) and (layer >= 0) and (layer < N_BARRELSx2)) regionIndex = BARREL_INDEX;
504 else if (barrel_ec == ENDCAP_A) regionIndex = ENDCAP_A_INDEX;
505 else if (barrel_ec == ENDCAP_C) regionIndex = ENDCAP_C_INDEX;
506
507 // Take into account offsets
508 ieta -= ((regionIndex==BARREL_INDEX) ? FIRST_ETA_BIN : FIRST_ETA_BIN_EC);
509 iphi -= ((regionIndex==BARREL_INDEX) ? FIRST_PHI_BIN : FIRST_PHI_BIN_EC);
510
511 if (b_category[CategoryErrors::MASKEDLINKALL]) {
512 nMaskedLinks[GENERAL_INDEX]++;
513 if (regionIndex!=GENERAL_INDEX) {
514 nMaskedLinks[regionIndex]++;
515 }
516 }
517
518 if (m_doPerLumiErrors) numErrorsPerLumi.at(regionIndex)[layer]++;
519
520 for (int errCate{0}; errCate < CategoryErrors::N_ERRCATEGORY; ++errCate) {
521 if (b_category[errCate] and regionIndex!=GENERAL_INDEX) {
522 categoryErrorMap[errCate][regionIndex][layer][ieta][iphi] = true;
523 }
524 }
525 }
526
527 if (m_doPerLumiErrors) {
528 std::size_t size{static_cast<size_t>(N_REGIONS*n_layers[ENDCAP_C_INDEX]*N_SIDES)};
529 std::vector<int> vErrorType;
530 std::vector<int> vLayerSide;
531 std::vector<float> vErrorFraction;
532 std::vector<bool> vIsEC;
533 std::vector<bool> vIsB;
534 std::vector<bool> vIsEA;
535 vErrorType.reserve(size);
536 vLayerSide.reserve(size);
537 vErrorFraction.reserve(size);
538 vIsEC.reserve(size);
539 vIsB.reserve(size);
540 vIsEA.reserve(size);
541 for (int reg{0}; reg<N_REGIONS; reg++) {
542 const int nLayers{n_layers[reg]*N_SIDES};
543 for (int layerSide{0}; layerSide<nLayers; layerSide++) {
544 float num_modules{static_cast<float>(getNumModules(index2Bec(reg), layerSide))};
545 if (num_modules==0.) continue;
546 vErrorType.push_back(err_type);
547 vLayerSide.push_back(layerSide);
548 vErrorFraction.push_back(static_cast<float>(numErrorsPerLumi[reg][layerSide])/num_modules);
549 vIsEC.push_back(reg==ENDCAP_C_INDEX);
550 vIsB.push_back(reg==BARREL_INDEX);
551 vIsEA.push_back(reg==ENDCAP_A_INDEX);
552 }
553 }
555 auto errorTypeAcc{Monitored::Collection("errorType", vErrorType)};
556 auto layerSideAcc{Monitored::Collection("layerSide", vLayerSide)};
557 auto errorFractionAcc{Monitored::Collection("errorFraction", vErrorFraction)};
558 auto isECAcc{Monitored::Collection("isEC", vIsEC)};
559 auto isBAcc{Monitored::Collection("isB", vIsB)};
560 auto isEAAcc{Monitored::Collection("isEA", vIsEA)};
561 fill("SCTErrMonitor", errorTypeAcc, layerSideAcc, errorFractionAcc, isECAcc, isBAcc, isEAAcc);
562 }
563
564 if (b_category[CategoryErrors::SUMMARY]) return nerrors;
565 return 0;
566}
567
568void
569SCTErrMonAlg::numByteStreamErrors(const std::set<IdentifierHash>& errors, int& ntot) const {
570 for (const auto& fit: errors) {
571 if (fit.is_valid()) {
572 ntot++;
573 }
574 }
575}
576
577bool SCTErrMonAlg::disabledSCT(const EventContext& ctx, std::set<IdentifierHash>& sctHashDisabled) const {
578 bool altered{false};
579 sctHashDisabled.clear();
580 const std::set<Identifier>* badModules{m_configurationTool->badModules(ctx)};
581
582 for (const Identifier& badModule: *badModules) {
583 altered = true;
584 IdentifierHash hashSide0{m_pSCTHelper->wafer_hash(badModule)};
585 IdentifierHash hashSide1;
586 m_pSCTHelper->get_other_side(hashSide0, hashSide1);
587 sctHashDisabled.insert(hashSide0);
588 sctHashDisabled.insert(hashSide1);
589 }
590 return altered;
591}
592
593bool SCTErrMonAlg::errorSCT(std::set<IdentifierHash>& sctHashBadLinkError,
594 std::set<IdentifierHash>& sctHashBadRODError,
595 std::set<IdentifierHash>& sctHashBadError) const {
596 sctHashBadLinkError.clear();
597 sctHashBadRODError.clear();
598 sctHashBadError.clear();
599 const EventContext& ctx{Gaudi::Hive::currentContext()};
600 //BadLinkLevelError
602 const std::set<IdentifierHash> sctErrors{m_byteStreamErrTool->getErrorSet( linkLevelBadErrors, ctx )};
603 for (const IdentifierHash& waferHash : sctErrors) {
604 sctHashBadLinkError.insert(waferHash);
605 }
606 }
607
608 //BadRODLevelError
610 const std::set<IdentifierHash> sctErrors{m_byteStreamErrTool->getErrorSet( RodLevelBadErrors, ctx )};
611 for (const IdentifierHash& waferHash : sctErrors) {
612 sctHashBadRODError.insert(waferHash);
613 }
614 }
615
616 //BadError = BadLinkLevelError + BadRODLevelError
618 const std::set<IdentifierHash> sctErrors{m_byteStreamErrTool->getErrorSet( tmpBadError, ctx )};
619 for (const IdentifierHash& waferHash : sctErrors) {
620 sctHashBadError.insert(waferHash);
621 }
622 }
623 return true;
624}
625
626// Total (SCT_ConditionsSummaryTool)
627bool SCTErrMonAlg::summarySCT(std::set<IdentifierHash>& sctHashAll, std::set<IdentifierHash>& sctHashSummary) const {
628 bool altered{false};
629 sctHashAll.clear();//All
630 sctHashSummary.clear();
631
632 const EventContext& ctx{Gaudi::Hive::currentContext()};
633
634 const unsigned int maxHash{static_cast<unsigned int>(m_pSCTHelper->wafer_hash_max())}; // 8176
635 for (unsigned int i{0}; i<maxHash; i++) {
636 IdentifierHash hash{i};
637 sctHashAll.insert(hash);//All
638 if (not m_pSummaryTool->isGood(hash, ctx)) {
639 sctHashSummary.insert(hash);
640 }
641 }
642 return altered;
643}
644
645// Power supply trip (SCT_DCSConditionsTool)
646bool SCTErrMonAlg::psTripDCSSCT(const EventContext& ctx, std::set<IdentifierHash>& sctHashPSTripDCS, float& psTripModules) const {
647 bool altered{false};
648 sctHashPSTripDCS.clear();
649
650 const unsigned int maxHash{static_cast<unsigned int>(m_pSCTHelper->wafer_hash_max())}; // 8176
651 int npsw{0};
652 for (unsigned int i{0}; i<maxHash; i++) {
653 IdentifierHash hash{i};
654 if (m_useDCS and (not m_dcsTool->isGood(hash, ctx))) {
655 npsw++; //Counting the number of PS sides
656 altered = true;
657 sctHashPSTripDCS.insert(hash);
658 }
659 }
660 psTripModules = npsw/2.;
661 return altered;
662}
663
664void SCTErrMonAlg::fillWafer(moduleGeo_t module, TH2F& histo) const {
665 double etaMin{module.first.first}, etaMax{module.first.second};
666 double phiMin{module.second.first}, phiMax{module.second.second};
667 unsigned int nRep{1};
668 if (etaMin<-s_rangeEta) { etaMin = -s_rangeEta; }
669 if (etaMax> s_rangeEta) { etaMax = s_rangeEta; }
670 if (phiMin>phiMax) {
671 phiMin = -M_PI;
672 nRep=2;
673 }
674 for (unsigned int iRep{0}; iRep<nRep; iRep++) {
675 if (iRep==1) {
676 phiMin = module.second.first;
677 phiMax = M_PI;
678 }
679 const int ixMin{static_cast<int>((etaMin/s_rangeEta+1.)*s_nBinsEta/2)+1};
680 const int ixMax{static_cast<int>((etaMax/s_rangeEta+1.)*s_nBinsEta/2)};
681 const int iyMin{static_cast<int>((phiMin/M_PI+1.)*s_nBinsPhi/2)+1};
682 const int iyMax{static_cast<int>((phiMax/M_PI+1.)*s_nBinsPhi/2)};
683 const double xMin{(static_cast<double>(ixMin)/s_nBinsEta*2-1.)*s_rangeEta};
684 const double xMax{(static_cast<double>(ixMax)/s_nBinsEta*2-1.)*s_rangeEta};
685 const double yMin{(static_cast<double>(iyMin)/s_nBinsPhi*2-1.)*M_PI};
686 const double yMax{(static_cast<double>(iyMax)/s_nBinsPhi*2-1.)*M_PI};
687 const double wxMin{(xMin-etaMin)/s_rangeEta*s_nBinsEta/2};
688 const double wxMax{(etaMax-xMax)/s_rangeEta*s_nBinsEta/2};
689 const double wxOne{(etaMax-etaMin)/s_rangeEta*s_nBinsEta/2};
690 const double wyMin{(yMin-phiMin)/M_PI*s_nBinsPhi/2};
691 const double wyMax{(phiMax-yMax)/M_PI*s_nBinsPhi/2};
692 const double wyOne{(phiMax-phiMin)/M_PI*s_nBinsPhi/2};
693 for (int ix{ixMin}; ix<=ixMax+1; ix++) {
694 double weightx{1.};
695 if (ixMin==ixMax+1) weightx = wxOne;
696 else if (ix==ixMin) weightx = wxMin;
697 else if (ix==ixMax+1) weightx = wxMax;
698 for (int iy{iyMin}; iy<=iyMax+1; iy++) {
699 double weight{weightx};
700 if (iyMin==iyMax+1) weight *= wyOne;
701 else if (iy==iyMin) weight *= wyMin;
702 else if (iy==iyMax+1) weight *= wyMax;
703 histo.SetBinContent(ix, iy, histo.GetBinContent(ix,iy)+weight); //Fill(ix, iy, weight);//
704 }
705 }
706 }
707 return;
708}
709
710double SCTErrMonAlg::calculateDetectorCoverage(const TH2F& histo, const TH2F& histoAll) const {
711 double occupancy{0.};
712
713 for (unsigned int i{0}; i < s_nBinsEta; i++) {
714 for (unsigned int j{0}; j < s_nBinsPhi; j++) {
715 double waferCell{histoAll.GetBinContent(i+1, j+1) - histo.GetBinContent(i+1, j+1)};
716
717 if (waferCell >= s_wafersThreshold) {
718 occupancy += 1.0;
719 } else if (waferCell > s_wafersThreshold - 1.0 ) {
720 occupancy += waferCell - (s_wafersThreshold - 1.0);
721 //Calculating the bin occupancy which has less than 1.
722 //For example, bin have a 2.3. In this case, we can understand that 30% of the bin is coverd by 3 sides/wafers and 70% of the bin is coverd by 2 sides/wafers.
723 //And it means that occupancy of the bin is 0.3 So, in this line, I take difference between s_wafersThreshold(3)-1 and waferCell, and add it to the occupancy.
724 }
725 }
726 }
727 double detector_coverage{100. * occupancy / ( static_cast<double>( s_nBinsEta ) * static_cast<double>( s_nBinsPhi ) )};
728 return detector_coverage;
729}
730
731const unsigned int SCTErrMonAlg::s_nBinsEta = 100;
732const double SCTErrMonAlg::s_rangeEta = 2.5;
733const unsigned int SCTErrMonAlg::s_nBinsPhi = 100;
734const double SCTErrMonAlg::s_wafersThreshold = 4.0;
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
@ Data
Definition BaseObject.h:11
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
static Double_t rz
This is an Identifier helper class for the SCT subdetector.
Handle class for reading from StoreGate.
size_t size() const
Number of registered mappings.
const ServiceHandle< StoreGateSvc > & detStore() const
virtual StatusCode initialize() override
initialize
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
SG::ReadHandleKey< xAOD::EventInfo > m_EventInfoKey
Key for retrieving EventInfo from StoreGate.
This is a "hash" representation of an Identifier.
Dedicated detector manager extending the functionality of the SiDetectorManager with dedicated SCT in...
virtual const SiDetectorElement * getDetectorElement(const Identifier &id) const override
access to individual elements via Identifier
Class to hold geometrical description of a silicon detector element.
void getEtaPhiRegion(double deltaZ, double &etaMin, double &etaMax, double &phiMin, double &phiMax, double &rz) const
Method for building up region of interest table.
Declare a monitored scalar variable.
void fillWafer(moduleGeo_t module, TH2F &histo) const
std::atomic_bool m_isFirstConfigurationDetails
bool errorSCT(std::set< IdentifierHash > &sctHashBadLinkError, std::set< IdentifierHash > &sctHashBadRODError, std::set< IdentifierHash > &sctHashBadError) const
int fillByteStreamErrorsHelper(const std::set< IdentifierHash > &errors, int err_type, categoryErrorMap_t &categoryErrorMap, std::array< int, SCT_Monitoring::N_REGIONS_INC_GENERAL > &nMaskedLinks) const
Used in fillByteStreamErrors().
ToolHandle< ISCT_ByteStreamErrorsTool > m_byteStreamErrTool
StatusCode fillByteStreamErrors(const EventContext &ctx) const
StatusCode fillConfigurationDetails(const EventContext &ctx) const
Used in fillHistograms().
BooleanProperty m_coverageCheck
ToolHandle< IInDetConditionsTool > m_pSummaryTool
BooleanProperty m_useDCS
double calculateDetectorCoverage(const TH2F &histo, const TH2F &histoAll) const
ToolHandle< IDQFilterTool > m_atlasReadyFilter
virtual StatusCode initialize() override final
initialize
static const double s_wafersThreshold
bool summarySCT(std::set< IdentifierHash > &sctHashAll, std::set< IdentifierHash > &sctHashSummary) const
SCTErrMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
ToolHandle< ISCT_DCSConditionsTool > m_dcsTool
bool disabledSCT(const EventContext &ctx, std::set< IdentifierHash > &sctHashDisabled) const
static const double s_rangeEta
static const unsigned int s_nBinsPhi
BooleanProperty m_doOnline
std::mutex m_mutex
BooleanProperty m_makeConfHisto
bool psTripDCSSCT(const EventContext &ctx, std::set< IdentifierHash > &sctHashPSTripDCS, float &PSTripModules) const
ToolHandle< ISCT_ConfigurationConditionsTool > m_configurationTool
BooleanProperty m_doPerLumiErrors
virtual StatusCode stop() override final
std::pair< std::pair< double, double >, std::pair< double, double > > moduleGeo_t
std::vector< moduleGeo_t > m_geo
BooleanProperty m_coverageCheckOnlyFirtsEventOfLB
ToolHandle< ISCT_FlaggedConditionTool > m_flaggedTool
void numByteStreamErrors(const std::set< IdentifierHash > &errors, int &ntot) const
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
const SCT_ID * m_pSCTHelper
static const unsigned int s_nBinsEta
std::vector< Identifier >::const_iterator const_id_iterator
Definition SCT_ID.h:73
virtual bool isValid() override final
Can the handle be successfully dereferenced?
@ Error
The sub-detector issued an error.
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
ErrorType
SCT byte stream error type enums used in SCT_RodDecoder, SCT_ByteStreamErrorsTool,...
static const std::vector< ErrorType > RodLevelBadErrors
Bad error enums in ROD level used in SCTErrMonAlg.
static const std::vector< std::string > ErrorTypeDescription
SCT byte stream error type strings used in SCTErrMonAlg.
static const std::vector< ErrorType > BadErrors
Bad error enums used in SCT_ByteStreamErrorsTool and SCTErrMonAlg.
static const std::vector< ErrorType > LinkLevelErrors
Error enums in FE-link level used in SCTErrMonAlg (assigned by SCT_RodDecoder::addSingleError).
static const std::vector< ErrorType > RodLevelErrors
Error enums in ROD level used in SCTErrMonAlg (assigned by SCT_RodDecoder::addRODError).
static const std::vector< ErrorType > LinkLevelBadErrors
Bad error enums in FE-link level used in SCTErrMonAlg.
static const std::vector< std::string > coverageVarNames
unsigned int bec2Index(const int becVal)
Conversion bec->index.
int getNumModules(const int reg, const int layer)
Bec index2Bec(const unsigned int i)
Conversion index->bec.
static const std::vector< TString > subDetNameShort
static const std::vector< std::string > CategoryErrorsNames
static const std::vector< int > n_layers
Definition index.py:1
void fill(H5::Group &out_file, size_t iterations)