ATLAS Offline Software
Loading...
Searching...
No Matches
LArCablingChecker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
10#include <algorithm>
11#include <sstream>
12#include <iomanip>
13
14LArCablingChecker::LArCablingChecker(const std::string& name, ISvcLocator* pSvcLocator)
15 : AthAlgorithm(name, pSvcLocator),
16 //m_chan(0),
18 m_emId(0),
25{
26 m_count = 0;
27 declareProperty("DigitKey", m_key = "");
28 declareProperty("FileName", m_outFileName = "CablingSummary.txt");
29 //declareProperty("Pattern", m_vPattern);
30 declareProperty("ADCThreshold", m_ADCThreshold = 1250);
31 declareProperty("DACHighGainThreshold", m_DACHighGainThreshold = 100);
32 declareProperty("DACMediumGainThreshold", m_DACMediumGainThreshold = 1000);
33 declareProperty("DACLowGainThreshold", m_DACLowGainThreshold = 10000);
34 declareProperty("PrintAllCellsAndEvents", m_PrintAllCellsAndEvents = false);
35 declareProperty("PrintDisconnectedCells", m_PrintDisconnectedCells = true);
36 declareProperty("PrintEventSummary", m_printEventSummary = false);
37 declareProperty("UseBadChannelTool", m_useBadChannelTool = true);
38}
39
43
45 ATH_CHECK( detStore()->retrieve(m_onlineHelper, "LArOnlineID") );
46 ATH_CHECK( m_cablingKey.initialize() );
47 ATH_CHECK( m_CLKey.initialize() );
48
50 ATH_CHECK( m_BCKey.initialize() );
51 }
52
53 m_outfile.open(m_outFileName.c_str(), std::ios::out);
54 if (!m_outfile.is_open()) {
55 ATH_MSG_ERROR ( "Unable to open output file with name " << m_outFileName );
56 return StatusCode::FAILURE;
57 }
58
59 const CaloCell_ID* idHelper = nullptr;
60 ATH_CHECK( detStore()->retrieve (idHelper, "CaloCell_ID") );
61 m_emId=idHelper->em_idHelper();
62
63 m_channelHashMax = m_onlineHelper->channelHashMax();
64
67 // Phony "previous" event so that the first event has something to compare to.
68 m_errorcellsThisEvent = new std::vector<bool>(m_channelHashMax);
71
72 ATH_MSG_DEBUG ( "======== LArCablingChecker initialize successfully ========" );
73 return StatusCode::SUCCESS;
74}
75
76StatusCode LArCablingChecker::execute(const EventContext& ctx) {
77 unsigned eventNb = ctx.eventID().event_number();
78
79 ATH_MSG_INFO ( "======== executing event "<< eventNb << " ========" );
80 //m_outfile << "Checking Event " << eventNb << "..." << std::endl;
81
82 //log << MSG::INFO << "Retrieving LArDigitContainer. Key= " << m_key << std::endl;
83 const LArDigitContainer* larDigitCont = nullptr;
84 ATH_CHECK( evtStore()->retrieve(larDigitCont, m_key) );
85
86 //const LArCalibParams* calibParams;
87 const LArCalibParams* calibParams = nullptr;
88 ATH_CHECK( detStore()->retrieve(calibParams,"LArCalibParams") );
89
91 const LArBadChannelCont *bcCont {*readHandle};
92 if(!bcCont) {
93 ATH_MSG_ERROR( "Do not have Bad chan container " << m_BCKey.key() );
94 return StatusCode::FAILURE;
95 }
96
98 const LArOnOffIdMapping* cabling=*cablingHdl;
99 if(!cabling) {
100 ATH_MSG_ERROR( "Do not have cabling object LArOnOffIdMapping" );
101 return StatusCode::FAILURE;
102 }
103
105 const LArCalibLineMapping *clCont {*clHdl};
106 if(!clCont) {
107 ATH_MSG_ERROR( "Do not have calib line mapping !!!" );
108 return StatusCode::FAILURE;
109 }
110
111
112 // Using vectors like this works because the hashes seem to be guaranteed to be collision-free.
113 delete m_errorcellsPreviousEvent; // OK to delete 0, Stroustrup 6.2.6
115 m_errorcellsThisEvent = new std::vector<bool>(m_channelHashMax); // All elements initialized to false, Stroustrup 16.3.4
116
119
120 int cellsCounter = 0;
121
122 int inconsistencyCounter = 0;
123 int disconnectedCounter = 0;
124 int badChannelCounter = 0;
125
126 bool signalPresent;
127 bool pulsed;
128 bool badChannel;
129 bool disconnected;
130
131 // Put errors in ErrorList, to print if needed.
132 std::ostringstream ErrorList;
133
134 // Loop on all cells (digits).
135 for (const LArDigit* digit : *larDigitCont) {
136 cellsCounter++;
137
138 ErrorList.clear();
139
140 // Get FEB info.
141 const HWIdentifier online_id = digit->hardwareID();
142 const HWIdentifier febid = m_onlineHelper->feb_Id(online_id);
143
144 int chNb = m_onlineHelper->channel(online_id);
145
146 // Check if channel is connected.
147 if (!cabling->isOnlineConnected(online_id)) {
148 disconnected = true;
149 disconnectedCounter++;
150 } else
151 disconnected = false;
152
153 Identifier offline_id;
154
155 // Get offline id.
156 bool noOffline_id = false;
157 try {
158 offline_id = cabling->cnvToIdentifier(online_id);
159 }
160 catch (const LArID_Exception&) {
161 noOffline_id = true;
162 }
163
164 // Find out if signal over theshold is present.
165 // Set signalPresent.
166 const int max = *max_element(digit->samples().begin(), digit->samples().end());
167 if (max >= m_ADCThreshold)
168 signalPresent = true;
169 else
170 signalPresent = false;
171
172 // Loop on calibchannels to see which, if any, that pulsed the cell.
173 // Set pulsed and DACvalue, and fill PulserList.
174 pulsed = false;
175 int DACvalue = -1;
176 std::ostringstream PulserList;
177 const std::vector<HWIdentifier>& calibChannelIDs=clCont->calibSlotLine(online_id);
178
179 for (HWIdentifier hwid : calibChannelIDs) {
180 //m_outfile << hwid.get_compact() << " ";
181 bool isPulsed=calibParams->isPulsed(eventNb, hwid);
182 if (isPulsed) {
183 int DACvalue_temp = calibParams->DAC(eventNb, hwid);
184 if (DACvalue_temp > DACvalue)
185 DACvalue = DACvalue_temp;
186 pulsed = true;
187 const int slot = m_onlineHelper->slot(hwid);
188 const int line = m_onlineHelper->channel(hwid);
189 PulserList << std::hex << hwid.get_compact() << std::dec << " " << slot << " " << line << " ";
190 }
191 }
192 //m_outfile << std::endl;
193
194 CaloGain::CaloGain gain = digit->gain();
195 bool DACOverThreshold;
196 switch (gain) {
198 DACOverThreshold = DACvalue >= m_DACLowGainThreshold;
199 break;
201 DACOverThreshold = DACvalue >= m_DACMediumGainThreshold;
202 break;
204 DACOverThreshold = DACvalue >= m_DACHighGainThreshold;
205 break;
206 default:
207 DACOverThreshold = DACvalue >= m_DACHighGainThreshold;
208 }
209
210 // Find out if we have a bad cell.
211 if (m_useBadChannelTool && !noOffline_id) {
212 if (bcCont->offlineStatus(offline_id).good()) {
213 badChannel = false;
214 } else {
215 badChannel = true;
216 badChannelCounter++;
217 }
218 } else {
219 badChannel = false;
220 }
221
222 // Analyze and report.
223
224 bool inconsistency = (signalPresent != pulsed) && DACOverThreshold;
225 if (inconsistency)
226 inconsistencyCounter++;
227
228 bool errorInCell = inconsistency || badChannel;
229 if (errorInCell)
231
232 std::ostringstream CellData;
233 CellData << "0x" << std::hex << std::setw(8) << febid.get_compact() << std::dec
234 << std::setw(5) << m_onlineHelper->feedthrough(febid)
235 << std::setw(5) << m_onlineHelper->slot(febid)
236 << std::setw(5) << chNb;
237
238 CellData << std::setw(5);
239 if (noOffline_id)
240 CellData << "-";
241 else
242 CellData << m_emId->sampling(offline_id);
243
244 CellData << std::setw(5);
245 if (noOffline_id)
246 CellData << "-";
247 else
248 CellData << m_emId->eta(offline_id);
249
250 CellData << std::setw(5);
251 if (noOffline_id)
252 CellData << "-";
253 else
254 CellData << m_emId->phi(offline_id);
255
256 CellData << std::setw(7) << max;
257 if (DACvalue >= 0) // Above have set DACvalue=-1 if got no DAC value.
258 CellData << std::setw(7) << DACvalue;
259 else
260 CellData << std::setw(7) << "-";
261
262 if (disconnected) {
264 ErrorList << " D ";
265 ErrorList << CellData.str() << std::endl;
266 }
267 }
268 else {
269 // Set relevant bit in m_errorcellsThisEvent if error in this cell.
270 if (errorInCell)
271 (*m_errorcellsThisEvent)[m_onlineHelper->channel_Hash(online_id)] = true;
272
273 if (errorInCell || m_PrintAllCellsAndEvents) {
274 if (inconsistency)
275 ErrorList << "I";
276 else
277 ErrorList << " ";
278 if (pulsed)
279 ErrorList << "P";
280 else
281 ErrorList << " ";
282 if (signalPresent)
283 ErrorList << "S";
284 else
285 ErrorList << " ";
286 if (badChannel)
287 ErrorList << "B ";
288 else
289 ErrorList << " ";
290
291 ErrorList << CellData.str();
292
293 if (pulsed)
294 ErrorList << " " << PulserList.str();
295
296 ErrorList << std::endl;
297 }
298 }
299 } //End looping on all cells
300
301 ErrorList << std::endl;
302
304 ErrorList << "Examined " << cellsCounter << " cells in event " << eventNb << ". Found:" << std::endl;
305 ErrorList << std::left << std::setw(25) << "Inconsistencies: "
306 << std::right << std::setw(4) << inconsistencyCounter << std::endl;
307 ErrorList << std::left << std::setw(25) << "Bad cells: "
308 << std::right << std::setw(4) << badChannelCounter << std::endl;
309 ErrorList << std::left << std::setw(25) << "Sum errors: "
310 << std::right << std::setw(4) << m_errorCounterThisEvent << std::endl;
311 ErrorList << std::left << std::setw(25) << "Disconnected cells: "
312 << std::right << std::setw(4) << disconnectedCounter << std::endl;
313 ErrorList << std::endl;
314 }
315
317 // Compare m_errorcellsThisEvent to m_errorcellsPreviousEvent
318 if (*m_errorcellsThisEvent == *m_errorcellsPreviousEvent) { // Pray to God this is optimized.
319 // Same status as previous event, increase counter and go to next event.
321 }
322 else {
323 // A new status for this event. Print number of repeats for the previous one and print new state, if an error.
325 m_outfile << "Last error occurred in "
326 << m_numberOfEventsWithThisErrorState << " events." << std::endl << std::endl;
327
328 if (m_errorCounterThisEvent != 0) {
329 m_outfile << "Error in event "<< std::setw(7) << eventNb
330 << " ==========================================================================" << std::endl;
331 m_outfile << "I=Inconsistency P=Pulsed S=Signal B=Bad D=Disconnected" << std::endl;
332 m_outfile << " "
333 << std::left << std::setw(10) << "FEB"
334 << std::right << std::setw(5) << "FT"
335 << std::setw(5) << "SL"
336 << std::setw(5) << "CH"
337 << std::setw(5) << "Smpl"
338 << std::setw(5) << "Eta"
339 << std::setw(5) << "Phi"
340 << std::setw(7) << "ADC"
341 << std::setw(7) << "DAC"
342 << " Pulsed by calibchannel slot line"
343 << std::endl;
344
345 m_outfile << ErrorList.str();
346 }
347
349 }
350 }
351 else { // m_PrintAllCellsAndEvents==true
352 m_outfile << "Status of event "<< std::setw(7) << eventNb
353 << " ==========================================================================" << std::endl;
354 m_outfile << "I=Inconsistency P=Pulsed S=Signal B=Bad D=Disconnected" << std::endl;
355 m_outfile << " "
356 << std::left << std::setw(10) << "FEB"
357 << std::right << std::setw(5) << "FT"
358 << std::setw(5) << "SL"
359 << std::setw(5) << "CH"
360 << std::setw(5) << "Smpl"
361 << std::setw(5) << "Eta"
362 << std::setw(5) << "Phi"
363 << std::setw(7) << "ADC"
364 << std::setw(7) << "DAC"
365 << " Pulsed by slot line"
366 << std::endl;
367
368 m_outfile << ErrorList.str();
369 }
370
371 return StatusCode::SUCCESS;
372}
373
376 m_outfile << "Last error occurred in " << m_numberOfEventsWithThisErrorState << " events." << std::endl << std::endl;
377
378 m_outfile.close();
379
382
383 return StatusCode::SUCCESS;
384}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
LArBadXCont< LArBadChannel > LArBadChannelCont
#define max(a, b)
Definition cfImp.cxx:41
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
Helper class for offline cell identifiers.
Definition CaloCell_ID.h:34
const LArEM_ID * em_idHelper() const
access to EM idHelper
Definition CaloCell_ID.h:63
value_type get_compact() const
Get the compact id.
bool good() const
Returns true if no problems at all (all bits at zero).
LArBC_t offlineStatus(const Identifier id) const
Query the status of a particular channel by offline ID This is the main client access method.
std::string m_outFileName
const LArOnlineID * m_onlineHelper
LArCablingChecker(const std::string &name, ISvcLocator *pSvcLocator)
const LArEM_ID * m_emId
SG::ReadCondHandleKey< LArCalibLineMapping > m_CLKey
std::ofstream m_outfile
SG::ReadCondHandleKey< LArBadChannelCont > m_BCKey
std::vector< bool > * m_errorcellsThisEvent
std::vector< bool > * m_errorcellsPreviousEvent
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
StatusCode execute(const EventContext &ctx)
Execute method.
LArOnlineID::size_type m_channelHashMax
const std::vector< HWIdentifier > & calibSlotLine(const HWIdentifier id) const
bool isPulsed(const unsigned event, const HWIdentifier calibLineID) const
unsigned DAC(const unsigned event, const HWIdentifier calibLineID) const
Container class for LArDigit.
Liquid Argon digit base class.
Definition LArDigit.h:25
Exception class for LAr Identifiers.
@ LARMEDIUMGAIN
Definition CaloGain.h:18
@ LARLOWGAIN
Definition CaloGain.h:18
@ LARHIGHGAIN
Definition CaloGain.h:18