ATLAS Offline Software
Loading...
Searching...
No Matches
LArFebErrorSummaryMaker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
11
12#include <bitset>
13#include <format>
14
16{
17 ATH_MSG_DEBUG(" initialize " );
18
19 ATH_CHECK(detStore()->retrieve( m_onlineHelper ) );
20
21 if (m_checkAllFeb) {
22 for (const HWIdentifier id : m_onlineHelper->feb_range()) {
23 m_all_febs.insert(id.get_identifier32().get_compact());
24 }
25 ATH_MSG_INFO(" number of FEBs from LArOnlineID "<< m_all_febs.size() );
26 }
27 else { // We should chack partition id
28 if(m_partition.size() > 0) {
29 unsigned length = m_partition.size();
30 if(m_partition.value().find("LArgHecFcal") < length && m_partition.value().find("EB-HEC") < length) m_isHec=true;
31 if(m_partition.value().find("LArgHecFcal") < length && m_partition.value().find("EB-FCAL") < length) m_isFcal=true;
32 if(m_partition.value().find("LArgBarrelPS") < length) {
33 m_isEmPS = true;
34 if(m_partition.value().find("EB-EMBA") < length) m_isAside = true;
35 if(m_partition.value().find("EB-EMBC") < length) m_isCside = true;
36 }
37 if(m_partition.value().find("LArgEm") < length && m_partition.value().find("EB-EMB") < length) {
38 m_isEmb = true;
39 if(m_partition.value().find("EB-EMBA") < length) m_isAside = true;
40 if(m_partition.value().find("EB-EMBC") < length) m_isCside = true;
41 }
42 if(m_partition.value().find("LArgEm") < length && m_partition.value().find("EB-EMEC") < length) {
43 m_isEmec = true;
44 if(m_partition.value().find("EB-EMECA") < length) m_isAside = true;
45 if(m_partition.value().find("EB-EMECC") < length) m_isCside = true;
46 }
47 }
48 if(m_isHec || m_isFcal || m_isEmb || m_isEmec || m_isEmPS) {
49 ATH_MSG_DEBUG("m_isHec: "<<m_isHec<<" m_isFcal: "<< m_isFcal <<" m_isEmb: "<< m_isEmb <<" m_isEmec: "<< m_isEmec <<" m_isEmbPS: "<< m_isEmPS );
50 } else {
51 ATH_MSG_WARNING("Wrong PartitionId property: "<<m_partition.value() );
52 ATH_MSG_WARNING("Missing FEB's will be not checked " );
53 }
54 // Now let's build the list of FEB's according partition
55 for (const HWIdentifier id : m_onlineHelper->feb_range()) {
56 if(m_isHec && m_onlineHelper->isHECchannel(id)) { m_all_febs.insert(id.get_identifier32().get_compact()); continue; }
57 if(m_isFcal && m_onlineHelper->isFCALchannel(id)) { m_all_febs.insert(id.get_identifier32().get_compact()); continue; }
58 if((m_isEmb && m_onlineHelper->isEMBchannel(id) && (!m_onlineHelper->isPS(id)))
59 || (m_isEmec && m_onlineHelper->isEMECchannel(id))
60 || (m_isEmPS && m_onlineHelper->isPS(id) && (!m_onlineHelper->isEMBchannel(id))) ) {
61 if(m_isAside && m_onlineHelper->pos_neg(id) == 1) {m_all_febs.insert(id.get_identifier32().get_compact()); continue; }
62 if(m_isCside && m_onlineHelper->pos_neg(id) == 0) {m_all_febs.insert(id.get_identifier32().get_compact()); continue; }
63 }
64 }
65 }
66 ATH_MSG_INFO("Number of expected FEB's: "<<m_all_febs.size() );
67
68 ATH_CHECK( m_readKey.initialize() );
69 ATH_CHECK( m_writeKey.initialize() );
70 ATH_CHECK( m_bfKey.initialize());
71 ATH_CHECK(m_eventInfoKey.initialize());
72 ATH_CHECK(m_eventInfoDecorKey.initialize());
73
74 //Set error counters to 0
75 for (unsigned int i=0;i<LArFebErrorSummary::N_LArFebErrorType;++i){
76 m_errors[i]=0;
77 }
78
79 ATH_MSG_INFO(" initialized " );
80
81 return StatusCode::SUCCESS ;
82
83}
84
85
86StatusCode LArFebErrorSummaryMaker::execute(const EventContext& ctx) const
87{
88 ATH_MSG_DEBUG(" execute " );
89
91
93 ATH_CHECK( febErrorSummary.record (std::make_unique<LArFebErrorSummary>()) );
94
96 const LArBadFebCont* badFebs{*h_bf};
97
98 // EventInfo
100 ATH_CHECK(eventInfo.isValid());
101
102 unsigned int nbSamplesFirst=0;
103 uint32_t eventTypeFirst = 999;
104
105 ATH_MSG_DEBUG( " LArFebHeaderContainer Size = "<< hdrCont->size() );
106
107 std::set<unsigned int> all_febs;
109
110 all_febs= m_all_febs;
111
112 }
113
114 int nbOfFebsInError = 0;
115
116 for (const auto* const it : *hdrCont) {
117
118 HWIdentifier febid = it->FEBId();
119 unsigned int int_id = febid.get_identifier32().get_compact();
120
122 all_febs.erase(int_id);
123 }
124 // ctrl3
125 // const std::vector <uint16_t> &febctrl3 = it->FebCtrl3();
126
127 // Retrieve rodstatus from DSP header
128 uint32_t rodstatus = it->RodStatus();
129 // Retrieve SCA adresses
130 const std::vector<uint16_t>& sca = it->SCA();
131 // Eventype = 2 : transparent/raw data - 4 : Physic - 7 : calibration - 10 : pedestal
132 uint32_t eventType = it->DetEventType();
133
134 // Check the type consistency among different FEBs
135 bool typeMism = false;
136 // The event type is not yet determined(1st FEB) - Take this as reference
137 if (eventTypeFirst == 999)
138 eventTypeFirst = eventType;
139 if (eventType != eventTypeFirst)
140 typeMism = true;
141
142 std::bitset<32> rodstatusbits(rodstatus);
143
144 bool scaOutOfRange = false;
145 bool badNbOfSp = false;
146 bool zeroSp = false;
147 bool checkSumErr = false;
148
149 // Extract the number of samples for the first non zero samples block
150 // This allow to allow to always plot the number of samples in the histo
151 if (nbSamplesFirst == 0) {
152 // Raw data / transparent : Nb of samples is here determined with size of raw data vector
153 if (eventType == 2 && (!sca.empty()))
154 nbSamplesFirst = sca.size();
155 // Physic : Nb of samples is here determined with method of LArFEBMonHeader
156 if (eventType == 4 && (it->NbSamples() != 0))
157 nbSamplesFirst = it->NbSamples();
158 }
159 // Test the uniformity of number of samples and that sca # is inside [0;143] only in raw data
160 if (eventType == 2) {
161 if (nbSamplesFirst != sca.size() && !sca.empty())
162 badNbOfSp = true;
163 for (unsigned int i = 0; i < sca.size(); ++i) {
164 if (sca[i] > 143)
165 scaOutOfRange = true;
166 }
167 }
168 if (eventType == 4 && (nbSamplesFirst != it->NbSamples()) && (it->NbSamples() != 0))
169 badNbOfSp = true;
170
171 // Test that the number of samples is not zero only in raw data and results mode
172 if (eventType == 2 && sca.empty())
173 zeroSp = true;
174 if (eventType == 4 && (it->RodResults1Size() == 0))
175 zeroSp = true;
176
177 if (!zeroSp) {
178 if (!it->ChecksumVerification())
179 checkSumErr = true;
180 if (eventType == 4) {
181 int expSize1 = 0;
182 if ((it->FormatVersion() & 0xF) <= 11)
183 expSize1 = it->NbSweetCells1() + 83 + (int)ceilf((it->NbSamples() + 1) / 2.0); // Old DSP version
184 if ((it->FormatVersion() & 0xF) >= 12)
185 expSize1 = it->NbSweetCells1() + 84 + (int)ceilf((it->NbSamples() + 1) / 2.0); // New DSP version after 07/11 with new extra word SumE
186 if (expSize1 != it->RodResults1Size()) {
187 checkSumErr = true;
188 }
189 int nbOf32bits = (it->NbSweetCells2() * it->NbSamples() + 1) / 2.0;
190 if (nbOf32bits != it->RodResults2Size()) {
191 checkSumErr = true;
192 }
193 }
194 }
195
196 uint16_t errw = 0;
197
198 /* enum LArFebErrorType{
199 Parity,BCID,SampleHeader,EVTID,ScacStatus,ScaOutOfRange,
200 GainMismatch,TypeMismatch,NumOfSamples,EmptyDataBlock,DspBlockSize,CheckSum, BadGain, N_LArFebErrorType
201 } ;
202 */
203
204 if (rodstatusbits[6])
205 errw = errw | (1 << LArFebErrorSummary::Parity);
206
207 if (rodstatusbits[2] || rodstatusbits[7])
208 errw = errw | (1 << LArFebErrorSummary::BCID);
209
210 if (rodstatusbits[3] || rodstatusbits[8])
211 errw = errw | (1 << LArFebErrorSummary::SampleHeader);
212
213 if ((rodstatusbits[1] || rodstatusbits[9]) && !masked(int_id, m_knownEvtId))
214 errw = errw | (1 << LArFebErrorSummary::EVTID);
215
216 if ((rodstatusbits[4] || rodstatusbits[11] || rodstatusbits[12]) && !masked(int_id, m_knownSCACStatus))
217 errw = errw | (1 << LArFebErrorSummary::ScacStatus);
218
219 if (scaOutOfRange)
220 errw = errw | (1 << LArFebErrorSummary::ScaOutOfRange);
221
222 if (rodstatusbits[5])
223 errw = errw | (1 << LArFebErrorSummary::GainMismatch);
224
225 if (rodstatusbits[24])
226 errw = errw | (1 << LArFebErrorSummary::BadGain);
227
228 if (typeMism)
229 errw = errw | (1 << LArFebErrorSummary::TypeMismatch);
230
231 if (badNbOfSp)
232 errw = errw | (1 << LArFebErrorSummary::NumOfSamples);
233
234 if (zeroSp && !masked(int_id, m_knownZeroSample))
235 errw = errw | (1 << LArFebErrorSummary::EmptyDataBlock);
236
237 if (checkSumErr)
238 // if (zeroSp)
239 errw = errw | (1 << LArFebErrorSummary::CheckSum);
240
241 if (errw != 0) {
242 // check which errors should be ignored for this feb
243 const LArBadFeb febStatus = badFebs->status(febid);
244 unsigned int err_toignore = febStatus.ignoreErrors();
245 if (err_toignore > 0) {
246 uint16_t erri = (uint16_t)(err_toignore);
247 errw = errw & (~erri);
248 }
249 }
250
251 if (errw !=0) {
252 std::lock_guard lock(m_mtx);
253 for (unsigned int i = 0; i < LArFebErrorSummary::N_LArFebErrorType; ++i) {
254 if (errw & (1 << i)) {
255 m_errors[i] += 1;
256 }
257 ++(m_errsPerFeb[int_id]);
258 }
259 }
260 ATH_MSG_DEBUG(std::format(" Error for this FEB id {:#x} is {:#x}",int_id,errw));
261
262 if (!febErrorSummary->set_feb_error(int_id, errw)) {
263
264 ATH_MSG_DEBUG(" failed to insert the error into LArFebErrorSummary " << std::hex << febid << std::dec);
265 }
266
267 if (errw != 0) { // should this FEB be counted as in error ?
268 const LArBadFeb febStatus = badFebs->status(febid);
269 if (!febStatus.inError() && !(febStatus.deadReadout() || febStatus.deadAll()))
270 nbOfFebsInError += 1;
271 }
272
273 } // loop over headers
274
276 const uint16_t errw = 1 << LArFebErrorSummary::MissingHeader;
277 bool warn = false;
278 for (auto it : all_febs) {
279 const HWIdentifier febid = HWIdentifier(Identifier32(it));
280 const LArBadFeb febStatus = badFebs->status(febid);
281 if (febStatus.deadReadout() || febStatus.deadAll() || febStatus.deactivatedInOKS()) {
282 ATH_MSG_DEBUG(" This FEB is not read out 0x" << std::hex << it << std::dec);
283 } else {
284 // Print warning only for first couple of events and if we have at least one FEB read out
285 //(dont' flood log with useless message is LAr is not in the run)
286 // if (this->outputLevel()<=MSG::WARNING && m_missingFebsWarns < m_warnLimit && hdrCont->size()>0) {
287 if (msgLvl(MSG::WARNING) && m_missingFebsWarns.load() < m_warnLimit && !hdrCont->empty()) {
288 warn = true;
289 const std::string bec = m_onlineHelper->barrel_ec(febid) == 0 ? "BARREL/" : "ENDCAP/";
290 const std::string side = m_onlineHelper->pos_neg(febid) == 0 ? "C/" : "A/";
291 ATH_MSG_WARNING("FEB [" << bec << side << m_onlineHelper->feedthrough(febid) << "/" << m_onlineHelper->slot(febid) << "] not read out!");
292 }
293
294 febErrorSummary->set_feb_error(it, errw);
296 } // end else missing FEB to report
297
298 } // end loop over febs
299 if (warn) {
301 ATH_MSG_WARNING("No more warnings about FEBs not read out!");
302 }
303 } // end if checkCompletness
304
305 if (nbOfFebsInError >= m_minFebsInError) {
306 ATH_MSG_DEBUG(" set error bit for LAr for this event ");
307 if (!eventInfo->updateErrorState(xAOD::EventInfo::LAr, xAOD::EventInfo::Error)) {
308 ATH_MSG_WARNING(" cannot set error state for LAr ");
309 }
310 if (!eventInfo->updateEventFlagBit(xAOD::EventInfo::LAr, LArEventBitInfo::DATACORRUPTED)) {
311 ATH_MSG_WARNING(" cannot set event bit info for LAr ");
312 }
313 }
314
315 return StatusCode::SUCCESS;
316}
317
318bool LArFebErrorSummaryMaker::masked (unsigned int hid, const std::set<unsigned int>& v_feb) {
319
320 //return v_feb.contains(hid); //C++20 only ..
321 return v_feb.find(hid) != v_feb.end();
322}
323
325{
326
327 ATH_MSG_INFO(" In finalize: Number of Errors for each type" );
328
329 for (unsigned int i=0;i<LArFebErrorSummary::N_LArFebErrorType;++i){
330 uint16_t err = 1<<i;
331 ATH_MSG_INFO( " type, name, count = " << i << " " << LArFebErrorSummary::error_to_string(err) << " " << m_errors[i] );
332 }
333
334 for (auto feb_err : m_errsPerFeb) {
335 ATH_MSG_INFO(std::format("Feb {:#x} {} had errors for {} event(s)",feb_err.first,m_onlineHelper->channel_name(HWIdentifier(feb_err.first)),feb_err.second));
336
337 }
338
339 return StatusCode::SUCCESS;
340
341}
342
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
double length(const pvec &v)
LArBadXCont< LArBadFeb > LArBadFebCont
Handle class for adding a decoration to an object.
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
value_type get_compact() const
Get the compact id.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
unsigned int ignoreErrors() const
Definition LArBadFeb.h:65
bool deadAll() const
FEB is completely missing, e.g. powered off.
Definition LArBadFeb.h:30
bool deactivatedInOKS() const
Deactivated in OKS.
Definition LArBadFeb.h:39
bool inError() const
FEB has readout errors, cannot be used.
Definition LArBadFeb.h:36
bool deadReadout() const
FEB is not sending readout data, but the L1 trigger path is working.
Definition LArBadFeb.h:33
LArBC_t status(const HWIdentifier channel) const
Query the status of a particular channel or FEB This is the main client access method.
std::set< unsigned int > m_all_febs
static bool masked(unsigned int hid, const std::set< unsigned int > &v_feb)
virtual StatusCode initialize() override final
Gaudi::Property< int > m_warnLimit
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
SG::ReadCondHandleKey< LArBadFebCont > m_bfKey
const LArOnlineID * m_onlineHelper
Gaudi::Property< std::set< unsigned int > > m_knownZeroSample
std::atomic< int > m_missingFebsWarns
SG::WriteDecorHandleKey< xAOD::EventInfo > m_eventInfoDecorKey
Gaudi::Property< int > m_minFebsInError
Minimum number of FEBs in error to trigger EventInfo::LArError Defined as 1 by default/bulk,...
Gaudi::Property< std::set< unsigned int > > m_knownSCACStatus
SG::ReadHandleKey< LArFebHeaderContainer > m_readKey
Gaudi::Property< std::set< unsigned int > > m_knownEvtId
Gaudi::Property< bool > m_checkAllFeb
SG::WriteHandleKey< LArFebErrorSummary > m_writeKey
virtual StatusCode finalize() override final
virtual StatusCode execute(const EventContext &ctx) const override final
Gaudi::Property< std::string > m_partition
static std::string error_to_string(uint16_t error)
interpret the error in string
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
@ LAr
The LAr calorimeter.
@ Error
The sub-detector issued an error.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())