ATLAS Offline Software
Loading...
Searching...
No Matches
LArBadChannelHunter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
14
15//#include <sstream>
16#include <fstream>
17#include <cmath>
18
19LArBadChannelHunter::LArBadChannelHunter(const std::string& name, ISvcLocator* pSvcLocator) :
20 AthAlgorithm(name,pSvcLocator),
21 m_onlineId(0),
22 m_caloId(0),
23 m_avgType(FEB) {
24
25 declareProperty("PedestalKey", m_pedKey="", "Key of the pedestal container");
26 declareProperty("CaliWaveKey", m_caliWaveKey="", "Key of the CaliWave container");
27
28 declareProperty("OutFileName", m_outFileName="", "File for text output");
29 declareProperty("OutOnlyNew", m_outOnlyNew=false, "remove all known bad channels in output list");
30 declareProperty("AverageType", m_avgTypeProp="FEB", "Reference options: average over 'FEB' or 'PHI'");
31 declareProperty("UndoCorrections", m_undoCorr=false, "go back to unpatched values for cali-waves");
32
33 declareProperty("CutType", m_cutType="SIG", "Cut criteria: bad if deviation > X 'SIG' (sigma) or 'PER' (percent)");
34 declareProperty("RecalcPer", m_recalcPer=0.03, "Condition cuts to do recalculation, <=0 means NO recalculation");
35
36
38 declareProperty("LowNoiseThresholdHG",m_lowNoiseTh[CaloGain::LARHIGHGAIN]=6.0,
39 "Channels with pedestal rms x sigma or percent above average are tagged 'low noise' (in high gain) ");
40 declareProperty("LowNoiseThresholdMG",m_lowNoiseTh[CaloGain::LARMEDIUMGAIN]=6.0,
41 "Channels with pedestal rms x sigma or percent above average are tagged 'low noise' (in medium gain) ");
42 declareProperty("LowNoiseThresholdLG",m_lowNoiseTh[CaloGain::LARLOWGAIN]=6.0,
43 "Channels with pedestal rms x sigma or percent above average are tagged 'low noise' (in low gain) ");
44
45 declareProperty("HighNoiseThresholdHG",m_highNoiseTh[CaloGain::LARHIGHGAIN]=50.0,
46 "Channels with pedestal rms x sigma or percent above average are tagged 'High noise' (in high gain) ");
47 declareProperty("HighNoiseThresholdMG",m_highNoiseTh[CaloGain::LARMEDIUMGAIN]=50.0,
48 "Channels with pedestal rms x sigma or percent above average are tagged 'High noise' (in medium gain) ");
49 declareProperty("HighNoiseThresholdLG",m_highNoiseTh[CaloGain::LARLOWGAIN]=50.0,
50 "Channels with pedestal rms x sigma or percent above average are tagged 'High noise' (in low gain) ");
51
53 declareProperty("DeadThresholdAmpHG",m_amplTh[CaloGain::LARHIGHGAIN]=60.0,
54 "Channels with amplitudes x sigma or percent above the average are tagged as 'deadReadout' or 'deadCalib' (H gain)");
55 declareProperty("DeadThresholdAmpMG",m_amplTh[CaloGain::LARMEDIUMGAIN]=60.0,
56 "Channels with amplitudes x sigma or percent above the average are tagged as 'deadReadout' or 'deadCalib' (M gain)");
57 declareProperty("DeadThresholdAmpLG",m_amplTh[CaloGain::LARLOWGAIN]=60.0,
58 "Channels with amplitudes x sigma or percent above the average are tagged as 'deadReadout' or 'deadCalib' (L gain)");
59
60 declareProperty("DistortThresholdAmpHG",m_distampTh[CaloGain::LARHIGHGAIN]=5.0,
61 "Channels with a width x sigma or percent above the average are tagged as 'distorted' (H gain)");
62 declareProperty("DistortThresholdAmpMG",m_distampTh[CaloGain::LARMEDIUMGAIN]=5.0,
63 "Channels with a width x sigma or percent above the average are tagged as 'distorted' (M gain)");
64 declareProperty("DistortThresholdAmpLG",m_distampTh[CaloGain::LARLOWGAIN]=5.0,
65 "Channels with a width x sigma or percent above the average are tagged as 'distorted' (L gain)");
66
68 declareProperty("DeadThresholdWidHG",m_widTh[CaloGain::LARHIGHGAIN]=100.0,
69 "Channels with a width x sigma or percent above the average are tagged as 'deadReadout' or 'deadCalib' (H gain)");
70 declareProperty("DeadThresholdWidMG",m_widTh[CaloGain::LARMEDIUMGAIN]=100.0,
71 "Channels with a width x sigma or percent above the average are tagged as 'deadReadout' or 'deadCalib' (M gain)");
72 declareProperty("DeadThresholdWidLG",m_widTh[CaloGain::LARLOWGAIN]=100.0,
73 "Channels with a width x sigma or percent above the average are tagged as 'deadReadout' or 'deadCalib' (L gain)");
74
75 declareProperty("DistortThresholdWidHG",m_distwidTh[CaloGain::LARHIGHGAIN]=4.0,
76 "Channels with a width x sigma or percent above the average are tagged as 'distorted' (H gain)");
77 declareProperty("DistortThresholdWidMG",m_distwidTh[CaloGain::LARMEDIUMGAIN]=4.0,
78 "Channels with a width x sigma or percent above the average are tagged as 'distorted' (M gain)");
79 declareProperty("DistortThresholdWidLG",m_distwidTh[CaloGain::LARLOWGAIN]=4.0,
80 "Channels with a width x sigma or percent above the average are tagged as 'distorted' (L gain)");
81
83 declareProperty("DistortThresholdTmaxHG",m_tmaxampTh[CaloGain::LARHIGHGAIN]=5.0,
84 "Distorted with a TamxAmpl x sigma or percent above the average are tagged as 'distorted' (H gain)");
85 declareProperty("DistortThresholdTmaxMG",m_tmaxampTh[CaloGain::LARMEDIUMGAIN]=5.0,
86 "Distorted with a TamxAmpl x sigma or percent above the average are tagged as 'distorted' (M gain)");
87 declareProperty("DistortThresholdTmaxLG",m_tmaxampTh[CaloGain::LARLOWGAIN]=5.0,
88 "Distorted with a TamxAmpl x sigma or percent above the average are tagged as 'distorted' (L gain)");
89}
90
93 if (m_avgTypeProp=="FEB")
95 else if (m_avgTypeProp=="PHI")
97 else {
98 ATH_MSG_ERROR ( "Unknown AverageType " << m_avgTypeProp << ". Allowed values are 'FEB' or 'PHI'" ) ;
99 return StatusCode::FAILURE;
100 }
101
102 for (int i=0; i < CaloGain::LARNGAIN; i++) {
103 if (m_lowNoiseTh[i]>=m_highNoiseTh[i]) {
104 ATH_MSG_ERROR ( "Low noise threshold (" << m_lowNoiseTh << ") is supposed to lower than the high noise threshold ("
105 << m_highNoiseTh << ")" ) ;
106 return StatusCode::FAILURE;
107 }
108 }
109 ATH_CHECK( m_cablingKey.initialize() );
110 ATH_CHECK( m_BCKey.initialize() );
111 ATH_CHECK( m_CLKey.initialize() );
112
113 return StatusCode::SUCCESS;
114}
115
117StatusCode LArBadChannelHunter::stop ATLAS_NOT_THREAD_SAFE () {
118 ATH_CHECK( detStore()->retrieve(m_onlineId, "LArOnlineID") );
119 ATH_CHECK( detStore()->retrieve(m_caloId, "CaloCell_ID") );
120
121 const ILArPedestal* pedestal = nullptr;
122 ATH_CHECK( detStore()->retrieve(pedestal,m_pedKey) );
123
124 const LArCaliWaveContainer* caliwave = nullptr;
125 ATH_CHECK( detStore()->retrieve(caliwave,m_caliWaveKey) );
126
127 if (m_undoCorr) {
128 LArCaliWaveContainer* caliwavecomplete= const_cast<LArCaliWaveContainer*>(caliwave);
129 ATH_MSG_INFO ( "Undo caliwave corrections now." ) ;
130 ATH_CHECK( caliwavecomplete->undoCorrections() );
131 }
132
133 SG::ReadCondHandle<LArBadChannelCont> readHandle{m_BCKey};
134 const LArBadChannelCont *bcCont {*readHandle};
135 if(!bcCont) {
136 ATH_MSG_ERROR( "Do not have Bad chan container " << m_BCKey.key() );
137 return StatusCode::FAILURE;
138 }
140 const LArCalibLineMapping *clCont {*clHdl};
141 if(!clCont) {
142 ATH_MSG_ERROR( "Do not have calib line mapping !!!" );
143 return StatusCode::FAILURE;
144 }
145 SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{m_cablingKey};
146 const LArOnOffIdMapping* cabling=*cablingHdl;
147 if(!cabling) {
148 ATH_MSG_ERROR( "Do not have cabling object LArOnOffIdMapping" );
149 return StatusCode::FAILURE;
150 }
151
153 LArWaveHelper waveHelper;
154
155 //HWIdentifier lastfeb=HWIdentifier(0);
156 //Map of Averages per region (defined by getSymId)
157 std::map<unsigned,Average> averageMap;
158 //List of all individual values
159 std::vector<CellData> cellData;
160
161 std::vector<HWIdentifier>::const_iterator itOnId = m_onlineId->channel_begin();
162 std::vector<HWIdentifier>::const_iterator itOnIdEnd = m_onlineId->channel_end();
163
164 for(; itOnId!=itOnIdEnd;++itOnId){
165 const HWIdentifier chid = *itOnId;
166 if (!cabling->isOnlineConnected(chid)) continue;
167 //const HWIdentifier febid= m_onlineId->feb_Id(chid);
168 float ped=pedestal->pedestalRMS(chid,0);
169 const LArCaliWaveVec& cwv=caliwave->get(chid,0);
170 if (cwv.size()==0 || ped <=(1.0+LArElecCalib::ERRORCODE)) continue; //Want at least high-gain ped and wave
171 const float ampl=waveHelper.getMaxAmp(cwv[0]);
172 const float wid =waveHelper.getWidth(cwv[0])*cwv[0].getDt();
173 const float tmax=waveHelper.getMax(cwv[0])*cwv[0].getDt();
174
175 CellData thisCellData;
176 thisCellData.m_chid=chid;
177 thisCellData.m_ampl=ampl;
178 thisCellData.m_wid =wid;
179 thisCellData.m_tmax=tmax;
180
181 const unsigned regId=getSymId(chid, cabling);
182 Average& avreg=averageMap[regId];
183
184 for(unsigned igain=CaloGain::LARHIGHGAIN; igain<CaloGain::LARNGAIN; igain++) {
185 //get Pedestal RMS
186 float ped=pedestal->pedestalRMS(chid,igain);
187 if (ped >= (1.0+LArElecCalib::ERRORCODE)) {
188 avreg.m_avPedRMS[igain]+=ped;
189 avreg.m_avPedRMSSD[igain]+=(ped*ped);
190 avreg.m_nPed[igain]++;
191 avreg.m_vmedPedRMS[igain].push_back(ped);
192 thisCellData.m_pedRMS[igain]=ped;
193 }
194 }//end loop over gains
195
196 avreg.m_avAmpl[0]+=ampl;
197 avreg.m_avAmplSD[0]+=ampl*ampl;
198 avreg.m_nAmpls[0]++;
199 avreg.m_vmedAmpl[0].push_back(ampl);
200
201 avreg.m_avWid[0]+=wid;
202 avreg.m_avWidSD[0]+=wid*wid;
203 avreg.m_nWids[0]++;
204 avreg.m_vmedWid[0].push_back(wid);
205
206 avreg.m_avTmax[0]+=tmax;
207 avreg.m_avTmaxSD[0]+=tmax*tmax;
208 avreg.m_nTmaxs[0]++;
209 avreg.m_vmedTmax[0].push_back(tmax);
210
211 cellData.push_back(thisCellData);
212 }//End loop over cells
213
215 for(auto &[i, average]:averageMap) {
216 average.finish(m_recalcPer);
217 }
218
219
221 //Keep track to bad cells ...
223 typedef std::vector<std::pair<HWIdentifier,LArBadChannel> > BCV_t;
224
225 BCV_t badChanVec;
226 LArBadChanBitPacking packing;
227 PROB_t lownoiseProb[CaloGain::LARNGAIN], highnoiseProb[CaloGain::LARNGAIN];
231
235
236 typedef std::pair<unsigned,std::vector<size_t> > goodAndBad_t;
237 typedef std::map<HWIdentifier,goodAndBad_t> goodAndBadMap_t; //the key is the calibLineID
238
239 goodAndBadMap_t calibLineMap;
240
241 //Second loop: Find bad channels:
242 std::vector<CellData>::const_iterator itcells=cellData.begin();
243 std::vector<CellData>::const_iterator itcells_e=cellData.end();
244
245 for (;itcells!=itcells_e;++itcells) {
246 const CellData& thisCellData=*itcells;
247 const HWIdentifier chid = thisCellData.m_chid;
248
249 unsigned regId=getSymId(chid, cabling);
250 ATH_MSG_VERBOSE ( "Checking " << channelDescription(chid, cabling) ) ;
251 std::map<unsigned,Average>::const_iterator febit=averageMap.find(regId);
252 if (febit==averageMap.end()) continue;
253 const Average& avreg=febit->second;
254
255 LArBadChannel problem(0);
256 LArBadChannel bc = bcCont->status(chid);
257
258 for(unsigned igain=CaloGain::LARHIGHGAIN; igain<CaloGain::LARNGAIN; igain++) {
259 if (avreg.m_nPed[igain]>2) {//Check if have average ped-rms for this cell & gain
260 const float rms=thisCellData.m_pedRMS[igain];
261 float lowCut_rms=0.;
262 float higCut_rms=0.;
263 if ( m_cutType=="SIG" ) {
264 lowCut_rms=m_lowNoiseTh[igain]*avreg.m_avPedRMSSD[igain];
265 higCut_rms=m_highNoiseTh[igain]*avreg.m_avPedRMSSD[igain];
266 }
267 else if ( m_cutType=="PER") {
268 lowCut_rms=m_lowNoiseTh[igain]*avreg.m_avPedRMS[igain]*0.01;
269 higCut_rms=m_highNoiseTh[igain]*avreg.m_avPedRMS[igain]*0.01;
270 }
271
272 if (rms==-1)
273 ATH_MSG_ERROR ( "No Pedestal found for " << channelDescription(chid,cabling, igain) ) ;
274 else {
275 ATH_MSG_VERBOSE ( "PedRMS, gain: " << igain << ":" << rms << " Average: "
276 << avreg.m_avPedRMS[igain] << " Median: " << avreg.m_medPedRMS ) ;
278 if ( (rms-avreg.m_avPedRMS[igain]) > higCut_rms ) {
279 packing.setBit(highnoiseProb[igain],problem);
280 }
281 else if ( (rms-avreg.m_avPedRMS[igain]) > lowCut_rms ) {
282 packing.setBit(lownoiseProb[igain],problem);
283 }
285 if (fabs(rms-avreg.m_avPedRMS[igain]) > lowCut_rms || (bc.lowNoiseHG()||bc.highNoiseHG()) ) {
286 std::string my_status;
287 if (fabs(rms-avreg.m_avPedRMS[igain]) < lowCut_rms && (bc.lowNoiseHG()||bc.highNoiseHG()))
288 my_status="BCN ";
289 else
290 my_status=(bc.lowNoiseHG()||bc.highNoiseHG()) ? "BC " : "NEW ";
291
292 ATH_MSG_INFO( my_status << channelDescription(chid,cabling,igain)
293 << " RMS: " << rms << " ( " << avreg.m_avPedRMS[igain] << " , "
294 << float(int(10000*(rms-avreg.m_avPedRMS[igain])/avreg.m_avPedRMS[igain]))/100 <<" %) " << ", #Sig: "
295 << float(int(100*(rms-avreg.m_avPedRMS[igain])/avreg.m_avPedRMSSD[igain]))/100
296 << " ( " << avreg.m_avPedRMSSD[igain] << " ) " ) ;
297 }// end bad channels information output
298 } //end if(rms==-1)
299 }//end if have ped rms for this cell & gain
300 }//end loop over gains
301
303 if (avreg.m_nAmpls[0]>2 && avreg.m_nWids[0]>2 && avreg.m_nTmaxs[0]>2) {//Check if we have average ampls for this cell & gain
304 const float ampl=thisCellData.m_ampl;
305 const float wid=thisCellData.m_wid;
306 const float tmax=thisCellData.m_tmax;
307
308 float lowCut_amp=0.;
309 float higCut_amp=0.;
310 float lowCut_wid=0.;
311 float higCut_wid=0.;
312 float Cut_tmax=0.;
313
314 if ( m_cutType=="SIG" ) {
315 lowCut_amp=m_distampTh[0]*avreg.m_avAmplSD[0];
316 higCut_amp=m_amplTh[0]*avreg.m_avAmplSD[0];
317 lowCut_wid=m_distwidTh[0]*avreg.m_avWidSD[0];
318 higCut_wid=m_widTh[0]*avreg.m_avWidSD[0];
319 Cut_tmax=m_tmaxampTh[0]*avreg.m_avTmaxSD[0];
320 }
321 else if ( m_cutType=="PER") {
322 lowCut_amp=m_distampTh[0]*avreg.m_avAmpl[0]*0.01;
323 higCut_amp=m_amplTh[0]*avreg.m_avAmpl[0]*0.01;
324 lowCut_wid=m_distwidTh[0]*avreg.m_avWid[0]*0.01;
325 higCut_wid=m_widTh[0]*avreg.m_avWid[0]*0.01;
326 Cut_tmax=m_tmaxampTh[0]*avreg.m_avTmax[0]*0.01;
327 } // end if loop
328
329
330 if (ampl==-1 || wid==-1) {
331 ATH_MSG_INFO ( "No Amplitude or Width found for " << channelDescription(chid,cabling,0) ) ;
333 }
334 else {
335 ATH_MSG_VERBOSE ( "Ampl gain: "<< 0<< ":"<< ampl<< " Average: " << avreg.m_avAmpl[0]) ;
337 if (fabs(ampl-avreg.m_avAmpl[0])>higCut_amp || fabs(wid-avreg.m_avWid[0])>higCut_wid) {
339 }
341 else if (fabs(ampl-avreg.m_avAmpl[0])>lowCut_amp || fabs(wid-avreg.m_avWid[0])>lowCut_wid){
343 }
345 else if (fabs(tmax-avreg.m_avTmax[0])>Cut_tmax) {
347// std::string my_status=(bc.good()) ? "NEW " : "BC ";
348// log << MSG::INFO << my_status << channelDescription(chid,cabling,0) << " Tmax: " << tmax << " ( " << avreg.m_avTmax[0] << " , "
349// << float(int(10000*(tmax-avreg.m_avTmax[0])/avreg.m_avTmax[0]))/100 << " %) "
350// << " #Sig:" << float(int(100*(tmax-avreg.m_avTmax[0])/avreg.m_avTmaxSD[0]))/100
351// << " ( " << avreg.m_avTmaxSD[0] << " ) " << endmsg;
352 }
354// if (fabs(ampl-avreg.m_avAmpl[0])>lowCut_amp || fabs(wid-avreg.m_avWid[0])>lowCut_wid) {
356 if ( problem.deadReadout()||problem.distorted() || bc.deadReadout()||bc.deadCalib()||bc.deadPhys()||bc.distorted()||bc.shortProblem() ){
357 std::string my_status;
358 if ( !(problem.deadReadout()||problem.distorted())
359 &&(bc.deadReadout()||bc.deadCalib()||bc.deadPhys()||bc.distorted()||bc.shortProblem()) )
360 my_status="BCN ";
361 else
362 my_status=(bc.deadReadout()||bc.deadCalib()||bc.deadPhys()||bc.distorted()||bc.shortProblem()) ? "BC " : "NEW ";
363
364 ATH_MSG_INFO ( my_status << channelDescription(chid,cabling,0)
365 << " Amp: " << ampl << " ( " << avreg.m_avAmpl[0] << " , "
366 << float(int(10000*(ampl-avreg.m_avAmpl[0])/avreg.m_avAmpl[0]))/100 << " %) " << " #Sig: "
367 << float(int(100*(ampl-avreg.m_avAmpl[0])/avreg.m_avAmplSD[0]))/100 << " ( " << avreg.m_avAmplSD[0] <<" ) "
368 << " FWHM: " << wid << " ( " << avreg.m_avWid[0] << " , "
369 << float(int(10000*(wid-avreg.m_avWid[0])/avreg.m_avWid[0]))/100 << " %) " << " #Sig: "
370 << float(int(100*(wid-avreg.m_avWid[0])/avreg.m_avWidSD[0]))/100
371 << " ( " << avreg.m_avWidSD[0] << " ) "
372 << " Tmax: " << tmax << " ( " << avreg.m_avTmax[0] << " , "
373 << float(int(10000*(tmax-avreg.m_avTmax[0])/avreg.m_avTmax[0]))/100 << " %) " << " #Sig:"
374 << float(int(100*(tmax-avreg.m_avTmax[0])/avreg.m_avTmaxSD[0]))/100
375 ) ;
376 }
377 }
378 }//end if have amplitude for this cell
379
380
381 const std::vector<HWIdentifier>& cLids=clCont->calibSlotLine(chid);
382 for (const HWIdentifier& hwid : cLids) {
383 goodAndBad_t& gb=calibLineMap[hwid];
384 if (problem.deadReadout()||problem.distorted())
385 gb.second.push_back(badChanVec.size());
386 else
387 ++gb.first;
388 }
389 if (!problem.good()) badChanVec.push_back(std::make_pair(chid,problem));
390
391 }//end loop over channels
392
393
394 for(const auto & kv: calibLineMap) {
395 const goodAndBad_t& gb=kv.second;
396 for (unsigned i=0;i<gb.second.size();i++) {
397 if (gb.first==0) {
398 ATH_MSG_INFO ( "All channels belonging to calibLine " << channelDescription(badChanVec[gb.second[i]].first, cabling)
399 << " don't respond to pulses. Assume bad calib line." ) ;
400 packing.setBit(LArBadChannel::LArBadChannelEnum::deadReadoutBit,badChanVec[gb.second[i]].second,false);
401 packing.setBit(LArBadChannel::LArBadChannelEnum::distortedBit,badChanVec[gb.second[i]].second,false);
402 packing.setBit(LArBadChannel::LArBadChannelEnum::deadCalibBit,badChanVec[gb.second[i]].second,true);
403 }//end loop over all channels belonging to this calibline
404 }
405 }//end loop over calibline vector
406
407 if (m_outFileName.size()) {
408 std::ofstream outfile(m_outFileName.c_str());
409 if (!outfile.is_open()) {
410 ATH_MSG_ERROR ( "Failed to open output file " << m_outFileName << ". No output will be written." ) ;
411 }
412 else {
413 BCV_t::const_iterator bcvit=badChanVec.begin();
414 BCV_t::const_iterator bcvit_e=badChanVec.end();
415 for(;bcvit!=bcvit_e;++bcvit) {
416 const HWIdentifier chid=bcvit->first;
417 const LArBadChannel bc=bcvit->second;
418 const HWIdentifier cLid=clCont->calibSlotLine(chid)[0];
419 const LArBadChannel bc2=bcCont->status(chid);
420 std::string my_ps=(bc2.good())? "NEW " : "BC ";
421 if (!bc2.good()&&m_outOnlyNew) continue; // just new
422 outfile << m_onlineId->barrel_ec(chid) << " "
423 << m_onlineId->pos_neg(chid) << " "
424 << m_onlineId->feedthrough(chid) << " "
425 << m_onlineId->slot(chid) << " "
426 << m_onlineId->channel(chid) << " "
427 << m_onlineId->channel(cLid) << " "
428 << packing.stringStatus(bc) << " "
429 << my_ps << std::endl;
430// << packing.stringStatus(bc) << std::endl;
431 }
432 outfile.close();
433 } //end if out file open
434 } // end if have out file name
435 return StatusCode::SUCCESS;
436}
437
439 const LArOnOffIdMapping *cabling,
440 const unsigned gain) const {
441
444 std::ostringstream output;
445
446 if (gain<=2)
447 output << "Gain:"<< gain << " ";
448
449 output << "Channel [";
450// output << " id=0x" << std::hex << chid.get_compact() << std::dec << " [";
451 if (m_onlineId->barrel_ec(chid)==0)
452 output << "Bar";
453 else
454 output << "End";
455
456// output << ",Side:";
457 if (m_onlineId->pos_neg(chid)==0)
458 output << ",C";
459 else
460 output << ",A";
461
462 output << ",FT:" << m_onlineId->feedthrough(chid)
463 << ",Sl:" << m_onlineId->slot(chid);
464
465 output << ",Ch:" << m_onlineId->channel(chid);
466 if (!m_onlineId->isCalibration(chid)) {
467 try {
468 if (cabling->isOnlineConnected(chid)) {
469 if (m_onlineId->isFCALchannel(chid))
470 output << ",FCAL";
471 if (m_onlineId->isHECchannel(chid))
472 output << ",HEC";
473 if (m_onlineId->isEMBchannel(chid))
474 output << ",EMB";
475 if (m_onlineId->isEMECchannel(chid))
476 output << ",EMEC";
477 }//end if is connected
478 else
479 output << ",disconnected";
480 }
481 catch (LArID_Exception&) {}
482 }//end if !isCalibration
483 output << "]";
484 return output.str();
485}
486
487
488
490 for(unsigned igain=CaloGain::LARHIGHGAIN; igain<CaloGain::LARNGAIN; igain++){
491 m_nPed[igain]=0;
492 m_avPedRMS[igain]=0;
493 m_avPedRMSSD[igain]=0;
494
495 m_nAmpls[igain]=0;
496 m_avAmpl[igain]=0.;
497 m_avAmplSD[igain]=0.;
498
499 m_nWids[igain]=0;
500 m_avWid[igain]=0.;
501 m_avWidSD[igain]=0.;
502
503 m_nTmaxs[igain]=0;
504 m_avTmax[igain]=0.;
505 m_avTmaxSD[igain]=0.;
506
507 m_medPedRMS[igain]=0;
508 m_medAmpl[igain]=0;
509 m_medWid[igain]=0;
510 m_medTmax[igain]=0;
511 }
512}
513
514
515void LArBadChannelHunter::Average::finish(float my_recalcPer) {
516 for(unsigned igain=CaloGain::LARHIGHGAIN; igain<CaloGain::LARNGAIN; igain++) {
517
518 if (m_nPed[igain]) {
519 m_avPedRMS[igain]/=m_nPed[igain];
520 //sample standard deviation of average
521 m_avPedRMSSD[igain]=(m_avPedRMSSD[igain]-(m_nPed[igain]*m_avPedRMS[igain]*m_avPedRMS[igain]))/(m_nPed[igain]);
522 m_avPedRMSSD[igain]=sqrt(m_avPedRMSSD[igain]);
523 //Find median
524 std::sort(m_vmedPedRMS[igain].begin(),m_vmedPedRMS[igain].end());
525 m_medPedRMS[igain]=m_vmedPedRMS[igain].at(m_vmedPedRMS[igain].size()/2);
526 }
527 if (m_nAmpls[igain]) {
528 m_avAmpl[igain]/=m_nAmpls[igain];
529 //sample standard deviation of average
530 m_avAmplSD[igain]=(m_avAmplSD[igain]-(m_nAmpls[igain]*m_avAmpl[igain]*m_avAmpl[igain]))/(m_nAmpls[igain]);
531 m_avAmplSD[igain]=sqrt(m_avAmplSD[igain]);
532 //Find median
533 std::sort(m_vmedAmpl[igain].begin(),m_vmedAmpl[igain].end());
534 m_medAmpl[igain]=m_vmedAmpl[igain].at(m_vmedAmpl[igain].size()/2);
535 }
536 if (m_nWids[igain]) {
537 m_avWid[igain]/=m_nWids[igain];
538 //sample standard deviation of average
539 m_avWidSD[igain]=(m_avWidSD[igain]-(m_nWids[igain]*m_avWid[igain]*m_avWid[igain]))/(m_nWids[igain]);
540 m_avWidSD[igain]=sqrt(m_avWidSD[igain]);
541 //Find median
542 std::sort(m_vmedWid[igain].begin(),m_vmedWid[igain].end());
543 m_medWid[igain]=m_vmedWid[igain].at(m_vmedWid[igain].size()/2);
544 }
545 if (m_nTmaxs[igain]) {
546 m_avTmax[igain]/=m_nTmaxs[igain];
547 //sample standard deviation of average
548 m_avTmaxSD[igain]=(m_avTmaxSD[igain]-(m_nTmaxs[igain]*m_avTmax[igain]*m_avTmax[igain]))/(m_nTmaxs[igain]);
549 m_avTmaxSD[igain]=sqrt(m_avTmaxSD[igain]);
550 //Find median
551 std::sort(m_vmedTmax[igain].begin(),m_vmedTmax[igain].end());
552 m_medTmax[igain]=m_vmedTmax[igain].at(m_vmedTmax[igain].size()/2);
553 }
554
555
558
559 if (my_recalcPer>=0.){
561 if ( m_avPedRMSSD[igain]>my_recalcPer*m_avPedRMS[igain]) {
562 float re_avPed=0.; float re_avPedSD=0.; int re_nPed=0;
563 std::vector<float>::iterator p_loop = m_vmedPedRMS[igain].begin();
564 std::vector<float>::iterator p_loop_e=m_vmedPedRMS[igain].end();
565 for (;p_loop!=p_loop_e; ++p_loop){
566 if ( fabs(*p_loop-m_medPedRMS[igain])<my_recalcPer*m_medPedRMS[igain] ){
567 re_avPed+=*p_loop;
568 re_avPedSD+=*p_loop*(*p_loop);
569 re_nPed++;
570 }
571 }
572 if (re_nPed > 0) {
573 re_avPed/=re_nPed;
574 re_avPedSD=(re_avPedSD- re_nPed*re_avPed*re_avPed)/(re_nPed);
575 }
576 re_avPedSD=sqrt(re_avPedSD);
577 std::cout <<" PedRMS mean && RMS are recalc: Orig (recalc) are: "<< m_avPedRMS[igain]<< " ( "<< re_avPed
578 <<" ) and "<< m_avPedRMSSD[igain]<<" ( "<<re_avPedSD<<" )"<<std::endl;
579 m_avPedRMS[igain]=re_avPed; m_avPedRMSSD[igain]=re_avPedSD;
580 }
582 if ( m_avAmplSD[igain]>my_recalcPer*m_avAmpl[igain] ) {
583 float re_avAmpl=0.; float re_avAmplSD=0.; int re_nAmpl=0;
584 std::vector<float>::iterator re_loop = m_vmedAmpl[igain].begin();
585 std::vector<float>::iterator re_loop_e=m_vmedAmpl[igain].end();
586 for (;re_loop!=re_loop_e; ++re_loop){
587 if ( fabs(*re_loop-m_medAmpl[igain])<my_recalcPer*m_medAmpl[igain] ){
588 re_avAmpl+=*re_loop;
589 re_avAmplSD+=*re_loop*(*re_loop);
590 re_nAmpl++;
591 }
592 }
593 if (re_nAmpl > 0) {
594 re_avAmpl/=re_nAmpl;
595 re_avAmplSD=(re_avAmplSD- re_nAmpl*re_avAmpl*re_avAmpl)/(re_nAmpl);
596 }
597 re_avAmplSD=sqrt(re_avAmplSD);
598 std::cout <<" MaxAmp mean && RMS are recalc: Orig (recalc) are: "<< m_avAmpl[igain]<< " ( "<< re_avAmpl
599 <<" ) and "<< m_avAmplSD[igain]<<" ( "<<re_avAmplSD<<" )"<<std::endl;
600 m_avAmpl[igain]=re_avAmpl; m_avAmplSD[igain]=re_avAmplSD;
601 }
603 if ( m_avWidSD[igain]>my_recalcPer*m_avWid[igain] ) {
604 float re_avWid=0.; float re_avWidSD=0.; int re_nWid=0;
605 std::vector<float>::iterator w_loop = m_vmedWid[igain].begin();
606 std::vector<float>::iterator w_loop_e=m_vmedWid[igain].end();
607 for (;w_loop!=w_loop_e; ++w_loop){
608 if ( fabs(*w_loop-m_medWid[igain])<my_recalcPer*m_medWid[igain] ){
609 re_avWid+=*w_loop;
610 re_avWidSD+=*w_loop*(*w_loop);
611 re_nWid++;
612 }
613 }
614 if (re_nWid > 0) {
615 re_avWid/=re_nWid;
616 re_avWidSD=(re_avWidSD- re_nWid*re_avWid*re_avWid)/(re_nWid);
617 }
618 re_avWidSD=sqrt(re_avWidSD);
619 std::cout <<" FWHM mean && RMS are recalc: Orig (recalc) are: "<< m_avWid[igain]<< " ( "<< re_avWid
620 <<" ) and "<< m_avWidSD[igain]<<" ( "<<re_avWidSD<<" )"<<std::endl;
621 m_avWid[igain]=re_avWid; m_avWidSD[igain]=re_avWidSD;
622 }
624 if ( m_avTmaxSD[igain]>my_recalcPer*m_avTmax[igain] ) {
625 float re_avTmax=0.; float re_avTmaxSD=0.; int re_nTmax=0;
626 std::vector<float>::iterator t_loop = m_vmedTmax[igain].begin();
627 std::vector<float>::iterator t_loop_e=m_vmedTmax[igain].end();
628 for (;t_loop!=t_loop_e; ++t_loop){
629 if ( fabs(*t_loop-m_medTmax[igain])<my_recalcPer*m_medTmax[igain] ){
630 re_avTmax+=*t_loop;
631 re_avTmaxSD+=*t_loop*(*t_loop);
632 re_nTmax++;
633 }
634 }
635 if (re_nTmax > 0) {
636 re_avTmax/=re_nTmax;
637 re_avTmaxSD=(re_avTmaxSD- re_nTmax*re_avTmax*re_avTmax)/(re_nTmax);
638 }
639 re_avTmaxSD=sqrt(re_avTmaxSD);
640 std::cout <<"TmaxAmp mean && RMS are recalc: Orig (recalc) are: "<< m_avTmax[igain]<< " ( "<< re_avTmax
641 <<" ) and "<< m_avTmaxSD[igain]<<" ( "<<re_avTmaxSD<<" )"<<std::endl;
642 m_avTmax[igain]=re_avTmax; m_avTmaxSD[igain]=re_avTmaxSD;
643 }
644 }
645
646 }//end loop over gains
647}
648
649
650
651unsigned LArBadChannelHunter::getSymId(const HWIdentifier chid, const LArOnOffIdMapping *cabling) const {
652 if (m_avgType==FEB)
653 return m_onlineId->feb_Id(chid).get_identifier32().get_compact();
654 else {
655 const unsigned caloRegionHashMax=m_caloId->calo_region_hash_max();
656 const Identifier id=cabling->cnvToIdentifier(chid);
657 const Identifier regid=m_caloId->region_id(id);
658 const unsigned reghash=m_caloId->calo_region_hash(regid);
659 const int eta=m_caloId->eta(id);
660
661
662
663 if (eta<0 || eta==CaloCell_ID::NOT_VALID || regid==CaloCell_ID::NOT_VALID ||reghash==CaloCell_ID::NOT_VALID || caloRegionHashMax!=64) {
664 std::cout << "ERROR unexpected idetifier:"
665 << std::hex << " id=0x" << id << " regionId=0x" << regid
666 << std::dec << " reghash=" << reghash << " eta=" << eta
667 << " caloRegionHashMax=" << caloRegionHashMax
668 << std::endl;
669 assert(0);
670 }
671 //can't reach here if eta is negative
672 //cppcheck-suppress shiftNegativeLHS
673 const unsigned retval= (eta<<8) | reghash;
674 return retval;
675 }
676}
Scalar eta() const
pseudorapidity method
#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)
LArBadXCont< LArBadChannel > LArBadChannelCont
StatusCode LArBadChannelHunter::stop ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
Algorithm to find funny channels in LAr.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
virtual float pedestalRMS(const HWIdentifier &id, int gain) const =0
access to RMS of Pedestal index by Identifier, and gain setting
std::vector< float > m_vmedTmax[CaloGain::LARNGAIN]
float m_medAmpl[CaloGain::LARNGAIN]
float m_avTmax[CaloGain::LARNGAIN]
std::vector< float > m_vmedWid[CaloGain::LARNGAIN]
float m_avPedRMS[CaloGain::LARNGAIN]
float m_avTmaxSD[CaloGain::LARNGAIN]
float m_avWid[CaloGain::LARNGAIN]
unsigned m_nTmaxs[CaloGain::LARNGAIN]
float m_avPedRMSSD[CaloGain::LARNGAIN]
float m_avWidSD[CaloGain::LARNGAIN]
std::vector< float > m_vmedAmpl[CaloGain::LARNGAIN]
float m_medTmax[CaloGain::LARNGAIN]
unsigned m_nWids[CaloGain::LARNGAIN]
float m_avAmpl[CaloGain::LARNGAIN]
std::vector< float > m_vmedPedRMS[CaloGain::LARNGAIN]
float m_medWid[CaloGain::LARNGAIN]
unsigned m_nPed[CaloGain::LARNGAIN]
float m_medPedRMS[CaloGain::LARNGAIN]
float m_avAmplSD[CaloGain::LARNGAIN]
unsigned m_nAmpls[CaloGain::LARNGAIN]
float m_distampTh[CaloGain::LARNGAIN]
float m_highNoiseTh[CaloGain::LARNGAIN]
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
float m_widTh[CaloGain::LARNGAIN]
SG::ReadCondHandleKey< LArBadChannelCont > m_BCKey
const std::string channelDescription(const HWIdentifier &chid, const LArOnOffIdMapping *cabling, const unsigned gain=99) const
float m_amplTh[CaloGain::LARNGAIN]
const CaloCell_ID * m_caloId
const LArOnlineID * m_onlineId
LArBadChannelHunter(const std::string &name, ISvcLocator *pSvcLocator)
Regular algorithm constructor.
SG::ReadCondHandleKey< LArCalibLineMapping > m_CLKey
float m_lowNoiseTh[CaloGain::LARNGAIN]
virtual StatusCode initialize() override
Standard initialization method.
unsigned getSymId(const HWIdentifier, const LArOnOffIdMapping *cabling) const
float m_distwidTh[CaloGain::LARNGAIN]
float m_tmaxampTh[CaloGain::LARNGAIN]
bool shortProblem() const
bool lowNoiseHG() const
bool deadReadout() const
bool highNoiseHG() const
bool deadCalib() const
bool deadPhys() const
bool good() const
Returns true if no problems at all (all bits at zero)
bool distorted() const
LArBC_t status(const HWIdentifier channel) const
Query the status of a particular channel or FEB This is the main client access method.
Liquid Argon Cumulative Wave Container.
const std::vector< HWIdentifier > & calibSlotLine(const HWIdentifier id) const
StatusCode undoCorrections()
undo corrections that have been already applied
ConstReference get(const HWIdentifier id, unsigned int gain=0) const
get data with online identifier
Exception class for LAr Identifiers.
double getMaxAmp(const LArWave &theWave) const
double getWidth(const LArWave &theWave) const
unsigned int getMax(const LArWave &theWave) const
return index of maximum sample
void setBit(typename T::ProblemType pb, LArBadChannel::BitWord &word, bool value=true) const
std::string stringStatus(const LArBadChannel &bc) const
@ LARMEDIUMGAIN
Definition CaloGain.h:18
@ LARLOWGAIN
Definition CaloGain.h:18
@ LARNGAIN
Definition CaloGain.h:19
@ LARHIGHGAIN
Definition CaloGain.h:18
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.