ATLAS Offline Software
Loading...
Searching...
No Matches
SCTCalib.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
23
26
27#include "SCT_CalibUtilities.h"
28#include "XmlHeader.h"
29#include "XmlStreamer.h"
30
31//InnerDetector
33
34//Gaudi
35#include "GaudiKernel/IEventProcessor.h"
36
37//root
38#include "TFile.h"
39#include "TH1I.h"
40#include "TH2D.h"
41#include "TF1.h"
42#include "TProfile.h"
43#include "TProfile2D.h"
44#include "Math/ProbFuncMathCore.h"
45
46#include <array>
47#include <cmath>
48
49using namespace SCT_CalibAlgs;
50
51namespace {
52 const std::string_view lineFeed{"\n"};
53 enum Bec {ENDCAP_C = -2, BARREL = 0, ENDCAP_A = 2};
54 // String names for the detector parts
55 const std::string shortNames[] = {"EndCapC", "Barrel", "EndCapA"};
56
57 bool areConsecutiveIntervals(const std::pair<int, int>& i1, const std::pair<int, int>& i2, const int withinLimits) {
58 return i1.second <= (i2.first + withinLimits);
59 }
60 const std::string xmlHeader{"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"};
61 const std::string linefeed{"\n"};
62 std::string
63 associateStylesheet(const std::string& stylesheetName) {
64 return std::string("<?xml-stylesheet type=\"text/xsl\" href=\"")+stylesheetName+"\"?>";
65 }
66
67 template <class T>
68 std::string
69 xmlPartData(const Bec bec, const int layer, const int eta, const std::string& dataName, const T data) {
70 std::ostringstream os;
71 const std::string thisPart{shortNames[bec2Index(bec)]};
72 os << " <parts>" << lineFeed
73 << " " << xmlValue("part", thisPart) << lineFeed
74 << " " << xmlValue("layer", layer) << lineFeed
75 << " ";
76 std::string barrelEtaXml{xmlValue("eta", "all")};
77 std::string endcapEtaXml{xmlValue("eta", eta)};
78 if (bec==BARREL) os << barrelEtaXml;
79 else os << endcapEtaXml;
80 os << lineFeed
81 << " " << xmlValue(dataName, data) << lineFeed
82 << " </parts>" << lineFeed;
83 return os.str();
84 }
85
86 template <class T>
87 std::string
88 xmlModuleData(const Bec bec, const int layer, const int side, const int phi, const int eta, std::string_view dataName, const T data, std::string_view serial, std::string_view listOfErrors) {
89 std::ostringstream os;
90 os << " <module>\n"
91 << " " << xmlValue("SN", serial) << lineFeed;
92
93 if (bec==ENDCAP_C) os << " " << xmlValue("barrel_endcap", "-2") << lineFeed;
94 else if (bec==BARREL) os << " " << xmlValue("barrel_endcap", "0") << lineFeed;
95 else if (bec==ENDCAP_A) os << " " << xmlValue("barrel_endcap", "2") << lineFeed;
96 os << " " << xmlValue("layer", layer) << lineFeed
97 << " " << xmlValue("side", side) << lineFeed
98 << " " << xmlValue("eta", eta) << lineFeed
99 << " " << xmlValue("phi", phi) << lineFeed
100 << " " << xmlValue(dataName, data) << lineFeed;
101 os << listOfErrors;
102 os << " </module>" << lineFeed;
103 return os.str();
104 }
105
106
107}
108
109
111// Constructor
113SCTCalib::SCTCalib(const std::string& name, ISvcLocator* pSvcLocator) :
114 AthAlgorithm(name, pSvcLocator)
115{
117}
118
119
121// Initialization
124
125 ATH_MSG_INFO("----- in initialize() ----- ");
126 if (detStore()->retrieve(m_pSCTHelper, "SCT_ID").isFailure()) {
127 ATH_MSG_ERROR("Unable to retrieve SCTHelper");
128 return StatusCode::FAILURE;
129 }
130
131 if (not retrievedService(m_pCalibWriteTool)) return StatusCode::FAILURE;
132 if (m_doHV) ATH_MSG_FATAL("Not yet properly implemented and tested!");
133
134 ATH_CHECK(m_ConfigurationConditionsTool.retrieve(EnableTool {m_useConfiguration}));
135
136 if (not m_useCalibration) {
137 ATH_MSG_DEBUG("ReadCalibDataTool was removed in initialization");
138 m_ReadCalibDataTool.disable();
139 } else {
140 if (m_ReadCalibDataTool.retrieve().isFailure()) return StatusCode::FAILURE;
141 }
142
143 if (not m_useMajority) {
144 ATH_MSG_DEBUG("MajorityConditionsTool was removed in initialization");
145 } else {
146 if (m_MajorityConditionsTool.retrieve().isFailure()) return StatusCode::FAILURE;
147 }
148
149 if (not retrievedService(m_calibHitmapTool)) return StatusCode::FAILURE;
150
151 if (not retrievedService(m_calibModuleListTool)) return StatusCode::FAILURE;
152
153 if (not retrievedService(m_calibEvtInfoTool)) return StatusCode::FAILURE;
154
155 if (not m_useBSError) {
156 ATH_MSG_DEBUG("ByteStreamErrorsSvc was removed in initialization");
157 } else {
158 if (not retrievedService(m_calibBsErrTool)) return StatusCode::FAILURE;
159 }
160 if (not retrievedService(m_calibLbTool)) return StatusCode::FAILURE;
161
162 ATH_CHECK(m_CablingTool.retrieve());
163 ATH_CHECK(m_SCTDetEleCollKey.initialize());
164
165 //--- LB range
166 try {
167 m_LBRange = std::stoi(m_LBMax);
168 m_calibHitmapTool->setNumberOfLb(m_LBRange);
169 m_calibLbTool->setNumberOfLb(m_LBRange);
170 m_calibBsErrTool->setNumberOfLb(m_LBRange);
171 } catch (...) {
172 ATH_MSG_ERROR("Couldn't cast m_LBMax=\"" << m_LBMax << "\" to m_LBRange...");
173 m_LBRange = 0;
174 }
175
176 m_calibHitmapTool->setLbToMerge(m_nLbsMerged);
177 m_calibLbTool->setLbToMerge(m_nLbsMerged);
178 m_calibBsErrTool->setLbToMerge(m_nLbsMerged);
179
181
182 if (m_readBS and m_readHIST) {
183 ATH_MSG_ERROR("Both BS and HIST are set to be read. Choose either of BS or HIST.");
184 return StatusCode::FAILURE;
185 }
186
187 //--- Open BS
188 if (m_readBS) {
189 ATH_MSG_INFO("------------> Reading from ByteStream <-------------");
190 m_calibEvtInfoTool->setSource("BS");
191 }
192
193 //--- Open HIST
194 if (m_readHIST) {
195 ATH_MSG_INFO("------------> Reading from HIST <-------------");
196 m_calibEvtInfoTool->setSource("HIST");
197 //--- List of HIST
198 std::string hist{""};
199 std::vector<std::string> histCollection{m_input_hist.value()};
200 ATH_MSG_INFO("The input histogram name is : " << m_input_hist);
201 if (not histCollection.empty()) {
202 hist=histCollection.back();
203 if (histCollection.size() > 1) ATH_MSG_WARNING("The Histogram collection contains more than one histogram; using the last one.");
204 } else {
205 ATH_MSG_ERROR("The input histogram collection property is empty");
206 return StatusCode::FAILURE;
207 }
208
209 //in case of DeadStrip or DeadChip, change open from EOS to
210 //copy and open locally. Delete the file after processing
211 m_inputHist = TFile::Open(hist.c_str());
212
213 ATH_MSG_INFO("opening HIST file : " << hist.c_str());
214
215 if (m_inputHist) {
216 //--- Check run number
217 const std::string os{std::to_string(m_runNumber.value())};
218 ATH_MSG_INFO("Getting HIST directory : " << m_runNumber.value());
219 if (not m_inputHist->GetDirectory("/run_"+TString{os})) {
220 ATH_MSG_ERROR("RunNumber in HIST is inconsistent with jobO : " << os);
221 return StatusCode::FAILURE ;
222 }
223 ATH_MSG_INFO("Getting Number of events: " << m_calibEvtInfoTool->counter());
224 //--- Read number of events : Previously from entry of "tier0ESD" in "/GLOBAL/DQTDataFlow/events_lb"
225 std::string osHist{std::string{"/run_"} + std::to_string(m_runNumber.value())+"/SCT/GENERAL/Conf/NumberOfEventsVsLB"};
226 TH1F* hist_events{static_cast<TH1F*>(m_inputHist->Get(osHist.c_str()))};
227 m_numberOfEventsHist = hist_events->GetEntries();
228 } else {
229 ATH_MSG_WARNING("can not open HIST : " << hist.c_str());
230 }
231
232
233 ATH_MSG_INFO("Initialization of TimeStamp/LB, taken from runInfo.txt");
234 //--- Initialization of TimeStamp/LB, taken from runInfo.txt
235 m_calibEvtInfoTool->setSource("HIST");
237 m_calibEvtInfoTool->setRunNumber(m_runNumber);
238 m_calibEvtInfoTool->setEventNumber(m_eventNumber);
239 }
240
241 //--- Booking histograms for hitmaps
242 if (m_doHitMaps) m_calibHitmapTool->book();
243 //--- Booking histograms for BSErrors
245
246 //--- Reading histograms for hitmaps
247 if ((not m_doHitMaps and not m_doHitMapsLB) and m_readHitMaps) {
248 ATH_MSG_INFO("Set CalibEventInfo for m_readHitMaps == true");
249 m_calibEvtInfoTool->setSource("HIST");
250 m_calibHitmapTool->read("./SCTHitMaps.root");
253 m_calibEvtInfoTool->setRunNumber(m_runNumber);
254 m_calibEvtInfoTool->setEventNumber(m_eventNumber);
255 if (m_doNoisyStrip) {
256 m_calibLbTool->read("./SCTLB.root");
257 }
258 if (m_doBSErrors) {
259 m_calibBsErrTool->read("./SCTBSErrors.root");
260 }
261 }
262 //--- Hit-vs-LB for LBs in noisy links/chips
263 if (m_doHitMapsLB) m_calibLbTool->book();
264
265 //--- Check statistics for NoiseOccupancy
267 //--- Check statistics for RawOccupancy
269 //--- Check statistics for Efficiency
271 //--- Check statistics for BSError
272 if (m_doBSErrorDB and notEnoughStatistics(m_BSErrorDBMinStat, m_numberOfEventsHist)) return StatusCode::FAILURE;
273 //--- Check statistics for LorentzAngle
275 //
276
277 ATH_MSG_INFO("----- end of initialize() ----- ");
278 return StatusCode::SUCCESS;
279}
280
281
282bool
283SCTCalib::notEnoughStatistics(const int required, const int obtained, const std::string& histogramName) const {
284 if (obtained<required) {
285 ATH_MSG_ERROR("Number of events in " << histogramName << ": " << obtained << " is less than the required minimum number of events " << required);
286 return true;
287 }
288 return false;
289}
290
291
293// Execute - on event by event
295StatusCode SCTCalib::execute(const EventContext& ctx) {
296
297 ATH_MSG_DEBUG("----- in execute() ----- ");
298
299 const bool majorityIsGoodOrUnused{(m_useMajority and m_MajorityConditionsTool->isGood(ctx)) or !m_useMajority};
300 if (m_readBS) {
301 //--- TimeStamp/LB range analyzed
302 const int timeStamp{static_cast<int>(ctx.eventID().time_stamp())};
303 const int lumiBlock{static_cast<int>(ctx.eventID().lumi_block())};
304 int timeStampBeginOld;
305 int timeStampEndOld;
306 m_calibEvtInfoTool->getTimeStamps(timeStampBeginOld, timeStampEndOld);
307 m_calibEvtInfoTool->setTimeStamp(std::min(timeStamp, timeStampBeginOld), std::max(timeStamp, timeStampEndOld));
308 int lbBeginOld;
309 int lbEndOld;
310 m_calibEvtInfoTool->getLumiBlock(lbBeginOld, lbEndOld);
311 m_calibEvtInfoTool->setLumiBlock(std::min(lumiBlock, lbBeginOld), std::max(lumiBlock, lbEndOld));
312 m_calibEvtInfoTool->setLumiBlock(lumiBlock);
313 m_calibEvtInfoTool->setTimeStamp(timeStamp);
314 if (m_doHitMapsLB and majorityIsGoodOrUnused) {
315 m_calibLbTool->setLb(ctx.eventID().lumi_block());
316 }
317 }
318
319 //--- Fill histograms for (1) Number of events and (2) Hitmaps
320 if (m_doHitMaps and majorityIsGoodOrUnused) m_calibHitmapTool->fill(m_readBS);
321
322 //--- Fill histograms for (1) Number of events and (2) Hits as a function of LB
323 if (m_doHitMapsLB and majorityIsGoodOrUnused) {
324 m_calibLbTool->fill(m_readBS);
325 }
326
327 //--- Fill histograms for (1) Number of events and (2) BSErrors
329
330 //--- Increment event counter : to be ready for the next event loop
331 m_calibEvtInfoTool->incrementCounter();
332
333 ATH_MSG_DEBUG("----- end of execute() ----- ");
334
335 return StatusCode::SUCCESS;
336}
337
338
342StatusCode SCTCalib::stop ATLAS_NOT_THREAD_SAFE () { // Thread unsafe getNoisyStrip, getDeadStrip, getNoiseOccupancy, getRawOccupancy, getEfficiency, getBSErrors, getLorentzAngle methods are used.
343 ATH_MSG_INFO("----- in stop() ----- ");
344 //--- Number of events processed
345 m_numberOfEvents = (m_readHIST or (!m_doHitMaps and m_readHitMaps)) ? m_numberOfEventsHist : m_calibEvtInfoTool->counter();
346 m_calibEvtInfoTool->getTimeStamps(m_utcBegin, m_utcEnd);
347
348 //--- IOV range defined by RunNumber and LB
349 unsigned int beginRun{static_cast<unsigned int>(m_runNumber.value())};
350 unsigned int endRun{static_cast<unsigned int>(m_runNumber.value())};
351 unsigned int beginLB{IOVTime::MINEVENT};
352 unsigned int endLB{IOVTime::MAXEVENT};
353 m_iovStart.setRunEvent(static_cast<unsigned long>(beginRun), static_cast<unsigned long>(beginLB));
354 m_iovStop.setRunEvent(static_cast<unsigned long>(endRun), static_cast<unsigned long>(endLB));
355
356 //--- Find noisy strips from hitmaps
357 const bool doNoisyStripAnalysis{((!m_doHitMaps and m_readHitMaps) or !m_readHitMaps) and m_doNoisyStrip};
358 if (doNoisyStripAnalysis) {
359 if (getNoisyStrip().isFailure()) {
360 ATH_MSG_ERROR("Failed to run getNoisyStrip()");
361 return StatusCode::FAILURE;
362 }
363 }
364
365 //--- Upload hv
366 if (m_doHV) {
367 m_gofile.open(m_badModulesFile.value().c_str(), std::ios::out);
368 if (not m_gofile) ATH_MSG_ERROR("Problem opening " << m_badModulesFile);
369 //
370 XmlHeader myXml{m_gofile};
371 XmlStreamer root{"modules", m_gofile};
372 SCT_ID::const_id_iterator waferItr{m_pSCTHelper->wafer_begin()};
373 SCT_ID::const_id_iterator waferItrE{m_pSCTHelper->wafer_end()};
374 const unsigned int onlyDummy{1};
375 std::pair<int, int> timeInterval{0, 0};
376 std::pair<int, int> lbRange{0, 0};
377 const int withinLimits{m_maxtbins};
378 //
379 for (; waferItr not_eq waferItrE; ++waferItr) {
380 const Identifier waferId{*waferItr};
381 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
382 const std::vector<std::pair<int, int>>& tvec{m_summarytrips.at(waferHash.value())};
383 const std::vector<std::pair<int, int>>& tlbn{m_summarytripslb.at(waferHash.value())};
384 //tvec is a pair of times in general, although the very first one is a dummy
385 const unsigned int numberOfElements{static_cast<unsigned int>(tvec.size())};
386 if (numberOfElements > onlyDummy) {
387 //only care if something happened in this module
388 timeInterval=tvec.at(1);
389 lbRange=tlbn.at(1);
390 for (unsigned int itrip{2}; itrip != numberOfElements; ++itrip) { //skip 0 since that is just the dummy pair.
391 if (areConsecutiveIntervals(tvec[itrip], timeInterval, withinLimits)) {
392 timeInterval.second = tvec.at(itrip).second;
393 lbRange.second = tlbn.at(itrip).second;
394 } else {
395 //not consecutive, so first print out the old one
396 doHVPrintXML(timeInterval, lbRange, waferId);
397 timeInterval = tvec.at(itrip);
398 lbRange = tlbn.at(itrip);
399 }
400 } // end loop over times
401 doHVPrintXML(timeInterval, lbRange, waferId);
402 }
403 } // end loop over wafers
404 }
405
406 //--- Find dead strips/chips from hitmaps
407 if ((m_doDeadStrip or m_doDeadChip) and getDeadStrip().isFailure()) {
408 ATH_MSG_ERROR("Failed to run getDeadStrip()");
409 return StatusCode::FAILURE;
410 }
411
412 //--- Upload noise occupancy
413 if (m_doNoiseOccupancy and getNoiseOccupancy().isFailure()) {
414 ATH_MSG_ERROR("Failed to run getNoiseOccupancy()");
415 return StatusCode::FAILURE;
416 }
417
418 //--- Upload raw occupancy
419 if (m_doRawOccupancy and getRawOccupancy().isFailure()) {
420 ATH_MSG_ERROR("Failed to run getRawOccupancy()");
421 return StatusCode::FAILURE;
422 }
423
424 //--- Upload efficiency
425 if (m_doEfficiency and getEfficiency().isFailure()) {
426 ATH_MSG_ERROR("Failed to run getEfficiency()");
427 return StatusCode::FAILURE;
428 }
429
430 //--- Upload ByteStream Errors
431 if (m_doBSErrorDB and getBSErrors().isFailure()) {
432 ATH_MSG_ERROR("Failed to run getBSErrors()");
433 return StatusCode::FAILURE;
434 }
435
436 //--- Upload Lorentz Angle
437 if (m_doLorentzAngle and getLorentzAngle().isFailure()) {
438 ATH_MSG_ERROR("Failed to run getLorentzAngle()");
439 return StatusCode::FAILURE;
440 }
441
442 //--- Close HIST
443 if (m_readHIST) m_inputHist->Close();
444
445 return StatusCode::SUCCESS;
446}
447
448
452StatusCode SCTCalib::finalize() {
453 ATH_MSG_INFO("----- in finalize() ----- ");
454
455 if (m_writeToCool) {
456 if (!m_pCalibWriteTool.release().isSuccess()) {
457 ATH_MSG_ERROR("Failed to release m_pCalibWriteTool");
458 return StatusCode::FAILURE;
459 }
460 }
461
462 return StatusCode::SUCCESS;
463}
464
465
470void SCTCalib::doHVPrintXML(const std::pair<int, int>& timeInterval, const std::pair<int, int>& lbRange, Identifier waferId) {
471 const IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
472 const SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
473
474 XmlStreamer mod{"module", m_gofile};
475 {
476 XmlStreamer v{"value", "name", "SN", m_gofile};
477 m_gofile << sn.str();
478 }
479 {
480 XmlStreamer v{"value", "name", "BecLayerPhiEta", m_gofile};
481 m_gofile << formatPosition(waferId, m_pSCTHelper, ".", false);
482 }
483 {
484 XmlStreamer v{"value", "name", "StartTime", m_gofile};
485 m_gofile << timeInterval.first;
486 }
487 {
488 XmlStreamer v{"value", "name", "EndTime", m_gofile};
489 m_gofile << timeInterval.second;
490 }
491 {
492 XmlStreamer v{"value", "name", "StartLBN", m_gofile};
493 m_gofile << lbRange.first;
494 }
495 {
496 XmlStreamer v{"value", "name", "EndLBN", m_gofile};
497 m_gofile << lbRange.second;
498 }
499}
500
501
506StatusCode SCTCalib::getNoisyStrip ATLAS_NOT_THREAD_SAFE () { // Thread unsafe writeModuleListToCool method is used.
507 enum Categories {ALL, NEW, REF, N_CATEGORIES};
508
509
510 ATH_MSG_INFO("----- in getNoisyStrip() ----- ");
511
512 const EventContext& ctx = Gaudi::Hive::currentContext();
513
514 //--- Number of LBs processed
515 m_numOfLBsProcessed = 0;
516 for (int iLB{0}; iLB != m_LBRange; ++iLB) {
517 if (m_calibLbTool and m_calibLbTool->getNumberOfEventsInBin(iLB + 1) > 0) ++m_numOfLBsProcessed;
518 }
519
520 //--- Choice of threshold
521 //three module lists: all, new, ref
522 using ModuleList_t = std::map<Identifier, std::set<Identifier>>;
523 ModuleList_t moduleLists[N_CATEGORIES];
524 //Reading data from COOL
525 // original code switched on this :if (m_noisyUpdate)
526 ATH_MSG_DEBUG("in getNoisyStrips: before readModuleList");
527 if (m_calibModuleListTool->readModuleList(ctx, moduleLists[REF]).isFailure()) {
528 ATH_MSG_ERROR("Could not read moduleList");
529 return StatusCode::FAILURE;
530 }
531
532 //two bad strip lists: all, new
533 using StripList_t = std::set<Identifier>;
534 StripList_t stripIdLists[2];
535
536 //--- Loop over wafers
537 SCT_ID::const_id_iterator waferItr{m_pSCTHelper->wafer_begin()};
538 SCT_ID::const_id_iterator waferItrE{m_pSCTHelper->wafer_end()};
539 for (; waferItr not_eq waferItrE; ++waferItr) {
540 //--- Identifier/SN
541 Identifier waferId{*waferItr};
542 Identifier moduleId{m_pSCTHelper->module_id(waferId)};
543 //--- Initialization in *module*
544 if (m_pSCTHelper->side(waferId) == 0) {
545 stripIdLists[ALL].clear();
546 stripIdLists[NEW].clear();
547 }
548 std::pair<int, bool> noisy{getNumNoisyStrips(waferId)};
549 const int numNoisyStripsInWafer{noisy.first};
550 const bool isNoisyWafer{noisy.second};
551 if (numNoisyStripsInWafer!=0 || m_noisyWriteAllModules) {
552 if (m_noisyWaferFinder and isNoisyWafer) { //in noisy wafer
553
554 if (not m_noisyWaferWrite) break;
555 if (m_noisyWaferAllStrips) { //write out all strips
556 if (addStripsToList(ctx, waferId, stripIdLists[ALL], false, false).isFailure() or addStripsToList(ctx, waferId, stripIdLists[NEW], false, true).isFailure()) {
557 ATH_MSG_ERROR("Could not add stripIds to the list");
558 return StatusCode::FAILURE;
559 }
560 break;
561 } else {
562 //only noisy strips in noisy wafer
563 if (addStripsToList(ctx, waferId, stripIdLists[ALL], true, false).isFailure() or addStripsToList(ctx, waferId, stripIdLists[NEW], true, true).isFailure()) {
564 ATH_MSG_ERROR("Could not add stripIds to the list");
565 return StatusCode::FAILURE;
566 }
567 }
568 } else { // not in noisy wafer
569 if (addStripsToList(ctx, waferId, stripIdLists[ALL], true, false).isFailure() or addStripsToList(ctx, waferId, stripIdLists[NEW], true, true).isFailure()) {
570 ATH_MSG_ERROR("Could not add stripIds to the list");
571 return StatusCode::FAILURE;
572 }
573 }
574 }//endif numnoisystrips!=0
575 //--- Create objects for a module
576 if (m_pSCTHelper->side(waferId) == 1) {
577 if (!stripIdLists[ALL].empty()) moduleLists[ALL].insert(std::map< Identifier, std::set<Identifier> >::value_type(moduleId, stripIdLists[ALL]));
578 if (!stripIdLists[NEW].empty()) moduleLists[NEW].insert(std::map< Identifier, std::set<Identifier> >::value_type(moduleId, stripIdLists[NEW]));
579 }
580 }//end loop over wafers
581
582 //--- Local sqlite files here
583 ATH_MSG_DEBUG("------ Before writing into COOL ------");
584 if (m_writeToCool) {
585 if (writeModuleListToCool(moduleLists[ALL], moduleLists[NEW], moduleLists[REF]).isFailure()) {
586 ATH_MSG_ERROR("Could not write NoisyStrips into COOL");
587 return StatusCode::FAILURE;
588 }
589 }
590 //--- XML outputs
591 if (noisyStripsToXml(moduleLists[ALL], m_badStripsAllFile).isFailure()) {
592 ATH_MSG_ERROR("Could not write XML file");
593 return StatusCode::FAILURE;
594 }
595 if (noisyStripsToXml(moduleLists[NEW], m_badStripsNewFile).isFailure()) {
596 ATH_MSG_ERROR("Could not write XML file");
597 return StatusCode::FAILURE;
598 }
599 //if (noisyStripsToSummaryXml(moduleLists[ALL], moduleLists[NEW], moduleLists[REF], m_badStripsSummaryFile).isFailure()) {
600 if (noisyStripsToSummaryXml(moduleLists[ALL], moduleLists[REF], m_badStripsSummaryFile).isFailure()) {
601 ATH_MSG_ERROR("Could not write XML file");
602 return StatusCode::FAILURE;
603 }
604
605 return StatusCode::SUCCESS;
606}
607
608
609//====================================================================================================
610// SCTCalib :: getDeadStrip
611//====================================================================================================
612StatusCode SCTCalib::getDeadStrip ATLAS_NOT_THREAD_SAFE () { // Thread unsafe SCTCalibWriteTool::createListStrip, SCTCalibWriteTool::createListChip methods are used.
613 //Function to identify and print out the dead strips.
614 ATH_MSG_INFO("getDeadStrip() called");
615
616 const EventContext& ctx = Gaudi::Hive::currentContext();
617
618 // Bad Mods
619 const std::set<Identifier>* badMods{m_ConfigurationConditionsTool->badModules(ctx)};
620 std::set<Identifier>::const_iterator ModItr{badMods->begin()};
621 std::set<Identifier>::const_iterator ModEnd{badMods->end()};
622 // Bad links
623 const std::map<IdentifierHash, std::pair<bool, bool> >* badLinks{m_ConfigurationConditionsTool->badLinks(ctx)};
624 std::map<IdentifierHash, std::pair<bool, bool> >::const_iterator linkItr{badLinks->begin()};
625 std::map<IdentifierHash, std::pair<bool, bool> >::const_iterator linkEnd{badLinks->end()};
626 // Bad chips
627 const std::map<Identifier, unsigned int>* badChips{m_ConfigurationConditionsTool->badChips(ctx)};
628 std::map<Identifier, unsigned int>::const_iterator chipItr{badChips->begin()};
629 std::map<Identifier, unsigned int>::const_iterator chipEnd{badChips->end()};
630 // Bad strips (w/o bad modules and chips)
631 std::set<Identifier> badStripsExclusive;
632 m_ConfigurationConditionsTool->badStrips(badStripsExclusive, ctx, true, true);
633 std::set<Identifier>::const_iterator stripEnd(badStripsExclusive.end());
634 //To get #(Enabled Modules)
635 int numEnabledModules_B[n_barrels] = {n_phiBinsB0*n_etaInBarrel, n_phiBinsB1*n_etaInBarrel, n_phiBinsB2*n_etaInBarrel, n_phiBinsB3*n_etaInBarrel};
636 int numEnabledModules_EC[n_disks][n_etaBinsEC] = {{0}, {0}};
637 for (int i{0}; i<n_disks; i++) {
638 for (int j{0}; j<n_etaBinsEC; j++) {
639 if (!((i==0 and j==2) or (i==6 and j==2) or (i==7 and j==2) or (i==8 and j==1) or (i==8 and j==2))) {
640 numEnabledModules_EC[i][j] = j==0 ? n_phiBinsECOuter*2 : n_phiBinsECMiddle*2;
641 }
642 }
643 }
644 for (; ModItr!=ModEnd; ++ModItr) {
645 Identifier moduleId{*ModItr};
646 if (m_pSCTHelper->barrel_ec(moduleId)==BARREL) numEnabledModules_B[m_pSCTHelper->layer_disk(moduleId)]--;
647 else numEnabledModules_EC[m_pSCTHelper->layer_disk(moduleId)][m_pSCTHelper->eta_module(moduleId)]--;
648 }
649 //calculate meanOccupancy of layer etc...
650 double meanOccupancy_Barrel[n_barrels] = {0};
651 double meanOccupancy_EC[n_disks][n_etaBinsEC] = {{0}, {0}};
652 SCT_ID::const_id_iterator waferItr{m_pSCTHelper->wafer_begin()};
653 SCT_ID::const_id_iterator waferItrE{m_pSCTHelper->wafer_end()};
654 for (; waferItr != waferItrE; ++waferItr) {
655 Identifier waferId{*waferItr};
656 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
657 for (int j{0}; j<n_stripPerChip*n_chipPerSide; j++) {
658 double n_hits{m_calibHitmapTool->getBinForHistogramIndex(j+1, waferHash.value())};
659 if (n_hits/m_numberOfEvents<m_noisyThr4DeadFinding) {
660 if (m_pSCTHelper->barrel_ec(waferId)==BARREL) {
661 meanOccupancy_Barrel[m_pSCTHelper->layer_disk(waferId)]+=m_calibHitmapTool->getBinForHistogramIndex(j+1, waferHash.value());
662 } else {
663 meanOccupancy_EC[m_pSCTHelper->layer_disk(waferId)][m_pSCTHelper->eta_module(waferId)]+=m_calibHitmapTool->getBinForHistogramIndex(j+1, waferHash.value());
664 }
665 }
666 }
667 }
668
669 for (int i{0}; i<n_barrels; i++) {
670 meanOccupancy_Barrel[i]/=static_cast<double>(m_numberOfEvents*nbins*2*numEnabledModules_B[i]);
671 ATH_MSG_INFO("Barrel : layer=" << i << ", meanOccupancy=" << meanOccupancy_Barrel[i] << ", nbins:" << nbins << ", #enabledModule=" << numEnabledModules_B[i]);
672 }
673
674 for (int i{0}; i<n_disks; i++) {
675 for (int j{0}; j<n_etaBinsEC; j++) {
676 if (numEnabledModules_EC[i][j]!=0) {
677 meanOccupancy_EC[i][j]/=static_cast<double>(m_numberOfEvents*nbins*2*numEnabledModules_EC[i][j]);
678 ATH_MSG_INFO("EndCap : disk=" << i << ", eta=" << j << ", meanOccupancy=" << meanOccupancy_EC[i][j] << ", #enabledModule=" << numEnabledModules_EC[i][j]);
679 }
680 }
681 }
682 bool busyStream{meanOccupancy_Barrel[3]>m_busyThr4DeadFinding ? true : false};
683 unsigned int minStat{busyStream ? static_cast<unsigned int>(m_deadStripMinStatBusy) : static_cast<unsigned int>(m_deadStripMinStat)};
684 if (m_doDeadStrip and m_numberOfEvents<minStat) {
685 ATH_MSG_WARNING("required minimum statistics is " << minStat/1E3 << "k events for DeadStrip search with this stream");
686 m_doDeadStrip = true; // CS: do it anyway
687 }
688 if (m_doDeadChip and m_numberOfEvents<m_deadChipMinStat) {
689 ATH_MSG_WARNING("required minimum statistics is " << static_cast<unsigned int>(m_deadChipMinStat) << " events for DeadChip search");
690 m_doDeadChip = true; // CS: do it anyway
691 }
692 if (m_doDeadStrip==false and m_doDeadChip==false) {
693 ATH_MSG_ERROR("Number of events " << m_numberOfEvents << " is less than the required minimum number of events... exit getDeadStrip()");
694 return StatusCode::FAILURE;
695 }
696 //create XML files
697 if (m_doDeadStrip) {
698 if (openXML4DB(m_outDeadStrips, "DeadStrip", m_tagID4DeadStrips.value().c_str(), m_iovStart, m_iovStop).isFailure()) {
699 ATH_MSG_ERROR("Problem opening " << m_deadStripsFile);
700 return StatusCode::FAILURE;
701 }
702 }
703 if (m_doDeadChip) {
704 if (openXML4DB(m_outDeadChips, "DeadChip", m_tagID4DeadChips.value().c_str(), m_iovStart, m_iovStop).isFailure()) {
705 ATH_MSG_ERROR("Problem opening " << m_deadChipsFile);
706 return StatusCode::FAILURE;
707 }
708 }
709
710 // Get SCT_DetectorElementCollection
712 const InDetDD::SiDetectorElementCollection* elements{sctDetEle.retrieve()};
713 if (elements==nullptr) {
714 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
715 return StatusCode::FAILURE;
716 }
717
718 //Dead identification
719 bool hasDeadStrip{false};
720 bool hasDeadChip{false};
721 bool isNoHitLink{false};
722 bool isDead{false};
723 bool beforeIsDead{false};
724 int n_deadStrip{0};
725 int n_deadChip{0};
726 int n_deadLink{0};
727 int n_deadModule{0};
728 int n_checkedChip{0};
729 int beginDead{0};
730 int endDead{0};
731 std::string defectStrip;
732 std::string defectChip;
733 std::ostringstream summaryList;
734 defectStrip.erase();
735 defectChip.erase();
736 const double deadStripDefinition{ROOT::Math::gaussian_cdf_c(m_deadStripSignificance)};
737 const double deadChipDefinition{ROOT::Math::gaussian_cdf_c(m_deadChipSignificance)};
738
739 //--- Loop over wafers
740 waferItr = m_pSCTHelper->wafer_begin();
741 for (; waferItr != waferItrE; ++waferItr) {
742 Identifier waferId{*waferItr};
743 Identifier moduleId{m_pSCTHelper->module_id(waferId)};
744 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
745
746 bool disabledChip[n_chipPerModule] = {false};
747 unsigned int disabledChipFlag=0;
748 double numHitsInStrip[n_stripPerChip*n_chipPerSide] = {0};
749 double numHitsInChip[n_chipPerSide] = {0};
750 double totalHitsInWafer{0};
751 int n_noisyStrip{0};
752 int n_noHitsStrip{0};
753 int n_disabledStrip{0};
754 int n_disabledInChip[n_chipPerSide] = {0};
755
756 //initialize
757 int side{m_pSCTHelper->side(waferId)};
758 if (side==0) {
759 isDead=false;
760 beforeIsDead=false;
761 beginDead=0;
762 endDead=0;
763 defectStrip.erase();
764 defectChip.erase();
765 }
766
767 //check if module/link is disabled or not
768 bool disabled{false};
769 if (badMods->find(moduleId)!=badMods->end()) disabled=true;
770 linkItr=badLinks->find(waferHash);
771 if (linkItr!=linkEnd) {
772 std::pair<bool, bool> status{(*linkItr).second};
773 if ((side==0 and status.first==true) or (side==1 and status.second==true)) disabled=true;
774 }
775
776 //check BS Error
777 bool hasBSError{false};
778 if (m_calibBsErrTool->size(waferHash.value())>0) hasBSError=true;
779 if (disabled or hasBSError) { //goto WRITE_DB; //<-- who ever put this in should be shot; http://xkcd.com/292/
780 if (side==1) {
781 //write to DB & .xml.
782 if (defectChip==" 0-5 6-11 ") {
783 n_deadModule++;
784 } else if (defectChip==" 0-5 " or defectChip==" 6-11 ") {
785 n_deadLink++;
786 }
787
788 if (!(defectStrip.empty()) or !(defectChip.empty())) {
789 if (addToSummaryStr(summaryList, waferId, "DEAD", defectStrip, defectChip).isFailure()) {
790 ATH_MSG_ERROR("Could not add dead strips to the summary");
791 return StatusCode::FAILURE;
792 }
793 }
794
795 if (!(defectStrip.empty())) {
797 double threshold = m_deadStripSignificance;
798 if (!m_deadNotQuiet) threshold = m_quietThresholdStrip;
799 if (m_writeToCool) {
800 if (m_pCalibWriteTool->createListStrip(moduleId, m_pSCTHelper, 10000, "DEAD", threshold, defectStrip).isFailure()) {
801 ATH_MSG_ERROR("Could not create list");
802 return StatusCode::FAILURE;
803 }
804 }
805 if (addToXML4DB(m_outDeadStrips, waferId, "DEAD", threshold, defectStrip).isFailure()) {
806 ATH_MSG_ERROR("Could not add dead strips to the summary");
807 return StatusCode::FAILURE;
808 }
809
810 hasDeadStrip=true;
811 }
812
813 if (!(defectChip.empty())) {
815 double threshold = m_deadChipSignificance;
816 if (!m_deadNotQuiet) threshold = m_quietThresholdChip;
817 if (m_writeToCool) {
818 if (m_pCalibWriteTool->createListChip(moduleId, m_pSCTHelper, 10000, "DEAD", threshold, defectChip).isFailure()) {
819 ATH_MSG_ERROR("Could not create list");
820 return StatusCode::FAILURE;
821 }
822 }
823
824 if (addToXML4DB(m_outDeadChips, waferId, "DEAD", threshold, defectChip).isFailure()) {
825 ATH_MSG_ERROR("Could not add dead chips to the summary");
826 return StatusCode::FAILURE;
827 }
828
829 hasDeadChip=true;
830
831 }
832 }
833 continue;
834 }
835 //retrieving info of chip status
836 chipItr=badChips->find(moduleId);
837 if (chipItr!=chipEnd) disabledChipFlag = (*chipItr).second;
838 for (unsigned int i{0}; i<n_chipPerModule; i++) {
839 disabledChip[i] = ((disabledChipFlag & (1 << i)) != 0);
840 }
841
842 //retrieving #hits in each strip
843 for (int j=0; j<n_stripPerChip*n_chipPerSide; j++) {
844 const InDetDD::SiDetectorElement* pElement{elements->getDetectorElement(waferHash)};
845 bool swap{(pElement->swapPhiReadoutDirection()) ? true : false};
846 int chipNum{0};
847 if (side==0) chipNum = swap ? 5-j/n_stripPerChip : j/n_stripPerChip;
848 else chipNum = swap ? 11-j/n_stripPerChip : 6+j/n_stripPerChip;
849 int stripNum{swap ? 767-j : j};
850 Identifier stripId{m_pSCTHelper->strip_id(waferId, j)};
851
852 numHitsInStrip[stripNum] = m_calibHitmapTool->getBinForHistogramIndex(j+1, waferHash.value());
853 bool misMatch{false};
854 double n_hitsInDisable{numHitsInStrip[stripNum]};
855 if (((disabledChipFlag & (1 << chipNum))!=0) or badStripsExclusive.find(stripId)!=stripEnd) {
856 if (numHitsInStrip[stripNum]!=0) misMatch = true;
857 numHitsInStrip[stripNum] = -99;
858 }
859 if (misMatch) {
860 ATH_MSG_WARNING("hits in disabled Strip : "
861 << "n_hits=" << n_hitsInDisable << ", "
862 << "bec=" << m_pSCTHelper->barrel_ec(stripId) << ", "
863 << "layer=" << m_pSCTHelper->layer_disk(stripId) << ", "
864 << "phi=" << m_pSCTHelper->phi_module(stripId) << ", "
865 << "eta=" << m_pSCTHelper->eta_module(stripId) << ", "
866 << "side=" << m_pSCTHelper->side(stripId) << ", "
867 << "strip=" << m_pSCTHelper->strip(stripId));
868 }
869
870 if (numHitsInStrip[stripNum]==0) {
871 n_noHitsStrip++;
872 ATH_MSG_DEBUG("nohit strip : barrel_ec=" << m_pSCTHelper->barrel_ec(stripId)
873 << ", layer=" << m_pSCTHelper->layer_disk(stripId) << ", phi=" << m_pSCTHelper->phi_module(stripId)
874 << ", eta=" << m_pSCTHelper->eta_module(stripId) << ", side=" << m_pSCTHelper->side(stripId)
875 << ", strip=offline" << m_pSCTHelper->strip(stripId));
876 } else if (numHitsInStrip[stripNum]==-99) {
877 n_disabledStrip++;
878 n_disabledInChip[stripNum/n_stripPerChip]++;
879 ATH_MSG_DEBUG("disabled strip : barrel_ec=" << m_pSCTHelper->barrel_ec(stripId)
880 << ", layer=" << m_pSCTHelper->layer_disk(stripId) << ", phi=" << m_pSCTHelper->phi_module(stripId)
881 << ", eta=" << m_pSCTHelper->eta_module(stripId) << ", side=" << m_pSCTHelper->side(stripId)
882 << ", strip=offline" << m_pSCTHelper->strip(stripId));
883 } else if (numHitsInStrip[stripNum]/m_numberOfEvents>m_noisyThr4DeadFinding) {
884 n_noisyStrip++;
885 } else {
886 totalHitsInWafer+=numHitsInStrip[stripNum];
887 }
888
889 } //end strip loop
890
891 if (n_disabledStrip==768) {
892 if (side==1) {
893 if (defectChip==" 0-5 6-11 ") {
894 n_deadModule++;
895 } else if (defectChip==" 0-5 " or defectChip==" 6-11 ") {
896 n_deadLink++;
897 }
898 if (!(defectStrip.empty()) or !(defectChip.empty())) {
899 if (addToSummaryStr(summaryList, waferId, "DEAD", defectStrip, defectChip).isFailure()) {
900 ATH_MSG_ERROR("Could not add dead strips to the summary");
901 return StatusCode::FAILURE;
902 }
903 }
904
905 if (!(defectStrip.empty())) {
906 if (m_writeToCool) {
907 if (m_pCalibWriteTool->createListStrip(moduleId, m_pSCTHelper, 10000, "DEAD", m_deadStripSignificance, defectStrip).isFailure()) {
908 ATH_MSG_ERROR("Could not create strip list");
909 return StatusCode::FAILURE;
910 }
911 }
912
913 if (addToXML4DB(m_outDeadStrips, waferId, "DEAD", m_deadStripSignificance, defectStrip).isFailure()) {
914 ATH_MSG_ERROR("Could not add xml strip list");
915 return StatusCode::FAILURE;
916 }
917 hasDeadStrip=true;
918
919 }
920 if (!(defectChip.empty())) {
921 if (m_writeToCool) {
922 if (m_pCalibWriteTool->createListChip(moduleId, m_pSCTHelper, 10000, "DEAD", m_deadChipSignificance, defectChip).isFailure()) {
923 ATH_MSG_ERROR("Could not create strip list");
924 return StatusCode::FAILURE;
925 }
926 }
927
928 if (addToXML4DB(m_outDeadChips, waferId, "DEAD", m_deadChipSignificance, defectChip).isFailure()) {
929 ATH_MSG_ERROR("Could not add xml chip list");
930 return StatusCode::FAILURE;
931 }
932
933 hasDeadChip=true;
934
935 }
936 }
937 continue;
938
939 }
940
941 isNoHitLink=false;
942 if (n_noHitsStrip+n_disabledStrip==768) {
943 n_checkedChip+=n_chipPerSide;
944 isNoHitLink=true;
945
946 double meanOccu{0.};
947 if (m_pSCTHelper->barrel_ec(waferId)==BARREL) meanOccu=meanOccupancy_Barrel[m_pSCTHelper->layer_disk(waferId)];
948 else meanOccu=meanOccupancy_EC[m_pSCTHelper->layer_disk(waferId)][m_pSCTHelper->eta_module(waferId)];
949 double sum_binomial{ROOT::Math::binomial_cdf(0, meanOccu, m_numberOfEvents*n_stripPerChip*n_chipPerSide)};
950
951 if (sum_binomial<deadChipDefinition) {
952 ATH_MSG_INFO("DEADLINK : " << moduleId << ", side=" << side);
953 n_deadChip+=n_chipPerSide;
954
955 //For DeadStrip
956 if (m_doDeadStrip) {
957 if (side==0) beginDead=0, endDead=767;
958 else beginDead=768, endDead=1535;
959 defectStrip = m_pCalibWriteTool->addDefect(defectStrip, beginDead, endDead);
960 }
961
962 //For DeadChip
963 if (m_doDeadChip) {
964 if (side==0) beginDead=0, endDead=5;
965 else beginDead=6, endDead=11;
966 defectChip = m_pCalibWriteTool->addDefect(defectChip, beginDead, endDead);
967 }
968
969 if (side==1) {
970 if (defectChip==" 0-5 6-11 ") {
971 n_deadModule++;
972 } else if (defectChip==" 0-5 " or defectChip==" 6-11 ") {
973 n_deadLink++;
974 }
975
976 if (!(defectStrip.empty()) or !(defectChip.empty())) {
977 if (addToSummaryStr(summaryList, waferId, "DEAD", defectStrip, defectChip).isFailure()) {
978 ATH_MSG_ERROR("Could not add dead strips to the summary");
979 return StatusCode::FAILURE;
980 }
981 }
982 if (!(defectStrip.empty())) {
983 if (m_writeToCool) {
984 if (m_pCalibWriteTool->createListStrip(moduleId, m_pSCTHelper, 10000, "DEAD", m_deadStripSignificance, defectStrip).isFailure()) {
985 ATH_MSG_ERROR("Could not create strip list");
986 return StatusCode::FAILURE;
987 }
988 }
989
990 if (addToXML4DB(m_outDeadStrips, waferId, "DEAD", m_deadStripSignificance, defectStrip).isFailure()) {
991 ATH_MSG_ERROR("Could not add xml strip list");
992 return StatusCode::FAILURE;
993 }
994
995 hasDeadStrip=true;
996
997 }
998
999 if (!(defectChip.empty())) {
1000 if (m_writeToCool) {
1001 if (m_pCalibWriteTool->createListChip(moduleId, m_pSCTHelper, 10000, "DEAD", m_deadChipSignificance, defectChip).isFailure()) {
1002 ATH_MSG_ERROR("Could not create chip list");
1003 return StatusCode::FAILURE;
1004 }
1005 }
1006
1007 if (addToXML4DB(m_outDeadChips, waferId, "DEAD", m_deadChipSignificance, defectChip).isFailure()) {
1008 ATH_MSG_ERROR("Could not add xml chip list");
1009 return StatusCode::FAILURE;
1010 }
1011
1012 hasDeadChip=true;
1013
1014 }
1015 }
1016 continue;
1017 }
1018 } //end DeadLink
1019
1020 if (n_noHitsStrip>0 || !m_deadNotQuiet) {
1021 int n_deadChipInWafer{0};
1022
1023 double n_effectiveEvents{0.};
1024 if (busyStream) n_effectiveEvents = m_numberOfEvents*(n_stripPerChip*n_chipPerSide-n_disabledStrip-n_noisyStrip-n_noHitsStrip);
1025 else n_effectiveEvents = m_numberOfEvents*(n_stripPerChip*n_chipPerSide-n_disabledStrip-n_noisyStrip);
1026
1027 //First, check DeadChip
1028 double meanOccupancy{totalHitsInWafer/n_effectiveEvents};
1029 for (int j{0}; j<n_stripPerChip*n_chipPerSide; j++) {
1030 if (numHitsInStrip[j]>0) numHitsInChip[j/n_stripPerChip] += numHitsInStrip[j];
1031 }
1032
1033 for (int j{0}; j<n_chipPerSide; j++) {
1034 isDead=false;
1035 int chipNum{side==0 ? j : j+6};
1036 if ( !disabledChip[chipNum] && (numHitsInChip[j]==0 || !m_deadNotQuiet) ) {
1037 if (!isNoHitLink) n_checkedChip++;
1038 double sum_binomial{ROOT::Math::binomial_cdf(0, meanOccupancy, m_numberOfEvents*(n_stripPerChip-n_disabledInChip[j]))};
1040 if ((m_deadNotQuiet && sum_binomial<deadChipDefinition) ||
1041 (!m_deadNotQuiet && numHitsInChip[j]/(m_numberOfEvents*(n_stripPerChip-n_disabledInChip[j])) < meanOccupancy*m_quietThresholdChip)) {
1042 ATH_MSG_INFO("DEADCHIP : " << moduleId << ", side=" << side << ", chip(online)=" << (side==0 ? j : j+n_chipPerSide));
1043 isDead=true;
1044 n_deadChip++;
1045 n_deadChipInWafer++;
1046 endDead = side==0 ? j : j+n_chipPerSide;
1047 if (!beforeIsDead) beginDead = side==0 ? j : j+n_chipPerSide;
1048 }
1049 }
1050
1051 if (m_doDeadChip) {
1052 if ((beforeIsDead and !isDead) or (j==5 and isDead)) defectChip = m_pCalibWriteTool->addDefect(defectChip, beginDead, endDead);
1053 }
1054 beforeIsDead = isDead;
1055 } //end chip loop
1056
1057 //Second, check DeadStrip
1058 if (m_doDeadStrip) {
1059 double meanOccExceptDeadChip{totalHitsInWafer/(n_effectiveEvents-n_stripPerChip*n_deadChipInWafer)};
1060 double numHitsInStripOnlineOrder[n_stripPerChip*n_chipPerSide] = {0};
1061 for (int j{0}; j<n_stripPerChip*n_chipPerSide; j++) {
1062 numHitsInStripOnlineOrder[j] = side==0 ? numHitsInStrip[j] : numHitsInStrip[n_stripPerChip*n_chipPerSide-1-j];
1063 isDead=false;
1064 if (numHitsInStripOnlineOrder[j]==0 || !m_deadNotQuiet) {
1065 double sum_binomial{ROOT::Math::binomial_cdf(0, meanOccExceptDeadChip, m_numberOfEvents)};
1067 if ((m_deadNotQuiet && sum_binomial<deadStripDefinition) ||
1068 (!m_deadNotQuiet && numHitsInStripOnlineOrder[j]/m_numberOfEvents < meanOccExceptDeadChip*m_quietThresholdStrip)) {
1069 ATH_MSG_INFO("DEADSTRIP : " << moduleId << ", side=" << side << ", strip(offline)=" << j);
1070 isDead=true;
1071 n_deadStrip++;
1072 endDead = side==0 ? j : j+n_stripPerChip*n_chipPerSide;
1073 if (!beforeIsDead) beginDead = side==0 ? j : j+n_stripPerChip*n_chipPerSide;
1074 }
1075 }
1076
1077 if (m_doDeadStrip) {
1078 if ((beforeIsDead and !isDead) or (j==5 and isDead)) defectStrip = m_pCalibWriteTool->addDefect(defectStrip, beginDead, endDead);
1079 }
1080 beforeIsDead = isDead;
1081 }
1082 }
1083 } //if (n_noHitsStrip>0)
1084 } //Wafer Loop end
1085
1086
1087 //Close Files
1088 if (m_doDeadStrip) {
1089 ATH_MSG_INFO("total #DeadStrip : " << n_deadStrip);
1090 if (closeXML4DB(m_outDeadStrips).isFailure()) {
1091 ATH_MSG_ERROR("Problem closing " << m_deadStripsFile);
1092 return StatusCode::FAILURE;
1093 }
1094 }
1095 if (m_doDeadChip) {
1096 ATH_MSG_INFO("total #DeadChip : " << n_deadChip << ", #noHitChip : " << n_checkedChip);
1097 if (closeXML4DB(m_outDeadChips).isFailure()) {
1098 ATH_MSG_ERROR("Problem closing " << m_deadChipsFile);
1099 return StatusCode::FAILURE;
1100 }
1101 }
1102
1103 //Making Summary File
1104 if (openXML4DeadSummary(m_outDeadSummary, "DEAD", n_deadModule, n_deadLink, n_deadChip, n_deadStrip).isFailure()) {
1105 ATH_MSG_ERROR("Problem opening " << m_deadSummaryFile);
1106 return StatusCode::FAILURE;
1107 }
1108 if (wrapUpXML4Summary(m_outDeadSummary, "DEAD", summaryList).isFailure()) {
1109 ATH_MSG_ERROR("Problem closing " << m_deadSummaryFile);
1110 return StatusCode::FAILURE;
1111 }
1112
1113 if (m_writeToCool) {
1114 if (m_doDeadStrip and hasDeadStrip) {
1115 if (m_pCalibWriteTool->wrapUpDeadStrips().isFailure()) {
1116 ATH_MSG_ERROR("Could not get DeadStrips Info");
1117 return StatusCode::FAILURE;
1118 }
1119 }
1120 if (m_doDeadChip and hasDeadChip) {
1121 if (m_pCalibWriteTool->wrapUpDeadChips().isFailure()) {
1122 ATH_MSG_ERROR("Could not get DeadChips Info");
1123 return StatusCode::FAILURE;
1124 }
1125 }
1126 }
1127
1128 ATH_MSG_INFO("END HERE");
1129 return StatusCode::SUCCESS;
1130}
1131
1132
1137StatusCode SCTCalib::getNoiseOccupancy ATLAS_NOT_THREAD_SAFE () // Thread unsafe SCTCalibWriteTool::createListNO method is used.
1138{
1139 ATH_MSG_INFO("----- in getNoiseOccupancy() -----");
1140
1141 //--- Initialization
1142 int n_phiBinsBarrel[n_barrels] = {n_phiBinsB0, n_phiBinsB1, n_phiBinsB2, n_phiBinsB3};
1143 int n_phiBinsEndcap[n_disks][n_etaBinsEC] = {{n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1144 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1145 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1146 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1147 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1148 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1149 {n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1150 {n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1151 {n_phiBinsECOuter, 0, 0}
1152 };
1153
1154 double meanNO_Barrel[n_barrels] = {0};
1155 double meanNO_ECA[n_disks][n_etaBinsEC] = {{0}, {0}};
1156 double meanNO_ECC[n_disks][n_etaBinsEC] = {{0}, {0}};
1157
1158 //--- Directory in HIST
1159 std::string stem;
1160
1161 //--- EndcapC
1162 stem = "/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTEC/Noise/";
1163 m_pnoiseoccupancymapHistoVectorECm.clear();
1164 for (int iDisk{0}; iDisk < n_disks ; ++iDisk) {
1165 for (int iSide{0}; iSide < 2; ++iSide) {
1166 std::ostringstream streamHist;
1167 streamHist << "hitoccupancymap";
1168 if (m_noiseOccupancyTriggerAware) streamHist << "trigger";
1169 streamHist << "ECm_" << iDisk << "_" << iSide;
1170 std::string histName{stem + streamHist.str()};
1171 TProfile2D* hist_tmp{static_cast<TProfile2D*>(m_inputHist->Get(histName.c_str()))};
1172 m_pnoiseoccupancymapHistoVectorECm.push_back(hist_tmp);
1173 }
1174 }
1175 //--- Barrel
1176 stem = "/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTB/Noise/";
1177 m_pnoiseoccupancymapHistoVector.clear();
1178 for (int iLayer{0}; iLayer < n_barrels ; ++iLayer) {
1179 for (int iSide{0}; iSide < 2; ++iSide) {
1180 std::ostringstream streamHist;
1181 streamHist << "hitoccupancymap";
1182 if (m_noiseOccupancyTriggerAware) streamHist << "trigger";
1183 streamHist << "_" << iLayer << "_" << iSide;
1184 std::string histName{stem + streamHist.str()};
1185 TProfile2D* hist_tmp{static_cast<TProfile2D*>(m_inputHist->Get(histName.c_str()))};
1186 m_pnoiseoccupancymapHistoVector.push_back(hist_tmp);
1187 }
1188 }
1189 //--- EndcapA
1190 stem = "/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTEA/Noise/";
1191 m_pnoiseoccupancymapHistoVectorECp.clear();
1192 for (int iDisk{0}; iDisk < n_disks ; ++iDisk) {
1193 for (int iSide{0}; iSide < 2; ++iSide) {
1194 std::ostringstream streamHist;
1195 streamHist << "hitoccupancymap";
1196 if (m_noiseOccupancyTriggerAware) streamHist << "trigger";
1197 streamHist << "ECp_" << iDisk << "_" << iSide;
1198 std::string histName{stem + streamHist.str()};
1199 TProfile2D* hist_tmp{static_cast<TProfile2D*>(m_inputHist->Get(histName.c_str()))};
1200 m_pnoiseoccupancymapHistoVectorECp.push_back(hist_tmp);
1201 }
1202 }
1203
1204 //--- XML file
1205 const char* outputNoiseOccupancyFileName{m_noiseOccupancyFile.value().c_str()};
1206 std::ofstream outFile{outputNoiseOccupancyFileName, std::ios::out};
1207 if (!outFile.good()) {
1208 ATH_MSG_ERROR("Unable to open NoiseOccupancyFile : " << outputNoiseOccupancyFileName);
1209 return StatusCode::FAILURE;
1210 }
1211
1212 //--- Header for XML outputs
1213 std::ostringstream osHeader;
1214 osHeader << "<channels server=\"ATLAS_COOLPROD\" schema=\"ATLAS_COOLOFL_SCT\" dbname=\"MONP200\" folder=\"SCT/Derived/NoiseOccupancy\" "
1215 << "since=\"" << m_iovStart.re_time() << "\" "
1216 << "until=\"" << m_iovStop.re_time() << "\" "
1217 << "tag=\"" << m_tagID4NoiseOccupancy << "\" "
1218 << "version=\"" << "multi\">" << lineFeed;
1219 outFile << osHeader.str();
1220
1221 //--- EndcapC
1222 for (int iDisk{0}; iDisk < n_disks ; ++iDisk) {
1223 for (int iSide{0}; iSide < 2; ++iSide) {
1224 for (int iEta{0}; iEta < n_etaBinsEC; ++iEta) {
1225 for (int iPhi{0}; iPhi < n_phiBinsEndcap[iDisk][iEta]; ++iPhi) {
1226 Identifier waferId = m_pSCTHelper->wafer_id(ENDCAP_C, iDisk, iPhi, iEta, iSide);
1227 float occupancy{static_cast<float>(m_pnoiseoccupancymapHistoVectorECm[2*iDisk + iSide]->GetBinContent(iEta+1, iPhi+1))};
1228 occupancy /= static_cast<float>(ntimeBins);
1229 occupancy /= 1E5;
1230 //--- For calculating average Noise Occupancy
1231 meanNO_ECC[iDisk][iEta]+=occupancy;
1232 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
1233 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
1234 outFile << xmlChannelNoiseOccDataString(waferId, occupancy, sn) << lineFeed;
1235 //--- DB output
1236 if (m_writeToCool) {
1237 if (m_pCalibWriteTool->createListNO(waferId, m_pSCTHelper, 10000, occupancy).isFailure()) {
1238 ATH_MSG_ERROR("Unable to run createListNO");
1239 return StatusCode::FAILURE;
1240 }
1241 }
1242 }
1243 }
1244 }
1245 }
1246 //--- Barrel
1247 for (int iLayer{0}; iLayer < n_barrels; ++iLayer) {
1248 for (int iSide{0}; iSide < 2; ++iSide) {
1249 for (int iEta{0}; iEta < n_etaBins; ++iEta) {
1250 if (iEta-6 == 0) continue;
1251 for (int iPhi{0}; iPhi < n_phiBinsBarrel[iLayer]; ++iPhi) {
1252 Identifier waferId{m_pSCTHelper->wafer_id(BARREL, iLayer, iPhi, iEta-6, iSide)};
1253 float occupancy{static_cast<float>(m_pnoiseoccupancymapHistoVector[2*iLayer + iSide]->GetBinContent(iEta+1, iPhi+1))};
1254 occupancy /= static_cast<float>(ntimeBins);
1255 occupancy /= 1E5;
1256 //--- For calculating average Noise Occupancy
1257 meanNO_Barrel[iLayer]+=occupancy;
1258 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
1259 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
1260 outFile << xmlChannelNoiseOccDataString(waferId, occupancy, sn) << lineFeed;
1261 //--- DB output
1262 if (m_writeToCool) {
1263 if (m_pCalibWriteTool->createListNO(waferId, m_pSCTHelper, 10000, occupancy).isFailure()) {
1264 ATH_MSG_ERROR("Unable to run createListNO");
1265 return StatusCode::FAILURE;
1266 }
1267 }
1268 }
1269 }
1270 }
1271 }
1272 //--- EndcapA
1273 for (int iDisk{0}; iDisk < n_disks ; ++iDisk) {
1274 for (int iSide{0}; iSide < 2; ++iSide) {
1275 for (int iEta{0}; iEta < n_etaBinsEC; ++iEta) {
1276 for (int iPhi{0}; iPhi < n_phiBinsEndcap[iDisk][iEta]; ++iPhi) {
1277 Identifier waferId{m_pSCTHelper->wafer_id(ENDCAP_A, iDisk, iPhi, iEta, iSide)};
1278 float occupancy{static_cast<float>(m_pnoiseoccupancymapHistoVectorECp[2*iDisk + iSide]->GetBinContent(iEta+1, iPhi+1))};
1279 occupancy /= static_cast<float>(ntimeBins);
1280 occupancy /= 1E5;
1281 //--- For calculating average Noise Occupancy
1282 meanNO_ECA[iDisk][iEta]+=occupancy;
1283 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
1284 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
1285 outFile << xmlChannelNoiseOccDataString(waferId, occupancy, sn) << lineFeed;
1286 //--- DB output
1287 if (m_writeToCool) {
1288 if (m_pCalibWriteTool->createListNO(waferId, m_pSCTHelper, 10000, occupancy).isFailure()) {
1289 ATH_MSG_ERROR("Unable to run createListNO");
1290 return StatusCode::FAILURE;
1291 }
1292 }
1293 }
1294 }
1295 }
1296 }
1297
1298 //--- Tail of XML outputs
1299 outFile << "</channels>" << lineFeed;
1300
1301 //--- Summary XML output
1302 const static std::string meanNoStr{"meanNO"};
1303 std::ostringstream summaryList;
1304 for (int i{0}; i < n_disks; ++i) {
1305 for (int j{0}; j < n_etaBinsEC; ++j) {
1306 if (n_phiBinsEndcap[i][j] != 0) {
1307 meanNO_ECC[i][j] /= (n_phiBinsEndcap[i][j]*2);
1308 summaryList << xmlPartData(ENDCAP_C, i, j, meanNoStr, meanNO_ECC[i][j]);
1309 }
1310 }
1311 }
1312 for (int i{0}; i < n_barrels; ++i) {
1313 meanNO_Barrel[i] /= (n_phiBinsBarrel[i]*n_etaInBarrel*2);
1314 summaryList << xmlPartData(BARREL, i, 0, meanNoStr, meanNO_Barrel[i]);
1315 }
1316 for (int i{0}; i < n_disks; ++i) {
1317 for (int j{0}; j < n_etaBinsEC; ++j) {
1318 if (n_phiBinsEndcap[i][j] != 0) {
1319 meanNO_ECA[i][j] /= (n_phiBinsEndcap[i][j]*2);
1320 summaryList << xmlPartData(ENDCAP_A, i, j, meanNoStr, meanNO_ECA[i][j]);
1321 }
1322 }
1323 }
1324
1325 if (openXML4MonSummary(m_outNOSummary, "NoiseOccupancy").isFailure()) {
1326 ATH_MSG_ERROR("Problem in opening NoiseOccupancy file");
1327 return StatusCode::FAILURE;
1328 }
1329 if (wrapUpXML4Summary(m_outNOSummary, "NoiseOccupancy", summaryList).isFailure()) {
1330 ATH_MSG_ERROR("Problem in closing NoiseOccupancy file");
1331 return StatusCode::FAILURE;
1332 }
1333
1334 //--- DB output
1335 if (m_writeToCool) {
1336 if (m_pCalibWriteTool->wrapUpNoiseOccupancy().isFailure()) {
1337 ATH_MSG_ERROR("Could not get NoiseOccupancy");
1338 return StatusCode::FAILURE;
1339 }
1340 }
1341
1342 return StatusCode::SUCCESS;
1343}
1344
1345
1350StatusCode SCTCalib::getRawOccupancy ATLAS_NOT_THREAD_SAFE () // Thread unsafe SCTCalibWriteTool::createListRawOccu method is used.
1351{
1352 ATH_MSG_INFO("----- in getRawOccupancy() -----");
1353
1354 //--- Initialization
1355 int n_phiBinsBarrel[n_barrels] = {n_phiBinsB0, n_phiBinsB1, n_phiBinsB2, n_phiBinsB3};
1356 int n_phiBinsEndcap[n_disks][n_etaBinsEC] = {{n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1357 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1358 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1359 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1360 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1361 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1362 {n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1363 {n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1364 {n_phiBinsECOuter, 0, 0}
1365 };
1366
1367 double meanRO_Barrel[n_barrels] = {0};
1368 double meanRO_ECA[n_disks][n_etaBinsEC] = {{0}, {0}};
1369 double meanRO_ECC[n_disks][n_etaBinsEC] = {{0}, {0}};
1370
1371
1372 //--- Directory in HIST
1373 std::vector<std::pair<std::string, int>> EC_stems;
1374 EC_stems.clear();
1375 std::pair<std::string, int> stem_C("/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTEC/hits/", ENDCAP_C);
1376 std::pair<std::string, int> stem_A("/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTEA/hits/", ENDCAP_A);
1377 EC_stems.push_back(std::move(stem_C));
1378 EC_stems.push_back(std::move(stem_A));
1379 std::vector< std::pair<std::string, int> >::iterator stemItr{EC_stems.begin()};
1380
1381 //--- Endcaps
1382 for (stemItr=EC_stems.begin(); stemItr!=EC_stems.end(); ++stemItr) {
1383 for (int iDisk{0}; iDisk<n_disks; ++iDisk) {
1384 for (int iSide{0}; iSide<2; ++iSide) {
1385 for (int iEta{0}; iEta<n_etaBinsEC; ++iEta) {
1386 for (int iPhi{0}; iPhi<n_phiBinsEndcap[iDisk][iEta]; ++iPhi) {
1387 Identifier waferId{m_pSCTHelper->wafer_id((*stemItr).second, iDisk, iPhi, iEta, iSide)};
1388 std::string detector_part;
1389 detector_part.erase();
1390 if (m_histBefore2010) {
1391 if ((*stemItr).second==ENDCAP_C) detector_part = "ECm_hitsmap";
1392 else detector_part = "ECp_hitsmap";
1393 } else {
1394 if ((*stemItr).second==ENDCAP_C) detector_part = "hitsmapECm";
1395 else detector_part = "hitsmapECp";
1396 }
1397 std::ostringstream streamHist;
1398 streamHist << detector_part << "_" << iDisk << "_" << iSide;
1399 std::string hitsmapname{stemItr->first + streamHist.str()};
1400 TH2F* hist_tmp{static_cast<TH2F*>(m_inputHist->Get(hitsmapname.c_str()))};
1401 unsigned long long n_hits{static_cast<unsigned long long>(hist_tmp->GetBinContent(iEta+1, iPhi+1))};
1402 float raw_occu{0};
1403 if (m_numberOfEvents!=0) {
1404 raw_occu = static_cast<float>(n_hits)/(m_numberOfEvents*n_chipPerSide*n_stripPerChip);
1405 //--- For calculating average Raw Occupancy
1406 if (stemItr->second==ENDCAP_C) meanRO_ECC[iDisk][iEta] += static_cast<double>(raw_occu);
1407 else if (stemItr->second==ENDCAP_A) meanRO_ECA[iDisk][iEta] += static_cast<double>(raw_occu);
1408 }
1409 //--- DB writing
1410 if (m_writeToCool) {
1411 if (m_pCalibWriteTool->createListRawOccu(waferId, m_pSCTHelper, m_numberOfEvents, raw_occu).isFailure()) {
1412 ATH_MSG_ERROR("Unable to run createListRawOccu");
1413 return StatusCode::FAILURE;
1414 }
1415 }
1416 }
1417 }
1418 }
1419 }
1420 }
1421 //--- Barrel
1422 for (int iLayer{0}; iLayer<n_barrels; ++iLayer) {
1423 for (int iSide{0}; iSide<2; ++iSide) {
1424 for (int iEta{0}; iEta<n_etaBins; ++iEta) {
1425 if (iEta-6==0) continue;
1426 for (int iPhi{0}; iPhi<n_phiBinsBarrel[iLayer]; ++iPhi) {
1427 Identifier waferId{m_pSCTHelper->wafer_id(BARREL, iLayer, iPhi, iEta-6, iSide)};
1428 std::ostringstream streamHist;
1429 streamHist << iLayer << "_" << iSide;
1430 std::string hitsmapname{"/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTB/hits/hitsmap_" + streamHist.str()};
1431 TH2F* hist_tmp{static_cast<TH2F*>(m_inputHist->Get(hitsmapname.c_str()))};
1432 unsigned long long n_hits{static_cast<unsigned long long>(hist_tmp->GetBinContent(iEta+1, iPhi+1))};
1433 float raw_occu{0};
1434 if (m_numberOfEvents!=0) {
1435 raw_occu = static_cast<float>(n_hits)/(m_numberOfEvents*n_chipPerSide*n_stripPerChip);
1436 //--- For calculating average Raw Occupancy
1437 meanRO_Barrel[iLayer] += static_cast<double>(raw_occu);
1438 }
1439 //--- DB writing
1440 if (m_writeToCool) {
1441 if (m_pCalibWriteTool->createListRawOccu(waferId, m_pSCTHelper, m_numberOfEvents, raw_occu).isFailure()) {
1442 ATH_MSG_ERROR("Unable to run createListRawOccu");
1443 return StatusCode::FAILURE;
1444 }
1445 }
1446 }
1447 }
1448 }
1449 }
1450 //--- Summary XML output
1451 std::ostringstream summaryList;
1452 static const std::string meanROStr{"meanRO"};
1453 for (int i{0}; i < n_disks; ++i) {
1454 for (int j{0}; j < n_etaBinsEC; ++j) {
1455 if (n_phiBinsEndcap[i][j] != 0) {
1456 meanRO_ECC[i][j] /= (n_phiBinsEndcap[i][j]*2);
1457 summaryList << xmlPartData(ENDCAP_C, i, j, meanROStr, meanRO_ECC[i][j]);
1458 }
1459 }
1460 }
1461 for (int i{0}; i < n_barrels; ++i) {
1462 meanRO_Barrel[i] /= (n_phiBinsBarrel[i]*n_etaInBarrel*2);
1463 summaryList << xmlPartData(BARREL, i, 0, meanROStr, meanRO_Barrel[i]);
1464 }
1465 for (int i{0}; i < n_disks; ++i) {
1466 for (int j{0}; j < n_etaBinsEC; ++j) {
1467 if (n_phiBinsEndcap[i][j] != 0) {
1468 meanRO_ECA[i][j] /= (n_phiBinsEndcap[i][j]*2);
1469 summaryList << xmlPartData(ENDCAP_A, i, j, meanROStr, meanRO_ECA[i][j]);
1470 }
1471 }
1472 }
1473
1474 if (openXML4MonSummary(m_outROSummary, "RawOccupancy").isFailure()) {
1475 ATH_MSG_ERROR("Problem in opening RawOccupancy file");
1476 return StatusCode::FAILURE;
1477 }
1478 if (wrapUpXML4Summary(m_outROSummary, "RawOccupancy", summaryList).isFailure()) {
1479 ATH_MSG_ERROR("Problem in closing RawOccupancy file ");
1480 return StatusCode::FAILURE;
1481 }
1482
1483 //--- DB output
1484 if (m_writeToCool) {
1485 if (m_pCalibWriteTool->wrapUpRawOccupancy().isFailure()) {
1486 ATH_MSG_ERROR("Could not get RawOccupancy");
1487 return StatusCode::FAILURE;
1488 }
1489 }
1490
1491 return StatusCode::SUCCESS;
1492}
1493
1494
1499StatusCode SCTCalib::getEfficiency ATLAS_NOT_THREAD_SAFE () { // Thread unsafe SCTCalibWriteTool::createListEff method is used.
1500 ATH_MSG_INFO("----- in getEfficiency() -----");
1501
1502 //--- Initialization
1503 int n_phiBinsBarrel[n_barrels] = {n_phiBinsB0, n_phiBinsB1, n_phiBinsB2, n_phiBinsB3};
1504 int n_phiBinsEndcap[n_disks][n_etaBinsEC] = {{n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1505 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1506 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1507 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1508 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1509 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1510 {n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1511 {n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1512 {n_phiBinsECOuter, 0, 0}
1513 };
1514
1515 double meanEff_Barrel[n_barrels] = {0};
1516 double meanEff_ECA[n_disks][n_etaBinsEC] = {{0}, {0}};
1517 double meanEff_ECC[n_disks][n_etaBinsEC] = {{0}, {0}};
1518
1519 double meanEff_Barrel_bcid1[ n_barrels ] = { 0 };
1520 double meanEff_ECA_bcid1[ n_disks ][ n_etaBinsEC ] = { {0}, {0} };
1521 double meanEff_ECC_bcid1[ n_disks ][ n_etaBinsEC ] = { {0}, {0} };
1522
1523 //--- Directory in HIST
1524 std::vector<std::pair<std::string, int>> EC_stems;
1525 EC_stems.clear();
1526 std::pair<std::string, int> stem_C{"/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTEC/eff/", ENDCAP_C};
1527 std::pair<std::string, int> stem_A{"/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTEA/eff/", ENDCAP_A};
1528 EC_stems.push_back(std::move(stem_C));
1529 EC_stems.push_back(std::move(stem_A));
1530 std::vector<std::pair<std::string, int>>::iterator stemItr{EC_stems.begin()};
1531
1532 const char* outputEfficiencyFileName{m_efficiencyModuleFile.value().c_str()};
1533 std::ofstream outFile{outputEfficiencyFileName, std::ios::out};
1534 if (!outFile.good()) {
1535 ATH_MSG_ERROR("Unable to open EfficiencyFile : " << outputEfficiencyFileName);
1536 return StatusCode::FAILURE;
1537 }
1538
1539 std::string xslName{"EfficiencyInfo.xsl"};
1540 outFile << xmlHeader << linefeed << associateStylesheet(xslName) << linefeed << "<run>" << lineFeed;
1541 outFile << xmlValue("RunNumber", m_runNumber.value()) << linefeed
1542 << xmlValue("StartTime", m_utcBegin) << linefeed
1543 << xmlValue("EndTime", m_utcEnd) << linefeed
1544 << xmlValue("Duration", m_calibEvtInfoTool->duration()) << linefeed
1545 << xmlValue("LB", m_LBRange) << linefeed
1546 << xmlValue("Events", m_numberOfEvents) << linefeed
1547 << " <modules>" << lineFeed;
1548
1549 const char* outputEfficiencyFileNameChip{m_efficiencyChipFile.value().c_str()};
1550 std::ofstream outFileChip{outputEfficiencyFileNameChip, std::ios::out};
1551 if (!outFileChip.good()) {
1552 ATH_MSG_ERROR("Unable to open EfficiencyFile for chips : " << outputEfficiencyFileNameChip);
1553 return StatusCode::FAILURE;
1554 }
1555
1556 if (m_efficiencyDoChips) {
1557 std::string xslNameChip{"EfficiencyChipInfo.xsl"};
1558 outFileChip << xmlHeader << linefeed << associateStylesheet(xslNameChip) << linefeed << "<run>" << lineFeed;
1559 outFileChip << xmlValue("RunNumber", m_runNumber.value()) << linefeed
1560 << xmlValue("StartTime", m_utcBegin) << linefeed
1561 << xmlValue("EndTime", m_utcEnd) << linefeed
1562 << xmlValue("Duration", m_calibEvtInfoTool->duration()) << linefeed
1563 << xmlValue("LB", m_LBRange) << linefeed
1564 << xmlValue("Events", m_numberOfEvents) << linefeed
1565 << " <chips>" << lineFeed;
1566 }
1567
1568 //--- Endcaps
1569 for (stemItr=EC_stems.begin(); stemItr!=EC_stems.end(); ++stemItr) {
1570 for (int iDisk{0}; iDisk<n_disks; ++iDisk) {
1571 for (int iSide{0}; iSide<2; ++iSide) {
1572 for (int iEta{0}; iEta<n_etaBinsEC; ++iEta) {
1573 for (int iPhi{0}; iPhi<n_phiBinsEndcap[iDisk][iEta]; ++iPhi) {
1574 Identifier waferId = m_pSCTHelper->wafer_id((*stemItr).second, iDisk, iPhi, iEta, iSide);
1575 std::string detector_part;
1576 detector_part.erase();
1577 std::ostringstream streamProf;
1578 if ((*stemItr).second==ENDCAP_C) {
1579 detector_part = "m_eff";
1580 streamProf << detector_part << "_" << iDisk << "_" << iSide;
1581 } else {
1582 detector_part = "p_eff";
1583 streamProf << detector_part << "_" << iDisk << "_" << iSide;
1584 }
1585 std::string effmapname{stemItr->first + streamProf.str()};
1586 TProfile2D* prof_tmp{static_cast<TProfile2D*>(m_inputHist->Get(effmapname.c_str()))};
1587 int global_bin{prof_tmp->GetBin(iEta+1, iPhi+1)};
1588 float eff{static_cast<float>(prof_tmp->GetBinContent(global_bin))};
1589 unsigned long long eff_entry{static_cast<unsigned long long>(prof_tmp->GetBinEntries(global_bin))};
1590
1591 //--- For calculating average Efficiency
1592 if (stemItr->second==ENDCAP_C) meanEff_ECC[iDisk][iEta] += static_cast<double>(eff);
1593 else if (stemItr->second==ENDCAP_A) meanEff_ECA[iDisk][iEta] += static_cast<double>(eff);
1594
1595 std::string effmapname_bcid1 = effmapname+"_bcid";
1596 TProfile2D* prof_tmp_bcid1 = (TProfile2D*) m_inputHist->Get( effmapname_bcid1.c_str() );
1597 int global_bin_bcid1 = prof_tmp_bcid1->GetBin( iEta+1, iPhi+1 );
1598 float eff_bcid1 = (float)prof_tmp_bcid1->GetBinContent( global_bin_bcid1 );
1599
1600 //--- For calculating average Efficiency (BCID1)
1601 if( stemItr->second==ENDCAP_C ) meanEff_ECC_bcid1[iDisk][iEta]+=(double)eff_bcid1;
1602 else if( stemItr->second==ENDCAP_A ) meanEff_ECA_bcid1[iDisk][iEta]+=(double)eff_bcid1;
1603
1604 //--- Write out Efficiency to XML file as -1 if it is 0 due to no entries in histogram (e.g. for disabled links)
1605 float effToXML = (eff_entry == 0 ? -1. : eff);
1606
1607 //--- For Efficiency _not_ averaged over modules
1608 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
1609 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
1610 outFile << xmlChannelEfficiencyDataString(waferId, effToXML, sn, iSide) << lineFeed;
1611
1612 //--- Loop over chips
1613 if (m_efficiencyDoChips) {
1614 for (int iChip{0}; iChip<n_chipPerSide; ++iChip) {
1615 std::string detector_part_chip;
1616 detector_part_chip.erase();
1617 std::ostringstream streamProfChip;
1618 if ((*stemItr).second==ENDCAP_C) {
1619 detector_part_chip = "m_eff";
1620 streamProfChip << detector_part_chip << "_" << "chip" << iChip<< "_" << iDisk << "_" << iSide;
1621 } else {
1622 detector_part_chip = "p_eff";
1623 streamProfChip << detector_part_chip << "_" << "chip" << iChip<< "_" << iDisk << "_" << iSide;
1624 }
1625 std::string effchipmapname{stemItr->first + "chip" + std::to_string(iChip) + "/" + streamProfChip.str()};
1626 TProfile2D* profChip_tmp{static_cast<TProfile2D*>(m_inputHist->Get(effchipmapname.c_str()))};
1627 global_bin = profChip_tmp->GetBin(iEta+1, iPhi+1);
1628 float effChip{static_cast<float>(profChip_tmp->GetBinContent(global_bin))};
1629 unsigned long long effChip_entry{static_cast<unsigned long long>(profChip_tmp->GetBinEntries(global_bin))};
1630
1631 //--- Write out Efficiency to XML file as -1 if it is 0 due to no entries in histogram (e.g. for disabled links)
1632 effToXML = (effChip_entry == 0 ? -1. : effChip);
1633
1634 std::string effchipmapname_bcid1 = effchipmapname+"_bcid";
1635 TProfile2D* profChip_tmp_bcid1 = (TProfile2D*) m_inputHist->Get( effchipmapname_bcid1.c_str() );
1636 global_bin_bcid1 = profChip_tmp_bcid1->GetBin( iEta+1, iPhi+1 );
1637 eff_bcid1 = (float)profChip_tmp_bcid1->GetBinContent( global_bin_bcid1 );
1638 outFileChip << xmlChannelEfficiencyDataStringChip(waferId, effToXML, eff_bcid1, sn, iSide, iChip) << lineFeed;
1639 }
1640 }
1641
1642 //--- DB writing
1643 if (m_writeToCool) {
1644 if (m_pCalibWriteTool->createListEff(waferId, m_pSCTHelper, eff_entry, eff).isFailure()) {
1645 ATH_MSG_ERROR("Unable to run createListEff");
1646 return StatusCode::FAILURE;
1647 }
1648 }
1649 }
1650 }
1651 }
1652 }
1653 }
1654 //--- Barrel
1655 for (int iLayer{0}; iLayer<n_barrels; ++iLayer) {
1656 for (int iSide{0}; iSide<2; ++iSide) {
1657 for (int iEta{0}; iEta<n_etaBins; ++iEta) {
1658 if (iEta-6==0) continue;
1659 for (int iPhi{0}; iPhi<n_phiBinsBarrel[iLayer]; ++iPhi) {
1660 Identifier waferId{m_pSCTHelper->wafer_id(BARREL, iLayer, iPhi, iEta-6, iSide)};
1661 std::ostringstream streamProf;
1662 streamProf << iLayer << "_" << iSide;
1663
1664 std::string effmapname{"/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTB/eff/eff_" + streamProf.str()};
1665 TProfile2D* prof_tmp{static_cast<TProfile2D*>(m_inputHist->Get(effmapname.c_str()))};
1666 int global_bin{prof_tmp->GetBin(iEta+1, iPhi+1)};
1667 float eff{static_cast<float>(prof_tmp->GetBinContent(global_bin))};
1668 unsigned long long eff_entry{static_cast<unsigned long long>(prof_tmp->GetBinEntries(global_bin))};
1669
1670 //--- For calculating average Efficiency
1671 meanEff_Barrel[iLayer] += static_cast<double>(eff);
1672
1673 std::string effmapname_bcid1 = effmapname+"_bcid";
1674 TProfile2D* prof_tmp_bcid1 = (TProfile2D*) m_inputHist->Get( effmapname_bcid1.c_str() );
1675 int global_bin_bcid1 = prof_tmp_bcid1->GetBin( iEta+1, iPhi+1 );
1676 float eff_bcid1 = (float)prof_tmp_bcid1->GetBinContent( global_bin_bcid1 );
1677
1678 //--- For calculating average Efficiency (BCID1)
1679 meanEff_Barrel_bcid1[iLayer]+=(double)eff_bcid1;
1680
1681 //--- Write out Efficiency to XML file as -1 if it is 0 due to no entries in histogram (e.g. for disabled links)
1682 float effToXML = (eff_entry == 0 ? -1. : eff);
1683
1684 //--- For Efficiency _not_ averaged over modules
1685 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
1686 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
1687 outFile << xmlChannelEfficiencyDataString(waferId, effToXML, sn, iSide) << lineFeed;
1688
1689 //--- Loop over chips
1690 if (m_efficiencyDoChips) {
1691 for (int iChip{0}; iChip<n_chipPerSide; ++iChip) {
1692 std::ostringstream streamProfChip;
1693 streamProfChip << "chip" << iChip << "_" << iLayer << "_" << iSide;
1694
1695 std::string effchipmapname{"/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTB/eff/chip" + std::to_string(iChip) + "/eff_" + streamProfChip.str()};
1696 TProfile2D* profChip_tmp{static_cast<TProfile2D*>(m_inputHist->Get(effchipmapname.c_str()))};
1697 global_bin = profChip_tmp->GetBin(iEta+1, iPhi+1);
1698 float effChip{static_cast<float>(profChip_tmp->GetBinContent(global_bin))};
1699 unsigned long long effChip_entry{static_cast<unsigned long long>(profChip_tmp->GetBinEntries(global_bin))};
1700
1701 //--- Write out Efficiency to XML file as -1 if it is 0 due to no entries in histogram (e.g. for disabled links)
1702 effToXML = (effChip_entry == 0 ? -1. : effChip);
1703
1704 std::string effchipmapname_bcid1 = effchipmapname+"_bcid";
1705 TProfile2D* profChip_tmp_bcid1 = (TProfile2D*) m_inputHist->Get( effchipmapname_bcid1.c_str() );
1706 int global_bin_bcid1 = profChip_tmp_bcid1->GetBin( iEta+1, iPhi+1 );
1707 float eff_bcid1 = (float)profChip_tmp_bcid1->GetBinContent( global_bin_bcid1 );
1708
1709 outFileChip << xmlChannelEfficiencyDataStringChip(waferId, effToXML, eff_bcid1, sn, iSide, iChip) << lineFeed;
1710 }
1711 }
1712
1713 //--- DB writing
1714 if (m_writeToCool) {
1715 if (m_pCalibWriteTool->createListEff(waferId, m_pSCTHelper, eff_entry, eff).isFailure()) {
1716 ATH_MSG_ERROR("Unable to run createListEff");
1717 return StatusCode::FAILURE;
1718 }
1719 }
1720 }
1721 }
1722 }
1723 }
1724
1725 outFile << " </modules>\n" ;
1726 outFile << "</run>\n" ;
1727
1728 if (m_efficiencyDoChips) {
1729 outFileChip << " </chips>\n";
1730 outFileChip << "</run>\n";
1731 }
1732
1733 //--- Summary XML output
1734 std::ostringstream summaryList;
1735 static const std::string meanEffStr{"meanEff"};
1736 static const std::string meanEffBcidStr{"meanEff_bcid1"};
1737 for (int i{0}; i < n_disks; ++i) {
1738 for (int j{0}; j < n_etaBinsEC; ++j) {
1739 if (n_phiBinsEndcap[i][j] != 0) {
1740 meanEff_ECC[i][j] /= (n_phiBinsEndcap[i][j]*2);
1741 summaryList << xmlPartData(ENDCAP_C, i, j, meanEffStr, meanEff_ECC[i][j]);
1742 meanEff_ECC_bcid1[i][j] /= (n_phiBinsEndcap[i][j]*2);
1743 summaryList<<xmlPartData(ENDCAP_C, i, j, meanEffBcidStr,meanEff_ECC_bcid1[i][j]);
1744 }
1745 }
1746 }
1747 for (int i{0}; i < n_barrels; ++i) {
1748 meanEff_Barrel[i] /= (n_phiBinsBarrel[i]*n_etaInBarrel*2);
1749 summaryList << xmlPartData(BARREL, i, 0, meanEffStr, meanEff_Barrel[i]);
1750 meanEff_Barrel_bcid1[i] /= (n_phiBinsBarrel[i]*n_etaInBarrel*2);
1751 summaryList<<xmlPartData(BARREL, i, 0, meanEffBcidStr,meanEff_Barrel_bcid1[i]);
1752 }
1753 for (int i{0}; i < n_disks; ++i) {
1754 for (int j{0}; j < n_etaBinsEC; ++j) {
1755 if (n_phiBinsEndcap[i][j] != 0) {
1756 meanEff_ECA[i][j] /= (n_phiBinsEndcap[i][j]*2);
1757 summaryList << xmlPartData(ENDCAP_A, i, j, meanEffStr, meanEff_ECA[i][j]);
1758 meanEff_ECA_bcid1[i][j] /= (n_phiBinsEndcap[i][j]*2);
1759 summaryList<<xmlPartData(ENDCAP_A, i, j, meanEffBcidStr,meanEff_ECA_bcid1[i][j]);
1760 }
1761 }
1762 }
1763
1764 if (openXML4MonSummary(m_outEffSummary, "Efficiency").isFailure()) {
1765 ATH_MSG_ERROR("Problem in opening Efficiency file");
1766 return StatusCode::FAILURE;
1767 }
1768
1769 if (wrapUpXML4Summary(m_outEffSummary, "Efficiency", summaryList).isFailure()) {
1770 ATH_MSG_ERROR("Problem in closing Efficiency file ");
1771 return StatusCode::FAILURE;
1772 }
1773
1774 //--- DB output
1775 if (m_writeToCool) {
1776 if (m_pCalibWriteTool->wrapUpEfficiency().isFailure()) {
1777 ATH_MSG_ERROR("Could not get Efficiency");
1778 return StatusCode::FAILURE;
1779 }
1780 }
1781
1782 return StatusCode::SUCCESS;
1783}
1784
1785
1790StatusCode SCTCalib::getBSErrors ATLAS_NOT_THREAD_SAFE () { // Thread unsafe SCTCalibWriteTool::createListBSErr method is used.
1791 ATH_MSG_INFO("----- in getBSErrors() -----");
1792
1793 //--- Initialization
1794 int n_phiBinsBarrel[n_barrels] = {n_phiBinsB0, n_phiBinsB1, n_phiBinsB2, n_phiBinsB3};
1795 int n_phiBinsEndcap[n_disks][n_etaBinsEC] = {{n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1796 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1797 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1798 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1799 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1800 {n_phiBinsECOuter, n_phiBinsECMiddle, n_phiBinsECShort},
1801 {n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1802 {n_phiBinsECOuter, n_phiBinsECMiddle, 0},
1803 {n_phiBinsECOuter, 0, 0}
1804 };
1805
1806 unsigned long long nErrLink_Barrel[n_barrels]{};
1807 unsigned long long nErrLink_ECA[n_disks][n_etaBinsEC]{};
1808 unsigned long long nErrLink_ECC[n_disks][n_etaBinsEC]{};
1809
1810 unsigned long long nErrLink_Barrel_module[n_barrels][2][n_etaBins][n_phiBinsB3]{};
1811 unsigned long long nErrLink_ECA_module[n_disks][2][n_etaBinsEC][n_phiBinsECOuter]{};
1812 unsigned long long nErrLink_ECC_module[n_disks][2][n_etaBinsEC][n_phiBinsECOuter]{};
1813
1814 std::string nErrLink_Barrel_module_serial[n_barrels][2][n_etaBins][n_phiBinsB3];
1815 std::string nErrLink_ECA_module_serial[n_disks][2][n_etaBinsEC][n_phiBinsECOuter];
1816 std::string nErrLink_ECC_module_serial[n_disks][2][n_etaBinsEC][n_phiBinsECOuter];
1817
1818 float nErrs_Barrel_module[n_barrels][2][n_etaBins][n_phiBinsB3][15]{};
1819 float nErrs_ECA_module[n_disks][2][n_etaBinsEC][n_phiBinsECOuter][15]{};
1820 float nErrs_ECC_module[n_disks][2][n_etaBinsEC][n_phiBinsECOuter][15]{};
1821
1822 //--- ErrorList
1823 using IntStringMap = std::map<int, std::string>;
1824 IntStringMap ErrMap_C, ErrMap;
1825 const int numberOfErrorTypes{12};
1826 std::array<std::string, numberOfErrorTypes> errorNames = {{
1827 "ByteStreamParseError","TimeOutError","BCIDError","LVL1IDError","PreambleError","FormatterError",
1828 "ABCDError","RawError","MaskedLink","RODClockError",
1829 "TruncatedROD","ROBFragmentError"
1830 }
1831 };
1832 //
1833 std::array<std::string, numberOfErrorTypes> errorNames_C = {{
1834 "ByteStreamParseError","TimeOutError","BCIDError","LVL1IDError","PreambleError","FormatterError",
1835 "ABCDError","RawError","MaskedLink","RODClockError",
1836 "TruncatedROD","ROBFragmentError"
1837 }
1838 };
1839 std::array<int, numberOfErrorTypes> errorValues = {{0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 14}};
1840 //should do compile time check to ensure the sizes are equal.
1841 ErrMap_C.clear();
1842 for (int indx{0}; indx!=numberOfErrorTypes; ++indx) {
1843 ErrMap_C.insert(std::make_pair(errorValues[indx], errorNames_C[indx]));
1844 }
1845 ErrMap.clear();
1846 for (int indx{0}; indx!=numberOfErrorTypes; ++indx) {
1847 ErrMap.insert(std::make_pair(errorValues[indx], errorNames[indx]));
1848 }
1849
1850 //--- Directory in HIST
1851 const int N_ENDCAPS{2};
1852 std::array<std::string, N_ENDCAPS> detectorStems = {{"/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTEC/errors/", "/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTEA/errors/"}}; //barrel stem unused here
1853 std::array<IntStringMap::iterator, N_ENDCAPS> detectorIterators = {{ErrMap_C.begin(), ErrMap.begin()}};
1854 std::array<IntStringMap::iterator, N_ENDCAPS> detectorIteratorsE = {{ErrMap_C.end(), ErrMap.end()}};
1855 std::array<std::string, N_ENDCAPS> detectorParts = {{"EC", "EA"}};
1856 std::string defecttype{""};
1857 std::string n_defect{""};
1858 int n_errorLink{0};
1859 //--- Endcaps
1860 for (int stemIndex{0}; stemIndex!=N_ENDCAPS; ++stemIndex) {
1861 const int thisBec{(4 * stemIndex) - 2}; //map 0, 1 onto -2, 2
1862 const std::string detector_part{detectorParts[stemIndex]};
1863 for (int iDisk{0}; iDisk<n_disks; ++iDisk) {
1864 for (int iSide{0}; iSide<2; ++iSide) {
1865 for (int iEta{0}; iEta<n_etaBinsEC; ++iEta) {
1866 for (int iPhi{0}; iPhi<n_phiBinsEndcap[iDisk][iEta]; ++iPhi) {
1867 defecttype.erase();
1868 n_defect.erase();
1869 std::ostringstream osErrorList;
1870 std::ostringstream osProbList;
1871 Identifier waferId{m_pSCTHelper->wafer_id(thisBec, iDisk, iPhi, iEta, iSide)};
1872 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
1873 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
1874
1875 if (thisBec==ENDCAP_C) {
1876 nErrLink_ECC_module_serial[iDisk][iSide][iEta][iPhi]=sn.str();
1877 } else if (thisBec==ENDCAP_A) {
1878 nErrLink_ECA_module_serial[iDisk][iSide][iEta][iPhi]=sn.str();
1879 }
1880
1881 IntStringMap::iterator errItr{detectorIterators[stemIndex]};
1882 IntStringMap::iterator errItrE{detectorIteratorsE[stemIndex]};
1883 for (int iType{0}; iType < n_BSErrorType; ++iType) {
1884 float errorProb{0.};
1885 unsigned long long n_errors{0};
1886 if (errItr!=errItrE and iType == errItr->first) {
1887 std::ostringstream streamHist;
1888 std::ostringstream streamHistAlt;
1889 streamHist << "SCT_NumberOf" << errItr->second << detector_part << "_" << iDisk << "_" << iSide;
1890 streamHistAlt << "SCT_" << errItr->second << detector_part << "_" << iDisk << "_" << iSide;
1891 std::string folder = errItr->second+std::string("/");
1892 //histogram might or might not be inside a folder with the same name
1893 std::string profname = detectorStems[stemIndex] + folder +streamHist.str();
1894 std::string profnameShort = detectorStems[stemIndex] + streamHist.str();
1895 std::string profnameAlt = detectorStems[stemIndex] + folder +streamHistAlt.str();
1896 std::string profnameAltShort = detectorStems[stemIndex] + streamHistAlt.str();
1897
1898 TProfile2D* prof_tmp = (TProfile2D*) m_inputHist->Get( profname.c_str() );
1899 if(prof_tmp ==nullptr) {
1900 prof_tmp = (TProfile2D*) m_inputHist->Get( profnameShort.c_str() );
1901 }
1902 if(prof_tmp ==nullptr) {
1903 prof_tmp = (TProfile2D*) m_inputHist->Get( profnameAlt.c_str() );
1904 }
1905 if(prof_tmp ==nullptr) {
1906 prof_tmp = (TProfile2D*) m_inputHist->Get( profnameAltShort.c_str() );
1907 }
1908 if(prof_tmp ==nullptr) {
1909 msg( MSG::ERROR ) << "Unable to get profile for BSErrorsDB : " << profname << endmsg;
1910 return StatusCode::FAILURE;
1911 }
1912
1913 float n_errors_float = prof_tmp->GetBinContent(iEta+1, iPhi+1);
1914 if (n_errors_float != 0){
1915 if (thisBec==ENDCAP_C) {
1916 nErrs_ECC_module[iDisk][iSide][iEta][iPhi][errItr->first] = n_errors_float;
1917 } else if (thisBec==ENDCAP_A) {
1918 nErrs_ECA_module[iDisk][iSide][iEta][iPhi][errItr->first] = n_errors_float;
1919 }
1920 }
1921
1922 n_errors = static_cast<unsigned long long>(n_errors_float);
1923 if (n_errors!=0) {
1924 defecttype = m_pCalibWriteTool->addNumber(defecttype, errItr->first);
1925 n_defect = m_pCalibWriteTool->addNumber(n_defect, n_errors);
1926 errorProb = static_cast<float>(n_errors) / static_cast<float>(m_numberOfEvents);
1927 if (thisBec==ENDCAP_C) {
1928 nErrLink_ECC_module[iDisk][iSide][iEta][iPhi]+=n_errors;
1929 } else if (thisBec==ENDCAP_A) {
1930 nErrLink_ECA_module[iDisk][iSide][iEta][iPhi]+=n_errors;
1931 }
1932
1933 }//end if (n_errors!=0)
1934 ++errItr;
1935 }//end if (iType == (*errItr).first)
1936 osErrorList << n_errors;
1937 osProbList << errorProb;
1938 if (iType != n_BSErrorType-1) {
1939 osErrorList << " ";
1940 osProbList << " ";
1941 }
1942 }//end ErrorType Loop
1943 //--- DB writing
1944 if (!(defecttype.empty()) || n_errorLink == 0) {
1945 n_errorLink++;
1946 if (thisBec==ENDCAP_C) {
1947 nErrLink_ECC[iDisk][iEta]++;
1948 } else if (thisBec==ENDCAP_A) {
1949 nErrLink_ECA[iDisk][iEta]++;
1950 }
1951 if (m_writeToCool) {
1952 if (m_pCalibWriteTool->createListBSErr(waferId, m_pSCTHelper, m_numberOfEvents, osErrorList.str(), osProbList.str()).isFailure()) {
1953 ATH_MSG_ERROR("Unable to run createListBSError");
1954 return StatusCode::FAILURE;
1955 }
1956 }
1957 }
1958 }// end of for iPhi
1959 }//implicit end of iEta
1960 }//implicit end of iside
1961 }//implicit end of iDisk
1962 }//end of stemIndex loop
1963 //--- Barrel
1964 for (int iLayer{0}; iLayer<n_barrels; ++iLayer) {
1965 for (int iSide{0}; iSide<2; ++iSide) {
1966 for (int iEta{0}; iEta<n_etaBins; ++iEta) {
1967 if (iEta-6==0) continue;
1968 for (int iPhi{0}; iPhi<n_phiBinsBarrel[iLayer]; ++iPhi) {
1969 defecttype.erase();
1970 n_defect.erase();
1971 std::ostringstream osErrorList;
1972 std::ostringstream osProbList;
1973 Identifier waferId{m_pSCTHelper->wafer_id(BARREL, iLayer, iPhi, iEta-6, iSide)};
1974 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
1975 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
1976 nErrLink_Barrel_module_serial[iLayer][iSide][iEta][iPhi] = sn.str();
1977 IntStringMap::iterator errItr{ErrMap.begin()};
1978 IntStringMap::iterator errItrE{ErrMap.end()};
1979 for (int iType{0}; iType < n_BSErrorType; ++iType) {
1980 float errorProb{0.};
1981 unsigned long long n_errors{0};
1982 if (errItr!=errItrE and iType == errItr->first) {
1983 std::ostringstream streamHist;
1984 streamHist << "SCT_NumberOf" << errItr->second << "B" << "_" << iLayer << "_" << iSide;
1985 //histogram or might not be inside a folder with the same name
1986 std::string folder = errItr->second+std::string("/");
1987 std::string profname = "/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTB/errors/" + folder + streamHist.str();
1988 std::string profnameShort = "/run_" + std::to_string(m_runNumber.value()) + "/SCT/SCTB/errors/" + streamHist.str();
1989
1990 TProfile2D* prof_tmp = (TProfile2D*) m_inputHist->Get( profname.c_str() );
1991 if(prof_tmp ==nullptr) {
1992 prof_tmp = (TProfile2D*) m_inputHist->Get( profnameShort.c_str() );
1993 }
1994 if(prof_tmp ==nullptr) {
1995 msg( MSG::ERROR ) << "Unable to get profile for BSErrorsDB : " << profname << endmsg;
1996 return StatusCode::FAILURE;
1997 }
1998
1999 float n_errors_float = prof_tmp->GetBinContent(iEta+1, iPhi+1);
2000 if (n_errors_float != 0){
2001 nErrs_Barrel_module[iLayer][iSide][iEta][iPhi][errItr->first] = n_errors_float;
2002 }
2003
2004 n_errors = static_cast<unsigned long long>(n_errors_float);
2005 if (n_errors!=0) {
2006 defecttype = m_pCalibWriteTool->addNumber(defecttype, errItr->first);
2007 n_defect = m_pCalibWriteTool->addNumber(n_defect, n_errors);
2008 errorProb = static_cast<float>(n_errors) / static_cast<float>(m_numberOfEvents);
2009 nErrLink_Barrel_module[iLayer][iSide][iEta][iPhi]+=n_errors;
2010
2011 }//end if (n_errors!=0)
2012 ++errItr;
2013 }//end if (iType == (*errItr).first)
2014 osErrorList << n_errors;
2015 osProbList << errorProb;
2016 if (iType != n_BSErrorType-1) {
2017 osErrorList << " ";
2018 osProbList << " ";
2019 }
2020 } //end ErrorType Loop
2021 //--- DB writing
2022 if (!(defecttype.empty())) {
2023 n_errorLink++;
2024 nErrLink_Barrel[iLayer]++;
2025 if (m_writeToCool) {
2026 if (m_pCalibWriteTool->createListBSErr(waferId, m_pSCTHelper, m_numberOfEvents, osErrorList.str(), osProbList.str()).isFailure()) {
2027 ATH_MSG_ERROR("Unable to run createListBSError");
2028 return StatusCode::FAILURE;
2029 }
2030 }//end of if m_writeToCool
2031 } //end of if defecttype empty
2032 }//end of for iPhi
2033 }//endof for iEta, implicit end of for iSide and iLayer
2034 }
2035 }
2036
2037 ATH_MSG_INFO("#Links which send BSError : " << n_errorLink);
2038
2039 //--- Summary XML output
2040 std::ostringstream summaryList;
2041 static const std::string errLinkStr{"nErrLink"};
2042 for (int i{0}; i < n_disks; ++i) {
2043 for (int j{0}; j < n_etaBinsEC; ++j) {
2044 if (n_phiBinsEndcap[i][j] != 0) {
2045 summaryList << xmlPartData(ENDCAP_C, i, j, errLinkStr, nErrLink_ECC[i][j]);
2046 }
2047 }
2048 }
2049 for (int i{0}; i < n_barrels; ++i) {
2050 summaryList << xmlPartData(BARREL, i, 0, errLinkStr, nErrLink_Barrel[i]);
2051 }
2052
2053 for (int i{0}; i < n_disks; ++i) {
2054 for (int j{0}; j < n_etaBinsEC; ++j) {
2055 if (n_phiBinsEndcap[i][j] != 0) {
2056 summaryList << xmlPartData(ENDCAP_A, i, j, errLinkStr, nErrLink_ECA[i][j]);
2057 }
2058 }
2059 }
2060
2061 if (openXML4MonSummary(m_outBSErrSummary, "BSErrors").isFailure()) {
2062 ATH_MSG_ERROR("Problem in opening BSErrors file");
2063 return StatusCode::FAILURE;
2064 }
2065 if (wrapUpXML4Summary(m_outBSErrSummary, "BSErrors", summaryList).isFailure()) {
2066 ATH_MSG_ERROR("Problem in closing BSErrors file");
2067 return StatusCode::FAILURE;
2068 }
2069
2070 //module XML output
2071 std::ostringstream moduleList;
2072 std::string serial;
2073 for (int i{0}; i < n_disks; ++i) {
2074 for (int j{0}; j < n_etaBinsEC; ++j) {
2075 if (n_phiBinsEndcap[i][j] != 0) {
2076 for (int k{0}; k < 2; k++) {
2077 for (int l{0}; l < n_phiBinsEndcap[i][j]; l++) {
2078 serial = nErrLink_ECC_module_serial[i][k][j][l];
2079
2080 //fill ostringstream with number of error of each type for one particular module
2081 std::ostringstream errList;
2082 for (int errCount{0}; errCount < numberOfErrorTypes; errCount++) {
2083 int type{errorValues[errCount]}; //
2084 errList << " " << xmlValue(ErrMap[type], nErrs_ECC_module[i][k][j][l][type]) << lineFeed;
2085 }
2086
2087 moduleList << xmlModuleData(ENDCAP_C, i, k, j, l, "nErrors", nErrLink_ECC_module[i][k][j][l], serial, errList.str());
2088
2089 }
2090 }
2091 }
2092 }
2093 }
2094
2095
2096 for (int i{0}; i < n_barrels; i++) {
2097 for (int j{0}; j < 2; j++) {
2098 for (int k{0}; k < n_etaBins; k++) {
2099 for (int l{0}; l < n_phiBinsBarrel[i] ; l++) {
2100 serial = nErrLink_Barrel_module_serial[i][j][k][l];
2101
2102 std::ostringstream errList;
2103 for (int errCount{0}; errCount < numberOfErrorTypes; errCount++) {
2104 int type{errorValues[errCount]}; //
2105 errList << " " << xmlValue(ErrMap[type], nErrs_Barrel_module[i][j][k][l][type]) << lineFeed;
2106 }
2107
2108 moduleList << xmlModuleData(BARREL, i, j, k, l, "nErrors", nErrLink_Barrel_module[i][j][k][l], serial, errList.str());
2109 }
2110 }
2111 }
2112 }
2113
2114 for (int i{0}; i < n_disks; ++i) {
2115 for (int j{0}; j < n_etaBinsEC; ++j) {
2116 if (n_phiBinsEndcap[i][j] != 0) {
2117 for (int k{0}; k < 2; k++) {
2118 for (int l{0}; l < n_phiBinsEndcap[i][j]; l++) {
2119 serial = nErrLink_ECA_module_serial[i][k][j][l];
2120
2121 std::ostringstream errList;
2122 for (int errCount{0}; errCount < numberOfErrorTypes; errCount++) {
2123 int type{errorValues[errCount]}; //
2124 errList << " " << xmlValue(ErrMap[type], nErrs_ECA_module[i][k][j][l][type]) << lineFeed;
2125 }
2126
2127 moduleList << xmlModuleData(ENDCAP_A, i, k, j, l, "nErrors", nErrLink_ECA_module[i][k][j][l], serial, errList.str());
2128 }
2129 }
2130 }
2131 }
2132 }
2133
2134 if (openXML4MonSummary(m_outBSErrModule, "BSErrorsModule").isFailure()) {
2135 ATH_MSG_ERROR("Problem in opening BSErrorsModule file");
2136 return StatusCode::FAILURE;
2137 }
2138 if (wrapUpXML4Summary(m_outBSErrModule, "BSErrors", moduleList).isFailure()) {
2139 ATH_MSG_ERROR("Problem in closing BSErrors file");
2140 return StatusCode::FAILURE;
2141 }
2142
2143 //--- DB output
2144 if (m_writeToCool) {
2145 if (m_pCalibWriteTool->wrapUpBSErrors().isFailure()) {
2146 ATH_MSG_ERROR("Could not get ByteStream Errors");
2147 return StatusCode::FAILURE;
2148 }
2149 }
2150
2151 return StatusCode::SUCCESS;
2152}
2153
2154
2159StatusCode SCTCalib::getLorentzAngle ATLAS_NOT_THREAD_SAFE () { // Thread unsafe SCTCalibWriteTool::createListLA method is used.
2160 ATH_MSG_INFO("----- in getLorentzAngle() -----");
2161
2162 //--- Initialization
2163
2164 float A_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2165 float LA_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2166 float B_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2167 float Sigma_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2168
2169 float Err_A_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2170 float Err_LA_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2171 float Err_B_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2172 float Err_Sigma_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2173
2174 float MCW_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2175 float Err_MCW_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2176 float Chisq_BarrelSide[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}};
2177
2178 std::string DBUploadFlag{"G"}; // fit status flag
2179 std::string module[2] = {"100", "111"};
2180 int moduleint[2] = {100, 111};
2181
2182 int FitFlag[n_barrels][2][2] = {{{0}, {0}}, {{0}, {0}}}; // fit status flag
2183
2184 TFile* fitFile;
2185
2186
2187 //--- Directory in HIST
2188 std::string stem;
2189
2190 //--- Barrel
2191 stem = "/run_" + std::to_string(m_runNumber.value()) + "/SCT/GENERAL/lorentz/";
2192 m_h_phiVsNstripsSideHistoVector.clear();
2193 for (int iLayer{0}; iLayer < n_barrels ; ++iLayer) {
2194 for (int iSide{0}; iSide < 2; ++iSide) {
2195 for (int iModule{0}; iModule < 2; ++iModule) {
2196 std::ostringstream streamHist;
2197 streamHist << "h_phiVsNstrips_" << module[iModule] << "_" << iLayer << "Side" << iSide;
2198 std::string histName{stem + streamHist.str()};
2199 TProfile* hist_tmp{static_cast<TProfile*>(m_inputHist->Get(histName.c_str()))};
2200 if (hist_tmp ==nullptr) {
2201 ATH_MSG_ERROR("Unable to get histogram for LorentzAngle : " << histName);
2202 return StatusCode::FAILURE;
2203 }
2204 m_h_phiVsNstripsSideHistoVector.push_back(hist_tmp);
2205 }
2206 }
2207 }
2208
2209 //--- XML file
2210 const char* outputLorentzAngleFileName{m_LorentzAngleFile.value().c_str()};
2211 std::ofstream outFile{outputLorentzAngleFileName, std::ios::out};
2212 if (!outFile.good()) {
2213 ATH_MSG_ERROR("Unable to open LorentzAngleFile : " << outputLorentzAngleFileName);
2214 return StatusCode::FAILURE;
2215 }
2216
2217 //--- Header for XML outputs
2218 std::ostringstream osHeader;
2219 osHeader << "<folder>" << lineFeed;
2220 outFile << osHeader.str();
2221
2222 fitFile = new TFile("FittingDebugFile.root", "RECREATE");
2223
2224 //--- Barrel
2225 for (int iLayer{0}; iLayer < n_barrels; ++iLayer) {
2226 for (int iSide{0}; iSide < 2; ++iSide) {
2227 for (int iModule{0}; iModule < 2; ++iModule) {
2228 if (iLayer==1 and iModule==0) continue; // Layer 1 doesn't contain 100 modules
2229 ATH_MSG_INFO("LorentzAngle fit start : " << 4*iLayer + iSide +1 + iModule << " / 16");
2230 Int_t fitResult;
2231 Double_t par[4], err_par[4];
2232 TF1* LAfit{new TF1{"LAfit", LA_func, -9., 2., 4}};
2233 std::ostringstream streamFile;
2234 streamFile << "h_phiVsNstrips_" << module[iModule] << "_" << iLayer << "Side" << iSide;
2235
2236 LAfit->SetParLimits(3, 0.1, 50.);
2237 LAfit->SetParNames("a", "LA", "b", "sigma");
2238 LAfit->SetParameters(1., -5., 1.13, 2.);
2239 fitResult = m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Fit("LAfit", "E", "", -9., 2.);
2240 LAfit->GetParameters(par);
2241 err_par[0] = LAfit->GetParError(0);
2242 err_par[1] = LAfit->GetParError(1);
2243 err_par[2] = LAfit->GetParError(2);
2244 err_par[3] = LAfit->GetParError(3);
2245
2246 //DEBUG MODE
2247 if (m_LorentzAngleDebugMode) {
2248 std::ostringstream streamFileTmp;
2249 streamFileTmp << "h_phiVsNstrips_" << module[iModule] << "_" << iLayer << "Side" << iSide << "_First_Fit";
2250 std::string dn{streamFile.str()};
2251 std::string tmp_hn{streamFileTmp.str()};
2252 const char* dir_name{dn.c_str()};
2253 const char* histo_name{tmp_hn.c_str()};
2254 fitFile->cd();
2255 fitFile->mkdir(dir_name); //Creating Directories
2256 fitFile->cd(dir_name);
2257 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->SetName(histo_name);
2258 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Write();
2259 ATH_MSG_INFO("-------:Directory Name: " << dir_name << "--------");
2260 }
2261
2262 if (fitResult != 0) {
2263 ATH_MSG_INFO("Try to use parabola Fit to determine initial value!");
2264 TF1* parafit{new TF1{"parafit", "[0]*(x-[1])*(x-[1])+[2]", -9., 2.}};
2265 ATH_MSG_INFO("LorentzAngle 2nd para fit start : " << 4*iLayer + iSide +1 + iModule << " / 16");
2266 parafit->SetParameters(par[0], par[1], LAfit->Eval(par[1], 0, 0, 0));
2267 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Fit("parafit", "R", "", -9., 2.);
2268 ATH_MSG_INFO("LorentzAngle 2nd pre fit start : " << 4*iLayer + iSide +1 + iModule << " / 16");
2269 par[1] = parafit->GetParameter(1);
2270 LAfit->SetParameters(par[0], par[1], par[2], par[3]);
2271 LAfit->SetParLimits(1, par[1], par[1]);
2272 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Fit("LAfit", "R", "", -9., 2.);
2273 LAfit->GetParameters(par);
2274 LAfit->SetParLimits(1, -90., 90.);
2275 LAfit->SetParameters(par[0], par[1], par[2], par[3]);
2276 ATH_MSG_INFO("LorentzAngle 2nd main fit start : " << 4*iLayer + iSide +1 + iModule << " / 16");
2277 fitResult = m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Fit("LAfit", "E", "", -9., 2.);
2278 LAfit->GetParameters(par);
2279 if (m_LorentzAngleDebugMode) {
2280 std::ostringstream streamFileTmp;
2281 streamFileTmp << "h_phiVsNstrips_" << module[iModule] << "_" << iLayer << "Side" << iSide << "Second_Fit";
2282 std::string tmp_hn{streamFileTmp.str()};
2283 const char* histo_name{tmp_hn.c_str()};
2284 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->SetName(histo_name);
2285 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Write();
2286 }
2287 }
2288
2289 if (fitResult != 0) {
2290 ATH_MSG_INFO("Try to fix one parameter sigma=2.0 to determine other initial value!");
2291 ATH_MSG_INFO("LorentzAngle 3rd pre fit start : " << 4*iLayer + iSide +1+ iModule << " / 16");
2292 LAfit->SetParameters(par[0], par[1], par[2], 2.);
2293 LAfit->SetParLimits(3, 2., 2.);
2294 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Fit("LAfit", "R", "", -9., 2.);
2295 LAfit->GetParameters(par);
2296 LAfit->SetParLimits(3, 0., 50.);
2297 LAfit->SetParameters(par[0], par[1], par[2], par[3]);
2298 ATH_MSG_INFO("LorentzAngle 3rd main fit start : " << 4*iLayer + iSide +1 +iModule << " / 16");
2299 fitResult = m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Fit("LAfit", "E", "", -9., 2.);
2300 LAfit->GetParameters(par);
2301 if (m_LorentzAngleDebugMode) {
2302 std::ostringstream streamFileTmp;
2303 streamFileTmp << "h_phiVsNstrips_" << module[iModule] << "_" << iLayer << "Side" << iSide << "Third_Fit";
2304 std::string tmp_hn{streamFileTmp.str()};
2305 const char* histo_name{tmp_hn.c_str()};
2306 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->SetName(histo_name);
2307 m_h_phiVsNstripsSideHistoVector[4*iLayer + 2*iSide +iModule]->Write();
2308 }
2309 }
2310
2311 if (fitResult == 0) {
2312 FitFlag[iLayer][iSide][iModule] = 1;
2313 } else {
2314 DBUploadFlag = "R";
2315 FitFlag[iLayer][iSide][iModule] = 0;
2316 ATH_MSG_WARNING("Fit Failed! Unable to get LorentzAngle");
2317 }
2318 double A{par[0]};
2319 double LA{par[1]}; // Lorentz Angle
2320 double B{par[2]};
2321 double sigma{par[3]};
2322 double err_A{err_par[0]};
2323 double err_LA{err_par[1]}; // Lorentz Angle
2324 double err_B{err_par[2]};
2325 double err_sigma{err_par[3]};
2326 float MCW{static_cast<float>(LAfit->Eval(LA, 0, 0, 0))}; //Min-cluster-width
2327 float err_MCW{static_cast<float>(LAfit->Eval(std::abs(err_par[1]), 0, 0, 0))}; //Min-cluster-width
2328
2329 A_BarrelSide[iLayer][iSide][iModule] = A;
2330 LA_BarrelSide[iLayer][iSide][iModule] = LA;
2331 B_BarrelSide[iLayer][iSide][iModule] = B;
2332 Sigma_BarrelSide[iLayer][iSide][iModule] = sigma;
2333 Err_A_BarrelSide[iLayer][iSide][iModule] = err_A;
2334 Err_LA_BarrelSide[iLayer][iSide][iModule] = err_LA;
2335 Err_B_BarrelSide[iLayer][iSide][iModule] = err_B;
2336 Err_Sigma_BarrelSide[iLayer][iSide][iModule] = err_sigma;
2337 MCW_BarrelSide[iLayer][iSide][iModule] = MCW;
2338 Err_MCW_BarrelSide[iLayer][iSide][iModule] = err_MCW;
2339 Chisq_BarrelSide[iLayer][iSide][iModule] = LAfit->GetChisquare();
2340 }
2341 }
2342 }
2343
2344 if (m_LorentzAngleDebugMode) {
2345 fitFile->Close();
2346 }
2347
2348 for (int iLayer{0}; iLayer < n_barrels; ++iLayer) {
2349 for (int iSide{0}; iSide < 2; ++iSide) {
2350 for (int iModule{0}; iModule < 2; ++iModule) {
2351 Identifier waferId{m_pSCTHelper->wafer_id(BARREL, iLayer, 0, 0, iSide)};
2352 int ch{0};
2353 outFile << "<folderDefinition folder=\"SCT/Derived/LorentzAngleRun2_v2\" version=\"multi\">" << linefeed
2354 << " <folderDescription>" << linefeed
2355 << " <timeStamp>run-lumi</timeStamp>" << linefeed
2356 << " <addrHeader>" << linefeed
2357 << " <address_header service_type=\"71\" clid=\"1238547719\">" << linefeed
2358 << " </addrHeader>" << linefeed
2359 << " <typeName>CondAttrListCollection</typeName>" << linefeed
2360 << " </folderDescription>" << linefeed
2361 << " <payloadDescription>" << linefeed
2362 << " <payloadType name=\"moduleType\">" << moduleint[iModule] << "</payloadType>" << linefeed
2363 << " <payloadType name=\"lorentzAngle\">" << LA_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2364 << " <payloadType name=\"err_lorentzAngle\">" << Err_LA_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2365 << " <payloadType name=\"chisq\">" << Chisq_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2366 << " <payloadType name=\"fitParam_a\">" << A_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2367 << " <payloadType name=\"err_a\">" << Err_A_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2368 << " <payloadType name=\"fitParam_b\">" << B_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2369 << " <payloadType name=\"err_b\">" << Err_B_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2370 << " <payloadType name=\"fitParam_sigma\">" << Sigma_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2371 << " <payloadType name=\"err_sigma\">" << Err_Sigma_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2372 << " <payloadType name=\"minClusterWidth\">" << MCW_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2373 << " <payloadType name=\"err_minClusterWidth\">" << Err_MCW_BarrelSide[iLayer][iSide][iModule] << "</payloadType>" << linefeed
2374 << " </payloadDescription>" << linefeed
2375 << " <channel id=\"" << ch << "\" name=\"" << iLayer << "_" << iSide << " \" />" << linefeed
2376 << "</folderDefinition>" << lineFeed;
2377
2378 ch++;
2379
2380 //--- DB output
2381 if (m_writeToCool) {
2382 if (m_pCalibWriteTool->createListLA(waferId, m_pSCTHelper, 10000, moduleint[iModule], LA_BarrelSide[iLayer][iSide][iModule], Err_LA_BarrelSide[iLayer][iSide][iModule], Chisq_BarrelSide[iLayer][iSide][iModule], A_BarrelSide[iLayer][iSide][iModule], Err_A_BarrelSide[iLayer][iSide][iModule], B_BarrelSide[iLayer][iSide][iModule], Err_B_BarrelSide[iLayer][iSide][iModule], Sigma_BarrelSide[iLayer][iSide][iModule], Err_Sigma_BarrelSide[iLayer][iSide][iModule], MCW_BarrelSide[iLayer][iSide][iModule], Err_MCW_BarrelSide[iLayer][iSide][iModule]).isFailure()) {
2383 ATH_MSG_ERROR("Unable to run createListLA");
2384 return StatusCode::FAILURE;
2385 }
2386 }
2387
2388 }
2389 }
2390 }
2391
2392 //--- Tail of XML outputs
2393 outFile << "</folder>" << lineFeed;
2394
2395 //--- Summary XML output
2396 std::ostringstream summaryList;
2397 for (int i{0}; i < n_barrels; ++i) {
2398 for (int iSide{0}; iSide < 2; ++iSide) {
2399 for (int iModule{0}; iModule < 2; ++iModule) {
2400 const std::string thisPart{shortNames[bec2Index(BARREL)]};
2401 summaryList << " <parts>" << linefeed
2402 << xmlValue("part", thisPart) << linefeed
2403 << xmlValue("layer", i) << linefeed
2404 << xmlValue("Side", iSide) << linefeed
2405 << xmlValue("Module", module[iModule]) << linefeed
2406 << xmlValue("lorentzAngle", LA_BarrelSide[i][iSide][iModule]) << linefeed
2407 << xmlValue("minClusterWidth", MCW_BarrelSide[i][iSide][iModule]) << linefeed
2408 << xmlValue("Fit", FitFlag[i][iSide][iModule]) << linefeed
2409 << " </parts>" << linefeed;
2410 }
2411 }
2412 }
2413
2414 std::ofstream& file{m_outLASummary};
2415 using TwoStrings = std::pair<std::string, std::string>;
2416 using Names = std::map<std::string, TwoStrings, std::less<>>;
2417 Names nameAssociation;
2418 nameAssociation["LorentzAngle"]=TwoStrings(m_LorentzAngleSummaryFile, "LorentzAngleInfo.xsl");
2419 Names::iterator found{nameAssociation.find("LorentzAngle")};
2420 if (found!=nameAssociation.end()) {
2421 std::string filename{found->second.first};
2422 std::string xslName{found->second.second};
2423 file.open(filename.c_str(), std::ios::out);
2424 if (!file.good()) return StatusCode::FAILURE;
2425 file << xmlHeader << linefeed << associateStylesheet(xslName) << linefeed << "<run>" << lineFeed;
2426 } else {
2427 ATH_MSG_ERROR(" argument \"type\" needs to be LorentzAngle.");
2428 return StatusCode::FAILURE;
2429 }
2430
2431 file << xmlValue("RunNumber", m_runNumber.value()) << linefeed
2432 << xmlValue("StartTime", m_utcBegin) << linefeed
2433 << xmlValue("EndTime", m_utcEnd) << linefeed
2434 << xmlValue("Duration", m_calibEvtInfoTool->duration()) << linefeed
2435 << xmlValue("LB", m_LBRange) << linefeed
2436 << xmlValue("Events", m_numberOfEvents) << linefeed
2437 << xmlValue("Flag", std::move(DBUploadFlag)) << linefeed
2438 << " <data>" << lineFeed;
2439
2440 if (wrapUpXML4Summary(m_outLASummary, "LorentzAngle", summaryList).isFailure()) {
2441 ATH_MSG_ERROR("Problem in closing LorentzAngle file");
2442 return StatusCode::FAILURE;
2443 }
2444
2445 //--- DB output
2446 if (m_writeToCool) {
2447 if (m_pCalibWriteTool->wrapUpLorentzAngle().isFailure()) {
2448 ATH_MSG_ERROR("Could not get LorentzAngle");
2449 return StatusCode::FAILURE;
2450 }
2451 }
2452 return StatusCode::SUCCESS;
2453}
2454
2455
2457// Functions to handle XML File for COOL
2459StatusCode SCTCalib::openXML4DB(std::ofstream& file, std::string_view type, std::string_view tag, const IOVTime& start, const IOVTime& end) const {
2460 if (type == "DeadStrip") {
2461 file.open(m_deadStripsFile.value().c_str(), std::ios::out);
2462 if (!file.good()) return StatusCode::FAILURE;
2463 file << "<channels server=\"ATLAS_COOLPROD\" schema=\"ATLAS_COOLOFL_SCT\" dbname=\"MONP200\" folder=\"SCT/Derived/DeadStrips\" ";
2464 } else if (type == "DeadChip") {
2465 file.open(m_deadChipsFile.value().c_str(), std::ios::out);
2466 if (!file.good()) return StatusCode::FAILURE;
2467 file << "<channels server=\"ATLAS_COOLPROD\" schema=\"ATLAS_COOLOFL_SCT\" dbname=\"MONP200\" folder=\"SCT/Derived/DeadChips\" ";
2468 } else {
2469 ATH_MSG_ERROR("in openXML4DB : argument \"type\" needs to be (DeadStrip, DeadChip).");
2470 return StatusCode::FAILURE;
2471 }
2472 file << "since=\"" << start.re_time() << "\" "
2473 << "until=\"" << end.re_time() << "\" "
2474 << "tag=\"" << tag << "\" "
2475 << "version=\"" << "multi\">" << linefeed;
2476 return StatusCode::SUCCESS;
2477}
2478
2479
2480StatusCode SCTCalib::closeXML4DB(std::ofstream& file) const {
2481 file << "</channels>" << lineFeed;
2482 if (file.is_open()) {
2483 file.close();
2484 return StatusCode::SUCCESS;
2485 } else {
2486 return StatusCode::FAILURE;
2487 }
2488}
2489
2490
2491StatusCode SCTCalib::addToXML4DB(std::ofstream& file, const Identifier& waferId, std::string_view DefectType, float Threshold, std::string_view DefectList) const {
2492 std::string tmp{DefectList};
2493 int length{static_cast<int>(tmp.length())};
2494 std::string Defect4DB{tmp.substr(1, length-2)}; // Removing first&end spaces in DefectList
2495
2496 file << xmlOpenChannel(m_pSCTHelper->module_id(waferId).get_identifier32().get_compact(), m_iovStart.re_time(), m_iovStop.re_time()) << linefeed
2497 << xmlValue("SampleSize", "10000") << linefeed
2498 << xmlValue("BarrelEndcap", m_pSCTHelper->barrel_ec(waferId)) << linefeed
2499 << xmlValue("Layer", m_pSCTHelper->layer_disk(waferId)) << linefeed
2500 << xmlValue("Eta", m_pSCTHelper->eta_module(waferId)) << linefeed
2501 << xmlValue("Phi", m_pSCTHelper->phi_module(waferId)) << linefeed
2502 << xmlValue("DefectType", DefectType) << linefeed
2503 << xmlValue("Threshold", Threshold) << linefeed
2504 << xmlValue("DefectList", std::move(Defect4DB)) << linefeed
2505 << xmlCloseChannel() << lineFeed;
2506
2507 return StatusCode::SUCCESS;
2508}
2509
2510
2512// Functions to handle XML File for Summary
2514StatusCode SCTCalib::openXML4DeadSummary(std::ofstream& file, std::string_view type, int n_Module, int n_Link, int n_Chip, int n_Strip) const {
2515 if (type == "DEAD") {
2516 file.open(m_deadSummaryFile.value().c_str(), std::ios::out);
2517 if (!file.good()) return StatusCode::FAILURE;
2518 file << xmlHeader << linefeed << associateStylesheet("DeadInfo.xsl") << linefeed
2519 << "<run>" << linefeed;
2520 } else {
2521 ATH_MSG_ERROR("in openXML4DeadSummary : argument \"type\" needs to be \"DEAD\".");
2522 return StatusCode::FAILURE;
2523 }
2524
2525 //--- Upload flag
2526 std::string strUploadFlag{"U"};
2527 bool isNonZero{false};
2528
2530 if (n_Chip > 0) {
2531 isNonZero = true;
2532 strUploadFlag = "G";
2533 } else {
2534 strUploadFlag = "R";
2535 }
2536 }
2537
2538 //--- Upload test result
2539 std::ostringstream osNonZero;
2540 osNonZero << "#chips or #strips is non-zero";
2541 std::ostringstream osFlagReason;
2542 if (!isNonZero) osFlagReason << "FAILED in " << osNonZero.str();
2543 std::string strFlagEnable{(m_deadChipUploadTest or m_deadStripUploadTest) ? "ENABLED" : "DISABLED"};
2544 std::ostringstream osCheckList;
2545 osCheckList << osNonZero.str();
2546
2547 file << xmlValue("RunNumber", m_runNumber.value()) << linefeed
2548 << xmlValue("StartTime", m_utcBegin) << linefeed
2549 << xmlValue("EndTime", m_utcEnd) << linefeed
2550 << xmlValue("Duration", m_calibEvtInfoTool->duration()) << linefeed
2551 << xmlValue("LB", m_calibEvtInfoTool->numLumiBlocks()) << linefeed
2552 << xmlValue("Events", m_numberOfEvents) << linefeed
2553 << xmlValue("Modules", n_Module) << linefeed
2554 << xmlValue("Links", n_Link) << linefeed
2555 << xmlValue("Chips", n_Chip) << linefeed
2556 << xmlValue("Strips", n_Strip) << linefeed
2557 << xmlValue("Flag", std::move(strUploadFlag)) << linefeed
2558 << xmlValue("FlagReason", osFlagReason.str()) << linefeed
2559 << xmlValue("FlagEnable", std::move(strFlagEnable)) << linefeed
2560 << xmlValue("CheckList", osCheckList.str()) << linefeed
2561 << " <modules>" << lineFeed;
2562
2563 return StatusCode::SUCCESS;
2564}
2565
2566
2567StatusCode SCTCalib::openXML4MonSummary(std::ofstream& file, std::string_view type) const {
2568 using TwoStrings = std::pair<std::string, std::string>;
2569 using Names = std::map<std::string, TwoStrings, std::less<>>;
2570 Names nameAssociation;
2571 nameAssociation["NoiseOccupancy"] = TwoStrings(m_noiseOccupancySummaryFile, "NoiseOccupancyInfo.xsl");
2572 nameAssociation["RawOccupancy"] = TwoStrings(m_rawOccupancySummaryFile, "RawOccupancyInfo.xsl");
2573 nameAssociation["Efficiency"] = TwoStrings(m_efficiencySummaryFile, "EfficiencyInfo.xsl");
2574 nameAssociation["BSErrors"] = TwoStrings(m_BSErrorSummaryFile, "BSErrorInfo.xsl");
2575 nameAssociation["BSErrorsModule"] = TwoStrings(m_BSErrorModuleFile, "BSErrorInfo.xsl");
2576 Names::iterator found{nameAssociation.find(type)};
2577 if (found!=nameAssociation.end()) {
2578 std::string filename{found->second.first};
2579 std::string xslName{found->second.second};
2580 //
2581 file.open(filename.c_str(), std::ios::out);
2582 if (!file.good()) return StatusCode::FAILURE;
2583 file << xmlHeader << linefeed << associateStylesheet(xslName) << linefeed << "<run>" << lineFeed;
2584 } else {
2585 ATH_MSG_ERROR("in openXML4MonSummary : argument \"type\" needs to be (NoiseOccupancy, RawOccupancy, Efficiency, BSErrors).");
2586 return StatusCode::FAILURE;
2587 }
2588 file << xmlValue("RunNumber", m_runNumber.value()) << linefeed
2589 << xmlValue("StartTime", m_utcBegin) << linefeed
2590 << xmlValue("EndTime", m_utcEnd) << linefeed
2591 << xmlValue("Duration", m_calibEvtInfoTool->duration()) << linefeed
2592 << xmlValue("LB", m_LBRange) << linefeed
2593 << xmlValue("Events", m_numberOfEvents) << linefeed
2594 << " <data>" << lineFeed;
2595 return StatusCode::SUCCESS;
2596}
2597
2598
2599StatusCode SCTCalib::wrapUpXML4Summary(std::ofstream& file, std::string_view type, std::ostringstream& list) const {
2600 file << list.str();
2601 if (type == "DEAD") {
2602 file << " </modules>" << lineFeed;
2603 } else if ((type == "NoiseOccupancy") or (type == "RawOccupancy") or (type == "Efficiency") or (type == "BSErrors") or (type == "LorentzAngle")) {
2604 file << " </data>" << lineFeed;
2605 }
2606 file << "</run>" << lineFeed;
2607
2608 if (file.is_open()) {
2609 file.close();
2610 return StatusCode::SUCCESS;
2611 } else {
2612 return StatusCode::FAILURE;
2613 }
2614}
2615
2616
2617StatusCode SCTCalib::addToSummaryStr(std::ostringstream& list, const Identifier& waferId, std::string_view type, std::string_view stripId, std::string_view chipId) const {
2618 //--- Remove first&end spaces in DefectList
2619 const std::string tmpstrip{stripId};
2620 const std::string tmpchip{chipId};
2621 int len_strip{static_cast<int>(tmpstrip.length())};
2622 int len_chip{static_cast<int>(tmpchip.length())};
2623 std::string stripList{""};
2624 std::string chipList{""};
2625 if (len_strip > 0) {
2626 int stringLength = (len_strip-2 >0) ? len_strip-2 : len_strip;
2627 stripList = tmpstrip.substr(1, stringLength);
2628 }
2629 if (len_chip > 0) {
2630 int stringLength = (len_chip-2 >0) ? len_chip-2 : len_chip;
2631 chipList = tmpchip.substr(1, stringLength);
2632 }
2633 //--- Identifier/SN
2634 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
2635 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
2636 //--- Preparing linkList
2637 std::string linkList{chipList2LinkList(stripList)};
2638 //--- Push to summary stream
2639 XmlStreamer m{"module", list};
2640 {
2641 XmlStreamer v{"value", "name", "SN", list};
2642 list << sn.str();
2643 }
2644 {
2645 XmlStreamer v{"value", "name", "BecLayerPhiEta", list};
2646 list << formatPosition(waferId, m_pSCTHelper, ".", false);
2647 }
2648 {
2649 XmlStreamer v{"value", "name", "LinkID", list};
2650 list << linkList;
2651 }
2652 {
2653 XmlStreamer v{"value", "name", "ChipID", list};
2654 list << stripList;
2655 }
2656 if (type == "DEAD") {
2657 XmlStreamer v{"value", "name", "StripIDOnline", list};
2658 list << stripList;
2659 } else {
2660 ATH_MSG_ERROR("in addToSummaryStr : argument \"type\" needs to be \"DEAD\".");
2661 return StatusCode::FAILURE;
2662 }
2663
2664 return StatusCode::SUCCESS;
2665}
2666
2667
2668std::string
2669SCTCalib::xmlChannelNoiseOccDataString(const Identifier& waferId, const float occupancy, const SCT_SerialNumber& serial) const {
2670 std::ostringstream os;
2671 os << xmlOpenChannel(waferId.get_identifier32().get_compact(), m_iovStart.re_time(), m_iovStop.re_time()) << lineFeed
2672 << " " << xmlValue("SN", serial.str()) << lineFeed
2673 << " " << xmlValue("SampleSize", "10000") << lineFeed
2674 << " " << xmlValue("barrel_endcap", m_pSCTHelper->barrel_ec(waferId)) << lineFeed
2675 << " " << xmlValue("Layer", m_pSCTHelper->layer_disk(waferId)) << linefeed
2676 << " " << xmlValue("Eta", m_pSCTHelper->eta_module(waferId)) << lineFeed
2677 << " " << xmlValue("Phi", m_pSCTHelper->phi_module(waferId)) << lineFeed
2678 << " " << xmlValue("NoiseOccupancy", occupancy) << lineFeed
2679 << " " << xmlCloseChannel();
2680 return os.str();
2681}
2682
2683
2684std::string
2685SCTCalib::xmlChannelEfficiencyDataString(const Identifier& waferId, const float efficiency, const SCT_SerialNumber& serial, const int side) const {
2686 std::ostringstream os;
2687 os << " <module>" << lineFeed
2688 << " " << xmlValue("SN", serial.str()) << lineFeed
2689 << " " << xmlValue("SampleSize", "10000") << lineFeed
2690 << " " << xmlValue("barrel_endcap", m_pSCTHelper->barrel_ec(waferId)) << lineFeed
2691 << " " << xmlValue("Layer", m_pSCTHelper->layer_disk(waferId)) << linefeed
2692 << " " << xmlValue("Eta", m_pSCTHelper->eta_module(waferId)) << lineFeed
2693 << " " << xmlValue("Phi", m_pSCTHelper->phi_module(waferId)) << lineFeed
2694 << " " << xmlValue("Efficiency", efficiency) << lineFeed
2695 << " " << xmlValue("Side", side )<<std::endl
2696 << " </module>";
2697 return os.str();
2698}
2699
2700
2701std::string
2702SCTCalib::xmlChannelEfficiencyDataStringChip(const Identifier& waferId, const float efficiency, const float efficiency_bcid, const SCT_SerialNumber& serial, const int side, const int chip) const {
2703 std::ostringstream os;
2704 os << " <chip>" << lineFeed
2705 << " " << xmlValue("SN", serial.str()) << lineFeed
2706 << " " << xmlValue("SampleSize", "10000") << lineFeed
2707 << " " << xmlValue("barrel_endcap", m_pSCTHelper->barrel_ec(waferId)) << lineFeed
2708 << " " << xmlValue("Layer", m_pSCTHelper->layer_disk(waferId)) << linefeed
2709 << " " << xmlValue("Eta", m_pSCTHelper->eta_module(waferId)) << lineFeed
2710 << " " << xmlValue("Phi", m_pSCTHelper->phi_module(waferId)) << lineFeed
2711 << " " << xmlValue("Side", side )<<std::endl
2712 << " " << xmlValue("Chip", chip )<<std::endl
2713 << " " << xmlValue("Efficiency", efficiency) << lineFeed
2714 << " " << xmlValue("Efficiency_bcid", efficiency_bcid) << lineFeed
2715 << " </chip>";
2716 return os.str();
2717}
2718
2719std::pair<int, bool>
2721 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
2722 //--- Check if there are noisy strips in the wafer
2723 int numNoisyStripsInTheWafer{0};
2724 bool isNoisyWafer{false};
2726 for (int iStrip{0}; iStrip != nbins; ++iStrip) {
2727 if ( (float) m_calibHitmapTool->getBinForHistogramIndex(iStrip + 1, waferHash.value()) / m_numberOfEvents > noisyStripThr) ++numNoisyStripsInTheWafer;
2728 }
2729 //--- Define/counts noisy wafers using wafer occupancy and number of noisy strips
2730 double averageOccupancy{m_calibHitmapTool->size(waferHash.value())/static_cast<double>(nbins)/static_cast<double>(m_numberOfEvents)};
2731 const int subdetector{m_pSCTHelper->barrel_ec(waferId)};
2732 isNoisyWafer = (numNoisyStripsInTheWafer > m_noisyWaferFraction*nbins) and
2733 ((subdetector == ENDCAP_C and averageOccupancy > m_noisyWaferThrECC) or
2734 (subdetector == BARREL and averageOccupancy > m_noisyWaferThrBarrel) or
2735 (subdetector == ENDCAP_A and averageOccupancy > m_noisyWaferThrECA));
2736 if (isNoisyWafer) {
2737 ATH_MSG_INFO("Module: " << waferHash.value());
2738 ATH_MSG_INFO("Hits, Nevts, Occ: " << m_calibHitmapTool->size(waferHash.value()) << ", "
2739 << m_numberOfEvents << ", "
2740 << averageOccupancy);
2741 }
2742 return std::make_pair(numNoisyStripsInTheWafer, isNoisyWafer);
2743}
2744
2745
2746StatusCode
2747SCTCalib::addStripsToList(const EventContext& ctx, Identifier& waferId, std::set<Identifier>& stripIdList, bool isNoisy, bool isNew) const {
2748 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
2750 for (int iStrip{0}; iStrip != nbins; ++iStrip) {
2751 Identifier stripId{m_pSCTHelper->strip_id(waferId, iStrip)};
2752 if (!isNoisy) { //--- Add all strips
2753 stripIdList.insert(stripId);
2754 } else {
2755 const float stripOccupancy{ (float) m_calibHitmapTool->getBinForHistogramIndex(iStrip + 1, waferHash.value()) / m_numberOfEvents};
2756 if (stripOccupancy > noisyStripThr) {
2757 if (!isNew) { //--- All noisy strips
2758 stripIdList.insert(stripId);
2759 } else { //--- New noisy strips : compared with configuration and calibration
2760 const bool isGoodInConfiguration{m_useConfiguration ? m_ConfigurationConditionsTool->isGood(stripId, ctx, InDetConditions::SCT_STRIP) : true};
2761 const bool isGoodInCalibration{m_useCalibration ? m_ReadCalibDataTool->isGood(stripId, ctx, InDetConditions::SCT_STRIP) : true};
2763 if (isGoodInConfiguration and isGoodInCalibration) {
2764 stripIdList.insert(stripId);
2765 }
2766 }
2767 }
2768 }
2769 }
2770 }
2771 return StatusCode::SUCCESS;
2772}
2773
2774
2775StatusCode
2776SCTCalib::writeModuleListToCool ATLAS_NOT_THREAD_SAFE // Thread unsafe SCTCalibWriteTool::createListStrip method is used.
2777(const std::map<Identifier, std::set<Identifier>>& moduleListAll,
2778 const std::map<Identifier, std::set<Identifier>>& moduleListNew,
2779 const std::map<Identifier, std::set<Identifier>>& moduleListRef) {
2780 //--- Write out strips
2781 float noisyStripThr{m_noisyStripThrDef?(m_noisyStripThrOffline):(m_noisyStripThrOnline)};
2782 int nDefects{0};
2783 SCT_ID::const_id_iterator idItr{m_pSCTHelper->wafer_begin()};
2784 SCT_ID::const_id_iterator idItrE{m_pSCTHelper->wafer_end()};
2785 for (; idItr != idItrE; ++idItr) {
2786 if (m_pSCTHelper->side(*idItr) == 0) {
2787 Identifier moduleId{m_pSCTHelper->module_id(*idItr)};
2788 std::map<Identifier, std::set<Identifier>>::const_iterator moduleAllItr{moduleListAll.find(moduleId)};
2789 std::map<Identifier, std::set<Identifier>>::const_iterator moduleNewItr{moduleListNew.find(moduleId)};
2790 std::map<Identifier, std::set<Identifier>>::const_iterator moduleRefItr{moduleListRef.find(moduleId)};
2791 std::string defectStripsAll{moduleAllItr != moduleListAll.end() ? getStripList((*moduleAllItr).second) : ""};
2792 std::string defectStripsNew{moduleNewItr != moduleListNew.end() ? getStripList((*moduleNewItr).second) : ""};
2793 std::string defectStripsRef{moduleRefItr != moduleListRef.end() ? getStripList((*moduleRefItr).second) : ""};
2794 if (m_noisyUpdate) { //--- UPD1/UPD4
2795 if (defectStripsAll != defectStripsRef) {
2796 if (m_pCalibWriteTool->createCondObjects(moduleId, m_pSCTHelper, 10000, "NOISY", noisyStripThr, defectStripsAll).isFailure()) {
2797 ATH_MSG_ERROR("Could not create defect strip entry in the CalibWriteTool.");
2798 }
2799 nDefects++;
2800 };
2801 } else {
2802 if (m_noisyStripAll) { //--- ALL noisy strips
2803 if (!defectStripsAll.empty() || m_noisyWriteAllModules) {
2804 if (m_pCalibWriteTool->createCondObjects(moduleId, m_pSCTHelper, 10000, "NOISY", noisyStripThr, defectStripsAll).isFailure()) {
2805 ATH_MSG_ERROR("Could not create defect strip entry in the CalibWriteTool.");
2806 }
2807 }
2808 } else { //--- Only NEW noisy strips
2809 if (!defectStripsNew.empty()) {
2810 if (m_pCalibWriteTool->createCondObjects(moduleId, m_pSCTHelper, 10000, "NOISY", noisyStripThr, defectStripsNew).isFailure()) {
2811 ATH_MSG_ERROR("Could not create defect strip entry in the CalibWriteTool.");
2812 }
2813 }
2814 }
2815 }
2816 }
2817 }
2818 ATH_MSG_DEBUG("Number of modules for which conditions were created: " << nDefects << " !!!!");
2819 if (moduleListAll.empty() or ( nDefects==0 && m_noisyUpdate )) {
2820 ATH_MSG_INFO("Number of noisy strips was zero or the same list of noisy strips. No local DB was created.");
2821 } else {
2822 ATH_MSG_DEBUG("directly before call of wrapUpNoisyChannel");
2823 if (m_pCalibWriteTool->wrapUpNoisyChannel().isFailure()) {
2824 ATH_MSG_ERROR("Could not get NoisyStrips info");
2825 return StatusCode::FAILURE;
2826 }
2827 }
2828 ATH_MSG_DEBUG("before return");
2829 return StatusCode::SUCCESS;
2830}
2831
2832
2833std::set<Identifier>
2834SCTCalib::getOverlapStripList( const std::set<Identifier>& stripAllIdList, const std::set<Identifier>& stripRefIdList ) const {
2835 std::set<Identifier> stripList;
2836 std::set<Identifier>::const_iterator stripAllItrLast = stripAllIdList.end();
2837 std::set<Identifier>::const_iterator stripRefItrLast = stripRefIdList.end();
2838
2839 std::set<Identifier>::const_iterator stripAllItr = stripAllIdList.begin();
2840 for ( ; stripAllItr != stripAllItrLast; ++stripAllItr ) {
2841 std::set<Identifier>::const_iterator stripRefItr = stripRefIdList.begin();
2842 bool old = false;
2843 for ( ; stripRefItr != stripRefItrLast; ++stripRefItr ) {
2844 if (*stripAllItr == *stripRefItr) old = true;
2845 }
2846 if (!old) {
2847 stripList.insert(*stripAllItr);
2848 }
2849 }
2850 return stripList;
2851}
2852
2853
2854std::string
2855SCTCalib::getStripList(const std::set<Identifier>& stripIdList) const {
2856 std::string strList;
2857 if (!stripIdList.empty()) {
2858 int firstStrip{-1};
2859 int groupSize{-1};
2860
2861 std::set<Identifier>::const_iterator stripItrFirst{stripIdList.begin()};
2862 std::set<Identifier>::const_iterator stripItrLast{--stripIdList.end()};
2863
2864 std::set<Identifier>::const_iterator stripItr{stripIdList.begin()};
2865 std::set<Identifier>::const_iterator stripItrE{stripIdList.end()};
2866 for (; stripItr != stripItrE; ++stripItr) {
2867 Identifier stripId{*stripItr};
2868 int stripNum{m_pSCTHelper->side(stripId)*nbins + m_pSCTHelper->strip(stripId)};
2869 if (stripItr == stripItrFirst) {
2870 firstStrip = stripNum;
2871 groupSize = 1;
2872 } else {
2873 if (stripNum == firstStrip + groupSize) {
2874 ++groupSize;
2875 } else {
2876 int stripBegin{firstStrip};
2877 int stripEnd{firstStrip + groupSize -1};
2878 strList = m_pCalibWriteTool->addDefect(strList, stripBegin, stripEnd);
2879 firstStrip = stripNum;
2880 groupSize = 1;
2881 }
2882 }
2883 if (stripItr == stripItrLast) {
2884 int stripBegin{firstStrip};
2885 int stripEnd{stripNum};
2886 strList = m_pCalibWriteTool->addDefect(strList, stripBegin, stripEnd);
2887 }
2888 }
2889 }
2890 return strList;
2891}
2892
2893
2894StatusCode
2895SCTCalib::noisyStripsToXml(const std::map<Identifier, std::set<Identifier>>& moduleList, const std::string& badStripsFile) const {
2896 //--- Open
2897 const char* outputFileName{badStripsFile.c_str()};
2898 std::ofstream outFile{outputFileName, std::ios::out};
2899 if (!outFile.good()) {
2900 ATH_MSG_ERROR("Unable to open " << outputFileName);
2901 return(StatusCode::FAILURE);
2902 }
2904 //--- Create module list
2905 std::ostringstream osModuleList;
2906 //--- Loop over wafers
2907 SCT_ID::const_id_iterator waferItr{m_pSCTHelper->wafer_begin()};
2908 SCT_ID::const_id_iterator waferItrE{m_pSCTHelper->wafer_end()};
2909 for (; waferItr != waferItrE; ++waferItr) {
2910 Identifier waferId{*waferItr};
2911 Identifier moduleId{m_pSCTHelper->module_id(waferId)};
2912 if (m_pSCTHelper->side(waferId) != 0) continue;
2913 std::map< Identifier, std::set<Identifier> >::const_iterator moduleItr{moduleList.find(moduleId)};
2914 if (moduleItr != moduleList.end()) {
2915 std::string defectStrips{getStripList((*moduleItr).second)};
2916 osModuleList << " <channel id=\"" << m_pSCTHelper->module_id(waferId).get_compact() << "\" "
2917 << "since=\"" << m_iovStart.re_time() << "\" "
2918 << "until=\"" << m_iovStop.re_time() << "\">" << linefeed
2919 << " <value name=\"SampleSize\">" << "10000" << "</value>" << linefeed
2920 << " <value name=\"BarrelEndcap\">" << m_pSCTHelper->barrel_ec(waferId) << "</value>" << linefeed
2921 << " <value name=\"Layer\">" << m_pSCTHelper->layer_disk(waferId) << "</value>" << linefeed
2922 << " <value name=\"Eta\">" << m_pSCTHelper->eta_module(waferId) << "</value>" << linefeed
2923 << " <value name=\"Phi\">" << m_pSCTHelper->phi_module(waferId) << "</value>" << linefeed
2924 << " <value name=\"DefectType\">" << "NOISY" << "</value>" << linefeed
2925 << " <value name=\"Threshold\">" << noisyStripThr << "</value>" << linefeed
2926 << " <value name=\"DefectList\">" << normalizeList(std::move(defectStrips)) << "</value>" << linefeed
2927 << " </channel>" << lineFeed;
2928 }
2929 }
2930 //--- Write out the contents
2931 outFile << "<channels server=\"ATLAS_COOLPROD\" schema=\"ATLAS_COOLOFL_SCT\" dbname=\"CONDBR2\" folder=\"SCT/Derived/Monitoring\" "
2932 << "since=\"" << m_iovStart.re_time() << "\" "
2933 << "until=\"" << m_iovStop.re_time() << "\" "
2934 << "tag=\"" << m_tagID4NoisyStrips << "\" "
2935 << "version=\"" << "multi\">" << lineFeed
2936 << osModuleList.str()
2937 << "</channels>" << lineFeed;
2938
2939 return StatusCode::SUCCESS;
2940}
2941
2942
2943StatusCode SCTCalib::noisyStripsToSummaryXml(const std::map<Identifier, std::set<Identifier>>& moduleListAll,
2944 const std::map<Identifier, std::set<Identifier>>& moduleListRef,
2945 const std::string& badStripsFile) const {
2946
2947 ATH_MSG_DEBUG("noisyStripsToSummaryXml: start");
2948
2949 //--- Open
2950 const char* outputFileName{badStripsFile.c_str()};
2951 std::ofstream outFile{outputFileName, std::ios::out};
2952 if (!outFile.good()) {
2953 ATH_MSG_ERROR("Unable to open " << outputFileName);
2954 return(StatusCode::FAILURE);
2955 }
2956
2957 //--- Initialization
2958 int numLinksAll{0}, numChipsAll{0};
2959 int numModulesAll{0}, numModulesRef{0};
2960 int numStripsAll{0}, numStripsNew{0}, numStripsRef{0};
2961 int numModulesDiff{0};
2962
2963 std::string defectLinks, defectChips;
2964 std::string defectStripsAll, defectStripsNew, defectStripsRef;
2965 std::ostringstream osModuleList, osChipList;
2966
2967 //--- Create module list
2968 SCT_ID::const_id_iterator waferItr{m_pSCTHelper->wafer_begin()};
2969 SCT_ID::const_id_iterator waferItrE{m_pSCTHelper->wafer_end()};
2970 ATH_MSG_DEBUG("noisyStripsToSummaryXml: before wafer loop");
2971 for (; waferItr != waferItrE; ++waferItr) {
2972 //--- Identifier
2973 Identifier waferId{*waferItr};
2974 Identifier moduleId{m_pSCTHelper->module_id(waferId)};
2975 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
2976 SCT_SerialNumber sn{m_CablingTool->getSerialNumberFromHash(waferHash)};
2977
2978 //--- Initialization for a module
2979 if (m_pSCTHelper->side(waferId) == 0) {
2980 defectLinks.erase();
2981 defectChips.erase();
2982 defectStripsAll.erase();
2983 defectStripsNew.erase();
2984 defectStripsRef.erase();
2985 }
2986
2987 //--- Noisy links
2988 bool isNoisyWafer{getNumNoisyStrips(waferId).second}; // true if this wafer is noisy
2989 if (isNoisyWafer) {
2990 int link{m_pSCTHelper->side(waferId)};
2991 defectLinks = m_pCalibWriteTool->addDefect(defectLinks, link, link);
2992 ++numLinksAll;
2993 }
2994
2995 //--- Execute once in this module
2996 if (m_pSCTHelper->side(waferId) == 1) {
2997 ATH_MSG_DEBUG("noisyStripsToSummaryXml: ALL");
2998 //--- Noisy strips : All
2999 std::map< Identifier, std::set<Identifier> >::const_iterator moduleAllItr{moduleListAll.find(moduleId)};
3000 if (moduleAllItr != moduleListAll.end()) {
3001 defectStripsAll = getStripList((*moduleAllItr).second);
3002 ++numModulesAll;
3003 numStripsAll += (*moduleAllItr).second.size();
3004 }
3005
3006 ATH_MSG_DEBUG("noisyStripsToSummaryXml: REF");
3007 //--- Noisy strips : Ref
3008 std::map< Identifier, std::set<Identifier> >::const_iterator moduleRefItr{moduleListRef.find(moduleId)};
3009 if (moduleRefItr != moduleListRef.end()) {
3010 defectStripsRef = getStripList(moduleRefItr->second);
3011 ++numModulesRef;
3012 numStripsRef += moduleRefItr->second.size();
3013 }
3014
3015 ATH_MSG_DEBUG("noisyStripsToSummaryXml: NEW");
3016 //--- Noisy strips : New
3017 if ( moduleAllItr != moduleListAll.end() ) {
3018 if ( moduleRefItr != moduleListRef.end() ) {
3019 std::set<Identifier> listNEW = getOverlapStripList( (*moduleAllItr).second, (*moduleRefItr).second );
3020 defectStripsNew = getStripList( listNEW );
3021 numStripsNew += listNEW.size();
3022 } else {
3023
3024 defectStripsNew = getStripList( (*moduleAllItr).second );
3025 }
3026 }
3027
3028 ATH_MSG_DEBUG("noisyStripsToSummaryXml: stripIdList -> chipIdList");
3029 //--- Noisy chips : stripIdList -> chipIdList
3030 if (moduleAllItr != moduleListAll.end()) {
3031 std::set<int> chipIdList{getNoisyChips(moduleAllItr->second)};
3032 if (!chipIdList.empty()) {
3033 ++numChipsAll;
3034 std::set<int>::iterator chipItr{chipIdList.begin()};
3035 std::set<int>::iterator chipItrE{chipIdList.end()};
3036 for (; chipItr != chipItrE; ++chipItr) {
3037 int chipId{*chipItr};
3038 //--- To be written into module list
3039 defectChips = m_pCalibWriteTool->addDefect(defectChips, chipId, chipId);
3040 //--- LBs where this chip was noisy
3041 std::pair< std::string, float > defectLB{getNoisyLB(moduleId, chipId)};
3042 //--- Chip list written to XML
3043 osChipList << " <chip>" << linefeed
3044 << " <value name=\"SN\">" << sn.str() << "</value>" << linefeed
3045 << " <value name=\"BecLayerPhiEta\">" << m_pSCTHelper->barrel_ec(waferId) << "."
3046 << m_pSCTHelper->layer_disk(waferId) << "."
3047 << m_pSCTHelper->phi_module(waferId) << "."
3048 << m_pSCTHelper->eta_module(waferId) << "</value>" << linefeed
3049 << " <value name=\"ChipID\">" << chipId << "</value>" << linefeed
3050 << " <value name=\"LB\">" << normalizeList(defectLB.first) << "</value>" << linefeed
3051 << " <value name=\"LBFraction\">" << defectLB.second << "</value>" << linefeed
3052 << " </chip>" << lineFeed;
3053 }
3054 }
3055 }
3056 ATH_MSG_DEBUG("noisyStripsToSummaryXml: Difference between All & Ref");
3057 //--- Difference between All & Ref
3058 if (defectStripsAll != defectStripsRef) ++numModulesDiff;
3059 //--- Module list written to XML
3060 if (!defectStripsAll.empty() or (m_noisyUpdate and defectStripsAll != defectStripsRef)) {
3061 osModuleList << " <module>" << linefeed
3062 << " <value name=\"SN\">" << sn.str() << "</value>" << linefeed
3063 << " <value name=\"BecLayerPhiEta\">" << m_pSCTHelper->barrel_ec(waferId) << "."
3064 << m_pSCTHelper->layer_disk(waferId) << "."
3065 << m_pSCTHelper->phi_module(waferId) << "."
3066 << m_pSCTHelper->eta_module(waferId) << "</value>" << linefeed
3067 << " <value name=\"LinkID\">" << normalizeList(defectLinks) << "</value>" << linefeed
3068 << " <value name=\"ChipID\">" << normalizeList(defectChips) << "</value>" << linefeed
3069 << " <value name=\"StripOfflineAll\">" << normalizeList(defectStripsAll) << "</value>" << linefeed
3070 << " <value name=\"StripOfflineNew\">" << normalizeList(defectStripsNew) << "</value>" << linefeed
3071 << " <value name=\"StripOfflineRef\">" << normalizeList(defectStripsRef) << "</value>" << linefeed
3072 << " </module>" << lineFeed;
3073 }
3074 ATH_MSG_DEBUG("noisyStripsToSummaryXml: After Difference between All & Ref");
3075 }
3076 }//--- end loop : waferItr
3077
3078 ATH_MSG_DEBUG("noisyStripsToSummaryXml: after waferItr");
3079
3080 //--- Upload flag
3081 std::string strUploadFlag{"U"};
3082
3083 bool isRunsInCool{false};
3084 bool isNoisyMinStat{false}, isNoisyModuleList{false}, isNoisyModuleDiff{false}, isNoisyStripDiff{false};
3085 if (m_noisyUploadTest) {
3086 isRunsInCool = ((m_noisyModuleAverageInDB != -1.) and (m_noisyStripLastRunInDB != -999));
3087 if (isRunsInCool) {
3088 isNoisyMinStat = m_numberOfEvents > m_noisyMinStat;
3089 isNoisyModuleList = numModulesAll < m_noisyModuleList;
3090 isNoisyModuleDiff = ((static_cast<float>(numModulesAll) - m_noisyModuleAverageInDB)/m_noisyModuleAverageInDB) < m_noisyModuleDiff;
3091 isNoisyStripDiff = ((static_cast<float>(numStripsAll) - m_noisyStripAverageInDB)/m_noisyStripAverageInDB) < m_noisyStripDiff;
3092 if (!isNoisyMinStat or !isNoisyModuleList) {
3093 strUploadFlag = "R";
3094 } else {
3095 if (!isNoisyModuleDiff or !isNoisyStripDiff) {
3096 strUploadFlag = "Y";
3097 } else {
3098 strUploadFlag = "G";
3099 }
3100 }
3101 }
3102 }
3103
3104 ATH_MSG_DEBUG("noisyStripsToSummaryXml: after FlagChecking");
3105
3106 //--- Upload test result to XML
3107 std::ostringstream osNoisyMinStat, osNoisyModuleList, osNoisyModuleDiff, osNoisyStripDiff;
3108 osNoisyMinStat << "#events more than " << m_noisyMinStat.value();
3109 osNoisyModuleList << "#(modules w/ at least 1 noisy strip) less than " << m_noisyModuleList.value();
3110 osNoisyModuleDiff << "Increase of #(modules w/ at least 1 noisy strip) from average of recent runs less than " << m_noisyModuleDiff*100 << "%";
3111 osNoisyStripDiff << "Increase of #(noisy strips) from average of recent runs less than " << m_noisyStripDiff*100 << "%";
3112
3113 std::ostringstream osFlagReason;
3114 if (!isNoisyMinStat) osFlagReason << "FAILED in " << osNoisyMinStat.str() << "; ";
3115 if (!isNoisyModuleList) osFlagReason << "FAILED in " << osNoisyModuleList.str() << "; ";
3116 if (!isNoisyModuleDiff) osFlagReason << "FAILED in " << osNoisyModuleDiff.str() << "; ";
3117 if (!isNoisyStripDiff) osFlagReason << "FAILED in " << osNoisyStripDiff.str();
3118
3119 std::string strFlagEnable = m_noisyUploadTest ? "ENABLED" : "DISABLED";
3120 std::string strRunsInCool = isRunsInCool ? "AVAILABLE" : "UNAVAILABLE";
3121
3122 std::ostringstream osCheckList;
3123 osCheckList << osNoisyMinStat.str() << "; "
3124 << osNoisyModuleList.str() << "; "
3125 << osNoisyModuleDiff.str() << "; "
3126 << osNoisyStripDiff.str();
3127
3128 //--- Write out the contents to XML file
3129 outFile << xmlHeader << linefeed
3130 << associateStylesheet("BadStrips.xsl") << linefeed
3131 << "<run>" << linefeed
3132 << " <value name=\"RunNumber\">" << m_runNumber.value() << "</value>" << linefeed
3133 << " <value name=\"StartTime\">" << m_utcBegin << "</value>" << linefeed
3134 << " <value name=\"EndTime\">" << m_utcEnd << "</value>" << linefeed
3135 << " <value name=\"Duration\">" << m_calibEvtInfoTool->duration() << "</value>" << linefeed
3136 << " <value name=\"LB\">" << m_numOfLBsProcessed << "</value>" << linefeed
3137 << " <value name=\"Events\">" << m_numberOfEvents << "</value>" << linefeed
3138 << " <value name=\"Modules\">" << numModulesAll << "</value>" << linefeed
3139 << " <value name=\"Links\">" << numLinksAll << "</value>" << linefeed
3140 << " <value name=\"Chips\">" << numChipsAll << "</value>" << linefeed
3141 << " <value name=\"StripsOfflineAll\">" << numStripsAll << "</value>" << linefeed
3142 << " <value name=\"StripsOfflineNew\">" << numStripsNew << "</value>" << linefeed
3143 << " <value name=\"ModulesRef\">" << numModulesRef << "</value>" << linefeed
3144 << " <value name=\"StripsOfflineRef\">" << numStripsRef << "</value>" << linefeed
3145 << " <value name=\"ModulesDiff\">" << numModulesDiff << "</value>" << linefeed
3146 << " <value name=\"Flag\">" << strUploadFlag << "</value>" << linefeed
3147 << " <value name=\"FlagReason\">" << osFlagReason.str() << "</value>" << linefeed
3148 << " <value name=\"FlagEnable\">" << strFlagEnable << "</value>" << linefeed
3149 << " <value name=\"ReadCool\">" << strRunsInCool << "</value>" << linefeed
3150 << " <value name=\"CheckList\">" << osCheckList.str() << "</value>" << linefeed
3151 << " <chips>" << linefeed
3152 << osChipList.str()
3153 << " </chips>" << linefeed
3154 << " <modules>" << linefeed
3155 << osModuleList.str()
3156 << " </modules>" << linefeed
3157 << "</run>" << lineFeed;
3158
3159 ATH_MSG_DEBUG("noisyStripsToSummaryXml: before return");
3160
3161 return StatusCode::SUCCESS;
3162}
3163
3164
3165std::set<int>
3166SCTCalib::getNoisyChips(const std::set<Identifier>& stripIdList) const {
3167 std::set<int> chipIdList;
3168 chipIdList.clear();
3169
3170 // Get SCT_DetectorElementCollection
3172 const InDetDD::SiDetectorElementCollection* elements{sctDetEle.retrieve()};
3173 if (elements==nullptr) {
3174 ATH_MSG_FATAL(m_SCTDetEleCollKey.fullKey() << " could not be retrieved");
3175 return chipIdList;
3176 }
3177
3178 //--- Minimum number of noisy strips for a noisy chip
3179 unsigned int noisyChipThr{static_cast<unsigned int>(m_noisyChipFraction*n_stripPerChip)};
3180 if (stripIdList.size() > noisyChipThr) {
3181 unsigned int numStripsPerChip[n_chipPerModule] = {0};
3182 //--- Loop over stripIdList
3183 std::set<Identifier>::const_iterator stripItr{stripIdList.begin()};
3184 std::set<Identifier>::const_iterator stripItrE{stripIdList.end()};
3185 for (; stripItr != stripItrE; ++stripItr) {
3186 Identifier stripId{*stripItr};
3187 int stripOffline{m_pSCTHelper->strip(stripId)};
3188 //--- Chip number : taken from SCT_ConfigurationConditionsTool::getChip
3189 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(m_pSCTHelper->wafer_id(stripId))};
3190 const InDetDD::SiDetectorElement* pElement{elements->getDetectorElement(waferHash)};
3191 if (!pElement) {
3192 ATH_MSG_FATAL("Element pointer is nullptr");
3193 continue;
3194 }
3195 int stripOnline{(pElement->swapPhiReadoutDirection()) ? lastStrip - stripOffline : stripOffline};
3196 int chipId{m_pSCTHelper->side(stripId) == 0 ? stripOnline/n_stripPerChip : stripOnline/n_stripPerChip + n_chipPerSide};
3197 //--- Count number of noisy strips per chips
3198 ++numStripsPerChip[chipId];
3199 }
3200
3201 //--- Insert noisy chips
3202 for (int iChip{0}; iChip != n_chipPerModule; ++iChip) {
3203 if (numStripsPerChip[iChip] > noisyChipThr) chipIdList.insert(iChip);
3204 }
3205 }
3206 return chipIdList;
3207}
3208
3209
3210std::pair< std::string, float >
3211SCTCalib::getNoisyLB(const Identifier& moduleId, int& chipId) const {
3212 std::string defectLB{""}; //return value if invalid
3213 float defectLBFrac{0.0}; //return value if invalid
3215
3216 //--- Identifier
3217 Identifier waferId{m_pSCTHelper->wafer_id(m_pSCTHelper->barrel_ec(moduleId),
3218 m_pSCTHelper->layer_disk(moduleId),
3219 m_pSCTHelper->phi_module(moduleId),
3220 m_pSCTHelper->eta_module(moduleId),
3221 chipId < n_chipPerSide ? 0 : 1)};
3222 IdentifierHash waferHash{m_pSCTHelper->wafer_hash(waferId)};
3223 //--- Histogram for this chip
3224 int chipPositionInSide{m_pSCTHelper->side(waferId) == 0 ? chipId : chipId - n_chipPerSide};
3225 int histIndex{static_cast<int>((waferHash.value())*n_chipPerSide + chipPositionInSide)};
3226
3227 //--- Find LBs where this chip was noisy
3228 double chipOccupancyThr{noisyStripThr*n_stripPerChip*m_noisyChipFraction};
3229 std::set<int> LBList;
3230 LBList.clear();
3231 if (!m_calibLbTool) {
3232 ATH_MSG_ERROR("nullptr m_calibLbTool line " <<__LINE__);
3233 return std::make_pair(defectLB, defectLBFrac);
3234 }
3235
3236 for (int iLB{0}; iLB != m_LBRange; ++iLB) {
3237 double numEventsInLB{static_cast<double>(m_calibLbTool->getNumberOfEventsInBin(iLB + 1))};
3238 if (numEventsInLB == 0) continue;
3239 double chipOccupancy{(float) m_calibLbTool->getBinForHistogramIndex(iLB + 1, histIndex) / numEventsInLB};
3240 if (chipOccupancy > chipOccupancyThr) LBList.insert(iLB);
3241 }
3242 //--- Transform LBList to string and calculate a fraction of noisy LBs
3243 if (LBList.size() != 0) {
3244 defectLB = getLBList(LBList);
3245 defectLBFrac = static_cast<float>(LBList.size()) / m_numOfLBsProcessed;
3246 }
3247
3248 return std::make_pair(defectLB, defectLBFrac);
3249}
3250
3251
3252std::string SCTCalib::getLBList(const std::set<int>& LBList) const {
3253 std::string strList;
3254 strList.erase();
3255 if (!LBList.empty()) {
3256 int firstLB{-1};
3257 int LBSize{-1};
3258
3259 std::set<int>::const_iterator LBItrFirst{LBList.begin()};
3260 std::set<int>::const_iterator LBItrLast{--LBList.end()};
3261
3262 std::set<int>::const_iterator LBItr{LBList.begin()};
3263 std::set<int>::const_iterator LBItrE{LBList.end()};
3264 for (; LBItr != LBItrE; ++LBItr) {
3265 int iLB{*LBItr};
3266 if (LBItr == LBItrFirst) {
3267 firstLB = iLB;
3268 LBSize = 1;
3269 } else {
3270 if (iLB == firstLB + LBSize) {
3271 ++LBSize;
3272 } else {
3273 int LBBegin{firstLB};
3274 int LBEnd{firstLB + LBSize -1};
3275 strList = m_pCalibWriteTool->addDefect(strList, LBBegin, LBEnd);
3276 firstLB = iLB;
3277 LBSize = 1;
3278 }
3279 }
3280 if (LBItr == LBItrLast) {
3281 int LBBegin{firstLB};
3282 int LBEnd{iLB};
3283 strList = m_pCalibWriteTool->addDefect(strList, LBBegin, LBEnd);
3284 }
3285 }
3286 }
3287 return strList;
3288}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
void swap(DataVector< T > &a, DataVector< T > &b)
See DataVector<T, BASE>::swap().
double length(const pvec &v)
static const std::string outputFileName
StatusCode SCTCalib::stop ATLAS_NOT_THREAD_SAFE()
stop - process results accumulated in execute()
Definition SCTCalib.cxx:342
Header file for the SCTCalib class.
static const int n_BSErrorType
header file for the SCTCalibUtilities
Double_t LA_func(Double_t *x, Double_t *par)
Threshold
header file for the XmlHeader class
static const Attributes_t empty
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
const ServiceHandle< StoreGateSvc > & detStore() const
Basic time unit for IOVSvc.
Definition IOVTime.h:33
static constexpr uint32_t MINEVENT
Definition IOVTime.h:50
static constexpr uint32_t MAXEVENT
Definition IOVTime.h:51
value_type get_compact() const
Get the compact id.
This is a "hash" representation of an Identifier.
constexpr value_type value() const
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
Class to hold the SiDetectorElement objects to be put in the detector store.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Class to hold geometrical description of a silicon detector element.
bool swapPhiReadoutDirection() const
Determine if readout direction between online and offline needs swapping.
BooleanProperty m_doDeadChip
Definition SCTCalib.h:154
ToolHandle< ISCT_CalibHistoTool > m_calibBsErrTool
Definition SCTCalib.h:106
std::string getStripList(const std::set< Identifier > &stripIdList) const
BooleanProperty m_noisyUpdate
Definition SCTCalib.h:162
FloatProperty m_noisyWaferThrECC
Definition SCTCalib.h:182
UnsignedIntegerProperty m_rawOccupancyMinStat
Definition SCTCalib.h:203
BooleanProperty m_doNoiseOccupancy
Definition SCTCalib.h:155
std::ofstream m_gofile
Definition SCTCalib.h:115
StringProperty m_deadStripsFile
Definition SCTCalib.h:222
std::pair< int, bool > getNumNoisyStrips(const Identifier &waferId) const
UnsignedIntegerProperty m_efficiencyMinStat
Definition SCTCalib.h:204
FloatProperty m_noisyModuleDiff
Definition SCTCalib.h:169
FloatProperty m_noisyStripDiff
Definition SCTCalib.h:170
std::string xmlChannelNoiseOccDataString(const Identifier &waferId, const float occupancy, const SCT_SerialNumber &serial) const
StringProperty m_BSErrorSummaryFile
Definition SCTCalib.h:232
StatusCode addToSummaryStr(std::ostringstream &, const Identifier &, std::string_view, std::string_view, std::string_view) const
BooleanProperty m_doDeadStrip
Definition SCTCalib.h:153
std::string xmlChannelEfficiencyDataString(const Identifier &waferId, const float efficiency, const SCT_SerialNumber &serial, const int side) const
FloatProperty m_noisyStripThrOffline
Definition SCTCalib.h:175
std::pair< std::string, float > getNoisyLB(const Identifier &moduleId, int &chipId) const
StatusCode noisyStripsToXml(const std::map< Identifier, std::set< Identifier > > &moduleList, const std::string &badStripsFile) const
StatusCode noisyStripsToSummaryXml(const std::map< Identifier, std::set< Identifier > > &moduleListAll, const std::map< Identifier, std::set< Identifier > > &moduleListRef, const std::string &badStripsFile) const
StringProperty m_BSErrorModuleFile
Definition SCTCalib.h:233
FloatProperty m_noisyModuleAverageInDB
Definition SCTCalib.h:165
ToolHandle< ISCT_CalibModuleListTool > m_calibModuleListTool
Definition SCTCalib.h:107
bool retrievedService(S &service) const
Definition SCTCalib.h:285
StringProperty m_LBMax
Definition SCTCalib.h:134
ToolHandle< ISCT_ReadCalibDataTool > m_ReadCalibDataTool
Definition SCTCalib.h:101
ToolHandle< ISCT_CalibEvtInfo > m_calibEvtInfoTool
Definition SCTCalib.h:108
ToolHandle< ISCT_ConfigurationConditionsTool > m_ConfigurationConditionsTool
Definition SCTCalib.h:100
virtual StatusCode initialize() override
Definition SCTCalib.cxx:123
BooleanProperty m_doHV
Definition SCTCalib.h:152
std::set< int > getNoisyChips(const std::set< Identifier > &stripIdList) const
UnsignedIntegerProperty m_noiseOccupancyMinStat
Definition SCTCalib.h:202
std::set< Identifier > getOverlapStripList(const std::set< Identifier > &stripAllIdList, const std::set< Identifier > &stripRefIdList) const
BooleanProperty m_useMajority
Definition SCTCalib.h:138
ToolHandle< ISCT_CalibHistoTool > m_calibHitmapTool
Definition SCTCalib.h:104
const SCT_ID * m_pSCTHelper
Definition SCTCalib.h:96
StringProperty m_rawOccupancySummaryFile
Definition SCTCalib.h:228
BooleanProperty m_deadChipUploadTest
Definition SCTCalib.h:195
UnsignedIntegerProperty m_LorentzAngleMinStat
Definition SCTCalib.h:207
StatusCode openXML4DeadSummary(std::ofstream &file, std::string_view type, int n_Module=0, int n_Link=0, int n_Chip=0, int n_Strip=0) const
BooleanProperty m_doBSErrorDB
Definition SCTCalib.h:158
StringArrayProperty m_input_hist
Definition SCTCalib.h:141
BooleanProperty m_writeToCool
Definition SCTCalib.h:160
FloatProperty m_noisyWaferThrECA
Definition SCTCalib.h:181
IntegerProperty m_nLbsMerged
Definition SCTCalib.h:148
ToolHandle< ISCT_CablingTool > m_CablingTool
Definition SCTCalib.h:103
StringProperty m_deadChipsFile
Definition SCTCalib.h:223
FloatProperty m_noisyStripThrOnline
Definition SCTCalib.h:176
unsigned long long m_numberOfEventsHist
Definition SCTCalib.h:240
StringProperty m_deadSummaryFile
Definition SCTCalib.h:224
ToolHandle< ISCT_CalibHistoTool > m_calibLbTool
Definition SCTCalib.h:105
UnsignedIntegerProperty m_noisyMinStat
Definition SCTCalib.h:172
BooleanProperty m_readHitMaps
Definition SCTCalib.h:149
UnsignedIntegerProperty m_BSErrorDBMinStat
Definition SCTCalib.h:206
std::string m_utcBegin
Definition SCTCalib.h:241
std::string m_utcEnd
Definition SCTCalib.h:242
StringProperty m_efficiencySummaryFile
Definition SCTCalib.h:229
BooleanProperty m_doRawOccupancy
Definition SCTCalib.h:156
std::string xmlChannelEfficiencyDataStringChip(const Identifier &waferId, const float efficiency, const float efficiency_bcid, const SCT_SerialNumber &serial, const int side, const int chip) const
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
Definition SCTCalib.h:97
BooleanProperty m_doEfficiency
Definition SCTCalib.h:157
SCTCalib(const std::string &name, ISvcLocator *pSvcLocator)
Definition SCTCalib.cxx:113
void doHVPrintXML(const std::pair< int, int > &timeInterval, const std::pair< int, int > &lbRange, Identifier)
doHVPrintXML() Prints XML file for hv modules
Definition SCTCalib.cxx:470
StringProperty m_noiseOccupancySummaryFile
Definition SCTCalib.h:227
BooleanProperty m_useBSError
Definition SCTCalib.h:139
StatusCode openXML4DB(std::ofstream &, std::string_view, std::string_view, const IOVTime &, const IOVTime &) const
IntegerProperty m_eventNumber
Definition SCTCalib.h:130
StatusCode addToXML4DB(std::ofstream &, const Identifier &, std::string_view, float, std::string_view) const
BooleanProperty m_noisyStripThrDef
Definition SCTCalib.h:174
virtual StatusCode finalize() override
Finalize - delete any memory allocation from the heap.
Definition SCTCalib.cxx:452
StatusCode wrapUpXML4Summary(std::ofstream &, std::string_view, std::ostringstream &) const
StringProperty m_runStartTime
Definition SCTCalib.h:132
FloatProperty m_noisyChipFraction
Definition SCTCalib.h:184
FloatProperty m_noisyStripAverageInDB
Definition SCTCalib.h:167
ToolHandle< ISCT_DetectorLevelConditionsTool > m_MajorityConditionsTool
Definition SCTCalib.h:102
StatusCode closeXML4DB(std::ofstream &) const
StringProperty m_runEndTime
Definition SCTCalib.h:133
int m_numOfLBsProcessed
Definition SCTCalib.h:238
IntegerProperty m_runNumber
Definition SCTCalib.h:129
unsigned long long m_numberOfEvents
Definition SCTCalib.h:239
BooleanProperty m_useCalibration
Definition SCTCalib.h:137
BooleanProperty m_doLorentzAngle
Definition SCTCalib.h:159
BooleanProperty m_noisyUploadTest
Definition SCTCalib.h:164
bool m_readHIST
Definition SCTCalib.h:249
BooleanProperty m_doNoisyStrip
Definition SCTCalib.h:151
ToolHandle< SCTCalibWriteTool > m_pCalibWriteTool
Definition SCTCalib.h:99
BooleanProperty m_doBSErrors
Definition SCTCalib.h:150
FloatProperty m_noisyWaferFraction
Definition SCTCalib.h:183
TFile * m_inputHist
Definition SCTCalib.h:248
BooleanProperty m_doHitMaps
Definition SCTCalib.h:146
@ n_stripPerChip
Definition SCTCalib.h:90
@ n_chipPerSide
Definition SCTCalib.h:90
@ n_chipPerModule
Definition SCTCalib.h:90
std::string getLBList(const std::set< int > &LBList) const
FloatProperty m_noisyWaferThrBarrel
Definition SCTCalib.h:180
BooleanProperty m_doHitMapsLB
Definition SCTCalib.h:147
IOVTime m_iovStart
Definition SCTCalib.h:244
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
Definition SCTCalib.cxx:295
bool notEnoughStatistics(const int required, const int obtained, const std::string &histogramName="HIST") const
Definition SCTCalib.cxx:283
int m_LBRange
Definition SCTCalib.h:243
IOVTime m_iovStop
Definition SCTCalib.h:245
BooleanProperty m_readBS
Definition SCTCalib.h:143
@ lastStrip
Definition SCTCalib.h:78
@ firstStrip
Definition SCTCalib.h:78
BooleanProperty m_deadStripUploadTest
Definition SCTCalib.h:196
BooleanProperty m_useConfiguration
Definition SCTCalib.h:136
StringProperty m_tagID4NoisyStrips
Definition SCTCalib.h:211
IntegerProperty m_noisyModuleList
Definition SCTCalib.h:168
IntegerProperty m_noisyStripLastRunInDB
Definition SCTCalib.h:166
StatusCode openXML4MonSummary(std::ofstream &, std::string_view) const
StatusCode addStripsToList(const EventContext &ctx, Identifier &waferId, std::set< Identifier > &stripIdList, bool isNoisy, bool isNew) const
std::vector< Identifier >::const_iterator const_id_iterator
Definition SCT_ID.h:73
SCT_SerialNumber is a class to hold a serial number and provide check on validity,...
std::string str() const
Full serial number as a string.
const_pointer_type retrieve()
void efficiency(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
outFile
Comment Out Those You do not wish to run.
l
Printing final latex table to .tex output file.
std::string formatPosition(const Identifier &waferId, const SCT_ID *helper, std::string_view delimiter, const bool includeSide)
std::string chipList2LinkList(const std::string &chipList)
std::string xmlCloseChannel()
std::string xmlValue(std::string_view name, const T value)
std::string normalizeList(std::string s)
std::string xmlOpenChannel(const long id, const T since, const T until)
unsigned int bec2Index(const int bec)
std::string xmlHeader(const std::string &version="1.0", const std::string &encoding="UTF-8")
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
@ iPhi
Definition ParamDefs.h:47
status
Definition merge.py:16
int ALL
message levels --------------------------------------------------------—
setScale setgFexType iEta
hold the test vectors and ease the comparison
MsgStream & msg
Definition testRead.cxx:32
TFile * file