ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_ReadCalibDataTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
8
10
11// Include Athena stuff
17
18// Include STL
19#include <cstdint>
20
21//----------------------------------------------------------------------
22SCT_ReadCalibDataTool::SCT_ReadCalibDataTool(const std::string& type, const std::string& name, const IInterface* parent) :
23 base_class(type, name, parent)
24{
25}
26
27//----------------------------------------------------------------------
29 // Print where you are
30 ATH_MSG_DEBUG("in initialize()");
31
32 // Get SCT helper
33 ATH_CHECK(detStore()->retrieve(m_id_sct, "SCT_ID"));
34
35 // Retrieve SCT Cabling tool
36 ATH_CHECK(m_cabling.retrieve());
37
38 // Read Cond Handle Key
39 ATH_CHECK(m_condKeyGain.initialize());
40 ATH_CHECK(m_condKeyNoise.initialize());
41 ATH_CHECK(m_condKeyInfo.initialize());
42 ATH_CHECK(m_SCTDetEleCollKey.initialize());
43
44 return StatusCode::SUCCESS;
45} // SCT_ReadCalibDataTool::initialize()
46
47//----------------------------------------------------------------------
49 return StatusCode::SUCCESS;
50} // SCT_ReadCalibDataTool::finalize()
51
52//----------------------------------------------------------------------
53//Can only report good/bad at strip level
57
58//----------------------------------------------------------------------
59// Returns a bool summary of the data
60bool SCT_ReadCalibDataTool::isGood(const Identifier& elementId, const EventContext& ctx, InDetConditions::Hierarchy h) const {
61 // Status of the compId
62 bool status{true};
63 switch (h) {
65 {
66 // Retrieve isGood Wafer data
67 const SCT_AllGoodStripInfo* condDataInfo{getCondDataInfo(ctx)};
68 if (condDataInfo==nullptr) {
69 ATH_MSG_ERROR("In isGood, SCT_AllGoodStripInfo cannot be retrieved");
70 return false;
71 }
72 // Extract the wafer identifier from the strip identifier
73 Identifier waferId{m_id_sct->wafer_id(elementId)};
74 // Get hashId
75 IdentifierHash waferHash{m_id_sct->wafer_hash(waferId)};
76 // Get strip on wafer to check
77 int strip{m_id_sct->strip(elementId)};
78 // Set value
79 status = (*condDataInfo)[waferHash][strip];
80 break;
81 }
83 {
84 // Not applicable for Calibration data
85 ATH_MSG_WARNING("summary(): Module good/bad is not applicable for Calibration data");
86 break;
87 }
89 {
90 // Not applicable for Calibration data
91 ATH_MSG_WARNING("summary(): Wafer good/bad is not applicable for Calibration data");
92 break;
93 }
95 {
96 // Not applicable for Calibration data
97 ATH_MSG_WARNING("summary(): Chip good/bad is not applicable for Calibration data");
98 break;
99 }
100 default:
101 {
102 ATH_MSG_INFO("Unknown component has been asked for, should be Module/Wafer/Chip or Strip; returning 'good' and continuing");
103 }
104 } //end of switch structure
105
106 // Print status
107 return status;
108} //SCT_ReadCalibDataTool::summary()
109
111 const EventContext& ctx{Gaudi::Hive::currentContext()};
112
113 return isGood(elementId, ctx, h);
114}
115
119 if (not condDataHandle.isValid()) {
120 ATH_MSG_ERROR("Invalid cond data handle " << m_condKeyInfo.key() );
121 return;
122 }
123 if (whandle) {
124 whandle->addDependency (condDataHandle);
125 }
126 const SCT_AllGoodStripInfo* condDataInfo{condDataHandle.cptr()};
127
128 const std::vector<bool> &status = element_status.getElementStatus();
129 const std::vector<InDet::ChipFlags_t> &chip_status = element_status.getElementChipStatus();
130
131 std::vector<std::vector<unsigned short> > &bad_strips = element_status.getBadCells();
132 if (bad_strips.empty()) {
133 bad_strips.resize(condDataInfo->size());
134 }
135 unsigned int element_i=0;
136 for( const std::array<bool, SCT_ConditionsData::STRIPS_PER_WAFER> &good_strips : *condDataInfo) {
137 IdentifierHash moduleHash(element_i);
138 if (status.empty() || status.at(element_i)) {
139 std::vector<unsigned short> &bad_module_strips = bad_strips[element_i];
140 unsigned int last_geoemtrical_chip_id=SCT::N_CHIPS_PER_SIDE;
141 for (unsigned int strip_i=0; strip_i<good_strips.size(); ++strip_i) {
142 unsigned int geoemtrical_chip_id = SCT::getGeometricalChipID(strip_i);
143 if (geoemtrical_chip_id != last_geoemtrical_chip_id) {
144 last_geoemtrical_chip_id=geoemtrical_chip_id;
145 if (!chip_status.empty() && !(chip_status.at(element_i) & static_cast<InDet::ChipFlags_t>(1ul<<geoemtrical_chip_id))) {
146 strip_i += (SCT::N_STRIPS_PER_CHIP-1);
147 continue;
148 }
149 }
150 if (!good_strips[strip_i]) {
151 std::vector<unsigned short>::const_iterator iter = std::lower_bound(bad_module_strips.begin(),bad_module_strips.end(),strip_i);
152 if (iter == bad_module_strips.end() || *iter != strip_i) {
153 bad_module_strips.insert( iter, strip_i);
154 }
155 }
156 }
157 }
158 ++element_i;
159 }
160}
161
162//----------------------------------------------------------------------
163// Returns a defect summary of a defect strip, scan, type and value
165 // Print where you are
166 ATH_MSG_DEBUG("in defectType()");
167
168 // Create the calibDefectSummary
169 CalibDefectType theseSummaryDefects;
170
171 // Retrieve defect data
172 const SCT_CalibDefectData* condDataGain{getCondDataGain(ctx)};
173 if (condDataGain==nullptr) {
174 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (gain) cannot be retrieved.");
175 return theseSummaryDefects;
176 }
177 const SCT_CalibDefectData* condDataNoise{getCondDataNoise(ctx)};
178 if (condDataNoise==nullptr) {
179 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (noise) cannot be retrieved.");
180 return theseSummaryDefects;
181 }
182
183 // Extract the moduleId from the comp identifier
184 Identifier moduleId{m_id_sct->module_id(stripId)};
185 ATH_MSG_DEBUG("Summary wanted for component: " << stripId << " on module: " << moduleId);
186
187 // Create the CalibDataDefect objects
188 SCT_CalibDefectData::CalibModuleDefects wantedNPGDefects{condDataGain->findModule(moduleId)};
189 SCT_CalibDefectData::CalibModuleDefects wantedNODefects{condDataNoise->findModule(moduleId)};
190
191 switch (h) {
193 {
194 // Not applicable for Calibration data
195 ATH_MSG_WARNING("summary(): Module defect summary is not applicable for Calibration data");
196 break;
197 }
198
200 {
201 // Not applicable for Calibration data
202 ATH_MSG_WARNING("summary(): Wafer defect summary is not applicable for Calibration data");
203 break;
204 }
205
207 {
208 // Not applicable for Calibration data
209 ATH_MSG_WARNING("summary(): Chip defect summary is not applicable for Calibration data");
210 break;
211 }
213 {
214 // Get the strip/channel number to check
215 int side{m_id_sct->side(stripId)};
216 int strip{m_id_sct->strip(stripId)};
217 const Identifier waferId{m_id_sct->wafer_id(stripId)};
218 const IdentifierHash waferHash{m_id_sct->wafer_hash(waferId)};
219 unsigned int stripNum;
220 const InDetDD::SiDetectorElement* p_element{getDetectorElement(waferHash, ctx)};
221 if (p_element->swapPhiReadoutDirection()) {
222 if (side == 0) {
223 stripNum = STRIPS_PER_WAFER-1 - strip;
224 } else {
225 stripNum = 2*STRIPS_PER_WAFER-1 - strip;
226 }
227 } else {
228 stripNum = side * STRIPS_PER_WAFER + strip;
229 }
230
231 // Find the bad strip and fill calibDefectSummary
232 if (wantedNPGDefects.begDefects.empty()) {
233 ATH_MSG_VERBOSE("No NPtGain defects in this module");
234 } else {
235 for (unsigned int i{0}; i<wantedNPGDefects.begDefects.size(); ++i) {
236 if (stripNum>=wantedNPGDefects.begDefects[i] and stripNum<=wantedNPGDefects.endDefects[i]) {
237 theseSummaryDefects.scan.emplace_back("NPtGain");
238 theseSummaryDefects.defect.push_back(wantedNPGDefects.typeOfDefect[i]);
239 theseSummaryDefects.value.push_back(wantedNPGDefects.parValue[i]);
240 ATH_MSG_VERBOSE("NPtGain defect summary for strip " << stripNum << " filled");
241 }
242 }
243 }
244
245 if (wantedNODefects.begDefects.empty()) {
246 ATH_MSG_VERBOSE("No NoiseOccupancy defects in this module");
247 } else {
248 for (unsigned int i{0}; i != wantedNODefects.begDefects.size(); ++i) {
249 if (stripNum>=wantedNODefects.begDefects[i] and stripNum <= wantedNODefects.endDefects[i]) {
250 theseSummaryDefects.scan.emplace_back("NoiseOccupancy");
251 theseSummaryDefects.defect.push_back(wantedNODefects.typeOfDefect[i]);
252 theseSummaryDefects.value.push_back(wantedNODefects.parValue[i]);
253 ATH_MSG_VERBOSE("NoiseOccupancy defect summary for strip " << stripNum << " filled");
254 }
255 }
256 }
257 if (theseSummaryDefects.scan.empty()) {
258 ATH_MSG_VERBOSE("defectSummary(): can't retrieve the defects for this strip: " << stripNum << " since strip good");
259 }
260 break;
261 }
262 default:
263 {
264 ATH_MSG_INFO("Unknown component requested, should be one of Module/Side/Chip or Strip");
265 return theseSummaryDefects;
266 }
267
268 }//end of switch structure
269
270 return theseSummaryDefects;
271} //SCT_ReadCalibDataTool::defectType()
272
274 const EventContext& ctx{Gaudi::Hive::currentContext()};
275 return defectType(stripId, ctx, h);
276}
277//----------------------------------------------------------------------
278// Returns a summary of all defects on a module for a given scan
279SCT_CalibDefectData::CalibModuleDefects SCT_ReadCalibDataTool::defectsSummary(const Identifier& moduleId, const std::string& scan, const EventContext& ctx) const {
280 // Create pointer to the CalibDataDefect object
282
283 // Retrieve the correct defect map
284 if (scan == "NPtGain") {
285 const SCT_CalibDefectData* condDataGain{getCondDataGain(ctx)};
286 if (condDataGain==nullptr) {
287 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (gain) cannot be retrieved.");
288 } else {
289 wantedDefects = condDataGain->findModule(moduleId);
290 }
291 } else if (scan == "NoiseOccupancy") {
292 const SCT_CalibDefectData* condDataNoise{getCondDataNoise(ctx)};
293 if (condDataNoise==nullptr) {
294 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (noise) cannot be retrieved.");
295 } else {
296 wantedDefects = condDataNoise->findModule(moduleId);
297 }
298 } else {
299 ATH_MSG_ERROR("defectsSummary(): Module defects for scan" << scan << " does not exist (only NPtGain or NoiseOccupancy).");
300 }
301
302 return wantedDefects;
303} //SCT_ReadCalibDataTool::defectsSummary()
304
306 const EventContext& ctx{Gaudi::Hive::currentContext()};
307 return defectsSummary(moduleId, scan, ctx);
308}
309
310//----------------------------------------------------------------------
311//----------------------------------------------------------------------
312// Returns a list of all strips with a certain defects
313std::list<Identifier> SCT_ReadCalibDataTool::defectList(const std::string& defect, const EventContext& ctx) const {
314 std::list<Identifier> defectList;
315
316 // Retrieve defect data
317 const SCT_CalibDefectData* condDataGain{getCondDataGain(ctx)};
318 if (condDataGain==nullptr) {
319 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (gain) cannot be retrieved.");
320 return defectList;
321 }
322 const SCT_CalibDefectData* condDataNoise{getCondDataNoise(ctx)};
323 if (condDataNoise==nullptr) {
324 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (noise) cannot be retrieved.");
325 return defectList;
326 }
327
328 // Create pointer to the CalibDataDefect object
330
331 //Check which scan the defect belongs
332 bool npDefect{false};
333 bool noDefect{false};
334 if (defect=="NO_HI" or defect=="BAD_OPE" or defect=="DOUBTR_HI") {
335 noDefect = true;
336 } else {
337 npDefect = true;
338 }
339
340 //Loop over all wafers using hashIds from the cabling service
341 std::vector<std::uint32_t> listOfRODs;
342 m_cabling->getAllRods(listOfRODs, ctx);
343 std::vector<std::uint32_t>::iterator rodIter{listOfRODs.begin()};
344 std::vector<std::uint32_t>::iterator rodEnd{listOfRODs.end()};
345 for (; rodIter!=rodEnd; ++rodIter) {
346 std::vector<IdentifierHash> listOfHashes;
347 m_cabling->getHashesForRod(listOfHashes, *rodIter, ctx);
348 std::vector<IdentifierHash>::iterator hashIt{listOfHashes.begin()};
349 std::vector<IdentifierHash>::iterator hashEnd{listOfHashes.end()};
350 for (; hashIt != hashEnd; ++hashIt) {
351 Identifier waferId{m_id_sct->wafer_id(*hashIt)};
352 int side{m_id_sct->side(waferId)};
353 //Only use the hashid for side 0, since data saved per module basis
354 if (side!=0) continue;
355 Identifier moduleId{m_id_sct->module_id(waferId)};
356 if (npDefect) {
357 wantedDefects = condDataGain->findModule(moduleId);
358 } else if (noDefect) {
359 wantedDefects = condDataNoise->findModule(moduleId);
360 }
361 if (not wantedDefects.begDefects.empty()) {
362 for (unsigned int i{0}; i < wantedDefects.begDefects.size(); ++i) {
363 if (wantedDefects.typeOfDefect[i] == defect) {
364 // Create identifier for all strips inside begin to end
365 int strip_beg{static_cast<int>(wantedDefects.begDefects[i])};
366 int strip_end{static_cast<int>(wantedDefects.endDefects[i])};
367 // In DB: strip from 0-1535, need to convert to side and 0-767 and take into account phiSwaps
368 for (int strip{strip_beg}; strip<strip_end+1; strip++) {
369 int nside{(strip<STRIPS_PER_WAFER) ? 0 : 1};
370 int strip_cor;
371 const InDetDD::SiDetectorElement* p_element;
372 if (nside==1) { // if side 1 need waferId of side 1 to get phiswap and correct stripId
373 IdentifierHash hashSide1;
374 m_id_sct->get_other_side(*hashIt, hashSide1);
375 waferId = m_id_sct->wafer_id(hashSide1);
376 p_element = (getDetectorElement(hashSide1, ctx));
377 } else {
378 p_element = (getDetectorElement(*hashIt, ctx));
379 }
380 if (p_element->swapPhiReadoutDirection()) {
381 if (nside == 0) {
382 strip_cor = STRIPS_PER_WAFER-1 - strip;
383 } else {
384 strip_cor = 2*STRIPS_PER_WAFER-1 - strip;
385 }
386 } else {
387 strip_cor = strip - nside * STRIPS_PER_WAFER;
388 }
389 Identifier stripId{m_id_sct->strip_id(waferId,strip_cor)};
390 defectList.push_back(stripId);
391 }
392 }
393 }
394 }
395 }
396 }
397 return defectList;
398} //SCT_ReadCalibDataTool::defects()
399
400std::list<Identifier> SCT_ReadCalibDataTool::defectList(const std::string& defect) const {
401 const EventContext& ctx{Gaudi::Hive::currentContext()};
402 return defectList(defect, ctx);
403}
404//----------------------------------------------------------------------
405
407SCT_ReadCalibDataTool::getCondDataGain(const EventContext& ctx) const {
409 return condData.retrieve();
410}
411
412//----------------------------------------------------------------------
413
415SCT_ReadCalibDataTool::getCondDataNoise(const EventContext& ctx) const {
417 return condData.retrieve();
418}
419
420//----------------------------------------------------------------------
421
423SCT_ReadCalibDataTool::getCondDataInfo(const EventContext& ctx) const {
425 return condData.retrieve();
426}
427
428//----------------------------------------------------------------------
429
431SCT_ReadCalibDataTool::getDetectorElement(const IdentifierHash& waferHash, const EventContext& ctx) const {
433 if (not condData.isValid()) return nullptr;
434 return condData->getDetectorElement(waferHash);
435}
436
437//----------------------------------------------------------------------
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::array< SCT_WaferGoodStripInfo, SCT_ConditionsData::NUMBER_OF_WAFERS > SCT_AllGoodStripInfo
SCT_AllGoodStripInfo is std::array of SCT_WaferGoodStripInfo and is used in SCT_ReadCalibDataCondAlg ...
This is an Identifier helper class for the SCT subdetector.
Header file for SCT_ReadCalibDataTool.
Header file for AthHistogramAlgorithm.
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a silicon detector element.
bool swapPhiReadoutDirection() const
Determine if readout direction between online and offline needs swapping.
const std::vector< bool > & getElementStatus() const
const std::vector< ChipFlags_t > & getElementChipStatus() const
const std::vector< std::vector< unsigned short > > & getBadCells() const
Container with a list of defects derived from calibration data and used in SCT_ReadCalibDataCondAlg a...
CalibModuleDefects findModule(const Identifier &moduleId) const
Search the map for a module.
virtual StatusCode finalize() override
Gaudi finaliser.
SG::ReadCondHandleKey< SCT_AllGoodStripInfo > m_condKeyInfo
virtual StatusCode initialize() override
Gaudi initialiser.
SG::ReadCondHandleKey< SCT_CalibDefectData > m_condKeyGain
SG::ReadCondHandleKey< SCT_CalibDefectData > m_condKeyNoise
virtual SCT_CalibDefectData::CalibModuleDefects defectsSummary(const Identifier &moduleId, const std::string &scan, const EventContext &ctx) const override
Returns module summary of defect.
virtual bool isGood(const Identifier &elementId, InDetConditions::Hierarchy h=InDetConditions::DEFAULT) const override
Summarise the result from the tool as good/bad.
const SCT_ID * m_id_sct
Handle to SCT ID helper.
const SCT_CalibDefectData * getCondDataNoise(const EventContext &ctx) const
ToolHandle< ISCT_CablingTool > m_cabling
const SCT_CalibDefectData * getCondDataGain(const EventContext &ctx) const
const InDetDD::SiDetectorElement * getDetectorElement(const IdentifierHash &waferHash, const EventContext &ctx) const
virtual ISCT_ReadCalibDataTool::CalibDefectType defectType(const Identifier &stripId, const EventContext &ctx, InDetConditions::Hierarchy h=InDetConditions::DEFAULT) const override
Return summary of defect type and values for a strip.
const SCT_AllGoodStripInfo * getCondDataInfo(const EventContext &ctx) const
virtual void getDetectorElementStatus(const EventContext &ctx, InDet::SiDetectorElementStatus &element_status, SG::WriteCondHandle< InDet::SiDetectorElementStatus > *whandle) const override
virtual std::list< Identifier > defectList(const std::string &defect, const EventContext &ctx) const override
Returns module summary of defect.
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
virtual bool canReportAbout(InDetConditions::Hierarchy h) const override
SCT_ReadCalibDataTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor.
const_pointer_type retrieve()
const_pointer_type cptr()
void addDependency(const EventIDRange &range)
void scan(TDirectory *td=0, int depth=0)
Definition listroot.cxx:440
constexpr unsigned int N_STRIPS_PER_CHIP
constexpr unsigned int N_CHIPS_PER_SIDE
constexpr unsigned int getGeometricalChipID(unsigned int strip)
Get the geometrical chip ID for the given strip.