ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_MonitorConditionsTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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
109SCT_MonitorConditionsTool::isGood(const IdentifierHash& hashId, const EventContext& ctx) const {
110 Identifier elementId{m_pHelper->wafer_id(hashId)};
111 return isGood(elementId, ctx, InDetConditions::SCT_SIDE);
112}
113
117 if (not condDataHandle.isValid()) {
118 ATH_MSG_ERROR("Invalid cond data handle " << m_condKey.key() );
119 return;
120 }
121 const SCT_MonitorCondData* condData{condDataHandle.cptr() };
122 if (whandle) {
123 whandle->addDependency (condDataHandle);
124 }
125 if (condData) {
126 std::vector<bool> &status = element_status.getElementStatus();
127 if (status.empty()) {
128 status.resize(m_pHelper->wafer_hash_max(),true);
129 }
130 for (unsigned int hash=0; hash<status.size(); ++hash) {
131 status.at(hash) = status.at(hash) && not (condData->nBadStripsForWafer(hash)>=m_nhits_noisywafer);
132 }
133
134 std::vector<InDet::ChipFlags_t> &chip_status = element_status.getElementChipStatus();
135 if (chip_status.empty()) {
136 constexpr InDet::ChipFlags_t all_chips_set = static_cast<InDet::ChipFlags_t>((1ul<<(SCT::N_CHIPS_PER_SIDE*SCT::N_SIDES)) - 1ul);
137 static_assert( (1ul<<(SCT::N_CHIPS_PER_SIDE*SCT::N_SIDES)) - 1ul <= std::numeric_limits<InDet::ChipFlags_t>::max());
138 chip_status.resize(m_pHelper->wafer_hash_max(),all_chips_set);
139 }
140
141 std::vector<std::vector<unsigned short> > &bad_strips = element_status.getBadCells();
142 if (bad_strips.empty()) {
143 bad_strips.resize(status.size());
144 }
145
146 std::vector<std::pair<unsigned int, unsigned int> > tmp_bad_strips;
147 for (unsigned int module_hash=0; module_hash<status.size(); ++module_hash) {
148 IdentifierHash moduleHash(module_hash);
149
150 std::vector<unsigned short> &bad_module_strips_out = bad_strips.at(module_hash);
151 std::array<unsigned int, SCT::N_CHIPS_PER_SIDE> bad_strip_counts{};
152
153 const std::array<std::bitset<SCT_ConditionsData::STRIPS_PER_CHIP>,
155 &bad_module_strips_in = condData->badStripsForModule(moduleHash);
156
157 unsigned int strip_i=0;
158 tmp_bad_strips.clear();
159 tmp_bad_strips.reserve(bad_module_strips_in.size()*SCT_ConditionsData::STRIPS_PER_CHIP);
160
161 for (const auto& chip_i : bad_module_strips_in) {
162 unsigned int geoemtrical_chip_id = SCT::getGeometricalChipID(strip_i);
163
164 for (unsigned int strip_per_chip_i=0; strip_per_chip_i<chip_i.size(); ++strip_per_chip_i) {
165 if (chip_i.test(strip_per_chip_i)) {
166 tmp_bad_strips.emplace_back(geoemtrical_chip_id,strip_i);
167 ++bad_strip_counts.at(geoemtrical_chip_id);
168 }
169 ++strip_i;
170 }
171 }
172
173 InDet::ChipFlags_t bad_chips=0;
174 for (unsigned int the_chip=0; the_chip< bad_strip_counts.size(); ++the_chip) {
175 bad_chips |= static_cast<InDet::ChipFlags_t >((bad_strip_counts[the_chip]>=m_nhits_noisychip) << the_chip);
176 }
177 chip_status[module_hash] &= ~bad_chips;
178
179 for (const std::pair<unsigned int, unsigned int> &chip_and_strip : tmp_bad_strips) {
180 unsigned int strip_i=chip_and_strip.second;
181 std::vector<unsigned short>::const_iterator iter = std::lower_bound(bad_module_strips_out.begin(),bad_module_strips_out.end(),strip_i);
182 if (iter == bad_module_strips_out.end() || *iter != strip_i) {
183 bad_module_strips_out.insert( iter, strip_i);
184 }
185 }
186 }
187 }
188}
189
191
192void
193SCT_MonitorConditionsTool::badStrips(std::set<Identifier>& strips, const EventContext& ctx) const {
194 // Set of bad strip Identifers for all modules
195 SCT_ID::const_id_iterator waferItr{m_pHelper->wafer_begin()}, waferEnd{m_pHelper->wafer_end()};
196 // Loop over modules (side-0 of wafers)
197 for (; waferItr != waferEnd; ++waferItr) {
198 if (m_pHelper->side(*waferItr) != 0) continue;
199 Identifier moduleId{m_pHelper->module_id(*waferItr)};
200 badStrips(moduleId, strips, ctx);
201 }
202}
203
205
206void
207SCT_MonitorConditionsTool::badStrips(const Identifier& moduleId, std::set<Identifier>& strips, const EventContext& ctx) const {
208 // Set of bad strip Identifers for a given module
209 // Get defect string and check it is sensible, i.e. non-empty and contains numbers
210 std::string defectStr{getList(moduleId, ctx)};
211 if (doesNotHaveNumbers(defectStr)) return;
212
213 // Expand the string
214 std::set<int> defectList;
215 expandList(defectStr, defectList);
216
217 // Convert strip number to Identifier and add to list
218 std::set<int>::const_iterator defectItr{defectList.begin()}, defectEnd{defectList.end()};
219 for (; defectItr!=defectEnd; ++defectItr) {
220 // Strips in the DB are numbered 0-767 (side 0) and 768-1535 (side 1).
221 // This is different from the usual online/offline numbering schemes
222 int side{(*defectItr) > SCT_ConditionsData::STRIPS_PER_WAFER-1 ? 1 : 0};
223 int stripNum{side==1 ? (*defectItr) - SCT_ConditionsData::STRIPS_PER_WAFER : (*defectItr)};
224
225 Identifier stripId{m_pHelper->strip_id(m_pHelper->barrel_ec(moduleId), m_pHelper->layer_disk(moduleId),
226 m_pHelper->phi_module(moduleId), m_pHelper->eta_module(moduleId),
227 side, stripNum)};
228
229 ATH_MSG_DEBUG("Bad Strip: Strip number in DB = " << *defectItr<< ", side/offline strip number = " << side << "/" << stripNum<< ", Identifier = " << stripId);
230
231 strips.insert(stripId);
232 }
233}
234
236
237std::string
238SCT_MonitorConditionsTool::badStripsAsString(const Identifier& moduleId, const EventContext& ctx) const {
239 return getList(moduleId, ctx);
240}
241
243// Local stuff
245
246std::string
247SCT_MonitorConditionsTool::getList(const Identifier& moduleId, const EventContext& ctx) const {
248 string currentDefectList{""};
249 const SCT_MonitorCondData* condData{getCondData(ctx)};
250 if (condData) {
251 const IdentifierHash moduleHash{m_pHelper->wafer_hash(moduleId)};
252 condData->find(moduleHash, currentDefectList);
253 } else {
254 ATH_MSG_ERROR("In getList - no data");
255 }
256 return currentDefectList;
257}
258
260
261void
262SCT_MonitorConditionsTool::expandRange(const std::string& rangeStr, std::set<int>& rangeList) {
263 // Expand a given defect range
264 // Find separator
265 std::string::size_type sepPos{rangeStr.find(s_separator)};
266 // Check if it's a range
267 if (sepPos != std::string::npos) {
268 // Extract min and max
269 std::string::size_type len1{sepPos++}, len2{rangeStr.size()-sepPos};
270 int min{std::stoi(rangeStr.substr(0,len1))};
271 int max{std::stoi(rangeStr.substr(sepPos,len2))};
272 // Add all strips in range to list
273 while (min != (max+1)) rangeList.insert(min++);
274 } else {
275 // Assume single number
276 rangeList.insert(std::stoi(rangeStr));
277 }
278}
279
281
282void
283SCT_MonitorConditionsTool::expandList(const std::string& defectStr, std::set<int>& defectList) {
284 // Expand a given defect list
285
286 // Empty list or one without numbers
287 if (doesNotHaveNumbers(defectStr)) return;
288
289 std::istringstream is{defectStr};
290 std::istream_iterator<std::string> defectItr{is};
291 std::istream_iterator<std::string> defectEnd; //relies on default constructor to produce eof
292
293 // Loop over (space-seperated) defects and add to list
294 for (; defectItr != defectEnd; ++defectItr) expandRange(*defectItr, defectList);
295}
296
298
300SCT_MonitorConditionsTool::getCondData(const EventContext& ctx) const {
302 return condData.retrieve();
303}
#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
static void expandRange(const std::string &rangeStr, std::set< int > &rangeList)
UnsignedIntegerProperty m_nhits_noisychip
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 StatusCode finalize() override
virtual StatusCode initialize() override
virtual std::string badStripsAsString(const Identifier &moduleId, const EventContext &ctx) const override
String of bad strip numbers for a given module.
virtual void badStrips(std::set< Identifier > &strips, const EventContext &ctx) const override
List of bad strip Identifiers.
SCT_MonitorConditionsTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual bool isGood(const Identifier &elementId, const EventContext &ctx, InDetConditions::Hierarchy h=InDetConditions::DEFAULT) const override
Is the detector element good?
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