ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_ReadCalibDataTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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
113 if (not condDataHandle.isValid()) {
114 ATH_MSG_ERROR("Invalid cond data handle " << m_condKeyInfo.key() );
115 return;
116 }
117 if (whandle) {
118 whandle->addDependency (condDataHandle);
119 }
120 const SCT_AllGoodStripInfo* condDataInfo{condDataHandle.cptr()};
121
122 const std::vector<bool> &status = element_status.getElementStatus();
123 const std::vector<InDet::ChipFlags_t> &chip_status = element_status.getElementChipStatus();
124
125 std::vector<std::vector<unsigned short> > &bad_strips = element_status.getBadCells();
126 if (bad_strips.empty()) {
127 bad_strips.resize(condDataInfo->size());
128 }
129 unsigned int element_i=0;
130 for( const std::array<bool, SCT_ConditionsData::STRIPS_PER_WAFER> &good_strips : *condDataInfo) {
131 IdentifierHash moduleHash(element_i);
132 if (status.empty() || status.at(element_i)) {
133 std::vector<unsigned short> &bad_module_strips = bad_strips[element_i];
134 unsigned int last_geoemtrical_chip_id=SCT::N_CHIPS_PER_SIDE;
135 for (unsigned int strip_i=0; strip_i<good_strips.size(); ++strip_i) {
136 unsigned int geoemtrical_chip_id = SCT::getGeometricalChipID(strip_i);
137 if (geoemtrical_chip_id != last_geoemtrical_chip_id) {
138 last_geoemtrical_chip_id=geoemtrical_chip_id;
139 if (!chip_status.empty() && !(chip_status.at(element_i) & static_cast<InDet::ChipFlags_t>(1ul<<geoemtrical_chip_id))) {
140 strip_i += (SCT::N_STRIPS_PER_CHIP-1);
141 continue;
142 }
143 }
144 if (!good_strips[strip_i]) {
145 std::vector<unsigned short>::const_iterator iter = std::lower_bound(bad_module_strips.begin(),bad_module_strips.end(),strip_i);
146 if (iter == bad_module_strips.end() || *iter != strip_i) {
147 bad_module_strips.insert( iter, strip_i);
148 }
149 }
150 }
151 }
152 ++element_i;
153 }
154}
155
156//----------------------------------------------------------------------
157// Returns a defect summary of a defect strip, scan, type and value
159 // Print where you are
160 ATH_MSG_DEBUG("in defectType()");
161
162 // Create the calibDefectSummary
163 CalibDefectType theseSummaryDefects;
164
165 // Retrieve defect data
166 const SCT_CalibDefectData* condDataGain{getCondDataGain(ctx)};
167 if (condDataGain==nullptr) {
168 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (gain) cannot be retrieved.");
169 return theseSummaryDefects;
170 }
171 const SCT_CalibDefectData* condDataNoise{getCondDataNoise(ctx)};
172 if (condDataNoise==nullptr) {
173 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (noise) cannot be retrieved.");
174 return theseSummaryDefects;
175 }
176
177 // Extract the moduleId from the comp identifier
178 Identifier moduleId{m_id_sct->module_id(stripId)};
179 ATH_MSG_DEBUG("Summary wanted for component: " << stripId << " on module: " << moduleId);
180
181 // Create the CalibDataDefect objects
182 SCT_CalibDefectData::CalibModuleDefects wantedNPGDefects{condDataGain->findModule(moduleId)};
183 SCT_CalibDefectData::CalibModuleDefects wantedNODefects{condDataNoise->findModule(moduleId)};
184
185 switch (h) {
187 {
188 // Not applicable for Calibration data
189 ATH_MSG_WARNING("summary(): Module defect summary is not applicable for Calibration data");
190 break;
191 }
192
194 {
195 // Not applicable for Calibration data
196 ATH_MSG_WARNING("summary(): Wafer defect summary is not applicable for Calibration data");
197 break;
198 }
199
201 {
202 // Not applicable for Calibration data
203 ATH_MSG_WARNING("summary(): Chip defect summary is not applicable for Calibration data");
204 break;
205 }
207 {
208 // Get the strip/channel number to check
209 int side{m_id_sct->side(stripId)};
210 int strip{m_id_sct->strip(stripId)};
211 const Identifier waferId{m_id_sct->wafer_id(stripId)};
212 const IdentifierHash waferHash{m_id_sct->wafer_hash(waferId)};
213 unsigned int stripNum;
214 const InDetDD::SiDetectorElement* p_element{getDetectorElement(waferHash, ctx)};
215 if (p_element->swapPhiReadoutDirection()) {
216 if (side == 0) {
217 stripNum = STRIPS_PER_WAFER-1 - strip;
218 } else {
219 stripNum = 2*STRIPS_PER_WAFER-1 - strip;
220 }
221 } else {
222 stripNum = side * STRIPS_PER_WAFER + strip;
223 }
224
225 // Find the bad strip and fill calibDefectSummary
226 if (wantedNPGDefects.begDefects.empty()) {
227 ATH_MSG_VERBOSE("No NPtGain defects in this module");
228 } else {
229 for (unsigned int i{0}; i<wantedNPGDefects.begDefects.size(); ++i) {
230 if (stripNum>=wantedNPGDefects.begDefects[i] and stripNum<=wantedNPGDefects.endDefects[i]) {
231 theseSummaryDefects.scan.emplace_back("NPtGain");
232 theseSummaryDefects.defect.push_back(wantedNPGDefects.typeOfDefect[i]);
233 theseSummaryDefects.value.push_back(wantedNPGDefects.parValue[i]);
234 ATH_MSG_VERBOSE("NPtGain defect summary for strip " << stripNum << " filled");
235 }
236 }
237 }
238
239 if (wantedNODefects.begDefects.empty()) {
240 ATH_MSG_VERBOSE("No NoiseOccupancy defects in this module");
241 } else {
242 for (unsigned int i{0}; i != wantedNODefects.begDefects.size(); ++i) {
243 if (stripNum>=wantedNODefects.begDefects[i] and stripNum <= wantedNODefects.endDefects[i]) {
244 theseSummaryDefects.scan.emplace_back("NoiseOccupancy");
245 theseSummaryDefects.defect.push_back(wantedNODefects.typeOfDefect[i]);
246 theseSummaryDefects.value.push_back(wantedNODefects.parValue[i]);
247 ATH_MSG_VERBOSE("NoiseOccupancy defect summary for strip " << stripNum << " filled");
248 }
249 }
250 }
251 if (theseSummaryDefects.scan.empty()) {
252 ATH_MSG_VERBOSE("defectSummary(): can't retrieve the defects for this strip: " << stripNum << " since strip good");
253 }
254 break;
255 }
256 default:
257 {
258 ATH_MSG_INFO("Unknown component requested, should be one of Module/Side/Chip or Strip");
259 return theseSummaryDefects;
260 }
261
262 }//end of switch structure
263
264 return theseSummaryDefects;
265} //SCT_ReadCalibDataTool::defectType()
266
267//----------------------------------------------------------------------
268// Returns a summary of all defects on a module for a given scan
269SCT_CalibDefectData::CalibModuleDefects SCT_ReadCalibDataTool::defectsSummary(const Identifier& moduleId, const std::string& scan, const EventContext& ctx) const {
270 // Create pointer to the CalibDataDefect object
272
273 // Retrieve the correct defect map
274 if (scan == "NPtGain") {
275 const SCT_CalibDefectData* condDataGain{getCondDataGain(ctx)};
276 if (condDataGain==nullptr) {
277 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (gain) cannot be retrieved.");
278 } else {
279 wantedDefects = condDataGain->findModule(moduleId);
280 }
281 } else if (scan == "NoiseOccupancy") {
282 const SCT_CalibDefectData* condDataNoise{getCondDataNoise(ctx)};
283 if (condDataNoise==nullptr) {
284 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (noise) cannot be retrieved.");
285 } else {
286 wantedDefects = condDataNoise->findModule(moduleId);
287 }
288 } else {
289 ATH_MSG_ERROR("defectsSummary(): Module defects for scan" << scan << " does not exist (only NPtGain or NoiseOccupancy).");
290 }
291
292 return wantedDefects;
293} //SCT_ReadCalibDataTool::defectsSummary()
294
295//----------------------------------------------------------------------
296//----------------------------------------------------------------------
297// Returns a list of all strips with a certain defects
298std::list<Identifier> SCT_ReadCalibDataTool::defectList(const std::string& defect, const EventContext& ctx) const {
299 std::list<Identifier> defectList;
300
301 // Retrieve defect data
302 const SCT_CalibDefectData* condDataGain{getCondDataGain(ctx)};
303 if (condDataGain==nullptr) {
304 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (gain) cannot be retrieved.");
305 return defectList;
306 }
307 const SCT_CalibDefectData* condDataNoise{getCondDataNoise(ctx)};
308 if (condDataNoise==nullptr) {
309 ATH_MSG_ERROR("In defectType, SCT_CalibDefectData (noise) cannot be retrieved.");
310 return defectList;
311 }
312
313 // Create pointer to the CalibDataDefect object
315
316 //Check which scan the defect belongs
317 bool npDefect{false};
318 bool noDefect{false};
319 if (defect=="NO_HI" or defect=="BAD_OPE" or defect=="DOUBTR_HI") {
320 noDefect = true;
321 } else {
322 npDefect = true;
323 }
324
325 //Loop over all wafers using hashIds from the cabling service
326 std::vector<std::uint32_t> listOfRODs;
327 m_cabling->getAllRods(listOfRODs, ctx);
328 std::vector<std::uint32_t>::iterator rodIter{listOfRODs.begin()};
329 std::vector<std::uint32_t>::iterator rodEnd{listOfRODs.end()};
330 for (; rodIter!=rodEnd; ++rodIter) {
331 std::vector<IdentifierHash> listOfHashes;
332 m_cabling->getHashesForRod(listOfHashes, *rodIter, ctx);
333 std::vector<IdentifierHash>::iterator hashIt{listOfHashes.begin()};
334 std::vector<IdentifierHash>::iterator hashEnd{listOfHashes.end()};
335 for (; hashIt != hashEnd; ++hashIt) {
336 Identifier waferId{m_id_sct->wafer_id(*hashIt)};
337 int side{m_id_sct->side(waferId)};
338 //Only use the hashid for side 0, since data saved per module basis
339 if (side!=0) continue;
340 Identifier moduleId{m_id_sct->module_id(waferId)};
341 if (npDefect) {
342 wantedDefects = condDataGain->findModule(moduleId);
343 } else if (noDefect) {
344 wantedDefects = condDataNoise->findModule(moduleId);
345 }
346 if (not wantedDefects.begDefects.empty()) {
347 for (unsigned int i{0}; i < wantedDefects.begDefects.size(); ++i) {
348 if (wantedDefects.typeOfDefect[i] == defect) {
349 // Create identifier for all strips inside begin to end
350 int strip_beg{static_cast<int>(wantedDefects.begDefects[i])};
351 int strip_end{static_cast<int>(wantedDefects.endDefects[i])};
352 // In DB: strip from 0-1535, need to convert to side and 0-767 and take into account phiSwaps
353 for (int strip{strip_beg}; strip<strip_end+1; strip++) {
354 int nside{(strip<STRIPS_PER_WAFER) ? 0 : 1};
355 int strip_cor;
356 const InDetDD::SiDetectorElement* p_element;
357 if (nside==1) { // if side 1 need waferId of side 1 to get phiswap and correct stripId
358 IdentifierHash hashSide1;
359 m_id_sct->get_other_side(*hashIt, hashSide1);
360 waferId = m_id_sct->wafer_id(hashSide1);
361 p_element = (getDetectorElement(hashSide1, ctx));
362 } else {
363 p_element = (getDetectorElement(*hashIt, ctx));
364 }
365 if (p_element->swapPhiReadoutDirection()) {
366 if (nside == 0) {
367 strip_cor = STRIPS_PER_WAFER-1 - strip;
368 } else {
369 strip_cor = 2*STRIPS_PER_WAFER-1 - strip;
370 }
371 } else {
372 strip_cor = strip - nside * STRIPS_PER_WAFER;
373 }
374 Identifier stripId{m_id_sct->strip_id(waferId,strip_cor)};
375 defectList.push_back(stripId);
376 }
377 }
378 }
379 }
380 }
381 }
382 return defectList;
383} //SCT_ReadCalibDataTool::defects()
384
385//----------------------------------------------------------------------
386
388SCT_ReadCalibDataTool::getCondDataGain(const EventContext& ctx) const {
390 return condData.retrieve();
391}
392
393//----------------------------------------------------------------------
394
396SCT_ReadCalibDataTool::getCondDataNoise(const EventContext& ctx) const {
398 return condData.retrieve();
399}
400
401//----------------------------------------------------------------------
402
404SCT_ReadCalibDataTool::getCondDataInfo(const EventContext& ctx) const {
406 return condData.retrieve();
407}
408
409//----------------------------------------------------------------------
410
412SCT_ReadCalibDataTool::getDetectorElement(const IdentifierHash& waferHash, const EventContext& ctx) const {
414 if (not condData.isValid()) return nullptr;
415 return condData->getDetectorElement(waferHash);
416}
417
418//----------------------------------------------------------------------
#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.
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 bool isGood(const Identifier &elementId, const EventContext &ctx, InDetConditions::Hierarchy h=InDetConditions::DEFAULT) const override
Summarise the result from the tool as good/bad.
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.