ATLAS Offline Software
Loading...
Searching...
No Matches
SCTErrMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 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)) {
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 for (; waferIterator not_eq waferEnd; ++waferIterator) {
110 Identifier waferId{*waferIterator};
111 int layer{m_pSCTHelper->layer_disk(waferId)};
112 int side{m_pSCTHelper->side(waferId)};
113 int eta{m_pSCTHelper->eta_module(waferId)};
114 int phi{m_pSCTHelper->phi_module(waferId)};
115 int barrel_ec{m_pSCTHelper->barrel_ec(waferId)};
116
117 int reg{BARREL_INDEX};
118 if (barrel_ec == ENDCAP_A) reg = ENDCAP_A_INDEX;
119 if (barrel_ec == ENDCAP_C) reg = ENDCAP_C_INDEX;
120
121 int IN{m_configurationTool->isGood(waferId, InDetConditions::SCT_SIDE) ? 0 : 1};
122 if (m_pSCTHelper->side(waferId) == 0) { // Use only side 0 to check module level
123 if (IN == 1) {
124 moduleOut++;
125 auto mEtaAcc{Monitored::Scalar<int>("eta_out", eta)};
126 auto mPhiAcc{Monitored::Scalar<int>("phi_out", phi)};
127 auto mOutAcc{Monitored::Scalar<int>(std::string("modulemap")+subDetNameShort[reg].Data()+std::to_string(layer)+"_"+std::to_string(side), IN)};
128 fill("SCTErrMonitor", mEtaAcc, mPhiAcc, mOutAcc);
129 }
130 }
131 }
132 auto moduleOutBinAcc{Monitored::Scalar<int>("moduleOutBin", 0)};
133 auto moduleOutAcc{Monitored::Scalar<int>("moduleOut", moduleOut)};
134 fill("SCTErrMonitor", moduleOutBinAcc, moduleOutAcc);
135 }
136
137 return StatusCode::SUCCESS;
138}
139
140StatusCode
143 std::array<int, N_REGIONS_INC_GENERAL> maskedLinksBin{ENDCAP_C_INDEX, BARREL_INDEX, ENDCAP_A_INDEX, GENERAL_INDEX};
144 auto maskedLinksBinAcc{Monitored::Collection("maskedLinksBin", maskedLinksBin)};
145 auto maskedLinksAcc{Monitored::Collection("maskedLinks", m_nMaskedLinks)};
146 fill("SCTErrMonitor", maskedLinksBinAcc, maskedLinksAcc);
147
148 return StatusCode::SUCCESS;
149}
150
151StatusCode
152SCTErrMonAlg::fillConfigurationDetails(const EventContext& ctx) const {
153 ATH_MSG_DEBUG("Inside fillConfigurationDetails()");
154 unsigned int nBadMods{static_cast<unsigned int>(m_configurationTool->badModules()->size())}; // bad modules
155 const std::map<IdentifierHash, std::pair<bool, bool>>* badLinks{m_configurationTool->badLinks(ctx)}; // bad links
156 unsigned int nBadLink0{0}, nBadLink1{0}, nBadLinkBoth{0};
157 for (const std::pair<const IdentifierHash, std::pair<bool, bool>>& link: *badLinks) {
158 std::pair<bool, bool> status{link.second};
159 if ((status.first == false) and (status.second == true)) {
160 ++nBadLink0;
161 }
162 if ((status.first == true) and (status.second == false)) {
163 ++nBadLink1;
164 }
165 if ((status.first == false) and (status.second == false)) {
166 ++nBadLinkBoth;
167 }
168 }
169
170 const std::map<Identifier, unsigned int>* badChips{m_configurationTool->badChips(ctx)}; // bad chips
171 unsigned int nBadChips{0};
172 for (const std::pair<const Identifier, unsigned int>& chip : *badChips) {
173 unsigned int status{chip.second};
174 for (unsigned int i{0}; i < CHIPS_PER_MODULE; i++) {
175 nBadChips += ((status & (1 << i)) == 0 ? 0 : 1);
176 }
177 }
178
179 std::set<Identifier> badStripsAll; // bad strips
180 m_configurationTool->badStrips(badStripsAll, ctx);
181 unsigned int nBadStrips{static_cast<unsigned int>(badStripsAll.size())};
182
183 std::set<Identifier> badStripsExclusive; // bad strips w/o bad modules and chips
184 m_configurationTool->badStrips(badStripsExclusive, ctx, true, true);
185 int nBadStripsExclusive{static_cast<int>(badStripsExclusive.size())};
186 int nBadStripsExclusiveBEC[N_REGIONS] = {
187 0, 0, 0
188 };
189 for (const Identifier& strip: badStripsExclusive) {
190 int bec{m_pSCTHelper->barrel_ec(strip)};
191 nBadStripsExclusiveBEC[bec2Index(bec)] += 1;
192 }
193
195 std::vector<int> vDetailedConfBin(ConfbinsDetailed);
196 std::vector<double> vNBad(ConfbinsDetailed);
197 for (unsigned int i{0}; i<ConfbinsDetailed; i++) {
198 vDetailedConfBin[i] = i;
199 if (i==0) vNBad[i] = nBadMods;
200 else if (i==1) vNBad[i] = nBadLink0;
201 else if (i==2) vNBad[i] = nBadLink1;
202 else if (i==3) vNBad[i] = nBadChips;
203 else if (i==4) vNBad[i] = static_cast<double>(nBadStripsExclusive) / 100.;
204 }
205 auto detailedConfBinAcc{Monitored::Collection("detailedConfBin", vDetailedConfBin)};
206 auto nBadAcc{Monitored::Collection("nBad", vNBad)};
207 fill("SCTErrMonitor", detailedConfBinAcc, nBadAcc);
208
209 ATH_MSG_DEBUG("-----------------------------------------------------------------------");
210 ATH_MSG_DEBUG("Number of bad modules = " << nBadMods);
211 ATH_MSG_DEBUG("Number of bad link 0 = " << nBadLink0);
212 ATH_MSG_DEBUG("Number of bad link 1 = " << nBadLink1);
213 ATH_MSG_DEBUG("Number of bad link both = " << nBadLinkBoth);
214 ATH_MSG_DEBUG("Number of bad chips = " << nBadChips);
215 ATH_MSG_DEBUG("Number of bad strips = " << nBadStrips);
216 ATH_MSG_DEBUG("Number of bad strips exclusive = " << nBadStripsExclusive);
217 ATH_MSG_DEBUG("Number of bad strips exclusive (ECC, B, ECA) = "
218 << nBadStripsExclusiveBEC[ENDCAP_C_INDEX] << ", "
219 << nBadStripsExclusiveBEC[BARREL_INDEX] << ", "
220 << nBadStripsExclusiveBEC[ENDCAP_A_INDEX] << ", ");
221 ATH_MSG_DEBUG("-----------------------------------------------------------------------");
222
223 return StatusCode::SUCCESS;
224}
225
226StatusCode
227SCTErrMonAlg::fillByteStreamErrors(const EventContext& ctx) const {
229 if (not pEvent.isValid()) {
230 ATH_MSG_WARNING("Could not retrieve event info!");
231 return StatusCode::SUCCESS;
232 }
233
234 //--- Fill 1D histograms (vs LumiBlock) for each BS
235 for (int errType{0}; errType < SCT_ByteStreamErrors::NUM_ERROR_TYPES; ++errType) {
236 int nBSErrors{0};
237 // get number of BS errors
238 numByteStreamErrors(m_byteStreamErrTool->getErrorSet(errType, ctx), nBSErrors);
240 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
241 auto nBSErrorsAcc{Monitored::Scalar<int>("n_"+SCT_ByteStreamErrors::ErrorTypeDescription[errType], nBSErrors)};
242 fill("SCTErrMonitor", lumiBlockAcc, nBSErrorsAcc);
243 }
244
245 categoryErrorMap_t categoryErrorMap;
246 std::array<int, N_REGIONS_INC_GENERAL> nMaskedLinks{};
247 nMaskedLinks.fill(0);
248 for (int errType{0}; errType < SCT_ByteStreamErrors::NUM_ERROR_TYPES; ++errType) {
249 fillByteStreamErrorsHelper(m_byteStreamErrTool->getErrorSet(errType, ctx), errType, categoryErrorMap, nMaskedLinks);
250 }
251 for (int reg{0}; reg<N_REGIONS_INC_GENERAL; reg++) {
252 m_nMaskedLinks[reg] = nMaskedLinks[reg];
253 }
255 std::vector<int> vEta;
256 std::vector<int> vPhi;
257 std::vector<bool> vHasError;
258 for (int errCate{0}; errCate < CategoryErrors::N_ERRCATEGORY; ++errCate) {
259 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
260 auto nCategoryErrorsAcc{Monitored::Scalar<int>("n_"+CategoryErrorsNames[errCate],
261 categoryErrorMap.count(errCate))};
262 fill("SCTErrMonitor", lumiBlockAcc, nCategoryErrorsAcc);
263
264 for (int iReg{0}; iReg<N_REGIONS; iReg++) {
265 const int maxLayer{iReg==BARREL_INDEX ? N_BARRELSx2 : N_ENDCAPSx2};
266 const int firstEta{iReg==BARREL_INDEX ? FIRST_ETA_BIN : FIRST_ETA_BIN_EC};
267 const int lastEta{iReg==BARREL_INDEX ? LAST_ETA_BIN : LAST_ETA_BIN_EC};
268 const int firstPhi{iReg==BARREL_INDEX ? FIRST_PHI_BIN : FIRST_PHI_BIN_EC};
269 const int lastPhi{iReg==BARREL_INDEX ? LAST_PHI_BIN : LAST_PHI_BIN_EC};
270 const size_t size{static_cast<size_t>((lastEta-firstEta+1)*(lastPhi-firstPhi+1))};
271 for (int iLay{0}; iLay<maxLayer; iLay++) {
272 vEta.resize(size);
273 vPhi.resize(size);
274 vHasError.resize(size);
275 for (int eta{firstEta}; eta<=lastEta; eta++) {
276 const int iEta{eta-firstEta};
277 for (int phi{firstPhi}; phi<=lastPhi; phi++) {
278 const int iPhi{phi-firstPhi};
279 size_t index{static_cast<size_t>(iEta*(lastPhi-firstPhi+1)+iPhi)};
280 vEta[index] = eta;
281 vPhi[index] = phi;
282 vHasError[index] = categoryErrorMap[errCate][iReg][iLay][iEta][iPhi];
283 }
284 }
285 auto etaAcc{Monitored::Collection("eta", vEta)};
286 auto phiAcc{Monitored::Collection("phi", vPhi)};
287 auto hasErrorAcc{Monitored::Collection("hasError_"+CategoryErrorsNames[errCate]+"_"+subDetNameShort[iReg].Data()+"_"+std::to_string(iLay/2)+"_"+std::to_string(iLay%2),
288 vHasError)};
289 fill("SCTErrMonitor", etaAcc, phiAcc, hasErrorAcc);
290
291 if (m_doOnline and CategoryErrorsNames[errCate] == "Errors"){
292 auto hasErrorRecentAcc{Monitored::Collection("hasError_"+CategoryErrorsNames[errCate]+"_recent_"+subDetNameShort[iReg].Data()+"_"+std::to_string(iLay/2)+"_"+std::to_string(iLay%2),vHasError)};
293 fill("SCTErrMonitor", etaAcc, phiAcc, hasErrorRecentAcc);
294 }
295 }
296 }
297 }
298
299
300 bool doCoverage = false;
301 {
302 std::lock_guard<std::mutex> lock(m_mutex);
303 if (not (m_procLB.find(pEvent->lumiBlock()) != m_procLB.end() and m_coverageCheckOnlyFirtsEventOfLB) ) {
304 m_procLB.insert(pEvent->lumiBlock());
305 doCoverage = m_coverageCheck;
306 }
307 }
308
309 // Coverage check is time consuming and run at the first event of each lumi block.
310 if (doCoverage) {
311 ATH_MSG_DEBUG("Detector Coverage calculation starts" );
312
313 static const std::string names[numberOfProblemForCoverage] = {
314 "SCT_AllRegion", // All
315 "SCT_MapOfDisabledLinks", // Disabled
316 "SCT_MapOfLinksWithBadLinkLevelErrors", // BadLinkLevelError
317 "SCT_MapOfLinksWithBadRODLevelErrors", // BadRODLevelError
318 "SCT_MapOfLinksWithBadErrors", // BadError
319 "SCT_MapOfLinksWithPSTrip", // PSTrip (DCS)
320 "SCT_MapOfLinksWithAnyProbelm" // Summary
321 };
322 static const std::string titles[numberOfProblemForCoverage] = {
323 "Map of All Region", // All
324 "Map of Disabled Links", // Disabled
325 "Map of Links with bad LinkLevelErrors", // BadLinkLevelError
326 "Map of Links with Bad RODLevelErrors", // BadRODLevelError
327 "Map of Links with Bad Errors", // BadError
328 "Map of Links Affected by PS Trip", // PSTrip (DCS)
329 "Map of Links with Any Bad Problem" // Summary
330 };
331
332 std::lock_guard<std::mutex> lock{m_mutex};
333 CacheEntry* ent{m_cache.get(ctx)};
334 if (ent->m_evt!=ctx.evt()) { // New event in this slot
335 if (ent->m_mapSCT.empty()) { // First event
336 for (int iProblem{0}; iProblem<numberOfProblemForCoverage; iProblem++) {
337 ent->m_mapSCT.emplace_back(names[iProblem].c_str(), titles[iProblem].c_str(),
339 ent->m_mapSCT[iProblem].GetXaxis()->SetTitle("#eta");
340 ent->m_mapSCT[iProblem].GetYaxis()->SetTitle("#phi");
341 }
342 } else {
343 for (int iProblem{0}; iProblem<numberOfProblemForCoverage; iProblem++) {
344 ent->m_mapSCT[iProblem].Reset(); // Initialize histograms every event
345 }
346 }
347 ent->m_evt = ctx.evt();
348 }
349
350 std::set<IdentifierHash> sctHash[numberOfProblemForCoverage]{{}};
351 disabledSCT(sctHash[disabled]);
352 errorSCT(sctHash[badLinkError], sctHash[badRODError], sctHash[badError]);
353 summarySCT(sctHash[allRegion], sctHash[summary]);
354 float psTripModules{0.};
355 psTripDCSSCT(sctHash[psTripDCS], psTripModules);
356
357 sctHash[summary].clear();
358 sctHash[summary].insert(sctHash[disabled].begin(),sctHash[disabled].end()); // disabled
359 sctHash[summary].insert(sctHash[badError].begin(),sctHash[badError].end()); // bad error = bad link error + bad rod error
360 sctHash[summary].insert(sctHash[psTripDCS].begin(),sctHash[psTripDCS].end()); // pstrip
361
362 for (int iProblem{0}; iProblem<numberOfProblemForCoverage; iProblem++) {
363 for (const IdentifierHash& hash: sctHash[iProblem]) {
364 fillWafer(m_geo[hash], ent->m_mapSCT[iProblem]);
365 }
366
367 if (iProblem==allRegion) continue;
368
369 double detector_coverage{calculateDetectorCoverage(ent->m_mapSCT[iProblem], ent->m_mapSCT[allRegion])};
371 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
372 auto detectorCoverageAcc{Monitored::Scalar<double>("detectorCoverage"+coverageVarNames[iProblem], detector_coverage)};
373 fill("SCTErrMonitor", lumiBlockAcc, detectorCoverageAcc);
374
375 if (iProblem==summary) {
376 auto detectorCoverageR4PAcc{Monitored::Scalar<double>("detectorCoverage"+coverageVarNames[iProblem]+"InR4P", detector_coverage)};
377 bool atlasReady = m_atlasReadyFilter->accept();
378 if(atlasReady) {
379 fill("SCTErrMonitor", lumiBlockAcc, detectorCoverageR4PAcc);
380 }
381 }
382 }
383
385 // Modules affected by PS Tirp
386 auto lumiBlockAcc{Monitored::Scalar<int>("lumiBlock", pEvent->lumiBlock())};
387 auto psTripModulesAcc{Monitored::Scalar<int>("psTripModules", psTripModules)};
388 fill("SCTErrMonitor", lumiBlockAcc, psTripModulesAcc);
389
390 }
391
392 return StatusCode::SUCCESS;
393}
394
395int
396SCTErrMonAlg::fillByteStreamErrorsHelper(const std::set<IdentifierHash>& errors,
397 int err_type,
398 categoryErrorMap_t& categoryErrorMap,
399 std::array<int, N_REGIONS_INC_GENERAL>& nMaskedLinks) const {
400 //--- Check categories of the BS error
401 std::array<bool, CategoryErrors::N_ERRCATEGORY> b_category{};
402 b_category.fill(false);
403
404 // Error summaries
406 (err_type == SCT_ByteStreamErrors::MaskedLink) or (err_type == SCT_ByteStreamErrors::MaskedROD);
407
408 b_category[CategoryErrors::SUMMARY] = true;
409
410 b_category[CategoryErrors::BADERR] = false;
412 if (err_type == tmpBadError) {
413 b_category[CategoryErrors::BADERR] = true;
414 break;
415 }
416 }
417
418 b_category[CategoryErrors::LINKLEVEL] = false;
420 if (err_type == linkLevelError) {
421 b_category[CategoryErrors::LINKLEVEL] = true;
422 break;
423 }
424 }
425
426 b_category[CategoryErrors::RODLEVEL] = false;
428 if (err_type == rodLevelError) {
429 b_category[CategoryErrors::RODLEVEL] = true;
430 break;
431 }
432 }
433
434 b_category[CategoryErrors::MASKEDCHIP] =
435 (err_type == SCT_ByteStreamErrors::TempMaskedChip0) or (err_type == SCT_ByteStreamErrors::TempMaskedChip1) or
436 (err_type == SCT_ByteStreamErrors::TempMaskedChip2) or (err_type == SCT_ByteStreamErrors::TempMaskedChip3) or
437 (err_type == SCT_ByteStreamErrors::TempMaskedChip4) or (err_type == SCT_ByteStreamErrors::TempMaskedChip5);
438
439 // Each error
440 b_category[CategoryErrors::BYTESTREAMPARSEERROR] = (err_type == SCT_ByteStreamErrors::ByteStreamParseError);
441 b_category[CategoryErrors::TIMEOUTERROR] = (err_type == SCT_ByteStreamErrors::TimeOutError);
442 b_category[CategoryErrors::BCIDERROR] = (err_type == SCT_ByteStreamErrors::BCIDError);
443 b_category[CategoryErrors::LVL1IDERROR] = (err_type == SCT_ByteStreamErrors::LVL1IDError);
444 b_category[CategoryErrors::PREAMBLEERROR] = (err_type == SCT_ByteStreamErrors::PreambleError);
445 b_category[CategoryErrors::FORMATTERERROR] = (err_type == SCT_ByteStreamErrors::FormatterError);
446 b_category[CategoryErrors::TRAILERERROR] = (err_type == SCT_ByteStreamErrors::TrailerError);
447 b_category[CategoryErrors::TRAILEROVERFLOWERROR] = (err_type == SCT_ByteStreamErrors::TrailerOverflowError);
448 b_category[CategoryErrors::HEADERTRAILERLIMITERROR] = (err_type == SCT_ByteStreamErrors::HeaderTrailerLimitError);
449 b_category[CategoryErrors::ABCDERROR] = (err_type == SCT_ByteStreamErrors::ABCDError);
450 b_category[CategoryErrors::RAWERROR] = (err_type == SCT_ByteStreamErrors::RawError);
451 b_category[CategoryErrors::MASKEDLINK] = (err_type == SCT_ByteStreamErrors::MaskedLink);
452 b_category[CategoryErrors::RODCLOCKERROR] = (err_type == SCT_ByteStreamErrors::RODClockError);
453 b_category[CategoryErrors::TRUNCATEDROD] = (err_type == SCT_ByteStreamErrors::TruncatedROD);
454 b_category[CategoryErrors::ROBFRAGMENTERROR] = (err_type == SCT_ByteStreamErrors::ROBFragmentError);
455 b_category[CategoryErrors::MISSINGLINKHEADERERROR] = (err_type == SCT_ByteStreamErrors::MissingLinkHeaderError);
456 b_category[CategoryErrors::MASKEDROD] = (err_type == SCT_ByteStreamErrors::MaskedROD);
457 b_category[CategoryErrors::ABCDERROR_CHIP0] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip0);
458 b_category[CategoryErrors::ABCDERROR_CHIP1] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip1);
459 b_category[CategoryErrors::ABCDERROR_CHIP2] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip2);
460 b_category[CategoryErrors::ABCDERROR_CHIP3] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip3);
461 b_category[CategoryErrors::ABCDERROR_CHIP4] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip4);
462 b_category[CategoryErrors::ABCDERROR_CHIP5] = (err_type == SCT_ByteStreamErrors::ABCDError_Chip5);
463 b_category[CategoryErrors::ABCDERROR_ERROR1] = (err_type == SCT_ByteStreamErrors::ABCDError_Error1);
464 b_category[CategoryErrors::ABCDERROR_ERROR2] = (err_type == SCT_ByteStreamErrors::ABCDError_Error2);
465 b_category[CategoryErrors::ABCDERROR_ERROR4] = (err_type == SCT_ByteStreamErrors::ABCDError_Error4);
466 b_category[CategoryErrors::TEMPMASKEDCHIP0] = (err_type == SCT_ByteStreamErrors::TempMaskedChip0);
467 b_category[CategoryErrors::TEMPMASKEDCHIP1] = (err_type == SCT_ByteStreamErrors::TempMaskedChip1);
468 b_category[CategoryErrors::TEMPMASKEDCHIP2] = (err_type == SCT_ByteStreamErrors::TempMaskedChip2);
469 b_category[CategoryErrors::TEMPMASKEDCHIP3] = (err_type == SCT_ByteStreamErrors::TempMaskedChip3);
470 b_category[CategoryErrors::TEMPMASKEDCHIP4] = (err_type == SCT_ByteStreamErrors::TempMaskedChip4);
471 b_category[CategoryErrors::TEMPMASKEDCHIP5] = (err_type == SCT_ByteStreamErrors::TempMaskedChip5);
472 b_category[CategoryErrors::ABCDERROR_ERROR7] = (err_type == SCT_ByteStreamErrors::ABCDError_Error7);
473 b_category[CategoryErrors::ABCDERROR_INVALID] = (err_type == SCT_ByteStreamErrors::ABCDError_Invalid);
474 b_category[CategoryErrors::RODSIMULATEDDATA] = (err_type == SCT_ByteStreamErrors::RODSimulatedData);
475
476 std::vector<int> numErrorsPerLumi[N_REGIONS];
477 if (m_doPerLumiErrors) {
478 for (int reg{0}; reg<N_REGIONS; reg++) {
479 const int nLayers{n_layers[reg]*2};
480 numErrorsPerLumi[reg].resize(nLayers, 0);
481 }
482 }
483
484 //--- Count BS errors
485 int nerrors{0};
486 for (const auto& hash: errors) {
487 nerrors++;
488 if (not hash.is_valid()) continue;
489
490 //--- FIll module information with BS error
491 const Identifier fitId{m_pSCTHelper->wafer_id(hash)};
492 int layer{m_pSCTHelper->layer_disk(fitId)};
493 int side{m_pSCTHelper->side(fitId)};
494 int barrel_ec{m_pSCTHelper->barrel_ec(fitId)};
495 int ieta{m_pSCTHelper->eta_module(fitId)};
496 int iphi{m_pSCTHelper->phi_module(fitId)};
497 layer = layer * 2 + side;
498 // barrel_ec = {ENDCAP_C=-2, BARREL=0, ENDCAP_A=2}
499 // -> regionIndex = {ENDCAP_C_INDEX=0, BARREL_INDEX=1, ENDCAP_A_INDEX=2, GENERAL_INDEX=3}
500 int regionIndex{GENERAL_INDEX};
501 if ((barrel_ec == BARREL) and (layer >= 0) and (layer < N_BARRELSx2)) regionIndex = BARREL_INDEX;
502 else if (barrel_ec == ENDCAP_A) regionIndex = ENDCAP_A_INDEX;
503 else if (barrel_ec == ENDCAP_C) regionIndex = ENDCAP_C_INDEX;
504
505 // Take into account offsets
506 ieta -= ((regionIndex==BARREL_INDEX) ? FIRST_ETA_BIN : FIRST_ETA_BIN_EC);
507 iphi -= ((regionIndex==BARREL_INDEX) ? FIRST_PHI_BIN : FIRST_PHI_BIN_EC);
508
509 if (b_category[CategoryErrors::MASKEDLINKALL]) {
510 nMaskedLinks[GENERAL_INDEX]++;
511 if (regionIndex!=GENERAL_INDEX) {
512 nMaskedLinks[regionIndex]++;
513 }
514 }
515
516 if (m_doPerLumiErrors) numErrorsPerLumi[regionIndex][layer]++;
517
518 for (int errCate{0}; errCate < CategoryErrors::N_ERRCATEGORY; ++errCate) {
519 if (b_category[errCate] and regionIndex!=GENERAL_INDEX) {
520 categoryErrorMap[errCate][regionIndex][layer][ieta][iphi] = true;
521 }
522 }
523 }
524
525 if (m_doPerLumiErrors) {
526 std::size_t size{static_cast<size_t>(N_REGIONS*n_layers[ENDCAP_C_INDEX]*N_SIDES)};
527 std::vector<int> vErrorType;
528 std::vector<int> vLayerSide;
529 std::vector<float> vErrorFraction;
530 std::vector<bool> vIsEC;
531 std::vector<bool> vIsB;
532 std::vector<bool> vIsEA;
533 vErrorType.reserve(size);
534 vLayerSide.reserve(size);
535 vErrorFraction.reserve(size);
536 vIsEC.reserve(size);
537 vIsB.reserve(size);
538 vIsEA.reserve(size);
539 for (int reg{0}; reg<N_REGIONS; reg++) {
540 const int nLayers{n_layers[reg]*N_SIDES};
541 for (int layerSide{0}; layerSide<nLayers; layerSide++) {
542 float num_modules{static_cast<float>(getNumModules(index2Bec(reg), layerSide))};
543 if (num_modules==0.) continue;
544 vErrorType.push_back(err_type);
545 vLayerSide.push_back(layerSide);
546 vErrorFraction.push_back(static_cast<float>(numErrorsPerLumi[reg][layerSide])/num_modules);
547 vIsEC.push_back(reg==ENDCAP_C_INDEX);
548 vIsB.push_back(reg==BARREL_INDEX);
549 vIsEA.push_back(reg==ENDCAP_A_INDEX);
550 }
551 }
553 auto errorTypeAcc{Monitored::Collection("errorType", vErrorType)};
554 auto layerSideAcc{Monitored::Collection("layerSide", vLayerSide)};
555 auto errorFractionAcc{Monitored::Collection("errorFraction", vErrorFraction)};
556 auto isECAcc{Monitored::Collection("isEC", vIsEC)};
557 auto isBAcc{Monitored::Collection("isB", vIsB)};
558 auto isEAAcc{Monitored::Collection("isEA", vIsEA)};
559 fill("SCTErrMonitor", errorTypeAcc, layerSideAcc, errorFractionAcc, isECAcc, isBAcc, isEAAcc);
560 }
561
562 if (b_category[CategoryErrors::SUMMARY]) return nerrors;
563 return 0;
564}
565
566void
567SCTErrMonAlg::numByteStreamErrors(const std::set<IdentifierHash>& errors, int& ntot) const {
568 for (const auto& fit: errors) {
569 if (fit.is_valid()) {
570 ntot++;
571 }
572 }
573}
574
575bool SCTErrMonAlg::disabledSCT(std::set<IdentifierHash>& sctHashDisabled) const {
576 bool altered{false};
577 sctHashDisabled.clear();
578 const std::set<Identifier>* badModules{m_configurationTool->badModules()};
579
580 for (const Identifier& badModule: *badModules) {
581 altered = true;
582 IdentifierHash hashSide0{m_pSCTHelper->wafer_hash(badModule)};
583 IdentifierHash hashSide1;
584 m_pSCTHelper->get_other_side(hashSide0, hashSide1);
585 sctHashDisabled.insert(hashSide0);
586 sctHashDisabled.insert(hashSide1);
587 }
588 return altered;
589}
590
591bool SCTErrMonAlg::errorSCT(std::set<IdentifierHash>& sctHashBadLinkError,
592 std::set<IdentifierHash>& sctHashBadRODError,
593 std::set<IdentifierHash>& sctHashBadError) const {
594 sctHashBadLinkError.clear();
595 sctHashBadRODError.clear();
596 sctHashBadError.clear();
597 const EventContext& ctx{Gaudi::Hive::currentContext()};
598 //BadLinkLevelError
600 const std::set<IdentifierHash> sctErrors{m_byteStreamErrTool->getErrorSet( linkLevelBadErrors, ctx )};
601 for (const IdentifierHash& waferHash : sctErrors) {
602 sctHashBadLinkError.insert(waferHash);
603 }
604 }
605
606 //BadRODLevelError
608 const std::set<IdentifierHash> sctErrors{m_byteStreamErrTool->getErrorSet( RodLevelBadErrors, ctx )};
609 for (const IdentifierHash& waferHash : sctErrors) {
610 sctHashBadRODError.insert(waferHash);
611 }
612 }
613
614 //BadError = BadLinkLevelError + BadRODLevelError
616 const std::set<IdentifierHash> sctErrors{m_byteStreamErrTool->getErrorSet( tmpBadError, ctx )};
617 for (const IdentifierHash& waferHash : sctErrors) {
618 sctHashBadError.insert(waferHash);
619 }
620 }
621 return true;
622}
623
624// Total (SCT_ConditionsSummaryTool)
625bool SCTErrMonAlg::summarySCT(std::set<IdentifierHash>& sctHashAll, std::set<IdentifierHash>& sctHashSummary) const {
626 bool altered{false};
627 sctHashAll.clear();//All
628 sctHashSummary.clear();
629
630 const EventContext& ctx{Gaudi::Hive::currentContext()};
631
632 const unsigned int maxHash{static_cast<unsigned int>(m_pSCTHelper->wafer_hash_max())}; // 8176
633 for (unsigned int i{0}; i<maxHash; i++) {
634 IdentifierHash hash{i};
635 sctHashAll.insert(hash);//All
636 if (not m_pSummaryTool->isGood(hash, ctx)) {
637 sctHashSummary.insert(hash);
638 }
639 }
640 return altered;
641}
642
643// Power supply trip (SCT_DCSConditionsTool)
644bool SCTErrMonAlg::psTripDCSSCT(std::set<IdentifierHash>& sctHashPSTripDCS, float& psTripModules) const {
645 bool altered{false};
646 sctHashPSTripDCS.clear();
647
648 const unsigned int maxHash{static_cast<unsigned int>(m_pSCTHelper->wafer_hash_max())}; // 8176
649 int npsw{0};
650 for (unsigned int i{0}; i<maxHash; i++) {
651 IdentifierHash hash{i};
652 if (m_useDCS and (not m_dcsTool->isGood(hash))) {
653 npsw++; //Counting the number of PS sides
654 altered = true;
655 sctHashPSTripDCS.insert(hash);
656 }
657 }
658 psTripModules = npsw/2.;
659 return altered;
660}
661
662void SCTErrMonAlg::fillWafer(moduleGeo_t module, TH2F& histo) const {
663 double etaMin{module.first.first}, etaMax{module.first.second};
664 double phiMin{module.second.first}, phiMax{module.second.second};
665 unsigned int nRep{1};
666 if (etaMin<-s_rangeEta) { etaMin = -s_rangeEta; }
667 if (etaMax> s_rangeEta) { etaMax = s_rangeEta; }
668 if (phiMin>phiMax) {
669 phiMin = -M_PI;
670 nRep=2;
671 }
672 for (unsigned int iRep{0}; iRep<nRep; iRep++) {
673 if (iRep==1) {
674 phiMin = module.second.first;
675 phiMax = M_PI;
676 }
677 const int ixMin{static_cast<int>((etaMin/s_rangeEta+1.)*s_nBinsEta/2)+1};
678 const int ixMax{static_cast<int>((etaMax/s_rangeEta+1.)*s_nBinsEta/2)};
679 const int iyMin{static_cast<int>((phiMin/M_PI+1.)*s_nBinsPhi/2)+1};
680 const int iyMax{static_cast<int>((phiMax/M_PI+1.)*s_nBinsPhi/2)};
681 const double xMin{(static_cast<double>(ixMin)/s_nBinsEta*2-1.)*s_rangeEta};
682 const double xMax{(static_cast<double>(ixMax)/s_nBinsEta*2-1.)*s_rangeEta};
683 const double yMin{(static_cast<double>(iyMin)/s_nBinsPhi*2-1.)*M_PI};
684 const double yMax{(static_cast<double>(iyMax)/s_nBinsPhi*2-1.)*M_PI};
685 const double wxMin{(xMin-etaMin)/s_rangeEta*s_nBinsEta/2};
686 const double wxMax{(etaMax-xMax)/s_rangeEta*s_nBinsEta/2};
687 const double wxOne{(etaMax-etaMin)/s_rangeEta*s_nBinsEta/2};
688 const double wyMin{(yMin-phiMin)/M_PI*s_nBinsPhi/2};
689 const double wyMax{(phiMax-yMax)/M_PI*s_nBinsPhi/2};
690 const double wyOne{(phiMax-phiMin)/M_PI*s_nBinsPhi/2};
691 for (int ix{ixMin}; ix<=ixMax+1; ix++) {
692 double weightx{1.};
693 if (ixMin==ixMax+1) weightx = wxOne;
694 else if (ix==ixMin) weightx = wxMin;
695 else if (ix==ixMax+1) weightx = wxMax;
696 for (int iy{iyMin}; iy<=iyMax+1; iy++) {
697 double weight{weightx};
698 if (iyMin==iyMax+1) weight *= wyOne;
699 else if (iy==iyMin) weight *= wyMin;
700 else if (iy==iyMax+1) weight *= wyMax;
701 histo.SetBinContent(ix, iy, histo.GetBinContent(ix,iy)+weight); //Fill(ix, iy, weight);//
702 }
703 }
704 }
705 return;
706}
707
708double SCTErrMonAlg::calculateDetectorCoverage(const TH2F& histo, const TH2F& histoAll) const {
709 double occupancy{0.};
710
711 for (unsigned int i{0}; i < s_nBinsEta; i++) {
712 for (unsigned int j{0}; j < s_nBinsPhi; j++) {
713 double waferCell{histoAll.GetBinContent(i+1, j+1) - histo.GetBinContent(i+1, j+1)};
714
715 if (waferCell >= s_wafersThreshold) {
716 occupancy += 1.0;
717 } else if (waferCell > s_wafersThreshold - 1.0 ) {
718 occupancy += waferCell - (s_wafersThreshold - 1.0);
719 //Calculating the bin occupancy which has less than 1.
720 //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.
721 //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.
722 }
723 }
724 }
725 double detector_coverage{100. * occupancy / ( static_cast<double>( s_nBinsEta ) * static_cast<double>( s_nBinsPhi ) )};
726 return detector_coverage;
727}
728
729const unsigned int SCTErrMonAlg::s_nBinsEta = 100;
730const double SCTErrMonAlg::s_rangeEta = 2.5;
731const unsigned int SCTErrMonAlg::s_nBinsPhi = 100;
732const 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
static Double_t rz
This is an Identifier helper class for the SCT subdetector.
Handle class for reading from StoreGate.
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
bool psTripDCSSCT(std::set< IdentifierHash > &sctHashPSTripDCS, float &PSTripModules) const
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
static const double s_rangeEta
static const unsigned int s_nBinsPhi
BooleanProperty m_doOnline
std::mutex m_mutex
bool disabledSCT(std::set< IdentifierHash > &sctHashDisabled) const
BooleanProperty m_makeConfHisto
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)