ATLAS Offline Software
Loading...
Searching...
No Matches
LArStripsCrossTalkCorrector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
9
15#include <cmath>
16
17
19
20 StatusCode sc = detStore()->retrieve(m_onlineHelper, "LArOnlineID");
21 if (sc.isFailure()) {
22 ATH_MSG_ERROR( "Could not get LArOnlineID helper !" );
23 return StatusCode::FAILURE;
24 }
25
26 sc = detStore()->retrieve(m_emId, "LArEM_ID");
27 if (sc.isFailure()) {
28 ATH_MSG_ERROR( "Could not get LArEM_ID helper !" );
29 return StatusCode::FAILURE;
30 }
31
32
34 ATH_CHECK(m_dontCorrMask.buildBitMask(m_dontCorr,msg()));
35
36 ATH_CHECK(m_BCKey.initialize());
37 ATH_CHECK(m_BFKey.initialize());
38 ATH_CHECK(m_cablingKey.initialize());
39 ATH_CHECK(m_pedKey.initialize());
40
41 m_acceptableDifference.value()/=100; //Convert from % to fraction
42
43 //Initialize strips lookup table:
44 for (unsigned bec : {0,1}) {
45 m_stripsLookUp[bec].resize(2*m_MAXphi); //change index to coded index
46 for (unsigned iside=0;iside<2;++iside) {
47 for (unsigned iphi=0; iphi!=m_MAXphi; ++iphi) {
48 m_stripsLookUp[bec][iphi+iside*m_MAXphi].resize(m_MAXeta[bec],nullptr);
49 }
50 }
51 }
52 return StatusCode::SUCCESS;
53}
54
55
57{
58 if ( m_event_counter < 100 || ( m_event_counter < 1000 && m_event_counter%100==0 ) || m_event_counter%1000==0 )
59 ATH_MSG_INFO( "Processing event " << m_event_counter );
61
62 if (m_keylist.size()==0) {
63 ATH_MSG_ERROR( "Key list is empty! No containers to process!" );
64 return StatusCode::FAILURE;
65 }
66
67
68 StatusCode sc;
69 unsigned nSaturation=0;
70
71 const LArFebErrorSummary* febErrSum=nullptr;
72 if (evtStore()->contains<LArFebErrorSummary>("LArFebErrorSummary")) {
73 sc=evtStore()->retrieve(febErrSum);
74 if (sc.isFailure()) {
75 ATH_MSG_ERROR( "Failed to retrieve FebErrorSummary object!" );
76 return sc;
77 }
78 }
79 else
80 if (m_event_counter==1)
81 ATH_MSG_WARNING( "No FebErrorSummaryObject found! Feb errors not checked!" );
82
84 const LArOnOffIdMapping* cabling{*cablingHdl};
85 if(!cabling) {
86 ATH_MSG_ERROR( "Do not have cabling object LArOnOffIdMapping");
87 return StatusCode::FAILURE;
88 }
89
91 const LArBadChannelCont* bcCont{*bcHdl};
92
94 const ILArPedestal* larPedestal=*pedHdl;
95
96
97 const LArAccumulatedCalibDigitContainer* larAccumulatedCalibDigitContainer;
98
99 // now start to deal with digits
100
101 for (const std::string& key : m_keylist) { // Loop over all containers that are to be processed (e.g. different gains)
102
103 sc = evtStore()->retrieve(larAccumulatedCalibDigitContainer,key);
104 if (sc.isFailure()){
105 ATH_MSG_WARNING( "Cannot read LArAccumulatedCalibDigitContainer from StoreGate! key=" << key );
106 continue; // Try next container
107 }
108
109
110 LArAccumulatedCalibDigit febErrorDummy; //Use the address of this object to mark cells belonging to a errornous FEB
111 LArAccumulatedCalibDigit inexistingDummy; //Use the address of this object for "cells" that would be outside of cryostat
112
113
114 HWIdentifier lastFailedFEB(0);
115
116 if(larAccumulatedCalibDigitContainer->empty()) {
117 ATH_MSG_DEBUG( "LArAccumulatedCalibDigitContainer with key = " << key << " is empty " );
118 //return StatusCode::SUCCESS;
119 continue; // Try next container
120 } else {
121 ATH_MSG_DEBUG( "Processing LArAccumulatedCalibDigitContainer with key = " << key
122 << ". Size: " << larAccumulatedCalibDigitContainer->size() );
123 }
124
125 //Fill missing febs (if not done yet)
126 if (!m_missingFEBsDone) {
128 }
129
130
131 //Reset strips lookup table to nullptr:
132 for (int bec : {0,1}) {
133 for (unsigned ieta=0;ieta!=m_MAXeta[bec];++ieta) { //Loop over Strips cells
134 for (unsigned iphi=0;iphi!=m_MAXphi;++iphi) { //Loop over Strips cells
135 for (unsigned iside=0;iside<2;++iside) {
136 m_stripsLookUp[bec][iphi+iside*m_MAXphi][ieta]=nullptr;
137 }
138 }
139 }
140 } //end loop over barrel & EC
141 ATH_MSG_DEBUG( "Filling strips lookup table..." ) ;
142 int nStrips=0;
143
144 for (const LArAccumulatedCalibDigit* dig : *larAccumulatedCalibDigitContainer) { //Loop over all cells to fill Strips lookup table
145 const HWIdentifier chid=dig->hardwareID();
146 if (!(m_onlineHelper->isEMBchannel(chid) || m_onlineHelper->isEMECchannel(chid))) continue; //Deal only with EM calos case
147 if (!cabling->isOnlineConnected(chid)) continue; //ignore disconnected channels
148
149
150 const Identifier id=cabling->cnvToIdentifier(chid);
151 if (m_emId->sampling(id)!=1) continue; //Deal only with strips
152
153 const HWIdentifier febid=m_onlineHelper->feb_Id(chid);
154 if (febErrSum) {
155 const uint16_t febErrs=febErrSum->feb_error(febid);
156 if (febErrs & m_fatalFebErrorPattern) {
157 if (febid!=lastFailedFEB) {
158 lastFailedFEB=febid;
159 ATH_MSG_ERROR( "Event " << m_event_counter << " Feb " << m_onlineHelper->channel_name(febid)
160 << " reports error(s):" << febErrSum->error_to_string(febErrs) << ". Data ignored." );
161 }
162 dig=&febErrorDummy;
163 } //end if fatal feb error
164 }//end if check feb error summary
165
166
167 const int bec=m_onlineHelper->barrel_ec(chid);
168 const size_t ieta=getEtaIndex(id);
169 if (ieta==m_noIdx) continue; //Not a cell we care about
170 const size_t iphi=getPhiIndex(id);
171 if (iphi>=2*m_MAXphi || ieta>=m_MAXeta[bec]) {
172 ATH_MSG_FATAL( "Array index out of range: iphi=" << iphi << " (max " << m_MAXphi << "), ieta="
173 << ieta << "(max " << m_MAXeta[bec] << ")" );
174 return StatusCode::FAILURE;
175 }
176 ++nStrips;
177
178
179 //check for saturation:
180 bool saturated=false;
181 if (m_ADCsatur>0) {
182 const std::vector<uint64_t>& samples=dig->sampleSum();
183 const size_t& nS=samples.size();
184 const uint32_t maxValue=(uint32_t)(m_ADCsatur*dig->nTriggers());
185 for (size_t i=0;i<nS;++i) {
186 if (samples[i] >= maxValue) {
187 saturated=true;
188 ATH_MSG_DEBUG("Found saturating digit (index = " << i
189 << ", <ADC> = " << samples[i]/dig->nTriggers()
190 << ", DAC = " << dig->DAC()
191 << ") for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
192 << ". Skipping.");
193 break;
194 }//end if>maxvalue
195 }//end loop over digits
196 }
197 if (saturated) {
198 ++nSaturation;
199 continue; //Skip this channel
200 }
201
202 m_stripsLookUp[bec][iphi][ieta]=dig;
203
204 }//End loop over all cells
205
206 if (m_nStrips<0)
207 m_nStrips=nStrips;
208
209 if (m_nStrips != nStrips) {
210 ATH_MSG_WARNING( "Number of strips changed! Have " << nStrips << ", had " << m_nStrips << " before.");
211 m_nStrips=nStrips;
212 }
213 else
214 ATH_MSG_DEBUG("strips lookup table filled. Have " << nStrips << " out of " << 2*m_MAXphi*(1+m_MAXeta[0]-m_MINeta[0])
215 << " barrel channels plus " << 2*m_MAXphi*(1+m_MAXeta[1]-m_MINeta[1]) << "endcap channels.");
216
217
218 //Weight for the four neighbors:
219 //only half the signal of the next-to-next neihbor is summed
220 //A more correct approach would be to check if the 'mirrored' neighbor is pulsed as well and compute this weights on-the-fly
221 //const float weight[4]={0.5,1,1,0.5};
222 neighbour_t neighbours[4]={}; //Keep pointers for the four neightbors
223 neighbours[0].dist=-2;
224 neighbours[1].dist=-1;
225 neighbours[2].dist=1;
226 neighbours[3].dist=2;
227
228 for (unsigned bec : {0,1}) { //Loop over barrel and endcap
229 for (unsigned iside=0; iside<2; iside++) { //Loop over both sides of the detector
230 for (int ieta=0; ieta<(int)m_MAXeta[bec]; ieta++) { // Loop over eta range
231 for (unsigned iphi=0; iphi<m_MAXphi; iphi++) { // Loop over phi range
232 const unsigned iphi2=iphi+m_MAXphi*iside; //Phi index inside lookup table
233 const LArAccumulatedCalibDigit* currDig=m_stripsLookUp[bec][iphi2][ieta];
234 if (currDig==nullptr || currDig==&febErrorDummy) continue; //Digit not found or FEB in error: ignore
235
236 if ( currDig->isPulsed() ) {
237 HWIdentifier chid = currDig->hardwareID();
238 CaloGain::CaloGain t_gain = currDig->gain();
239 if (m_dontCorrMask.cellShouldBeMasked(bcCont,chid)) {
240 ATH_MSG_DEBUG("Strip " << m_onlineHelper->channel_name(chid) <<" (Eta = " << ieta << ", Phi = "
241 << iphi2 << ") should not be touched accoring to jobConfig");
242 continue;
243 }
244
245 const unsigned NtotSamples = currDig->nsamples();
246 const unsigned NbTriggers = currDig->nTriggers();
247 ATH_MSG_VERBOSE("Now processing strip "<< m_onlineHelper->channel_name(chid) << " (Eta = " << ieta << ", Phi = " << iphi2 << ")");
248
249 //Fill the pointers and pedestal in the 'neighbours' array
250 for (unsigned i=0;i<4;i++) {
251 //Set all zero to start with...
252 neighbours[i].dig=nullptr;
253 neighbours[i].ped=0.;
254 const int neigbEtaItx=neighbours[i].dist+(int)ieta;
255 //Check if we are supposed to have this neighbour
256 if (neigbEtaItx<(int)m_MINeta[bec] || neigbEtaItx>=(int)m_MAXeta[bec]) {
257 ATH_MSG_DEBUG("Neighbour " << neighbours[i].dist <<" , ieta=" << neigbEtaItx
258 << " doesn't exist. (min="<< m_MINeta[bec] << " ,max=" << m_MAXeta[bec] << ")");
259 neighbours[i].dig=&inexistingDummy;
260 continue;
261 }
262 const LArAccumulatedCalibDigit* neighDig=m_stripsLookUp[bec][iphi2][neigbEtaItx];
263 //Check if neighbour is present
264 if (!neighDig) {
265 //neighbor missing. Could be known missing FEB or new problem
266 //Reported only if at least WARNING
267 if (msgLvl(MSG::WARNING)) {
268 if (m_knownMissingFebs[bec][neigbEtaItx].test(iphi2)) {
269 ATH_MSG_DEBUG("FEB missing for neighbour " << neighbours[i].dist << " to be added to strip 0x"
270 << m_onlineHelper->channel_name(chid) << " (Eta = " << ieta << ", Phi = " << iphi << ")");
271 }
272 else {
273 ATH_MSG_WARNING( "Cannot find neighbour " << neighbours[i].dist << " to be added to strip 0x"
274 << m_onlineHelper->channel_name(chid) << " (Eta = " << ieta << ", Phi = " << iphi << ")" );
275 }
276 }//end if msgLvl(WARNING)
277 continue;
278 }//end if !neighDIg
279 if (neighDig==&febErrorDummy) { //Pointer comparison!!
280 ATH_MSG_WARNING("Neighbour " << neighbours[i].dist << " of strip " << m_onlineHelper->channel_name(chid)
281 << " (Eta = " << ieta << ", Phi = " << iphi <<"), has a FEB error. Ignored.");
282 continue;
283 }
284
285 //Check if neighbour is pulsed
286 if (neighDig->isPulsed()) {
287 ATH_MSG_WARNING( "Neighbour " << neighbours[i].dist << " of strip " << m_onlineHelper->channel_name(chid)
288 << " (Eta = " << ieta << ", Phi = " << iphi <<", " << printMaxSample(neighDig)
289 << ") is pulsed. Not used for correction." );
290 continue;
291 }
292
293 //Check if neighbour is on the bad-channel list
294 if (m_dontUseForCorrMask.cellShouldBeMasked(bcCont,neighDig->hardwareID())) {
295 ATH_MSG_DEBUG("Neighbour " << neighbours[i].dist << " of strip " << m_onlineHelper->channel_name(chid)
296 << " (Eta = " << ieta << ", Phi = " << iphi
297 << ") is flagged by the LArBadChannelMaskingTool. Not used for correction.");
298 continue;
299 }
300
301 //Get Pedestal
302 const float pedestal = larPedestal->pedestal(neighDig->hardwareID(),t_gain);
303 if (pedestal <= (1.0+LArElecCalib::ERRORCODE)) {
304 ATH_MSG_ERROR( "No pedestal are available for neighbour " << neighbours[i].dist << " of strip "
305 << m_onlineHelper->channel_name(chid) << " (Eta = " << ieta << ", Phi = " << iphi << "). Not used for correction!" );
306 continue;
307 }
308 //All went ok, fill struct
309 neighbours[i].dig=neighDig;
310 neighbours[i].ped=pedestal;
311
312 //The weight is one, unless the neighbor-of-the-neighbor is pulsed too
313 neighbours[i].weight=1.0;
314 //Now check if the neighbor-of-the-neighbor is pulsed to set a different weight.
315 const int nnEta=ieta+2*neighbours[i].dist;
316 if (nnEta>=(int)m_MINeta[bec] && nnEta<(int)m_MAXeta[bec]) {
317 const LArAccumulatedCalibDigit* nnDig=m_stripsLookUp[bec][iphi2][nnEta];
318 if (nnDig!=nullptr) {
319 //Could be also FebErrorDummy (which will always pretentd to be not pulsed)
320 if (nnDig->isPulsed()) {
321 ATH_MSG_VERBOSE("Neighbour " << neighbours[i].dist << " of strip " << m_onlineHelper->channel_name(chid)
322 << " has another pulsed cell in the neighborhood. Setting weight to 0.5");
323 neighbours[i].weight=0.5;
324 }//end if isPulsed
325 }//end if neighbor-of-neighbor not NULL
326 }//end if neighbor-of-neighbor in eta range
327 }//End loop over four neighbours
328
329
330 //Now loop over samples to apply xtalk correction
331 std::vector<double> SampleSums(NtotSamples);
332 for (std::size_t SampleIndex=0;SampleIndex<NtotSamples; ++SampleIndex ) {
333 SampleSums[SampleIndex]=(double)currDig->sampleSum()[SampleIndex];
334 ATH_MSG_VERBOSE("SampleSum " << SampleIndex << " (" << SampleSums[SampleIndex] << " ADC counts / " << NbTriggers << " Ntriggers)");
335 }
336 //Loop over the neighbours and apply corrections
337 for (unsigned i=0;i<4;i++) {
338 if (neighbours[i].dig==&inexistingDummy) { //Pointer comparision!
339 ATH_MSG_VERBOSE("Neighbour " << neighbours[i].dist << " of strip " << m_onlineHelper->channel_name(chid)
340 << " (Eta = " << ieta << ", Phi = " << iphi << ") does not exist.");
341 //no neighbor (end of calorimeter). Do nothing
342 continue;
343 }
344
345 if (neighbours[i].dig) { //"Normal" case
346 correctSamples(SampleSums,neighbours[i]);
347 ATH_MSG_VERBOSE("Neighbour " << neighbours[i].dist << " of strip " << m_onlineHelper->channel_name(chid)
348 << " (Eta = " << ieta << ", Phi = " << iphi << ") is used for correction");
349 } //end if have pointer to neighbor cell
350 else { //Neighbor not usable for some reason, try mirrored neighbor
351 const int j = 3-i; //get mirrored neighbor
352 ATH_MSG_INFO( "Neighbour " << neighbours[i].dist << " of strip " << m_onlineHelper->channel_name(chid)
353 << " cannot be used. Taking mirrored neighbour " << neighbours[j].dist << " instead." );
354 if (neighbours[j].dig!=nullptr && neighbours[j].dig!=&inexistingDummy){
355 correctSamples(SampleSums,neighbours[j]);
356 ATH_MSG_VERBOSE("Mirrored neighbour " << neighbours[j].dist << " of strip " << m_onlineHelper->channel_name(chid)
357 << " (Eta = " << ieta << ", Phi = " << iphi << ") is used for correction");
358 }//end if neighbours[j].dig
359 else {
360 ATH_MSG_WARNING( "Mirrored Neighbour " << neighbours[j].dist << " of strip " << m_onlineHelper->channel_name(chid)
361 << " cannot be used too. No correction applied" );
362 }
363 }//end if no neighboring cell
364 }//end loop over the four neighbors
365
366
367 std::vector<uint64_t> SampleSumInt(NtotSamples);
368 bool unresonable=false;
369 std::size_t iPeak=std::max_element(currDig->sampleSum().begin(),currDig->sampleSum().end())-currDig->sampleSum().begin();
370 for (std::size_t SampleIndex=0;SampleIndex<NtotSamples; ++SampleIndex ) {
371 const double& thisSampleSum=SampleSums[SampleIndex];
372 const uint32_t& oldVal=currDig->sampleSum()[SampleIndex];
373 if (thisSampleSum<0) {
374 unresonable=true;
375 ATH_MSG_WARNING( "Channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
376 << " (Eta = " << ieta << ", Phi = " << iphi << ") Resulting ADC sample " << SampleIndex <<" negative! "
377 << thisSampleSum << " instead of " << oldVal << " Not corrected." );
378 break;
379 }
380
381 if (SampleIndex==iPeak) { //check value of correction at peak
382 const float dev=(thisSampleSum-oldVal)/oldVal;
383 m_differences.add(currDig,dev);
384 if (std::fabs(dev)>m_acceptableDifference) {
385 unresonable=true;
386 ATH_MSG_WARNING("Strip " << m_onlineHelper->channel_name(chid) << " (Eta = " << ieta << ", Phi = " << iphi
387 << ") DAC=" << currDig->DAC() << ": Resulting ADC sample " << SampleIndex <<" looks unreasonable: "
388 << thisSampleSum << " instead of " << oldVal << " (off by " << dev*100 << "%)"
389 << " (=" << thisSampleSum/NbTriggers << " -> " << oldVal/NbTriggers <<", ped="
390 << larPedestal->pedestal(chid,t_gain)
391 << " Not Corrected.");
392 break;
393 }//end if dev>m_acceptableDifference
394 } // end if at peak sample
395 SampleSumInt[SampleIndex] = (uint64_t)(thisSampleSum);
396 }//End loop over samples
397
398
399 if (unresonable) {
400 m_uncorrectedIds.insert(chid);
401 ATH_MSG_DEBUG("Correction for channel " << m_onlineHelper->channel_name(chid) << " failed");
402 }
403 else {
404 ATH_MSG_VERBOSE("Correction for channel " << m_onlineHelper->channel_name(chid) << " DAC="<<currDig->DAC() << " succeeded "
405 << currDig->sampleSum()[2] << "->" << SampleSumInt[2]);
406 // FIXME: const_cast, modifying object in SG.
407 const_cast<LArAccumulatedCalibDigit*>(currDig)->setSampleSum(SampleSumInt);
408 }
409 }// end if-pulsed
410 }//end loop over phi
411 }//end loop over eta
412 }//End loop over sides
413 }//End loop over barrel-EC
414 } //End loop over all containers
415
416 if (nSaturation) {
417 ATH_MSG_INFO( "Found " << nSaturation << " saturating digits in this event." );
418 }
419 return StatusCode::SUCCESS;
420}
421
422
423
425 if (msgLvl(MSG::WARNING) && !m_uncorrectedIds.empty() ) {
426 const LArBadChanBitPacking packing;
427 ATH_MSG_WARNING( "The following "<< m_uncorrectedIds.size() << " channels are (partly) uncorrected because of unresonable high correction:" );
429 const LArBadChannelCont* bcCont{*bcHdl};
430 if(bcCont) {
431 std::set<HWIdentifier>::const_iterator it=m_uncorrectedIds.begin();
432 std::set<HWIdentifier>::const_iterator it_e=m_uncorrectedIds.end();
433 for (;it!=it_e;++it) {
434 LArBadChannel bc=bcCont->status(*it);
435 ATH_MSG_WARNING( "Not corrected: " << m_onlineHelper->channel_name(*it) << " " << packing.stringStatus(bc) );
436 }
437 }
438 }
439
441
442 return StatusCode::SUCCESS;
443}
444
445
447
448 const std::vector<uint64_t>& ss=thisDig->sampleSum();
449 std::vector<uint64_t>::const_iterator imax=std::max_element(ss.begin(),ss.end());
450 std::ostringstream output;
451 output << "S[" << imax-ss.begin() << "]=" << *imax/thisDig->nTriggers();
452 return output.str();
453}
454
455
457unsigned nMissing=0;
458
459 for (unsigned bec : {0,1}) {
460 m_knownMissingFebs[bec].clear();
461 m_knownMissingFebs[bec].resize(m_MAXeta[bec]);
462 }
463
464 //const std::vector<HWIdentifier> mf=m_badChannelTool->missingFEBs();
466 const LArBadFebCont* bfCont{*bfHdl};
467 if(!bfCont) {
468 ATH_MSG_ERROR( "Do not have missing FEBs " << m_BFKey.key() );
469 return StatusCode::FAILURE;
470 }
472 const LArOnOffIdMapping* cabling{*cablingHdl};
473 if(!cabling) {
474 ATH_MSG_ERROR( "Do not have cabling object LArOnOffIdMapping");
475 return StatusCode::FAILURE;
476 }
477
479 for (const auto& entry : bfCont->fullCont()) {
480 const HWIdentifier hid=HWIdentifier(entry.first);
481 mf.emplace_back(LArBadChannelDBTools::BadFebEntry(hid,entry.second));
482 }
483
484 //ATH_MSG_DEBUG( "Got " << mf.size() << " missing FEBs" );
485 LArBadChannelDBTools::BadFebVec::const_iterator it=mf.begin();
486 LArBadChannelDBTools::BadFebVec::const_iterator it_e=mf.end();
487 for (;it!=it_e;++it) {
488 const HWIdentifier& fid=it->first;
489 const LArBadFeb& bf=it->second;
490 if (bf.deadAll() || bf.deadReadout() || bf.deactivatedInOKS()) {
491 if (m_onlineHelper->isEMBchannel(fid) || m_onlineHelper->isEMECchannel(fid)) {
492 ATH_MSG_DEBUG( "Feb " << MSG::hex << fid.get_compact() << MSG::dec << " reported as missing" );
493 const int nChan=m_onlineHelper->channelInSlotMax(fid);
494 const unsigned bec=m_onlineHelper->barrel_ec(fid);
495 for (int c=0;c<nChan;++c) {
496 const HWIdentifier chid=m_onlineHelper->channel_Id(fid,c);
497 const Identifier id=cabling->cnvToIdentifier(chid);
498 const size_t ieta=getEtaIndex(id);
499 if (ieta==m_noIdx) continue; //Not a cell we care about
500 const size_t iphi=getPhiIndex(id);
501 if (iphi>=2*m_MAXphi || ieta>=m_MAXeta[bec]) {
502 ATH_MSG_FATAL( "Array index out of range: iphi=" << iphi << " (max " << m_MAXphi << "), ieta="
503 << ieta << "(max " << m_MAXeta[bec] << ")" );
504 return StatusCode::FAILURE;
505 }
506 m_knownMissingFebs[bec][ieta].set(iphi);
507 ++nMissing;
508 }//end loop over channels of one feb
509 }//end if is barrel/endcap & EM
510 }//end if is dead
511 }//end loop over problematic febs
512 ATH_MSG_INFO( "Number of known missing strip cells: "<< nMissing );
514 return StatusCode::SUCCESS;
515}
516
517
518XtalkCorrHisto::XtalkCorrHisto(const unsigned nBins, const float upperLimit) :
519 m_nBins(nBins),
520 m_binwidth(upperLimit/nBins),
521 m_diffs(nBins,0)
522{}
523
524void XtalkCorrHisto::add(const LArAccumulatedCalibDigit* dig, const float reldiff) {
525
526 unsigned iBin=(unsigned)(std::fabs(reldiff)/m_binwidth);
527 if (iBin>=m_nBins-1) {
528 iBin=m_nBins-1;
529 m_maxlist.emplace_back(dig->hardwareID(),dig->DAC(),dig->delay(),reldiff);
530 }
531 ++m_diffs[iBin];
532}
533
534void XtalkCorrHisto::print(MsgStream& out, const LArOnlineID* onlId, MSG::Level lvl) {
535
536 const unsigned nBins=m_diffs.size();
537 if (nBins==0) return;
538 out << lvl << "Cross Talk Correction Summary:" << endmsg;
539 for (unsigned i=0;i<nBins-1;++i)
540 out << lvl << " " << i*m_binwidth << " - " << (i+1)*m_binwidth << ":" << m_diffs[i] << " channels" << endmsg;
541
542 out << lvl << " " << (nBins-1)*m_binwidth << " - max" << ":" << m_diffs[nBins-1] << " channels" << endmsg;
543
544 if (!m_maxlist.empty()) {
545 out << lvl << "Data points with the highes correction:" << endmsg;
546 std::vector<maxlistitem>::const_iterator it=m_maxlist.begin();
547 std::vector<maxlistitem>::const_iterator it_e=m_maxlist.end();
548 for(;it!=it_e;++it)
549 out << lvl << " " << onlId->channel_name(it->chid) << " DAC=" << it->dac << " Delay=" << it->delay << " Deviation:" << it->reldiff << endmsg;
550 }
551 }
552
553
554
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define maxValue(current, test)
LArBadXCont< LArBadFeb > LArBadFebCont
LArBadXCont< LArBadChannel > LArBadChannelCont
static Double_t ss
static Double_t sc
int imax(int i, int j)
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
size_type size() const noexcept
Returns the number of elements in the collection.
bool empty() const noexcept
Returns true if the collection is empty.
virtual float pedestal(const HWIdentifier &id, int gain) const =0
value_type get_compact() const
Get the compact id.
Container class for LArAccumulatedCalibDigit.
Data class for calibration ADC samples preprocessed by the DSP.
bool isPulsed() const
Tell if this channel was pulsed.
CaloGain::CaloGain gain() const
return gain value
int delay() const
return the setting of the delay
const HWIdentifier & hardwareID() const
Return HWIdentifier.
const std::vector< uint64_t > & sampleSum() const
return a reference to a stl vector containing the sample-sums
int DAC() const
return the number of samples
unsigned nTriggers() const
return the number of triggers
size_t nsamples() const
return number of samples
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 deadReadout() const
FEB is not sending readout data, but the L1 trigger path is working.
Definition LArBadFeb.h:33
const BadChanVec & fullCont() const
LArBC_t status(const HWIdentifier channel) const
Query the status of a particular channel or FEB This is the main client access method.
Holds information from the FEB Error Summary.
static std::string error_to_string(uint16_t error)
interpret the error in string
uint16_t feb_error(HWIdentifier febid) const
get error for feb
std::string channel_name(const HWIdentifier id) const
Return a string corresponding to a feedthrough name given an identifier.
void correctSamples(std::vector< double > &dest, const neighbour_t &neighbor) const
SG::ReadCondHandleKey< ILArPedestal > m_pedKey
std::set< HWIdentifier > m_uncorrectedIds
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
virtual StatusCode finalize() override final
std::array< std::vector< std::bitset< 128 > >, 2 > m_knownMissingFebs
SG::ReadCondHandleKey< LArBadFebCont > m_BFKey
size_t getEtaIndex(const Identifier) const
SG::ReadCondHandleKey< LArBadChannelCont > m_BCKey
Gaudi::Property< std::vector< std::string > > m_dontUseForCorr
Gaudi::Property< float > m_acceptableDifference
virtual StatusCode execute() override final
static std::string printMaxSample(const LArAccumulatedCalibDigit *thisDig)
size_t getPhiIndex(const Identifier) const
std::array< std::vector< std::vector< const LArAccumulatedCalibDigit * > >, 2 > m_stripsLookUp
Gaudi::Property< std::vector< std::string > > m_keylist
virtual StatusCode initialize() override final
Gaudi::Property< std::vector< std::string > > m_dontCorr
Gaudi::Property< unsigned int > m_ADCsatur
std::string stringStatus(const LArBadChannel &bc) const
void add(const LArAccumulatedCalibDigit *dig, const float reldiff)
std::vector< unsigned > m_diffs
void print(MsgStream &stream, const LArOnlineID *onlId, MSG::Level lvl=MSG::INFO)
std::vector< maxlistitem > m_maxlist
XtalkCorrHisto(const unsigned nBins, const float maxbin)
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
std::pair< HWIdentifier, LArBadFeb > BadFebEntry
std::vector< BadFebEntry > BadFebVec