ATLAS Offline Software
LArRawChannelBuilder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "LArRawChannelBuilder.h"
6 
8 
10 //#include "LArElecCalib/ILArRamp.h"
11 #include "LArElecCalib/ILArOFC.h"
12 #include "LArElecCalib/ILArShape.h"
13 #include "CLHEP/Units/SystemOfUnits.h"
14 #include "StoreGate/StoreGateSvc.h"
15 #include "StoreGate/ReadHandle.h"
17 #include "StoreGate/WriteHandle.h"
18 #include "GaudiKernel/ThreadLocalContext.h"
19 
20 #include <cmath>
21 
22 using CLHEP::MeV;
23 using CLHEP::megahertz;
24 using CLHEP::nanosecond;
25 using CLHEP::picosecond;
26 
27 LArRawChannelBuilder::LArRawChannelBuilder (const std::string& name, ISvcLocator* pSvcLocator):
28  AthAlgorithm(name, pSvcLocator),
29  m_onlineHelper(nullptr),
30  m_Ecut(256*MeV),
31  m_initialTimeSampleShift(0),
32  m_ramp_max(),
33  m_noEnergy(0),
34  m_noTime(0),
35  m_noShape(0),
36  m_noShapeDer(0),
37  m_saturation(0),
38  m_lastNoEnergy(0),
39  m_lastNoTime(0),
40  m_lastNoShape(0),
41  m_lastNoShapeDer(0),
42  m_aveNoEnergy(0),
43  m_aveNoTime(0),
44  m_aveNoShape(0),
45  m_aveNoShapeDer(0),
46  m_aveSaturCells(0),
47  m_nEvents(0),
48  m_aveChannels(0),
49  m_SamplingPeriodeUpperLimit(0),
50  m_SamplingPeriodeLowerLimit(0),
51  m_emId(nullptr),
52  m_firstSample(0)
53  , m_pedestalKey("LArPedestal")
54  , m_shapesKey("LArShape")
55  {
56  //m_useIntercept={false,false,false,false};
57  declareProperty("Ecut", m_Ecut);
58  declareProperty("UseHighGainRampIntercept", m_useIntercept[CaloGain::LARHIGHGAIN]=false);
59  declareProperty("UseMedGainRampIntercept", m_useIntercept[CaloGain::LARMEDIUMGAIN]=false);
60  declareProperty("UseLowGainRampIntercept", m_useIntercept[CaloGain::LARLOWGAIN]=false);
61  declareProperty("InitialTimeSampleShift", m_initialTimeSampleShift);
62  declareProperty("NOFCTimeBins", m_NOFCTimeBins=25); //Number of OFC time bins in a sampling periode
64  declareProperty("NOFCPhases", m_NOFCPhases); //Total number of available OFC sets
65  declareProperty("UseOFCPhase", m_useOFCPhase=false);
66  declareProperty("PhaseInversion", m_phaseInv=false);
67  declareProperty("SamplingPeriod", m_SamplingPeriode=1/(40.08*megahertz));
69  declareProperty("BinHalfOffset", m_binHalfOffset=false);
70  declareProperty("AllowTimeSampleJump", m_allowTimeJump=true);
71  declareProperty("PedestalFallbackMode", m_pedestalFallbackMode=0); // 0=only DB, 1=Only if missing,
72  declareProperty("PedestalSample", m_iPedestal=0); // 2=Low, 3=Low+Me dium, 4=All LAr
73  declareProperty("ShapeMode", m_shapeMode=0);
74  declareProperty("SkipSaturCellsMode", m_skipSaturCells=0);
75  declareProperty("ADCMax", m_AdcMax=4095);
76  declareProperty("firstSample", m_firstSample," first sample used in shape");
77  declareProperty("PedestalKey", m_pedestalKey);
78  declareProperty("ShapesKey", m_shapesKey);
79 }
80 
81 
83 {
84  ATH_CHECK( detStore()->retrieve(m_onlineHelper, "LArOnlineID") );
85 
88 
89  // ***
90 
91  const CaloCell_ID* idHelper = nullptr;
92  ATH_CHECK( detStore()->retrieve (idHelper, "CaloCell_ID") );
93  m_emId=idHelper->em_idHelper();
94  if (!m_emId) {
95  ATH_MSG_ERROR( "Could not get lar EM ID helper" );
96  return StatusCode::FAILURE;
97  }
98 
100 
101 
102  //Set counters for errors and warnings to zero
103  m_noEnergy = 0; // Number of events with at least completly failed channel
104  m_noTime = 0; // Number of events with at least one channel without time info
105  m_noShape = 0; // Number of events with at least one channel without Shape (=with not quality factor);
106  m_noShapeDer = 0; // Number of events with at least one channel without ShapeDerivative (=not taken into accout for quality factor);
107  m_saturation = 0; // Number of events with at least one saturating channel
108 
109  m_lastNoEnergy = -1; // Number of completly failed channels in previous event
110  m_lastNoTime = -1; // Number of channels without time info in previous event
111  m_lastNoShape = -1; // Number of channels without Shape (=with not quality factor) in previous event
112  m_lastNoShapeDer = -1; // Number of channels without ShapeDerivative in previous event
113 
114  //m_lastSaturCells = -1; // Number of saturating channels without in previous event (not used)
115 
116  m_aveNoEnergy = 0.; // Average number of completly failed channels per event
117  m_aveNoTime = 0.; // Average number of channels without time info per event
118  m_aveNoShape = 0.; // Average number of channels without Shape (=with not quality factor) per event
119  m_aveNoShapeDer = 0.; // Average number of channels without ShapeDerivative per event
120  m_aveSaturCells = 0.; // Average number of saturating channels without per event
121 
122  m_nEvents = 0 ; // Total number of processed events ;
123  m_aveChannels = 0 ; // Average number of readout channels per event
124 
125  if ( m_skipSaturCells > 2 ) m_skipSaturCells = 0 ;
126 
130 
131  // Validity range for a set of OFC's. If the time shift is larger than this number,
132  // we make a ADC sample jump (e.g. from [0,5] to [1,6]. The second half of the uppermost
133  // bin should already be rounded to the 0th bin of the following ADC sample.
134  if ( m_binHalfOffset ) {
137  } else {
140  }
141 
142  ATH_MSG_DEBUG( "Number of OFC time bins per sampling periode=" << m_NOFCTimeBins );
143  ATH_MSG_DEBUG( "Sampling Periode=" << m_SamplingPeriode << "ns" );
144  ATH_MSG_DEBUG( "Sampling Periode Limits: (" << m_SamplingPeriodeLowerLimit
145  << "," << m_SamplingPeriodeUpperLimit << ") ns" );
146 
149 
150  return StatusCode::SUCCESS;
151 }
152 
153 
154 
156 {
157  const EventContext& ctx = Gaudi::Hive::currentContext();
158  //Counters for errors & warnings per event
159  int noEnergy = 0; // Number of completly failed channels in a given event
160  int BadTiming = 0; // Number of channels with bad timing in a given event
161  int noTime = 0; // Number of channels without time info in a given event
162  int noShape = 0; // Number of channels without Shape (= with no quality factor) in a given event
163  int noShapeDer = 0; // Number of channels without ShapeDerivative in a given event
164  int highE = 0; // Number of channels with 'high' (above threshold) energy in a given event
165  int saturation = 0; // Number of saturating channels in a given event
166 
167  //Pointer to conditions data objects
168  const ILArPedestal* larPedestal=nullptr;
169  const ILArShape* larShape=nullptr;
170  //Retrieve Digit Container
171 
173  const LArOnOffIdMapping* cabling{*cablingHdl};
174  if(!cabling) {
175  ATH_MSG_ERROR( "Do not have cabling mapping from key " << m_cablingKey.key() );
176  return StatusCode::FAILURE;
177  }
178 
180 
181  //Pointer to input data container
183 
184  //Retrieve calibration data
185  ATH_CHECK( detStore()->retrieve(larPedestal,m_pedestalKey) );
186  ATH_CHECK( detStore()->retrieve(larShape,m_shapesKey) );
187 
188  ATH_MSG_DEBUG( "Retrieving LArOFC object" );
190 
191  auto larRawChannelContainer = std::make_unique<LArRawChannelContainer>();
192  larRawChannelContainer->reserve(digitContainer->size());
193 
194  // Average number of LArDigits per event
195  m_nEvents++;
196  m_aveChannels += digitContainer->size();
197 
198  // Now all data is available, start loop over Digit Container
199  int ntot_raw=0;
200 
201  for (const LArDigit* digit : *digitContainer) {
202 
203  //Data that goes into RawChannel:
204  float energy=0;
205  float time=0;
206  float quality=0;
207 
208  int OFCTimeBin=0;
209  int timeSampleShift=m_initialTimeSampleShift;
210 
211  //Get data from LArDigit
212  const std::vector<short>& samples=digit->samples();
213  const unsigned nSamples=samples.size();
214  const HWIdentifier chid=digit->channelID();
215  const CaloGain::CaloGain gain=digit->gain();
216 
217  // to be used in case of DEBUG output
218  int layer = -99999 ;
219  int eta = -99999 ;
220  int phi = -99999 ;
221  int region = -99999 ;
222  if (msgLvl (MSG::DEBUG)) {
223  Identifier id ;
224  try {
225  id = cabling->cnvToIdentifier(chid);
226  } catch ( LArID_Exception & except ) {
227  ATH_MSG_DEBUG( "A Cabling exception was caught for channel 0x!"
228  << MSG::hex << chid.get_compact() << MSG::dec );
229  continue ;
230  }
231  layer = m_emId->sampling(id);
232  eta = m_emId->eta(id);
233  phi = m_emId->phi(id);
234  region = m_emId->region(id);
235  //log << MSG::VERBOSE << "Channex 0x" << MSG::hex << chid.get_compact() << MSG::dec
236  // << " [ Layer = " << layer << " - Eta = " << eta
237  // << " - Phi = " << phi << " - Region = " << region << " ] " << endmsg ;
238  }
239 
240  // check for saturation, in case skip channel
241  int nSatur=-1 ;
242  for (unsigned iSample=0;iSample<samples.size();iSample++) {
243  if (samples[iSample]>=m_AdcMax) {
244  nSatur++;
245  break ;
246  }
247  }
248  if ( nSatur>-1 ) {
249  if (msgLvl (MSG::DEBUG))msg() << MSG::DEBUG << "Saturation on channel 0x" << MSG::hex << chid.get_compact() << MSG::dec ;
250  saturation++;
251  }
252  if ( m_skipSaturCells && nSatur>-1 ) {
253  msg() << ". Skipping channel." << endmsg;
254  continue; // Ignore this cell, saturation on at least one sample
255  } else if ( nSatur>-1 ) {
256  msg() << "." << endmsg;
257  }
258 
259  //Get conditions data for this channel:
260 
261  // Pedestal
262  float pedestal=larPedestal->pedestal(chid,gain);
263  float pedestalAverage;
264  if (pedestal <= (1.0+LArElecCalib::ERRORCODE)) {
265  if( m_pedestalFallbackMode >= 1 ) {
266  ATH_MSG_DEBUG( "No pedestal found for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
267  << " Gain " << gain <<". Using time sample " << m_iPedestal );
268  pedestalAverage=samples[m_iPedestal];
269  } else {
270  ATH_MSG_DEBUG( noEnergy << ". No pedestal found for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
271  << " [ Layer = " << layer << " - Eta = " << eta << " - Phi = " << phi << " - Region = " << region << " ]"
272  << " Gain = " << gain << ". Skipping channel." );
273  noEnergy++;
274  continue;
275  }
276  } else {
280  ATH_MSG_DEBUG( "Forcing pedestal fallback for channel 0x" << MSG::hex << chid.get_compact()
281  << MSG::dec << " Gain=" << gain << ". Using time sample " << m_iPedestal );
282  pedestalAverage=samples[m_iPedestal];
283  } else {
284  //Assume there is only one pedestal value, even the ILArPedestal object returns a vector<float>
285  pedestalAverage=pedestal;
286  }
287  }
288 
289  // Optimal Filtering Coefficients
290  ILArOFC::OFCRef_t ofc_a;
291  ILArOFC::OFCRef_t ofc_b;
292  {// get OFC from Conditions Store
293  double timeShift=0;
294  if (m_useOFCPhase) {
295  const double ofcTimeOffset=larOFC->timeOffset(chid,gain);
296  timeShift+=ofcTimeOffset;
297  if (msgLvl (MSG::VERBOSE)) msg() << MSG::VERBOSE << " OFC=" << ofcTimeOffset;
298  }
299 
300  if (msgLvl (MSG::VERBOSE)) msg() << MSG::VERBOSE << " Total=" << timeShift << endmsg;
301 
302  if (m_allowTimeJump && timeShift >= m_NOFCPhases*m_OFCTimeBin ) {
303  if (msgLvl (MSG::VERBOSE)) msg() << MSG::VERBOSE << "Time Sample jump: +1" << endmsg;
304  timeSampleShift += 1;
305  //timeShift -= m_NOFCTimeBins*m_OFCTimeBin ;
306  timeShift -= m_SamplingPeriode ;
307  }
308  else if (m_allowTimeJump && timeShift < 0 ) {
309  ATH_MSG_VERBOSE( "Time Sample jump: -1" );
310  timeSampleShift -= 1;
311  //timeShift += m_NOFCTimeBins*m_OFCTimeBin ;
312  timeShift += m_SamplingPeriode ;
313  }
314 
315  if (m_allowTimeJump && ( timeShift > m_NOFCPhases*m_OFCTimeBin || timeShift < 0 ) ) {
316  BadTiming++;
317  noEnergy++;
318  ATH_MSG_ERROR( noEnergy << ". Time offset out of range for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
319  << " Found " << timeShift << ", expected ( 0 - " << m_NOFCPhases*m_OFCTimeBin << ") ns. Skipping channel." );
320  continue;
321  }
322 
323  if (m_allowTimeJump && timeSampleShift < 0) {
324  BadTiming++;
325  noEnergy++;
326  ATH_MSG_ERROR( noEnergy << ". Negative time sample (" << timeSampleShift << ") shift for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
327  << " Found. Skipping channel." );
328  continue;
329  }
330 
331  OFCTimeBin = (int) ( timeShift / m_OFCTimeBin );
332 
333  if ( !m_phaseInv ) // if not done with PhaseTime at the beginning, invert time bin for OFC bin selection
334  OFCTimeBin = ( m_NOFCTimeBins - 1 ) - OFCTimeBin;
335  // do not use the following: 24<PhaseTime<25 you always get OFCTimeBin = -1!
336  //else
337  // OFCTimeBin -= 1 ;
338 
339  ATH_MSG_VERBOSE( "OFC bin width = " << m_OFCTimeBin << " - OFCBin = " << OFCTimeBin << " - timeShift = " << timeShift );
340 
341  if ( OFCTimeBin < 0 ) {
342  ATH_MSG_ERROR( "Channel " << MSG::hex << chid.get_compact() << MSG::dec << " asks for OFC bin = " << OFCTimeBin << ". Set to 0." );
343  OFCTimeBin=0;
344  } else if ( OFCTimeBin >= m_NOFCPhases ) {
345  ATH_MSG_ERROR( "Channel " << MSG::hex << chid.get_compact() << MSG::dec << " asks for OFC bin = " << OFCTimeBin << ". Set to (NOFCPhases-1) =" << m_NOFCTimeBins-1 );
346  OFCTimeBin = m_NOFCPhases-1;
347  }
348 
349  ofc_a=larOFC->OFC_a(chid,gain,OFCTimeBin);
350  //ofc_b=&(larOFC->OFC_b(chid,gain,OFCTimeBin)); retrieve only when needed
351  }
352 
353  //Check if we have OFC for this channel and time bin
354  if (ofc_a.size()==0) {
355  noEnergy++;
356  ATH_MSG_DEBUG( noEnergy << ". No OFC's found for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
357  << " [ Layer = " << layer << " - Eta = " << eta << " - Phi = " << phi << " - Region = " << region << " ]"
358  << " Time bin = " << OFCTimeBin << ", Gain = " << gain << ". Skipping channel." );
359  continue;
360  }
361  if (ofc_a.size()+timeSampleShift>nSamples) {
362  BadTiming++;
363  noEnergy++;
364  if (msgLvl (MSG::DEBUG)) {
365  if (timeSampleShift==0)
366  ATH_MSG_DEBUG( "Found LArDigit with " << nSamples << " samples, but OFCs for "
367  << ofc_a.size() << " samples. Skipping Channel " );
368  else //have time sample shift
369  ATH_MSG_DEBUG( "After time sample shift of " << timeSampleShift << ", " << nSamples-timeSampleShift
370  << " samples left, but have OFCs for " << ofc_a.size() << " samples. Skipping Channel " );
371  }
372  continue;
373  }
374 
375  //Now apply Optimal Filtering to get ADC peak
376  float ADCPeak=0;
377  for (unsigned i=0;i<(ofc_a.size());i++)
378  ADCPeak+=(samples[i+timeSampleShift]-pedestalAverage)*ofc_a.at(i);
379 
380  ATH_MSG_VERBOSE( "ADC Height calculated " << ADCPeak << " TimeBin=" << OFCTimeBin );
381 
382  //ADC2MeV (a.k.a. Ramp)
383  LArVectorProxy ramp = adc2mev->ADC2MEV(chid,gain);
384  //Check ramp coefficents
385  if (ramp.size()==0) {
386  noEnergy++;
387  ATH_MSG_DEBUG( noEnergy << ". No ADC2MeV data found for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
388  << " [ Layer = " << layer << " - Eta = " << eta << " - Phi = " << phi << " - Region = " << region << " ]"
389  << " Gain = " << gain << ". Skipping channel." );
390  continue;
391  }
392 
393  // temporary fix for bad ramps... should be done in the DB
394  // if(ramp[1]>500 || ramp[1]<0) {
395 
396  if(ramp[1]>m_ramp_max[gain] || ramp[1]<0) {
397  noEnergy++;
398  ATH_MSG_DEBUG( "Bad ramp for channel " << chid << " (ramp[1] = " << ramp[1] << "): skip this channel" );
399  continue;
400  }
401 
402  float ADCPeakPower=ADCPeak;
403 
404  if (m_useIntercept[gain])
405  energy=ramp[0];
406  //otherwise ignore intercept, E=0;
407  for (unsigned i=1;i<ramp.size();i++)
408  {energy+=ramp[i]*ADCPeakPower; //pow(ADCPeak,i);
409  //std::cout << "Step "<< i <<":" << ramp[i] << " * " << pow(ADCPeak,i) << "Sum=" << energy << std::endl;
410  ADCPeakPower*=ADCPeak;
411  }
412 
413  //Check if energy is above threshold for time & quality calculation
414  if (energy>m_Ecut) {
415  highE++;
416  ofc_b=larOFC->OFC_b(chid,gain,OFCTimeBin);
417  if (ofc_b.size() != ofc_a.size()) {//don't have proper number of coefficients
418  if (msgLvl (MSG::DEBUG)) {
419  if (ofc_b.size()==0)
420  ATH_MSG_DEBUG( "No time-OFC's found for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
421  << " Gain "<< gain << " found. Time not calculated." );
422  else
423  ATH_MSG_DEBUG( "OFC for time size " << ofc_b.size()
424  << " not equal to OFC for energy size " << ofc_a.size()
425  << " Time not calculated " );
426  }
427  noTime++;
428  }else{
429  for (unsigned i=0;i<(ofc_b.size());i++)
430  time+=(samples[i+timeSampleShift]-pedestalAverage)*ofc_b.at(i);
431  time/=ADCPeak;
432  // !! Time is now in ns with respect to calibration pulse shape
433  // Used to calculate quality factor
434  }
435  ATH_MSG_VERBOSE( "Time calculated " << time << " TimeBin=" << OFCTimeBin );
436 
437  //Calculate Quality factor
438  if (larShape) { //Have shape object
439  //Get Shape & Shape Derivative for this channel
440 
441  //const std::vector<float>& shape=larShape->Shape(chid,gain,OFCTimeBin);
442  //const std::vector<float>& shapeDer=larShape->ShapeDer(chid,gain,OFCTimeBin);
443  // ###
444  ILArShape::ShapeRef_t shape=larShape->Shape(chid,gain,OFCTimeBin,m_shapeMode);
445  ILArShape::ShapeRef_t shapeDer=larShape->ShapeDer(chid,gain,OFCTimeBin,m_shapeMode);
446  // ###
447  // fixing HEC to move +1 in case of 4 samples and firstSample 0
448  int ihecshift=0;
449  if(nSamples == 4 && m_firstSample == 0 ){
450  Identifier id ;
451  try {
452  id = cabling->cnvToIdentifier(chid);
453  if(m_emId->is_lar_hec(id)) {
454  ihecshift=1;
455  ATH_MSG_DEBUG( "Setting firstSample to 1 for HEC channel "<< chid.get_compact() );
456  }
457  } catch ( LArID_Exception & except ) {
458  ATH_MSG_DEBUG( "A Cabling exception was caught for channel 0x!"
459  << MSG::hex << chid.get_compact() << MSG::dec );
460  }
461  }
462 
463  //Check Shape
464  if ((shape.size()+m_firstSample+ihecshift) < ofc_a.size()) {
465  if (msgLvl (MSG::DEBUG)) {
466  if (shape.size()==0)
467  ATH_MSG_DEBUG( "No Shape found for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
468  << " Gain "<< gain << ". Quality factor not calculated." );
469  else
470  ATH_MSG_DEBUG( "Shape size " << shape.size()
471  << "smaller than OFC size " << ofc_a.size()
472  << "for channel 0x" << MSG::hex << chid.get_compact()
473  << MSG::dec << ". Quality factor not calculated." );
474  }
475  quality=0; //Can't calculate chi^2, assume good hit.
476  noShape++;
477  }
478  else {//Shape ok
479  if (time!=0 && shapeDer.size()!=shape.size()) {
480  //Send warning
481  ATH_MSG_DEBUG( "Shape-Derivative has different size than Shape for channel 0x" << MSG::hex << chid.get_compact() << MSG::dec
482  << ". Derivative not taken into accout for quality factor." );
483  noShapeDer++;
484  }//end-if
485  if (time==0 || shapeDer.size()!=shape.size() ) { //Calculate Q without time info
486  for (unsigned i=0;i<(ofc_a.size());i++)
487  quality+=((samples[i+timeSampleShift]-pedestalAverage)-shape[i+m_firstSample+ihecshift]*ADCPeak)*
488  ((samples[i+timeSampleShift]-pedestalAverage)-shape[i+m_firstSample+ihecshift]*ADCPeak);
489  }
490  else { //All input data ok, calculate Q with time info
491  for (unsigned i=0;i<(ofc_a.size());i++)
492  quality+=((samples[i+timeSampleShift]-pedestalAverage)-((shape[i+m_firstSample+ihecshift]-shapeDer[i+m_firstSample+ihecshift]*time)*ADCPeak))*
493  ((samples[i+timeSampleShift]-pedestalAverage)-((shape[i+m_firstSample+ihecshift]-shapeDer[i+m_firstSample+ihecshift]*time)*ADCPeak));
494  }
495  } // end else (Shape ok)
496 
497  } //end if larShape
498  else { //No Shape found at all
499  quality=0; //Can't calculate chi^2, assume good hit.
500  noShape++;
501  }
502  }// end-if energy>Ecut
503  else
504  quality=-1; //in case E<Ecut
505  //time*=1000.0;
506  time=time*(nanosecond/picosecond); //Convert time to ps
507  //Make LArRawChannel Object with new data
508 
509  uint16_t iqual=0;
510  uint16_t iprov=0xA5;
511  if (quality>=0) {
512  iqual = ( (int)(quality) ) & 0xFFFF;
513  iprov = iprov | 0x2000;
514  }
515 
516  LArRawChannel larRawChannel(chid,(int)energy,(int)time,iqual,iprov, gain);
517  larRawChannelContainer->push_back(larRawChannel); //Add to container
518  ntot_raw++;
519  ATH_MSG_VERBOSE( "Got LArRawChannel #" << ntot_raw << ", chid=0x" << MSG::hex << chid.get_compact() << MSG::dec
520  << " e=" << energy << " t=" << time << " Q=" << quality );
521  } // End loop over LArDigits
522 
523  ATH_MSG_DEBUG( ntot_raw << " channels successfully processed, (" << highE << " with high energy)" );
524 
525  // deal with bad timing
526  if(BadTiming>=128){
527  ATH_MSG_ERROR( "Too many channels (" <<BadTiming<< " !) have a bad timing !!" );
528  ATH_MSG_ERROR( "OFC time constants should be revisited !!!" );
529  ATH_MSG_ERROR( "Event is skipped" );
530  larRawChannelContainer->clear();
531  //return StatusCode::SUCCESS;
532  }
533 
534  // in case of at least one saturating cell, skip all event (if selected)
535  if ( saturation && m_skipSaturCells == 2 ) {
536  ATH_MSG_ERROR( saturation << " saturating channels were found. Event is skipped." );
537  larRawChannelContainer->clear();
538  }
539 
540  //Put this LArRawChannel container in the transient store
541  //sc = evtStore()->record(m_larRawChannelContainer, m_ChannelContainerName);
542  //if(sc.isFailure()) {
543  // log << MSG::ERROR << "Can't record LArRawChannelContainer in StoreGate" << endmsg;
544  //}
545  //else
546  // std::cout << "Successfully recorded LArRawChannelContainer to StoreGate" << std::endl;
547 
548  /*
549 
550  Error & Warning summary *per event*
551 
552  Strategy: 'No Energy' is an ERROR, no time or no quality is a WARNING
553 
554  Missing calibration constants are most likly missing for an entire run, threfore:
555  In DEBUG: Print summary for each event if something is missing
556  otherwise: Print summary only for new problems (different number of missing channels)
557 
558  Saturatin cells summary is shown in any case, WARNING if not skipped, ERROR if skipped
559 
560  */
561 
562  if (noEnergy) m_noEnergy++;
563  if (noTime) m_noTime++;
564  if (noShape) m_noShape++;
565  if (noShapeDer) m_noShapeDer++;
566  if (saturation) m_saturation++;
567 
568  m_aveNoEnergy += noEnergy;
569  m_aveNoTime += noTime;
570  m_aveNoShape += noShape;
571  m_aveNoShapeDer += noShapeDer;
572  m_aveSaturCells += saturation;
573 
574  if ( ( noEnergy!=m_lastNoEnergy
575  || noTime!=m_lastNoTime
576  || noShape>m_lastNoShape
577  || noShapeDer>m_lastNoShapeDer
578  || saturation>0 )
579  || ( msgSvc()->outputLevel(name()) <= MSG::DEBUG && ( noEnergy || noTime || noShape || noShapeDer || saturation ) )
580  ) {
581 
582  m_lastNoEnergy = noEnergy;
583  m_lastNoTime = noTime;
584  if (noShape>m_lastNoShape) m_lastNoShape=noShape;
585  if (noShapeDer>m_lastNoShapeDer) m_lastNoShapeDer=noShapeDer;
586  //m_lastSaturCells = saturation ;
587 
588  MSG::Level msglvl;
589  if (noEnergy)
590  msglvl=MSG::ERROR;
591  else if (noTime || noShape || noShapeDer || saturation)
592  msglvl=MSG::WARNING;
593  else
594  msglvl=MSG::INFO;
595 
596  msg() << msglvl << " *** Error & Warning summary for this event *** " << std::endl;
597 
598  if ( noEnergy ) {
599  msg() << msglvl << " " << noEnergy << " out of "
600  << digitContainer->size() << " channel(s) skipped due to a lack of basic calibration constants."
601  << std::endl;
602  }
603  if ( noTime ) {
604  msg() << msglvl << " " << noTime << " out of "
605  << highE << " high-enegy channel(s) have no time-info due to a lack of Optimal Filtering Coefficients."
606  << std::endl;
607  }
608  if ( noShape ) {
609  msg() << msglvl << " " << noShape << " out of "
610  << highE << " high-enegy channel(s) have no quality factor due to a lack of shape."
611  << std::endl;
612  }
613  if ( noShapeDer ) {
614  msg() << msglvl << " " << noShapeDer << " out of "
615  << highE << " high-enegy channel(s) lack the derivative of the shape. Not taken into accout for Quality factor."
616  << std::endl;
617  }
618  if ( saturation ) {
619  if ( m_skipSaturCells == 2 )
620  msg() << MSG::ERROR << " " << saturation << " out of "
621  << digitContainer->size() << " channel(s) showed saturations. The complete event was skipped." << std::endl;
622  else if ( m_skipSaturCells == 1 )
623  msg() << MSG::ERROR << " " << saturation << " out of "
624  << digitContainer->size() << " channel(s) showed saturations and were skipped." << std::endl;
625  else
626  msg() << MSG::WARNING << " " << saturation << " out of "
627  << digitContainer->size() << " channel(s) showed saturations." << std::endl;
628  }
629  msg() << endmsg;
630  }
631 
632  ATH_CHECK( SG::makeHandle(m_ChannelContainerName, ctx).record (std::move (larRawChannelContainer)) );
633 
634  return StatusCode::SUCCESS;
635 }
636 
638 {
639 
641  else m_aveNoEnergy=0;
642  if (m_noTime>0) m_aveNoTime /= m_noTime;
643  else m_aveNoTime=0;
644  if (m_noShape>0) m_aveNoShape /= m_noShape;
645  else m_aveNoShape=0;
647  else m_aveNoShapeDer=0;
649  else m_aveSaturCells=0;
650 
652  else m_aveChannels =0;
653 
654  // Error and Warning Summary for this job:
655 
656  ATH_MSG_DEBUG( " LArRawChannelBuilder::finalize "
657  << m_noEnergy << " " << m_noTime << " " << m_noShape << " " << m_noShapeDer << " " << m_saturation );
658 
660  MSG::Level msglvl;
661  if ( m_noEnergy || m_skipSaturCells )
662  msglvl=MSG::ERROR;
663  else
664  msglvl=MSG::WARNING;
665  msg() << msglvl << " *** Error & Warning Summary for all events *** " << std::endl ;
666 
667  if (m_noEnergy)
668  msg() << msglvl << " " << m_noEnergy << " events had on average " << (int)std::round(m_aveNoEnergy)
669  << " channels out of " << (int)std::round(m_aveChannels) << " without basic calibration constants."
670  << std::endl;
671 
672  if (m_noTime)
673  msg() << msglvl << " " << m_noTime << " events had on average " << (int)std::round(m_aveNoTime)
674  << " channels out of " << (int)std::round(m_aveChannels) << " without OFCs for timing."
675  << std::endl ;
676 
677  if (m_noShape)
678  msg() << msglvl << " " << m_noShape << " events had on average " << (int)std::round(m_aveNoShape)
679  << " channels out of " << (int)std::round(m_aveChannels) << " without shape information."
680  << std::endl;
681 
682  if (m_noShapeDer)
683  msg() << msglvl << " " << m_noShapeDer << " events had on average " << (int)std::round(m_aveNoShapeDer)
684  << " channels out of " << (int)std::round(m_aveChannels) << " without shape derivative."
685  << std::endl;
686 
687  if ( m_saturation )
688  msg() << msglvl << " " << m_saturation << " events had on average " << (int)std::round(m_aveSaturCells)
689  << " out of " << (int)std::round(m_aveChannels) << " saturating channels."
690  << std::endl ;
691 
692  msg() << endmsg;
693  }
694  else
695  ATH_MSG_INFO( "LArRawChannelBuilder finished without errors or warnings." );
696 
697  //if (m_larRawChannelContainer) {
698  //m_larRawChannelContainer->release();
699  //m_larRawChannelContainer = 0;
700  //}
701 
702  return StatusCode::SUCCESS;
703 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
LArRawChannelBuilder::m_initialTimeSampleShift
int m_initialTimeSampleShift
Definition: LArRawChannelBuilder.h:57
LArRawChannelBuilder::m_lastNoEnergy
int m_lastNoEnergy
Definition: LArRawChannelBuilder.h:84
ILArPedestal::pedestal
virtual float pedestal(const HWIdentifier &id, int gain) const =0
LArEM_Base_ID::phi
int phi(const Identifier id) const
return phi according to :
LArADC2MeV::ADC2MEV
const LArVectorProxy ADC2MEV(const HWIdentifier &id, int gain) const
Definition: LArADC2MeV.h:32
LArRawChannelBuilder::m_aveNoTime
float m_aveNoTime
Definition: LArRawChannelBuilder.h:91
LArRawChannelBuilder::m_noShape
int m_noShape
Definition: LArRawChannelBuilder.h:79
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
python.SystemOfUnits.nanosecond
int nanosecond
Definition: SystemOfUnits.py:119
CaloCell_ID::em_idHelper
const LArEM_ID * em_idHelper() const
access to EM idHelper
Definition: CaloCell_ID.h:63
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
LArRawChannelBuilder::m_noTime
int m_noTime
Definition: LArRawChannelBuilder.h:78
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
ILArPedestal
Definition: ILArPedestal.h:12
LArRawChannelBuilder::m_adc2mevKey
SG::ReadCondHandleKey< LArADC2MeV > m_adc2mevKey
Definition: LArRawChannelBuilder.h:109
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
ILArOFC::OFC_b
virtual OFCRef_t OFC_b(const HWIdentifier &id, int gain, int tbin=0) const =0
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
LArRawChannelBuilder::m_cablingKey
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
Definition: LArRawChannelBuilder.h:107
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
LArRawChannelBuilder::m_SamplingPeriodeLowerLimit
double m_SamplingPeriodeLowerLimit
Definition: LArRawChannelBuilder.h:100
ILArShape::ShapeDer
virtual ShapeRef_t ShapeDer(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
LArRawChannelBuilder::m_lastNoShape
int m_lastNoShape
Definition: LArRawChannelBuilder.h:86
AthCommonMsg< Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
LArEM_Base_ID::region
int region(const Identifier id) const
return region according to :
LArEM_Base_ID::sampling
int sampling(const Identifier id) const
return sampling according to :
LArRawChannelBuilder::m_iPedestal
unsigned int m_iPedestal
Definition: LArRawChannelBuilder.h:70
LArRawChannelBuilder::m_aveNoShapeDer
float m_aveNoShapeDer
Definition: LArRawChannelBuilder.h:93
ILArOFC.h
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
checkRpcDigits.digit
digit
Definition: checkRpcDigits.py:186
LArRawChannelBuilder::m_shapeMode
unsigned int m_shapeMode
Definition: LArRawChannelBuilder.h:71
HWIdentifier
Definition: HWIdentifier.h:13
LArRawChannelBuilder::m_skipSaturCells
unsigned m_skipSaturCells
Definition: LArRawChannelBuilder.h:73
ReadCondHandle.h
LArEM_Base_ID::eta
int eta(const Identifier id) const
return eta according to :
AthCommonDataStore< AthCommonMsg< Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
LArRawChannelBuilder::m_SamplingPeriode
double m_SamplingPeriode
Definition: LArRawChannelBuilder.h:65
WriteHandle.h
Handle class for recording to StoreGate.
python.SystemOfUnits.megahertz
int megahertz
Definition: SystemOfUnits.py:127
LArRawChannelBuilder::m_aveChannels
float m_aveChannels
Definition: LArRawChannelBuilder.h:97
LArRawChannelBuilder::m_aveNoEnergy
float m_aveNoEnergy
Definition: LArRawChannelBuilder.h:90
ILArOFC::timeOffset
virtual float timeOffset(const HWIdentifier &CellID, int gain) const =0
LArRawChannelBuilder::m_ChannelContainerName
SG::WriteHandleKey< LArRawChannelContainer > m_ChannelContainerName
Definition: LArRawChannelBuilder.h:55
TrigConf::MSGTC::Level
Level
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:21
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
LArRawChannelBuilder.h
LArRawChannelBuilder::m_ramp_max
float m_ramp_max[3]
Definition: LArRawChannelBuilder.h:63
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
LArVectorProxy::at
value_type at(size_t i) const
Vector indexing with bounds check.
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
LArRawChannelBuilder::m_useOFCPhase
bool m_useOFCPhase
Definition: LArRawChannelBuilder.h:61
LArDigit
Liquid Argon digit base class.
Definition: LArDigit.h:25
lumiFormat.i
int i
Definition: lumiFormat.py:92
LArRawChannel
Liquid Argon ROD output object base class.
Definition: LArRawChannel.h:40
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
01SubmitToGrid.samples
samples
Definition: 01SubmitToGrid.py:58
LArRawChannelBuilder::m_shapesKey
std::string m_shapesKey
Definition: LArRawChannelBuilder.h:113
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
LArRawChannelBuilder::m_pedestalKey
std::string m_pedestalKey
Definition: LArRawChannelBuilder.h:112
LArRawChannelBuilder::m_aveSaturCells
float m_aveSaturCells
Definition: LArRawChannelBuilder.h:94
LArRawChannelBuilder::m_NOFCPhases
int m_NOFCPhases
Definition: LArRawChannelBuilder.h:58
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
AtlasDetectorID::is_lar_hec
bool is_lar_hec(Identifier id) const
Definition: AtlasDetectorID.h:829
CaloCell_ID
Helper class for offline cell identifiers.
Definition: CaloCell_ID.h:34
LArRawChannelBuilder::finalize
virtual StatusCode finalize() override
Definition: LArRawChannelBuilder.cxx:637
LArRawChannelBuilder::m_saturation
int m_saturation
Definition: LArRawChannelBuilder.h:81
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
LArRawChannelBuilder::m_SamplingPeriodeUpperLimit
double m_SamplingPeriodeUpperLimit
Definition: LArRawChannelBuilder.h:100
LArRawChannelBuilder::m_firstSample
int m_firstSample
Definition: LArRawChannelBuilder.h:111
AthAlgorithm
Definition: AthAlgorithm.h:47
LArRawChannelBuilder::m_useIntercept
bool m_useIntercept[4]
Definition: LArRawChannelBuilder.h:60
LArRawChannelBuilder::m_pedestalFallbackMode
int m_pedestalFallbackMode
Definition: LArRawChannelBuilder.h:69
LArRawChannelBuilder::m_OFCTimeBin
float m_OFCTimeBin
Definition: LArRawChannelBuilder.h:66
ILArShape.h
LArRawChannelBuilder::m_nEvents
int m_nEvents
Definition: LArRawChannelBuilder.h:96
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:194
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
LArRawChannelBuilder::m_aveNoShape
float m_aveNoShape
Definition: LArRawChannelBuilder.h:92
LArRawChannelBuilder::m_onlineHelper
const LArOnlineID * m_onlineHelper
Definition: LArRawChannelBuilder.h:47
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
CaloGain::LARHIGHGAIN
@ LARHIGHGAIN
Definition: CaloGain.h:18
LArDigitContainer.h
LArRawChannelBuilder::m_Ecut
float m_Ecut
Definition: LArRawChannelBuilder.h:56
CaloGain::CaloGain
CaloGain
Definition: CaloGain.h:11
LArRawChannelBuilder::execute
virtual StatusCode execute() override
Definition: LArRawChannelBuilder.cxx:155
python.TrigPSCPythonDbSetup.outputLevel
outputLevel
Definition: TrigPSCPythonDbSetup.py:30
CaloGain::LARMEDIUMGAIN
@ LARMEDIUMGAIN
Definition: CaloGain.h:18
LArRawChannelBuilder::m_dataLocation
SG::ReadHandleKey< LArDigitContainer > m_dataLocation
Definition: LArRawChannelBuilder.h:53
Identifier::get_compact
value_type get_compact(void) const
Get the compact id.
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
LArRawChannelBuilder::m_allowTimeJump
bool m_allowTimeJump
Definition: LArRawChannelBuilder.h:68
ILArPedestal.h
LArRawChannelBuilder::m_AdcMax
short m_AdcMax
Definition: LArRawChannelBuilder.h:74
LArRawChannelBuilder::m_binHalfOffset
bool m_binHalfOffset
Definition: LArRawChannelBuilder.h:67
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg< Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
LArRawChannelBuilder::initialize
virtual StatusCode initialize() override
Definition: LArRawChannelBuilder.cxx:82
LArRawChannelBuilder::m_NOFCTimeBins
int m_NOFCTimeBins
Definition: LArRawChannelBuilder.h:59
ILArOFC::OFC_a
virtual OFCRef_t OFC_a(const HWIdentifier &id, int gain, int tbin=0) const =0
access to OFCs by online ID, gain, and tbin (!=0 for testbeam)
LArRawChannelBuilder::m_phaseInv
bool m_phaseInv
Definition: LArRawChannelBuilder.h:62
LArElecCalib::ERRORCODE
@ ERRORCODE
Definition: LArCalibErrorCode.h:17
LArDigits2NtupleDumper.nSamples
nSamples
Definition: LArDigits2NtupleDumper.py:70
LArRawChannelBuilder::m_lastNoTime
int m_lastNoTime
Definition: LArRawChannelBuilder.h:85
LArRawChannelBuilder::m_ofcKey
SG::ReadCondHandleKey< ILArOFC > m_ofcKey
Property: OFC coefficients (conditions input).
Definition: LArRawChannelBuilder.h:117
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
ReadHandle.h
Handle class for reading from StoreGate.
CaloGain::LARLOWGAIN
@ LARLOWGAIN
Definition: CaloGain.h:18
LArRawChannelBuilder::m_emId
const LArEM_ID * m_emId
Definition: LArRawChannelBuilder.h:106
ILArShape
Definition: ILArShape.h:13
StoreGateSvc.h
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
LArRawChannelBuilder::LArRawChannelBuilder
LArRawChannelBuilder(const std::string &name, ISvcLocator *pSvcLocator)
Definition: LArRawChannelBuilder.cxx:27
LArRawChannelBuilder::m_noShapeDer
int m_noShapeDer
Definition: LArRawChannelBuilder.h:80
LArID_Exception
Exception class for LAr Identifiers.
Definition: LArID_Exception.h:20
python.SystemOfUnits.picosecond
int picosecond
Definition: SystemOfUnits.py:123
LArRawChannelBuilder::m_noEnergy
int m_noEnergy
Definition: LArRawChannelBuilder.h:77
LArVectorProxy
Proxy for accessing a range of float values like a vector.
Definition: LArVectorProxy.h:38
LArOnOffIdMapping
Definition: LArOnOffIdMapping.h:20
ILArShape::Shape
virtual ShapeRef_t Shape(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
LArRawChannelBuilder::m_lastNoShapeDer
int m_lastNoShapeDer
Definition: LArRawChannelBuilder.h:87