ATLAS Offline Software
Loading...
Searching...
No Matches
TileBadChannelsCondAlg.cxx
Go to the documentation of this file.
1//Dear emacs, this is -*- c++ -*-
2/*
3 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4*/
5
6
7// Tile includes
13
14// Athena includes
17
18
19TileBadChannelsCondAlg::TileBadChannelsCondAlg(const std::string& name, ISvcLocator* pSvcLocator) :
20 AthCondAlgorithm(name, pSvcLocator)
21{
22}
23
24
26
27 for (const TileBchDecoder* tileBchDecoder : m_tileBchDecoder) {
28 delete tileBchDecoder;
29 }
30
31}
32
33
35
36 // Tile cabling service
37 ATH_CHECK( m_cablingSvc.retrieve() );
38
39 ATH_CHECK( m_badChannelsKey.initialize() );
40
41 //=== initialize bit pattern decoders for all possible versions
43 for (unsigned int i = 0; i < TileBchDecoder::MaxVersion; ++i) {
44 ATH_MSG_DEBUG( "Creating TileBchDecoder(" << i << ")" );
46 }
47
48
49 //=== TileCondIdTransforms
50 CHECK( m_tileIdTrans.retrieve() );
51
52 m_useOnlBch = !(m_onlBchProxy.empty());
53 //=== retrieve online proxy
54 ATH_CHECK( m_onlBchProxy.retrieve(EnableTool{m_useOnlBch}) );
55
56 m_useOflBch = !(m_oflBchProxy.empty());
57 //=== retrieve offline proxy
58 ATH_CHECK( m_oflBchProxy.retrieve(EnableTool{m_useOflBch}) );
59
60 if (m_useOnlBch && m_useOflBch) {
61 ATH_MSG_INFO("ProxyOnlBch and ProxyOflBch will be used for bad channel status");
62 } else if (m_useOnlBch) {
63 ATH_MSG_INFO("Only ProxyOnlBch will be used for bad channel status");
64 } else if (m_useOflBch) {
65 ATH_MSG_INFO("Only ProxyOflBch will be used for bad channel status");
66 } else {
67 ATH_MSG_INFO("ProxyOnlBch and ProxyOflBch will not be used for bad channel status => all channels are good");
68 }
69
70 return StatusCode::SUCCESS;
71}
72
73
74StatusCode TileBadChannelsCondAlg::execute(const EventContext& ctx) const {
75
77
78 if (badChannels.isValid()) {
79 ATH_MSG_DEBUG("Found valid TileBadChannels: " << badChannels.key());
80 return StatusCode::SUCCESS;
81 }
82
83 EventIDRange eventRange;
84
85 // Define validity of the output cond object
86 std::unique_ptr<TileCalibData<TileCalibDrawerBch>> onlBchData
87 = std::make_unique<TileCalibData<TileCalibDrawerBch>>();
88
89 if (m_useOnlBch) {
90 EventIDRange onlBchRange;
91 ATH_CHECK( m_onlBchProxy->fillCalibData(*onlBchData, onlBchRange) );
92 eventRange = EventIDRange::intersect(eventRange, onlBchRange);
93 }
94
95 std::unique_ptr<TileCalibData<TileCalibDrawerBch>> oflBchData
96 = std::make_unique<TileCalibData<TileCalibDrawerBch>>();
97
98 if (m_useOflBch) {
99 EventIDRange oflBchRange;
100 ATH_CHECK( m_oflBchProxy->fillCalibData(*oflBchData, oflBchRange) );
101 eventRange = EventIDRange::intersect(eventRange, oflBchRange);
102 }
103
104
105 std::unique_ptr<TileBadChannels> badChannelsData = std::make_unique<TileBadChannels>();
106
107 try {
108
109 //=== loop over the whole detector, hash affected ADCs
110 uint32_t adcBits(0), channelBits(0);
111
112 const TileHWID* tileHWID = m_tileIdTrans->getTileHWID();
113
114 IdContext adcContext = tileHWID->adc_context();
115 unsigned int maxAdcHash = tileHWID->adc_hash_max();
116
117 unsigned int drawerIdx(0);
118 unsigned int channel(0);
119 unsigned int adc(0);
120
121 for (IdentifierHash adcHash = 0; adcHash < maxAdcHash; adcHash += 1) {
122 HWIdentifier adcId;
123 if (tileHWID->get_id(adcHash, adcId, &adcContext) == 0) {
124
125 if (tileHWID->ros(adcId) == 0) continue;
126
127 m_tileIdTrans->getIndices(adcId, drawerIdx, channel, adc);
128
129 TileBchStatus adcStatus;
130
131 std::vector<const TileCalibDrawerBch*> calibDrawers;
132 if (m_useOnlBch) {
133 //=== online status ...
134 calibDrawers.push_back( onlBchData->getCalibDrawer(drawerIdx) );
135 }
136
137 if (m_useOflBch) {
138 //=== ... add offline status
139 calibDrawers.push_back( oflBchData->getCalibDrawer(drawerIdx) );
140 }
141
142 for (const TileCalibDrawerBch* calibDrawer : calibDrawers) {
143 TileBchDecoder::BitPatVer bitPatVer = calibDrawer->getBitPatternVersion();
144 calibDrawer->getStatusWords(channel, adc, adcBits, channelBits);
145 adcStatus += m_tileBchDecoder[bitPatVer]->decode(channelBits, adcBits);
146 }
147
148 if (!adcStatus.isGood()) {
149 //=== only add problematic adcs to map
150 HWIdentifier channelId = tileHWID->channel_id(adcId);
151 badChannelsData->addAdcStatus(channelId, adcId, adcStatus);
152 }
153 }
154 }
155
156
157 //============================================================
158 //=== Set definition of bad and noisy channel if specified.
159 //--- These definitions are stored in drawerIdx=1, since
160 //--- drawers 1,...,3 are not used in the default chain.
161 //---
162 //--- drawerIdx=1, channel=0: definition of bad channel
163 //--- drawerIdx=1, channel=1: definition of noisy channel
164 //--- drawerIdx=1, channel=2: definition of NoGainLevel1 channel
165 //--- drawerIdx=1, channel=3: definition of bad timing channel
166 //--- .... (this list could be extended if needed)
167 //============================================================
168 //=== Reset defintion to hard-coded defaults
170
171 const TileCalibDrawerBch* definitionsCalibDrawer;
172 if (m_useOflBch) definitionsCalibDrawer = oflBchData->getCalibDrawer(TileCalibUtils::DEFINITIONS_DRAWERIDX);
173 else definitionsCalibDrawer = onlBchData->getCalibDrawer(TileCalibUtils::DEFINITIONS_DRAWERIDX);
174
175 TileBchDecoder::BitPatVer bitPatVer = definitionsCalibDrawer->getBitPatternVersion();
176
177 //=== TileBchStatus.isBad() definition
178 definitionsCalibDrawer->getStatusWords(TileCalibUtils::BAD_DEFINITION_CHAN, 0, adcBits, channelBits);
179 TileBchStatus channelStatus(m_tileBchDecoder[bitPatVer]->decode(channelBits, adcBits));
180 if (channelStatus.isAffected()) {
181 ATH_MSG_INFO( "Updating TileBchStatus::isBad() definition from DB" );
182 TileBchStatus::defineBad(channelStatus);
183 } else {
184 ATH_MSG_INFO( "No TileBchStatus::isBad() definition found in DB, using defaults" );
185 }
186
187 //=== TileBchStatus.isNoisy() definition
188 definitionsCalibDrawer->getStatusWords(TileCalibUtils::NOISY_DEFINITION_CHAN, 0, adcBits, channelBits);
189 channelStatus = m_tileBchDecoder[bitPatVer]->decode(channelBits, adcBits);
190 if (channelStatus.isAffected()) {
191 ATH_MSG_INFO( "Updating TileBchStatus::isNoisy() definition from DB" );
192 TileBchStatus::defineNoisy(channelStatus);
193 } else {
194 ATH_MSG_INFO( "No TileBchStatus::isNoisy() definition found in DB, using defaults" );
195 }
196
197 //=== TileBchStatus.isNoGainL1() definition
198 definitionsCalibDrawer->getStatusWords(TileCalibUtils::NOGAINL1_DEFINITION_CHAN, 0, adcBits, channelBits);
199 channelStatus = m_tileBchDecoder[bitPatVer]->decode(channelBits, adcBits);
200 if (channelStatus.isAffected()) {
201 ATH_MSG_INFO( "Updating TileBchStatus::isNoGainL1() definition from DB" );
202 TileBchStatus::defineNoGainL1(channelStatus);
203 } else {
204 ATH_MSG_INFO( "No TileBchStatus::isNoGainL1() definition found in DB, using defaults" );
205 }
206
207
208 //=== TileBchStatus.isBadTiming() definition
209 definitionsCalibDrawer->getStatusWords(TileCalibUtils::BADTIMING_DEFINITION_CHAN, 0, adcBits, channelBits);
210 channelStatus = m_tileBchDecoder[bitPatVer]->decode(channelBits, adcBits);
211 if (channelStatus.isAffected()) {
212 ATH_MSG_INFO( "Updating TileBchStatus::isBadTiming() definition from DB" );
213 TileBchStatus::defineBadTiming(channelStatus);
214 } else {
215 ATH_MSG_INFO( "No TileBchStatus::isBadTiming() definition found in DB, using defaults" );
216 }
217
218 //=== TileBchStatus.isWrongBCID() definition
219 definitionsCalibDrawer->getStatusWords(TileCalibUtils::WRONGBCID_DEFINITION_CHAN, 0, adcBits, channelBits);
220 channelStatus = m_tileBchDecoder[bitPatVer]->decode(channelBits, adcBits);
221 if (channelStatus.isAffected()) {
222 ATH_MSG_INFO( "Updating TileBchStatus::isWrongBCID() definition from DB" );
223 TileBchStatus::defineWrongBCID(channelStatus);
224 } else {
225 ATH_MSG_INFO( "No TileBchStatus::isWrongBCID() definition found in DB, using defaults" );
226 }
227
228 //=== report current definitions
229 ATH_MSG_INFO( "TileBchStatus::isBad() is defined by: "
230 << TileBchStatus::getDefinitionBad().getString() );
231 ATH_MSG_INFO( "TileBchStatus::isNoisy() is defined by: "
232 << TileBchStatus::getDefinitionNoisy().getString() );
233 ATH_MSG_INFO( "TileBchStatus::isNoGainL1() is defined by: "
234 << TileBchStatus::getDefinitionNoGainL1().getString() );
235 ATH_MSG_INFO( "TileBchStatus::isBadTiming() is defined by: "
236 << TileBchStatus::getDefinitionBadTiming().getString() );
237 ATH_MSG_INFO( "TileBchStatus::isWrongBCID() is defined by: "
238 << TileBchStatus::getDefinitionWrongBCID().getString() );
239
240 // Find Tile drawers masked completely
241 std::vector<int> maskedDrawers;
242 const TileCablingService* cabling = m_cablingSvc->cablingService();
243 unsigned int maxChannels = cabling->getMaxChannels();
244
245 for (unsigned int ros = 1; ros < TileCalibUtils::MAX_ROS; ++ros) {
246 for (unsigned int drawer = 0; drawer < TileCalibUtils::MAX_DRAWER; ++drawer) {
247 unsigned int channel = 0;
248 for ( ; channel < maxChannels; ++channel) {
249 int index(-1);
250 int pmt(-1);
251 HWIdentifier channelID = tileHWID->channel_id(ros, drawer, channel);
252 cabling->h2s_cell_id_index(channelID, index, pmt);
253 if (index >= 0 && !badChannelsData->getChannelStatus(channelID).isBad()) { // good normal cell
254 break;
255 }
256 }
257 if (channel == maxChannels) maskedDrawers.push_back(tileHWID->frag(ros, drawer));
258 }
259 }
260
261
262 if (msgLvl(MSG::DEBUG)) {
263 if (!maskedDrawers.empty()) {
264 msg(MSG::DEBUG) << "List of fully masked drawers: " << MSG::hex;
265 for(int maskedDrawer : maskedDrawers) {
266 msg(MSG::DEBUG) << " 0x" << maskedDrawer;
267 }
268 msg(MSG::DEBUG) << MSG::dec << endmsg;
269 } else {
270 msg(MSG::DEBUG) << "No bad drawers found" << endmsg;
271 }
272 }
273
274 if (!maskedDrawers.empty()) badChannelsData->setMaskedDrawers(std::move(maskedDrawers));
275
276 // Check if drawer trips probabilities for simulation are exist in DB.
277 // By special convention trips probabilities are stored in drawer number: 2
278 // like integers number plus one denominator per ros
279 //--- drawerIdx=2, channel=1: 64 integers + denominator for LBA
280 //--- drawerIdx=2, channel=2: 64 integers + denominator for LBC
281 //--- drawerIdx=2, channel=3: 64 integers + denominator for EBA
282 //--- drawerIdx=2, channel=4: 64 integers + denominator for EBC
283 //============================================================
284 if (m_useOflBch) {
285 const TileCalibDrawerBch* tripsCalibDrawer = oflBchData->getCalibDrawer(TileCalibUtils::TRIPS_DRAWERIDX);
286
287 if (tripsCalibDrawer->getObjSizeUint32() == TileCalibUtils::MAX_DRAWER + 1
288 && tripsCalibDrawer->getNChans() == TileCalibUtils::MAX_ROS) {
289
290
291 ATH_MSG_INFO("Found drawer trips probabilities in DB");
292
293 std::vector<std::vector<float>> tripsProbs(TileCalibUtils::MAX_ROS - 1, std::vector<float>(TileCalibUtils::MAX_DRAWER, 0));
294
295 // Fill up arrays with trips probabilities for simulation purposes
296 // Trips probabilities are cached like floats: number / denominator.
297
298 for (unsigned int ros = 1; ros < TileCalibUtils::MAX_ROS; ++ros) {
299 const float denominator = (float) tripsCalibDrawer->getData(ros, 0, TileCalibUtils::MAX_DRAWER);
300 const float inv_denominator = 1. / denominator;
301 for (unsigned int mod = 0; mod < TileCalibUtils::MAX_DRAWER; ++mod) {
302 tripsProbs[ros - 1][mod] = ((float) tripsCalibDrawer->getData(ros, 0, mod)) * inv_denominator;
303 }
304 }
305
306 badChannelsData->setTripsProbabilities(std::move(tripsProbs));
307
308 } else {
309 ATH_MSG_INFO("No drawer trips probabilities found in DB");
310 }
311 }
312 } catch (TileCalib::Exception& e) {
313 ATH_MSG_ERROR( "Caught exception: " << e.what() );
314 return StatusCode::FAILURE;
315 }
316
317
318
319
320 if(badChannels.record(eventRange, badChannelsData.release()).isFailure()) {
321 ATH_MSG_ERROR("Could not record TileBadChannels object with "
322 << badChannels.key()
323 << " with EventRange " << eventRange
324 << " into Conditions Store");
325 return StatusCode::FAILURE;
326 } else {
327
328 ATH_MSG_VERBOSE("Recorded TileBadChannels object with "
329 << badChannels.key()
330 << " with EventRange " << eventRange
331 << " into Conditions Store");
332 }
333
334
335
336 return StatusCode::SUCCESS;
337
338}
#define endmsg
#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_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
bool msgLvl(const MSG::Level lvl) const
Base class for conditions algorithms.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
const std::string & key() const
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
virtual StatusCode initialize() override
std::vector< const TileBchDecoder * > m_tileBchDecoder
SG::WriteCondHandleKey< TileBadChannels > m_badChannelsKey
Name of output TileBadChannels.
ToolHandle< ITileCondProxy< TileCalibDrawerBch > > m_onlBchProxy
Tool to provide online Tile bad channel status.
TileBadChannelsCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
ToolHandle< ITileCondProxy< TileCalibDrawerBch > > m_oflBchProxy
Tool to provide ofline Tile bad channel status If it is provided online and offline Tile bad channel ...
ToolHandle< TileCondIdTransforms > m_tileIdTrans
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
virtual StatusCode execute(const EventContext &ctx) const override
Class providing the association between TileCal problems and status word bits.
Class holding bad channel problems.
static void initClassifierDefinitions()
bool isGood() const
static TileBchStatus getDefinitionNoisy()
static void defineNoGainL1(const TileBchStatus &status)
static TileBchStatus getDefinitionWrongBCID()
static void defineBadTiming(const TileBchStatus &status)
static TileBchStatus getDefinitionNoGainL1()
bool isAffected() const
static TileBchStatus getDefinitionBadTiming()
static TileBchStatus getDefinitionBad()
static void defineNoisy(const TileBchStatus &status)
static void defineBad(const TileBchStatus &status)
static void defineWrongBCID(const TileBchStatus &status)
Class for storing a 32 bit status word for each ADC.
void getStatusWords(unsigned int channel, unsigned int adc, uint32_t &adcStatus, uint32_t &chnStatus) const
Extracts the adc and channel status words.
TileBchDecoder::BitPatVer getBitPatternVersion() const
Returns the bit pattern version.
static const unsigned int MAX_ROS
Number of ROSs.
static const unsigned int NOGAINL1_DEFINITION_CHAN
Channel used for storing of NoGainLevel1 channel definitions.
static const unsigned int BADTIMING_DEFINITION_CHAN
Channel used for storing of bad timing channel definitions.
static const unsigned int WRONGBCID_DEFINITION_CHAN
Channel used for storing of wrong BCID channel definitions.
static const unsigned int MAX_DRAWER
Number of drawers in ROS 1-4.
static const unsigned int NOISY_DEFINITION_CHAN
Channel used for storing of noisy channel definitions.
static const unsigned int TRIPS_DRAWERIDX
DrawerIdx used for storing trips probabilities.
static const unsigned int DEFINITIONS_DRAWERIDX
Drawer used for storing of bad and noisy channel definitions.
static const unsigned int BAD_DEFINITION_CHAN
Channel used for storing of bad channel definitions.
Helper class for TileCal online (hardware) identifiers.
Definition TileHWID.h:49
int frag(const HWIdentifier &id) const
extract frag field from HW identifier
Definition TileHWID.h:181
size_type adc_hash_max() const
ADC hash table max size.
Definition TileHWID.h:276
virtual int get_id(const IdentifierHash &hash_id, HWIdentifier &id, const IdContext *context=0) const
create compact HW ID from hash id (return == 0 for OK)
Definition TileHWID.cxx:491
HWIdentifier channel_id(int ros, int drawer, int channel) const
channel HWIdentifer
Definition TileHWID.cxx:199
IdContext adc_context() const
idContext for ADCs
Definition TileHWID.cxx:485
int ros(const HWIdentifier &id) const
extract ros field from HW identifier
Definition TileHWID.h:167
Definition index.py:1