ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_ConfigurationConditionsTool.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
9// Athena includes
14#include <type_traits>
15#include <limits>
16
17// Constructor
18SCT_ConfigurationConditionsTool::SCT_ConfigurationConditionsTool(const std::string& type, const std::string& name, const IInterface* parent) :
19 base_class(type, name, parent)
20{
21}
22
23// Initialize
25 ATH_MSG_DEBUG("Initializing configuration");
26
27 ATH_CHECK(detStore()->retrieve(m_pHelper, "SCT_ID"));
28
29 // Read Cond Handle Key
30 ATH_CHECK(m_condKey.initialize());
31 ATH_CHECK(m_SCTDetEleCollKey.initialize());
32
33 return StatusCode::SUCCESS;
34}
35
36// What level of element can this service report about
44
45// Is an element with this Identifier and hierachy good?
46bool SCT_ConfigurationConditionsTool::isGood(const Identifier& elementId, const EventContext& ctx, InDetConditions::Hierarchy h) const {
47 if (not canReportAbout(h)) return true;
48
49 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
50 if (condData==nullptr) {
51 ATH_MSG_ERROR("In isGood, SCT_ConfigurationCondData pointer cannot be retrieved");
52 return false;
53 }
54
55 bool result{true};
57 result = (not condData->isBadStrip(m_pHelper->wafer_hash(m_pHelper->wafer_id(elementId)),
58 m_pHelper->strip(elementId)));
59 // If strip itself is not bad, check if it's in a bad module
60 if (result and m_checkStripsInsideModules) result = (not isStripInBadModule(elementId, condData));
61 } else if (h == InDetConditions::SCT_MODULE) {
62 result = (not condData->isBadModuleId(elementId));
64 result = (not condData->isBadWaferId(elementId));
65 } else if (h == InDetConditions::SCT_CHIP) {
66 result = isGoodChip(elementId, ctx);
67 }
68 return result;
69}
70
71
75 if (not condDataHandle.isValid() ) {
76 ATH_MSG_ERROR("Invalid cond data handle " << m_condKey.key());
77 return;
78 }
79 if (whandle) {
80 whandle->addDependency (condDataHandle);
81 }
82 const SCT_ConfigurationCondData* condData{ condDataHandle.cptr() };
83 const std::set<Identifier>* bad_wafers = condData->getBadWaferIds();
84 if (bad_wafers) {
85 std::vector<bool> &status = element_status.getElementStatus();
86 std::vector<InDet::ChipFlags_t> &chip_status = element_status.getElementChipStatus();
87 if (status.empty()) {
88 status.resize(m_pHelper->wafer_hash_max(),true);
89 }
90 constexpr unsigned int N_CHIPS_PER_SIDE = 6;
91 constexpr unsigned int N_SIDES = 2;
92 constexpr InDet::ChipFlags_t all_flags_set = static_cast<InDet::ChipFlags_t>((1ul<<(N_CHIPS_PER_SIDE*N_SIDES)) - 1ul);
93 static_assert( (1ul<<(N_CHIPS_PER_SIDE*N_SIDES)) - 1ul <= std::numeric_limits<InDet::ChipFlags_t>::max());
94 if (chip_status.empty()) {
95 chip_status.resize(status.size(), all_flags_set);
96 }
97 for (const Identifier &a_bad_wafer : *bad_wafers) {
98 IdentifierHash hash = m_pHelper->wafer_hash(a_bad_wafer);
99 status.at(hash.value())=false;
100 }
102 const std::set<Identifier>* bad_modules = condData->getBadModuleIds();
103 if (bad_modules) {
104 for (const Identifier &a_bad_module : *bad_modules) {
105 for (unsigned int side_i=0; side_i<N_SIDES; ++side_i) {
106 Identifier wafer_id{m_pHelper->wafer_id(m_pHelper->barrel_ec(a_bad_module),
107 m_pHelper->layer_disk(a_bad_module),
108 m_pHelper->phi_module(a_bad_module),
109 m_pHelper->eta_module(a_bad_module),
110 side_i)};
111 IdentifierHash hash = m_pHelper->wafer_hash(wafer_id);
112 chip_status.at(hash.value()) = 0;
113 }
114 }
115 }
116 }
117 if (condData->getBadChips()) {
118 std::array<unsigned int,N_SIDES> side_mask{0x3F, 0xFC0};
119 for (const std::pair<const Identifier, unsigned int> &a_bad_module : *(condData->getBadChips()) ) {
120 for (unsigned int side_i=0; side_i<N_SIDES; ++side_i) {
121 if (a_bad_module.second & side_mask[side_i]) {
122 Identifier wafer_id{m_pHelper->wafer_id(m_pHelper->barrel_ec(a_bad_module.first),
123 m_pHelper->layer_disk(a_bad_module.first),
124 m_pHelper->phi_module(a_bad_module.first),
125 m_pHelper->eta_module(a_bad_module.first),
126 side_i)};
127 IdentifierHash hash = m_pHelper->wafer_hash(wafer_id);
128 unsigned int bad_chip_flags = SCT::getGeometricalFromPhysicalChipFlags(*m_pHelper, *element_status.getDetectorElement(hash),a_bad_module.second );
129 chip_status.at(hash.value()) &= static_cast<InDet::ChipFlags_t>( ~(bad_chip_flags) );
130 }
131 }
132 }
133 }
134 if (condData->getBadStripIds()) {
135 std::vector<std::vector<unsigned short> > &bad_strips = element_status.getBadCells();
136 if (bad_strips.empty()) {
137 bad_strips.resize(status.size());
138 }
139 for (const Identifier &bad_strip : *(condData->getBadStripIds()) ) {
140 IdentifierHash hash = m_pHelper->wafer_hash(m_pHelper->wafer_id(bad_strip));
141 // skip bad modules and chips
142 if (!status.at(hash)) continue;
143 int strip_i = m_pHelper->strip(bad_strip);
144
145 std::vector<unsigned short> &bad_module_strips_combined = bad_strips.at(hash);
146 std::vector<unsigned short>::const_iterator iter = std::lower_bound(bad_module_strips_combined.begin(),bad_module_strips_combined.end(),strip_i);
147 if (iter == bad_module_strips_combined.end() || *iter != strip_i) {
148 bad_module_strips_combined.insert( iter, strip_i);
149 }
150 }
151 }
152 }
153}
154
155// Is a wafer with this IdentifierHash good?
156bool SCT_ConfigurationConditionsTool::isGood(const IdentifierHash& hashId, const EventContext& ctx) const {
157 const Identifier elementId{m_pHelper->wafer_id(hashId)};
158 return isGood(elementId, ctx, InDetConditions::SCT_SIDE);
159}
160
161// Is a chip with this Identifier good?
162bool SCT_ConfigurationConditionsTool::isGoodChip(const Identifier& stripId, const EventContext& ctx) const {
163 // This check assumes present SCT.
164 // Get module number
165 const Identifier moduleId{m_pHelper->module_id(stripId)};
166 if (not moduleId.is_valid()) {
167 ATH_MSG_WARNING("moduleId obtained from stripId " << stripId << " is invalid.");
168 return false;
169 }
170
171 // badChips word for the module
172 const unsigned int v_badChips{badChips(moduleId, ctx)};
173 // badChips holds 12 bits.
174 // bit 0 (LSB) is chip 0 for side 0.
175 // bit 5 is chip 5 for side 0.
176 // bit 6 is chip 6 for side 1.
177 // bit 11 is chip 11 for side 1.
178
179 // If there is no bad chip, this check is done.
180 if (v_badChips==0) return true;
181
182 const int side{m_pHelper->side(stripId)};
183 // Check the six chips on the side
184 // 0x3F = 0000 0011 1111
185 // 0xFC0 = 1111 1100 0000
186 // If there is no bad chip on the side, this check is done.
187 if ((side==0 and (v_badChips & 0x3F)==0) or (side==1 and (v_badChips & 0xFC0)==0)) return true;
188
189 int chip{getChip(stripId, ctx)};
190 if (chip<0 or chip>=12) {
191 ATH_MSG_WARNING("chip number is invalid: " << chip);
192 return false;
193 }
194
195 // Check if the chip is bad
196 const bool badChip{static_cast<bool>(v_badChips & (1<<chip))};
197
198 return (not badChip);
199}
200
201// Check if a strip is within a bad module
203 if (condData==nullptr) {
204 ATH_MSG_ERROR("In isStripInBadModule, SCT_ConfigurationCondData pointer cannot be retrieved");
205 return true;
206 }
207
208 const Identifier moduleId(m_pHelper->module_id(m_pHelper->wafer_id(stripId)));
209 return condData->isBadModuleId(moduleId);
210}
211
212// Check if a wafer is within a bad module
213bool SCT_ConfigurationConditionsTool::isWaferInBadModule(const Identifier& waferId, const EventContext& ctx) const {
214 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
215 if (condData==nullptr) {
216 ATH_MSG_ERROR("In isWaferInBadModule, SCT_ConfigurationCondData pointer cannot be retrieved");
217 return true;
218 }
219
220 const Identifier moduleId{m_pHelper->module_id(waferId)};
221 return condData->isBadModuleId(moduleId);
222}
223
224// Find the chip number containing a particular strip Identifier
225int SCT_ConfigurationConditionsTool::getChip(const Identifier& stripId, const EventContext& ctx) const {
226 // Check for swapped readout direction
227 const IdentifierHash waferHash{m_pHelper->wafer_hash(m_pHelper->wafer_id(stripId))};
228 const InDetDD::SiDetectorElement* pElement{getDetectorElement(waferHash, ctx)};
229 if (pElement==nullptr) {
230 ATH_MSG_FATAL("Element pointer is nullptr in 'badStrips' method");
231 return invalidChipNumber;
232 }
233 return SCT::getChip(*m_pHelper, *pElement, stripId);
234}
235
236const std::set<Identifier>* SCT_ConfigurationConditionsTool::badModules(const EventContext& ctx) const {
237 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
238 if (condData==nullptr) {
239 ATH_MSG_ERROR("In badModules, SCT_ConfigurationCondData pointer cannot be retrieved");
240 return nullptr;
241 }
242
243 return condData->getBadModuleIds();
244}
245
246void SCT_ConfigurationConditionsTool::badStrips(const Identifier& moduleId, std::set<Identifier>& strips, const EventContext& ctx, bool ignoreBadModules, bool ignoreBadChips) const {
247 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
248 if (condData==nullptr) {
249 ATH_MSG_ERROR("In badStrips, SCT_ConfigurationCondData pointer cannot be retrieved");
250 return;
251 }
252
253 // Bad strips for a given module
254 if (ignoreBadModules) {
255 // Ignore strips in bad modules
256 if (condData->isBadModuleId(moduleId)) return;
257 }
258
259 for (const Identifier& badStripId: *(condData->getBadStripIds())) {
260 if (ignoreBadChips) {
261 // Ignore strips in bad chips
262 const int chip{getChip(badStripId, ctx)};
263 if (chip!=invalidChipNumber) {
264 unsigned int chipStatusWord{condData->getBadChips(moduleId)};
265 if ((chipStatusWord & (1 << chip)) != 0) continue;
266 }
267 }
268 if (m_pHelper->module_id(m_pHelper->wafer_id(badStripId)) == moduleId) strips.insert(badStripId);
269 }
270}
271
272std::pair<bool, bool> SCT_ConfigurationConditionsTool::badLinks(const IdentifierHash& hash, const EventContext& ctx) const {
273 // Bad links for a given module
274 // Bad convetion is used. true is for good link and false is for bad link...
275 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
276 if (condData==nullptr) {
277 ATH_MSG_ERROR("In badLinks, SCT_ConfigurationCondData pointer cannot be retrieved");
278 return std::pair<bool, bool>{false, false};
279 }
280
281 return condData->areBadLinks(hash);
282}
283
284const std::map<IdentifierHash, std::pair<bool, bool>>* SCT_ConfigurationConditionsTool::badLinks(const EventContext& ctx) const {
285 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
286 if (condData==nullptr) {
287 ATH_MSG_ERROR("In badLinks, SCT_ConfigurationCondData pointer cannot be retrieved");
288 return nullptr;
289 }
290
291 return condData->getBadLinks();
292}
293
294const std::map<Identifier, unsigned int>* SCT_ConfigurationConditionsTool::badChips(const EventContext& ctx) const {
295 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
296 if (condData==nullptr) {
297 ATH_MSG_ERROR("In badChips, SCT_ConfigurationCondData pointer cannot be retrieved");
298 return nullptr;
299 }
300
301 return condData->getBadChips();
302}
303
304unsigned int SCT_ConfigurationConditionsTool::badChips(const Identifier& moduleId, const EventContext& ctx) const {
305 // Bad chips for a given module
306 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
307 if (condData==nullptr) {
308 ATH_MSG_ERROR("In badChips, SCT_ConfigurationCondData pointer cannot be retrieved");
309 return 0xFFF; // 12 bad chips
310 }
311
312 return condData->getBadChips(moduleId);
313}
314
315void
316SCT_ConfigurationConditionsTool::badStrips(std::set<Identifier>& strips, const EventContext& ctx, bool ignoreBadModules, bool ignoreBadChips) const {
317 const SCT_ConfigurationCondData* condData{getCondData(ctx)};
318 if (condData==nullptr) {
319 ATH_MSG_ERROR("In badStrips, SCT_ConfigurationCondData pointer cannot be retrieved");
320 return;
321 }
322
323 if (!ignoreBadModules and !ignoreBadChips) {
324 const std::set<Identifier>& bad_strips = *condData->getBadStripIds();
325 std::copy(bad_strips.begin(), bad_strips.end(), std::inserter(strips,strips.begin()));
326 return;
327 }
328 for (const Identifier& badStripId: *(condData->getBadStripIds())) {
329 const Identifier moduleId{m_pHelper->module_id(m_pHelper->wafer_id(badStripId))};
330 // Ignore strips in bad modules
331 if (ignoreBadModules) {
332 if (condData->isBadModuleId(moduleId)) continue;
333 }
334 // Ignore strips in bad chips
335 if (ignoreBadChips) {
336 const int chip{getChip(badStripId, ctx)};
337 if (chip!=invalidChipNumber) {
338 unsigned int chipStatusWord{condData->getBadChips(moduleId)};
339 if ((chipStatusWord & (1 << chip)) != 0) continue;
340 }
341 }
342 strips.insert(badStripId);
343 }
344}
345
347SCT_ConfigurationConditionsTool::getCondData(const EventContext& ctx) const {
349 return condData.retrieve();
350}
351
354 if (not condData.isValid()) return nullptr;
355 return condData->getDetectorElement(waferHash);
356}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
header file for tool which reads SCT configuration from database
This is an Identifier helper class for the SCT subdetector.
Header file for AthHistogramAlgorithm.
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
Class to hold geometrical description of a silicon detector element.
const std::vector< bool > & getElementStatus() const
const InDetDD::SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
const std::vector< ChipFlags_t > & getElementChipStatus() const
const std::vector< std::vector< unsigned short > > & getBadCells() const
Class for data object used in SCT_ConfigurationCondAlg and SCT_ConfigurationConditionsTool.
std::pair< bool, bool > areBadLinks(const IdentifierHash &hash) const
Check if a module has bad links.
bool isBadWaferId(const Identifier &waferId) const
Check if a wafer identifier is bad one.
const std::map< IdentifierHash, std::pair< bool, bool > > * getBadLinks() const
Get all bad links.
bool isBadModuleId(const Identifier &moduleId) const
Check if a module identifier is bad one.
bool isBadStrip(const IdentifierHash &hash, const int strip) const
Check if a strip identifier is bad one.
const std::set< Identifier > * getBadModuleIds() const
Get all bad module identifiers.
const std::set< Identifier > * getBadStripIds() const
Get all bad strip identifiers.
const std::set< Identifier > * getBadWaferIds() const
Get all bad wafer identifiers.
unsigned int getBadChips(const Identifier &moduleId) const
Get bad chips for a module.
const SCT_ID * m_pHelper
ID helper for SCT.
const SCT_ConfigurationCondData * getCondData(const EventContext &ctx) const
bool isStripInBadModule(const Identifier &stripId, const SCT_ConfigurationCondData *) const
Is a strip within a bad module.
bool isGoodChip(const Identifier &stripId, const EventContext &ctx) const
Is a chip with this Identifier good?
SG::ReadCondHandleKey< SCT_ConfigurationCondData > m_condKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_SCTDetEleCollKey
const InDetDD::SiDetectorElement * getDetectorElement(const IdentifierHash &waferHash, const EventContext &ctx) const
virtual bool canReportAbout(InDetConditions::Hierarchy h) const override
Can the tool report about the given component?
virtual bool isGood(const Identifier &elementId, const EventContext &ctx, InDetConditions::Hierarchy h=InDetConditions::DEFAULT) const override
Is the detector element good?
virtual const std::map< Identifier, unsigned int > * badChips(const EventContext &ctx) const override
List of bad chips.
virtual void getDetectorElementStatus(const EventContext &ctx, InDet::SiDetectorElementStatus &element_status, SG::WriteCondHandle< InDet::SiDetectorElementStatus > *whandle) const override
virtual std::pair< bool, bool > badLinks(const IdentifierHash &hash, const EventContext &ctx) const override
List of bad links.
virtual void badStrips(std::set< Identifier > &strips, const EventContext &ctx, bool ignoreBadModules=false, bool ignoreBadChips=false) const override
List of bad strips.
SCT_ConfigurationConditionsTool(const std::string &type, const std::string &name, const IInterface *parent)
bool isWaferInBadModule(const Identifier &waferId, const EventContext &ctx) const
Is a wafer in a bad module.
virtual int getChip(const Identifier &stripId, const EventContext &ctx) const override
Get the chip number containing a particular strip.
virtual const std::set< Identifier > * badModules(const EventContext &ctx) const override
List of bad modules.
const_pointer_type retrieve()
const_pointer_type cptr()
void addDependency(const EventIDRange &range)
constexpr unsigned int getGeometricalFromPhysicalChipFlags(unsigned int side, bool swap, unsigned int physical_chip_flags)
Convert a word in which each bit represents the status of a certain physical chip to a word in which ...
constexpr unsigned int getChip(unsigned int side, bool swap, unsigned int strip)
Get the physical chip ID for the given strip.