ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_MonitorConditionsTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
14
19
21
23
25
26#include <iterator>
27#include <istream>
28
29using std::string;
30
31namespace {
32 bool doesNotHaveNumbers(const std::string& numberString) {
33 return (numberString.empty() or numberString.find_first_of("0123456789") == std::string::npos);
34 }
35}
36
38
40
41SCT_MonitorConditionsTool::SCT_MonitorConditionsTool(const std::string& type, const std::string& name, const IInterface* parent):
42 base_class(type, name, parent)
43{
44}
45
47
48StatusCode
50 if (detStore()->retrieve(m_pHelper,"SCT_ID").isFailure()) {
51 ATH_MSG_FATAL("SCT helper failed to retrieve");
52 return StatusCode::FAILURE;
53 }
54
55 // Read Cond Handle Key
56 ATH_CHECK(m_condKey.initialize());
57
58 return StatusCode::SUCCESS;
59}
60
62
63StatusCode
65 return StatusCode::SUCCESS;
66}
67
69
70bool
75
77
78bool
79SCT_MonitorConditionsTool::isGood(const Identifier& elementId, const EventContext& ctx, InDetConditions::Hierarchy h) const {
80 const Identifier waferId{m_pHelper->wafer_id(elementId)};
81 const Identifier moduleId{m_pHelper->module_id(waferId)};
82 const IdentifierHash waferHash{m_pHelper->wafer_hash(waferId)};
83 const IdentifierHash moduleHash{m_pHelper->wafer_hash(moduleId)};
84 const int strip{m_pHelper->strip(elementId)};
85
86 const SCT_MonitorCondData* condData{getCondData(ctx)};
87 if (condData) {
88 switch (h) {
90 return not (condData->nBadStripsForModule(moduleHash)>=m_nhits_noisymodule);
92 return not (condData->nBadStripsForWafer(waferHash)>=m_nhits_noisywafer);
94 return not (condData->nBadStripsForChip(waferHash, strip)>=m_nhits_noisychip);
96 return not condData->isBadStrip(waferHash, strip);
97 }
98 default:
99 return true;
100 }//end of switch statement
101 }
102
103 return true;
104}
105
107
108bool
110 const EventContext& ctx{Gaudi::Hive::currentContext()};
111
112 return isGood(elementId, ctx, h);
113}
114
116
117bool
118SCT_MonitorConditionsTool::isGood(const IdentifierHash& hashId, const EventContext& ctx) const {
119 Identifier elementId{m_pHelper->wafer_id(hashId)};
120 return isGood(elementId, ctx, InDetConditions::SCT_SIDE);
121}
122
124
125bool
127 const EventContext& ctx{Gaudi::Hive::currentContext()};
128
129 return isGood(hashId, ctx);
130}
131
132
136 if (not condDataHandle.isValid()) {
137 ATH_MSG_ERROR("Invalid cond data handle " << m_condKey.key() );
138 return;
139 }
140 const SCT_MonitorCondData* condData{condDataHandle.cptr() };
141 if (whandle) {
142 whandle->addDependency (condDataHandle);
143 }
144 if (condData) {
145 std::vector<bool> &status = element_status.getElementStatus();
146 if (status.empty()) {
147 status.resize(m_pHelper->wafer_hash_max(),true);
148 }
149 for (unsigned int hash=0; hash<status.size(); ++hash) {
150 status.at(hash) = status.at(hash) && not (condData->nBadStripsForWafer(hash)>=m_nhits_noisywafer);
151 }
152
153 std::vector<InDet::ChipFlags_t> &chip_status = element_status.getElementChipStatus();
154 if (chip_status.empty()) {
155 constexpr InDet::ChipFlags_t all_chips_set = static_cast<InDet::ChipFlags_t>((1ul<<(SCT::N_CHIPS_PER_SIDE*SCT::N_SIDES)) - 1ul);
156 static_assert( (1ul<<(SCT::N_CHIPS_PER_SIDE*SCT::N_SIDES)) - 1ul <= std::numeric_limits<InDet::ChipFlags_t>::max());
157 chip_status.resize(m_pHelper->wafer_hash_max(),all_chips_set);
158 }
159
160 std::vector<std::vector<unsigned short> > &bad_strips = element_status.getBadCells();
161 if (bad_strips.empty()) {
162 bad_strips.resize(status.size());
163 }
164
165 std::vector<std::pair<unsigned int, unsigned int> > tmp_bad_strips;
166 for (unsigned int module_hash=0; module_hash<status.size(); ++module_hash) {
167 IdentifierHash moduleHash(module_hash);
168
169 std::vector<unsigned short> &bad_module_strips_out = bad_strips.at(module_hash);
170 std::array<unsigned int, SCT::N_CHIPS_PER_SIDE> bad_strip_counts{};
171
172 const std::array<std::bitset<SCT_ConditionsData::STRIPS_PER_CHIP>,
174 &bad_module_strips_in = condData->badStripsForModule(moduleHash);
175
176 unsigned int strip_i=0;
177 tmp_bad_strips.clear();
178 tmp_bad_strips.reserve(bad_module_strips_in.size()*SCT_ConditionsData::STRIPS_PER_CHIP);
179
180 for (const auto& chip_i : bad_module_strips_in) {
181 unsigned int geoemtrical_chip_id = SCT::getGeometricalChipID(strip_i);
182
183 for (unsigned int strip_per_chip_i=0; strip_per_chip_i<chip_i.size(); ++strip_per_chip_i) {
184 if (chip_i.test(strip_per_chip_i)) {
185 tmp_bad_strips.emplace_back(geoemtrical_chip_id,strip_i);
186 ++bad_strip_counts.at(geoemtrical_chip_id);
187 }
188 ++strip_i;
189 }
190 }
191
192 InDet::ChipFlags_t bad_chips=0;
193 for (unsigned int the_chip=0; the_chip< bad_strip_counts.size(); ++the_chip) {
194 bad_chips |= static_cast<InDet::ChipFlags_t >((bad_strip_counts[the_chip]>=m_nhits_noisychip) << the_chip);
195 }
196 chip_status[module_hash] &= ~bad_chips;
197
198 for (const std::pair<unsigned int, unsigned int> &chip_and_strip : tmp_bad_strips) {
199 unsigned int strip_i=chip_and_strip.second;
200 std::vector<unsigned short>::const_iterator iter = std::lower_bound(bad_module_strips_out.begin(),bad_module_strips_out.end(),strip_i);
201 if (iter == bad_module_strips_out.end() || *iter != strip_i) {
202 bad_module_strips_out.insert( iter, strip_i);
203 }
204 }
205 }
206 }
207}
208
210
211void
212SCT_MonitorConditionsTool::badStrips(std::set<Identifier>& strips, const EventContext& ctx) const {
213 // Set of bad strip Identifers for all modules
214 SCT_ID::const_id_iterator waferItr{m_pHelper->wafer_begin()}, waferEnd{m_pHelper->wafer_end()};
215 // Loop over modules (side-0 of wafers)
216 for (; waferItr != waferEnd; ++waferItr) {
217 if (m_pHelper->side(*waferItr) != 0) continue;
218 Identifier moduleId{m_pHelper->module_id(*waferItr)};
219 badStrips(moduleId, strips, ctx);
220 }
221}
222
223void
224SCT_MonitorConditionsTool::badStrips(std::set<Identifier>& strips) const {
225 const EventContext& ctx{Gaudi::Hive::currentContext()};
226 badStrips(strips, ctx);
227}
228
230
231void
232SCT_MonitorConditionsTool::badStrips(const Identifier& moduleId, std::set<Identifier>& strips, const EventContext& ctx) const {
233 // Set of bad strip Identifers for a given module
234 // Get defect string and check it is sensible, i.e. non-empty and contains numbers
235 std::string defectStr{getList(moduleId, ctx)};
236 if (doesNotHaveNumbers(defectStr)) return;
237
238 // Expand the string
239 std::set<int> defectList;
240 expandList(defectStr, defectList);
241
242 // Convert strip number to Identifier and add to list
243 std::set<int>::const_iterator defectItr{defectList.begin()}, defectEnd{defectList.end()};
244 for (; defectItr!=defectEnd; ++defectItr) {
245 // Strips in the DB are numbered 0-767 (side 0) and 768-1535 (side 1).
246 // This is different from the usual online/offline numbering schemes
247 int side{(*defectItr) > SCT_ConditionsData::STRIPS_PER_WAFER-1 ? 1 : 0};
248 int stripNum{side==1 ? (*defectItr) - SCT_ConditionsData::STRIPS_PER_WAFER : (*defectItr)};
249
250 Identifier stripId{m_pHelper->strip_id(m_pHelper->barrel_ec(moduleId), m_pHelper->layer_disk(moduleId),
251 m_pHelper->phi_module(moduleId), m_pHelper->eta_module(moduleId),
252 side, stripNum)};
253
254 ATH_MSG_DEBUG("Bad Strip: Strip number in DB = " << *defectItr<< ", side/offline strip number = " << side << "/" << stripNum<< ", Identifier = " << stripId);
255
256 strips.insert(stripId);
257 }
258}
259
260void
261SCT_MonitorConditionsTool::badStrips(const Identifier& moduleId, std::set<Identifier>& strips) const {
262 const EventContext& ctx{Gaudi::Hive::currentContext()};
263 return badStrips(moduleId, strips, ctx);
264}
265
267
268std::string
269SCT_MonitorConditionsTool::badStripsAsString(const Identifier& moduleId, const EventContext& ctx) const {
270 return getList(moduleId, ctx);
271}
272
273std::string
275 const EventContext& ctx{Gaudi::Hive::currentContext()};
276 return badStripsAsString(moduleId, ctx);
277}
278
280// Local stuff
282
283std::string
284SCT_MonitorConditionsTool::getList(const Identifier& moduleId, const EventContext& ctx) const {
285 string currentDefectList{""};
286 const SCT_MonitorCondData* condData{getCondData(ctx)};
287 if (condData) {
288 const IdentifierHash moduleHash{m_pHelper->wafer_hash(moduleId)};
289 condData->find(moduleHash, currentDefectList);
290 } else {
291 ATH_MSG_ERROR("In getList - no data");
292 }
293 return currentDefectList;
294}
295
297
298void
299SCT_MonitorConditionsTool::expandRange(const std::string& rangeStr, std::set<int>& rangeList) {
300 // Expand a given defect range
301 // Find separator
302 std::string::size_type sepPos{rangeStr.find(s_separator)};
303 // Check if it's a range
304 if (sepPos != std::string::npos) {
305 // Extract min and max
306 std::string::size_type len1{sepPos++}, len2{rangeStr.size()-sepPos};
307 int min{std::stoi(rangeStr.substr(0,len1))};
308 int max{std::stoi(rangeStr.substr(sepPos,len2))};
309 // Add all strips in range to list
310 while (min != (max+1)) rangeList.insert(min++);
311 } else {
312 // Assume single number
313 rangeList.insert(std::stoi(rangeStr));
314 }
315}
316
318
319void
320SCT_MonitorConditionsTool::expandList(const std::string& defectStr, std::set<int>& defectList) {
321 // Expand a given defect list
322
323 // Empty list or one without numbers
324 if (doesNotHaveNumbers(defectStr)) return;
325
326 std::istringstream is{defectStr};
327 std::istream_iterator<std::string> defectItr{is};
328 std::istream_iterator<std::string> defectEnd; //relies on default constructor to produce eof
329
330 // Loop over (space-seperated) defects and add to list
331 for (; defectItr != defectEnd; ++defectItr) expandRange(*defectItr, defectList);
332}
333
335
337SCT_MonitorConditionsTool::getCondData(const EventContext& ctx) const {
339 return condData.retrieve();
340}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_DEBUG(x)
header file containing the number of elements and enumerated type of parameters which may be retrieve...
This is an Identifier helper class for the SCT subdetector.
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
Header file for AthHistogramAlgorithm.
This is a "hash" representation of an Identifier.
const std::vector< bool > & getElementStatus() const
const std::vector< ChipFlags_t > & getElementChipStatus() const
const std::vector< std::vector< unsigned short > > & getBadCells() const
std::vector< Identifier >::const_iterator const_id_iterator
Definition SCT_ID.h:73
Class for data object used in SCT_MonitorCondAlg and SCT_MonitorConditionsTool.
std::size_t nBadStripsForModule(const IdentifierHash &moduleHash) const
Get the number of bad strips for a module.
bool find(const IdentifierHash &hash, std::string &defectList) const
Check if a module has a defect (a list of bad strips). If it does not have defect return false.
bool isBadStrip(const IdentifierHash &waferHash, const int strip) const
Check if a strip is bad.
const std::array< std::bitset< SCT_ConditionsData::STRIPS_PER_CHIP >, SCT_ConditionsData::CHIPS_PER_SIDE > & badStripsForModule(const IdentifierHash &waferHash) const
std::size_t nBadStripsForChip(const IdentifierHash &waferHash, const int strip) const
Get the number of bad strips for the chip, where a strip locates.
std::size_t nBadStripsForWafer(const IdentifierHash &waferHash) const
Get the number of bad strips for a wafer.
static void expandList(const std::string &defectStr, std::set< int > &defectList)
std::string getList(const Identifier &imodule, const EventContext &ctx) const
UnsignedIntegerProperty m_nhits_noisywafer
const SCT_MonitorCondData * getCondData(const EventContext &ctx) const
SG::ReadCondHandleKey< SCT_MonitorCondData > m_condKey
virtual bool isGood(const Identifier &elementId, InDetConditions::Hierarchy h=InDetConditions::DEFAULT) const override
Is the detector element good?
static void expandRange(const std::string &rangeStr, std::set< int > &rangeList)
UnsignedIntegerProperty m_nhits_noisychip
virtual void badStrips(std::set< Identifier > &strips) const override
List of bad strip Identifiers.
static const std::string s_separator
virtual void getDetectorElementStatus(const EventContext &ctx, InDet::SiDetectorElementStatus &element_status, SG::WriteCondHandle< InDet::SiDetectorElementStatus > *whandle) const override
virtual bool canReportAbout(InDetConditions::Hierarchy h) const override
Can the service report about the given component? (chip, module...)
UnsignedIntegerProperty m_nhits_noisymodule
virtual std::string badStripsAsString(const Identifier &moduleId) const override
String of bad strip numbers for a given module.
virtual StatusCode finalize() override
virtual StatusCode initialize() override
SCT_MonitorConditionsTool(const std::string &type, const std::string &name, const IInterface *parent)
const_pointer_type retrieve()
const_pointer_type cptr()
void addDependency(const EventIDRange &range)
constexpr unsigned int N_CHIPS_PER_SIDE
constexpr unsigned int getGeometricalChipID(unsigned int strip)
Get the geometrical chip ID for the given strip.
constexpr unsigned int N_SIDES