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