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
77 const EventContext& ctx = Gaudi::Hive::currentContext();
78 unsigned eventNb = ctx.eventID().event_number();
79
80 ATH_MSG_INFO ( "======== executing event "<< eventNb << " ========" );
81 //m_outfile << "Checking Event " << eventNb << "..." << std::endl;
82
83 //log << MSG::INFO << "Retrieving LArDigitContainer. Key= " << m_key << std::endl;
84 const LArDigitContainer* larDigitCont = nullptr;
85 ATH_CHECK( evtStore()->retrieve(larDigitCont, m_key) );
86
87 //const LArCalibParams* calibParams;
88 const LArCalibParams* calibParams = nullptr;
89 ATH_CHECK( detStore()->retrieve(calibParams,"LArCalibParams") );
90
92 const LArBadChannelCont *bcCont {*readHandle};
93 if(!bcCont) {
94 ATH_MSG_ERROR( "Do not have Bad chan container " << m_BCKey.key() );
95 return StatusCode::FAILURE;
96 }
97
99 const LArOnOffIdMapping* cabling=*cablingHdl;
100 if(!cabling) {
101 ATH_MSG_ERROR( "Do not have cabling object LArOnOffIdMapping" );
102 return StatusCode::FAILURE;
103 }
104
106 const LArCalibLineMapping *clCont {*clHdl};
107 if(!clCont) {
108 ATH_MSG_ERROR( "Do not have calib line mapping !!!" );
109 return StatusCode::FAILURE;
110 }
111
112
113 // Using vectors like this works because the hashes seem to be guaranteed to be collision-free.
114 delete m_errorcellsPreviousEvent; // OK to delete 0, Stroustrup 6.2.6
116 m_errorcellsThisEvent = new std::vector<bool>(m_channelHashMax); // All elements initialized to false, Stroustrup 16.3.4
117
120
121 int cellsCounter = 0;
122
123 int inconsistencyCounter = 0;
124 int disconnectedCounter = 0;
125 int badChannelCounter = 0;
126
127 bool signalPresent;
128 bool pulsed;
129 bool badChannel;
130 bool disconnected;
131
132 // Put errors in ErrorList, to print if needed.
133 std::ostringstream ErrorList;
134
135 // Loop on all cells (digits).
136 for (const LArDigit* digit : *larDigitCont) {
137 cellsCounter++;
138
139 ErrorList.clear();
140
141 // Get FEB info.
142 const HWIdentifier online_id = digit->hardwareID();
143 const HWIdentifier febid = m_onlineHelper->feb_Id(online_id);
144
145 int chNb = m_onlineHelper->channel(online_id);
146
147 // Check if channel is connected.
148 if (!cabling->isOnlineConnected(online_id)) {
149 disconnected = true;
150 disconnectedCounter++;
151 } else
152 disconnected = false;
153
154 Identifier offline_id;
155
156 // Get offline id.
157 bool noOffline_id = false;
158 try {
159 offline_id = cabling->cnvToIdentifier(online_id);
160 }
161 catch (const LArID_Exception&) {
162 noOffline_id = true;
163 }
164
165 // Find out if signal over theshold is present.
166 // Set signalPresent.
167 const int max = *max_element(digit->samples().begin(), digit->samples().end());
168 if (max >= m_ADCThreshold)
169 signalPresent = true;
170 else
171 signalPresent = false;
172
173 // Loop on calibchannels to see which, if any, that pulsed the cell.
174 // Set pulsed and DACvalue, and fill PulserList.
175 pulsed = false;
176 int DACvalue = -1;
177 std::ostringstream PulserList;
178 const std::vector<HWIdentifier>& calibChannelIDs=clCont->calibSlotLine(online_id);
179
180 for (HWIdentifier hwid : calibChannelIDs) {
181 //m_outfile << hwid.get_compact() << " ";
182 bool isPulsed=calibParams->isPulsed(eventNb, hwid);
183 if (isPulsed) {
184 int DACvalue_temp = calibParams->DAC(eventNb, hwid);
185 if (DACvalue_temp > DACvalue)
186 DACvalue = DACvalue_temp;
187 pulsed = true;
188 const int slot = m_onlineHelper->slot(hwid);
189 const int line = m_onlineHelper->channel(hwid);
190 PulserList << std::hex << hwid.get_compact() << std::dec << " " << slot << " " << line << " ";
191 }
192 }
193 //m_outfile << std::endl;
194
195 CaloGain::CaloGain gain = digit->gain();
196 bool DACOverThreshold;
197 switch (gain) {
199 DACOverThreshold = DACvalue >= m_DACLowGainThreshold;
200 break;
202 DACOverThreshold = DACvalue >= m_DACMediumGainThreshold;
203 break;
205 DACOverThreshold = DACvalue >= m_DACHighGainThreshold;
206 break;
207 default:
208 DACOverThreshold = DACvalue >= m_DACHighGainThreshold;
209 }
210
211 // Find out if we have a bad cell.
212 if (m_useBadChannelTool && !noOffline_id) {
213 if (bcCont->offlineStatus(offline_id).good()) {
214 badChannel = false;
215 } else {
216 badChannel = true;
217 badChannelCounter++;
218 }
219 } else {
220 badChannel = false;
221 }
222
223 // Analyze and report.
224
225 bool inconsistency = (signalPresent != pulsed) && DACOverThreshold;
226 if (inconsistency)
227 inconsistencyCounter++;
228
229 bool errorInCell = inconsistency || badChannel;
230 if (errorInCell)
232
233 std::ostringstream CellData;
234 CellData << "0x" << std::hex << std::setw(8) << febid.get_compact() << std::dec
235 << std::setw(5) << m_onlineHelper->feedthrough(febid)
236 << std::setw(5) << m_onlineHelper->slot(febid)
237 << std::setw(5) << chNb;
238
239 CellData << std::setw(5);
240 if (noOffline_id)
241 CellData << "-";
242 else
243 CellData << m_emId->sampling(offline_id);
244
245 CellData << std::setw(5);
246 if (noOffline_id)
247 CellData << "-";
248 else
249 CellData << m_emId->eta(offline_id);
250
251 CellData << std::setw(5);
252 if (noOffline_id)
253 CellData << "-";
254 else
255 CellData << m_emId->phi(offline_id);
256
257 CellData << std::setw(7) << max;
258 if (DACvalue >= 0) // Above have set DACvalue=-1 if got no DAC value.
259 CellData << std::setw(7) << DACvalue;
260 else
261 CellData << std::setw(7) << "-";
262
263 if (disconnected) {
265 ErrorList << " D ";
266 ErrorList << CellData.str() << std::endl;
267 }
268 }
269 else {
270 // Set relevant bit in m_errorcellsThisEvent if error in this cell.
271 if (errorInCell)
272 (*m_errorcellsThisEvent)[m_onlineHelper->channel_Hash(online_id)] = true;
273
274 if (errorInCell || m_PrintAllCellsAndEvents) {
275 if (inconsistency)
276 ErrorList << "I";
277 else
278 ErrorList << " ";
279 if (pulsed)
280 ErrorList << "P";
281 else
282 ErrorList << " ";
283 if (signalPresent)
284 ErrorList << "S";
285 else
286 ErrorList << " ";
287 if (badChannel)
288 ErrorList << "B ";
289 else
290 ErrorList << " ";
291
292 ErrorList << CellData.str();
293
294 if (pulsed)
295 ErrorList << " " << PulserList.str();
296
297 ErrorList << std::endl;
298 }
299 }
300 } //End looping on all cells
301
302 ErrorList << std::endl;
303
305 ErrorList << "Examined " << cellsCounter << " cells in event " << eventNb << ". Found:" << std::endl;
306 ErrorList << std::left << std::setw(25) << "Inconsistencies: "
307 << std::right << std::setw(4) << inconsistencyCounter << std::endl;
308 ErrorList << std::left << std::setw(25) << "Bad cells: "
309 << std::right << std::setw(4) << badChannelCounter << std::endl;
310 ErrorList << std::left << std::setw(25) << "Sum errors: "
311 << std::right << std::setw(4) << m_errorCounterThisEvent << std::endl;
312 ErrorList << std::left << std::setw(25) << "Disconnected cells: "
313 << std::right << std::setw(4) << disconnectedCounter << std::endl;
314 ErrorList << std::endl;
315 }
316
318 // Compare m_errorcellsThisEvent to m_errorcellsPreviousEvent
319 if (*m_errorcellsThisEvent == *m_errorcellsPreviousEvent) { // Pray to God this is optimized.
320 // Same status as previous event, increase counter and go to next event.
322 }
323 else {
324 // A new status for this event. Print number of repeats for the previous one and print new state, if an error.
326 m_outfile << "Last error occurred in "
327 << m_numberOfEventsWithThisErrorState << " events." << std::endl << std::endl;
328
329 if (m_errorCounterThisEvent != 0) {
330 m_outfile << "Error in event "<< std::setw(7) << eventNb
331 << " ==========================================================================" << std::endl;
332 m_outfile << "I=Inconsistency P=Pulsed S=Signal B=Bad D=Disconnected" << std::endl;
333 m_outfile << " "
334 << std::left << std::setw(10) << "FEB"
335 << std::right << std::setw(5) << "FT"
336 << std::setw(5) << "SL"
337 << std::setw(5) << "CH"
338 << std::setw(5) << "Smpl"
339 << std::setw(5) << "Eta"
340 << std::setw(5) << "Phi"
341 << std::setw(7) << "ADC"
342 << std::setw(7) << "DAC"
343 << " Pulsed by calibchannel slot line"
344 << std::endl;
345
346 m_outfile << ErrorList.str();
347 }
348
350 }
351 }
352 else { // m_PrintAllCellsAndEvents==true
353 m_outfile << "Status of event "<< std::setw(7) << eventNb
354 << " ==========================================================================" << std::endl;
355 m_outfile << "I=Inconsistency P=Pulsed S=Signal B=Bad D=Disconnected" << std::endl;
356 m_outfile << " "
357 << std::left << std::setw(10) << "FEB"
358 << std::right << std::setw(5) << "FT"
359 << std::setw(5) << "SL"
360 << std::setw(5) << "CH"
361 << std::setw(5) << "Smpl"
362 << std::setw(5) << "Eta"
363 << std::setw(5) << "Phi"
364 << std::setw(7) << "ADC"
365 << std::setw(7) << "DAC"
366 << " Pulsed by slot line"
367 << std::endl;
368
369 m_outfile << ErrorList.str();
370 }
371
372 return StatusCode::SUCCESS;
373}
374
377 m_outfile << "Last error occurred in " << m_numberOfEventsWithThisErrorState << " events." << std::endl << std::endl;
378
379 m_outfile.close();
380
383
384 return StatusCode::SUCCESS;
385}
#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
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