182{
183 const EventContext& ctx = Gaudi::Hive::currentContext();
184
185
186 int noEnergy = 0;
187 int BadTiming = 0;
188 int noTime = 0;
189 int noShape = 0;
190 int noShapeDer = 0;
191 int highE = 0;
192 int saturation = 0;
193
194 const ILArHVScaleCorr *oflHVCorr=nullptr;
197 oflHVCorr = *oflHVCorrHdl;
198 if(!oflHVCorr) {
200 return StatusCode::FAILURE;
201 }
202 }
203 SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{
m_cablingKey, ctx};
204 const LArOnOffIdMapping*
cabling{*cablingHdl};
205 if(!cabling) {
207 return StatusCode::FAILURE;
208 }
209
210
211 const LArDigitContainer* digitContainer=NULL;
212
213 float PhaseTime=0;
214 float globalTimeOffset=0;
215
216 const ILArFEBTimeOffset* larFebTimeOffset=NULL;
217 const ILArShape* larShape=NULL;
218
219
221
222
223 const ILArPedestal* larPedestal=nullptr;
225
229 if (
sc.isFailure()) {
230 ATH_MSG_WARNING (
"Can't retrieve LArShape from Conditions Store" << std::endl
231 << "Quality factor will not be caluclated." );
232 larShape=NULL;
233 }
234 }
235
237 SG::ReadCondHandle<ILArOFC> larOFC (
m_ofcKey, ctx);
238
239 const LArADC2MeV* adc2mev = nullptr;
241 SG::ReadCondHandle<LArADC2MeV> adc2mevH (
m_adc2mevKey, ctx);
242 adc2mev = *adc2mevH;
243 }
244
245
247 const TBPhase* theTBPhase = nullptr;
248 const ILArGlobalTimeOffset* larGlobalTimeOffset = nullptr;
250
252
255
256
257
259 if (
sc.isSuccess()) globalTimeOffset = larGlobalTimeOffset->
TimeOffset();
260
261
263 if (
sc.isFailure()) larFebTimeOffset=NULL;
264 }
265
266
268 larRawChannelContainer->reserve(digitContainer->
size());
271 ATH_MSG_ERROR (
"Can't record LArRawChannelContainer in StoreGate" );
272 }
273
274
277
280
281
282 int ntot_raw=0;
283
284 for (const LArDigit* digit : *(digitContainer)) {
285
286
289 float quality=0;
290
291 int OFCTimeBin=0;
293
294
295 const std::vector<short>& samples=
digit->samples();
296 const unsigned nSamples=samples.size();
297 const HWIdentifier chid=
digit->channelID();
299
300
304 int region = -99999 ;
305 if (
msgLvl(MSG::DEBUG) ) {
307 try {
308 id =
cabling->cnvToIdentifier(chid);
309 } catch ( LArID_Exception & except ) {
310 ATH_MSG_DEBUG (
"A Cabling exception was caught for channel 0x!"
312 continue ;
313 }
317 region =
m_emId->region(
id);
319 <<
" [ Layer = " << layer <<
" - Eta = " <<
eta
320 <<
" - Phi = " <<
phi <<
" - Region = " << region <<
" ] " );
321 }
322
323
324 int nSatur=-1 ;
325 for (unsigned iSample=0;iSample<samples.size();iSample++) {
327 nSatur++;
328 break ;
329 }
330 }
331 if ( nSatur>-1 ) {
332 msg() << MSG::DEBUG <<
"Saturation on channel 0x" << MSG::hex << chid.
get_compact() << MSG::dec ;
333 saturation++;
334 }
336 msg() <<
". Skipping channel." <<
endmsg;
337 continue;
338 } else if ( nSatur>-1 ) {
340 }
341
342
343
344
345 float pedestal=larPedestal->
pedestal(chid,gain);
346
347 float pedestalAverage;
351 <<
" Gain " << gain <<
". Using time sample " <<
m_iPedestal );
353 } else {
355 <<
" [ Layer = " << layer <<
" - Eta = " <<
eta <<
" - Phi = " <<
phi <<
" - Region = " << region <<
" ]"
356 << " Gain = " << gain << ". Skipping channel." );
357 noEnergy++;
358 continue;
359 }
360 } else {
365 << MSG::dec <<
" Gain=" << gain <<
". Using time sample " <<
m_iPedestal );
367 } else {
368 pedestalAverage=pedestal;
369 }
370 }
371
372
375 {
376 float febTimeOffset=0;
378 if (larFebTimeOffset)
379 febTimeOffset=larFebTimeOffset->
TimeOffset(febid);
380 double timeShift=PhaseTime+globalTimeOffset+febTimeOffset;
381 if (debugPrint)
382 msg() << MSG::VERBOSE <<
"Channel 0x" << MSG::hex << chid.
get_compact() << MSG::dec
383 << " phase=" << PhaseTime << " Feb=" << febTimeOffset
384 << " Global=" << globalTimeOffset;
385
387 const double ofcTimeOffset=larOFC->timeOffset(chid,gain);
388 timeShift+=ofcTimeOffset;
389 if (debugPrint)
msg() << MSG::VERBOSE <<
" OFC=" << ofcTimeOffset;
390 }
391
392 if (debugPrint)
msg() << MSG::VERBOSE <<
" Total=" << timeShift <<
endmsg;
393
396 timeSampleShift -= 1;
397
399 }
402 timeSampleShift += 1;
403
405 }
406
408 BadTiming++;
409 noEnergy++;
410 ATH_MSG_ERROR ( noEnergy <<
". Time offset out of range for channel 0x" << MSG::hex << chid.
get_compact() << MSG::dec
412 continue;
413 }
414
416 BadTiming++;
417 noEnergy++;
418 ATH_MSG_ERROR ( noEnergy <<
". Negative time sample (" << timeSampleShift <<
") shift for channel 0x" << MSG::hex << chid.
get_compact() << MSG::dec
419 << " Found. Skipping channel." );
420 continue;
421 }
422
424
427
428
429
430
431 if (debugPrint)
ATH_MSG_VERBOSE (
"OFC bin width = " <<
m_OFCTimeBin <<
" - OFCBin = " << OFCTimeBin <<
" - timeShift = " << timeShift );
432
433 if ( OFCTimeBin < 0 ) {
434 ATH_MSG_ERROR (
"Channel " << MSG::hex << chid.
get_compact() << MSG::dec <<
" asks for OFC bin = " << OFCTimeBin <<
". Set to 0." );
435 OFCTimeBin=0;
439 }
440
441 ofc_a=larOFC->OFC_a(chid,gain,OFCTimeBin);
442
443 }
444
445
446 if (ofc_a.size()==0) {
447 noEnergy++;
449 <<
" [ Layer = " << layer <<
" - Eta = " <<
eta <<
" - Phi = " <<
phi <<
" - Region = " << region <<
" ]"
450 << " Time bin = " << OFCTimeBin << ", Gain = " << gain << ". Skipping channel." );
451 continue;
452 }
453 if (ofc_a.size()+timeSampleShift>nSamples) {
454 BadTiming++;
455 noEnergy++;
456 if (timeSampleShift==0)
457 ATH_MSG_DEBUG (
"Found LArDigit with " << nSamples <<
" samples, but OFCs for "
458 << ofc_a.size() << " samples. Skipping Channel ");
459 else
460 ATH_MSG_DEBUG (
"After time sample shift of " << timeSampleShift <<
", " << nSamples-timeSampleShift
461 << " samples left, but have OFCs for " << ofc_a.size() << " samples. Skipping Channel ");
462 continue;
463 }
464
465
466 float ADCPeak=0;
467 for (
unsigned i=0;
i<(ofc_a.size());
i++)
468 ADCPeak+=(samples[i+timeSampleShift]-pedestalAverage)*ofc_a.
at(i);
469
470 if (debugPrint)
ATH_MSG_VERBOSE (
"ADC Height calculated " << ADCPeak <<
" TimeBin=" << OFCTimeBin );
471
473
474 LArVectorProxy ramp = adc2mev->
ADC2MEV(chid,gain);
475
476 if (ramp.size()==0) {
477 noEnergy++;
479 <<
" [ Layer = " << layer <<
" - Eta = " <<
eta <<
" - Phi = " <<
phi <<
" - Region = " << region <<
" ]"
480 << " Gain = " << gain << ". Skipping channel." );
481 continue;
482 }
483
484
486 noEnergy++;
487 ATH_MSG_DEBUG (
"Bad ramp for channel " << chid <<
" (ramp[1] = " << ramp[1] <<
"): skip this channel" );
488 continue;
489 }
490
491 float ADCPeakPower=ADCPeak;
492
495
496 for (
unsigned i=1;
i<ramp.size();
i++)
498 ADCPeakPower*=ADCPeak;
499 }
500 } else {
504 Identifier
id =
cabling->cnvToIdentifier(chid);
507 }
508
509
510
512
513 float hvCorr = oflHVCorr-> HVScaleCorr(chid);
515 }
516
517
519 highE++;
520 ofc_b=larOFC->OFC_b(chid,gain,OFCTimeBin);
521 if (ofc_b.size() != ofc_a.size()) {
522 if (ofc_b.size()==0)
524 << " Gain "<< gain << " found. Time not calculated." );
525 else
527 << " not equal to OFC for energy size " << ofc_a.size()
528 << " Time not calculated " );
529 noTime++;
530 }else{
531 for (
unsigned i=0;
i<(ofc_b.size());
i++)
532 time+=(samples[i+timeSampleShift]-pedestalAverage)*ofc_b.
at(i);
534
535
536 }
537 if (debugPrint)
ATH_MSG_VERBOSE (
"Time calculated " << time <<
" TimeBin=" << OFCTimeBin );
538
539
540 if (larShape) {
541
542
543
544
545
548
549
550
551 if (shape.size() < ofc_a.size()) {
552 if (shape.size()==0)
554 << " Gain "<< gain << ". Quality factor not calculated." );
555 else
557 << "smaller than OFC size " << ofc_a.size()
558 <<
"for channel 0x" << MSG::hex << chid.
get_compact()
559 << MSG::dec << ". Quality factor not calculated." );
560 quality=0;
561 noShape++;
562 }
563 else {
564 if (time!=0 && shapeDer.size()!=shape.size()) {
565
566 ATH_MSG_DEBUG (
"Shape-Derivative has different size than Shape for channel 0x" << MSG::hex << chid.
get_compact() << MSG::dec
567 << ". Derivative not taken into accout for quality factor." );
568 noShapeDer++;
569 }
570 if (time==0 || shapeDer.size()!=shape.size() ) {
571 for (
unsigned i=0;
i<(ofc_a.size());
i++)
572 quality+=((samples[i+timeSampleShift]-pedestalAverage)-shape[i]*ADCPeak)*
573 ((samples[
i+timeSampleShift]-pedestalAverage)-shape[
i]*ADCPeak);
574 }
575 else {
576 for (
unsigned i=0;
i<(ofc_a.size());
i++)
577 quality+=((samples[i+timeSampleShift]-pedestalAverage)-((shape[i]-shapeDer[i]*time)*ADCPeak))*
578 ((samples[
i+timeSampleShift]-pedestalAverage)-((shape[
i]-shapeDer[
i]*
time)*ADCPeak));
579 }
580 }
581 }
582 else {
583 quality=0;
584 noShape++;
585 }
586
587
588 }
589 else
590 quality=-1;
591
593
594
597 if (quality>=0) {
598 iquality = ((
int)(quality) ) & 0xFFFF;
599 iprovenance=iprovenance | 0x2000;
600 }
601
602
603 LArRawChannel larRawChannel(chid,(int)energy,(int)time,iquality,iprovenance, gain);
604 larRawChannelContainer->push_back(larRawChannel);
605 ntot_raw++;
606 if (debugPrint)
608 << " e=" << energy << " t=" << time << " Q=" << quality );
609 }
610
611 ATH_MSG_DEBUG ( ntot_raw <<
" channels successfully processed, (" << highE <<
" with high energy)" );
612
613
614 if(BadTiming>=128){
615 ATH_MSG_ERROR (
"Too many channels (" <<BadTiming<<
" !) have a bad timing !!" );
616 ATH_MSG_ERROR (
"OFC time constants should be revisited !!!" );
618 larRawChannelContainer->clear();
619
620 }
621
622
624 ATH_MSG_ERROR ( saturation <<
" saturating channels were found. Event is skipped." );
625 larRawChannelContainer->clear();
626 }
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
655
661
666 || saturation>0 )
667 || (
msgSvc()->
outputLevel(
name()) <= MSG::DEBUG && ( noEnergy || noTime || noShape || noShapeDer || saturation ) )
668 ) {
669
674
675
676 MSG::Level msglvl;
677 if (noEnergy)
678 msglvl=MSG::ERROR;
679 else
680 msglvl=MSG::WARNING;
681 msg() << msglvl <<
" *** Error & Warning summary for this event *** " << std::endl;
682
683 if ( noEnergy ) {
684 msg() << msglvl <<
" " << noEnergy <<
" out of "
685 << digitContainer->
size() <<
" channel(s) skipped due to a lack of basic calibration constants."
686 << std::endl;
687 }
688 if ( noTime ) {
689 msg() << msglvl <<
" " << noTime <<
" out of "
690 << highE << " high-enegy channel(s) have no time-info due to a lack of Optimal Filtering Coefficients."
691 << std::endl;
692 }
693 if ( noShape ) {
694 msg() << msglvl <<
" " << noShape <<
" out of "
695 << highE << " high-enegy channel(s) have no quality factor due to a lack of shape."
696 << std::endl;
697 }
698 if ( noShapeDer ) {
699 msg() << msglvl <<
" " << noShapeDer <<
" out of "
700 << highE << " high-enegy channel(s) lack the derivative of the shape. Not taken into accout for Quality factor."
701 << std::endl;
702 }
703 if ( saturation ) {
705 msg() << MSG::ERROR <<
" " << saturation <<
" out of "
706 << digitContainer->
size() <<
" channel(s) showed saturations. The complete event was skipped." << std::endl;
708 msg() << MSG::ERROR <<
" " << saturation <<
" out of "
709 << digitContainer->
size() <<
" channel(s) showed saturations and were skipped." << std::endl;
710 else
711 msg() << MSG::WARNING <<
" " << saturation <<
" out of "
712 << digitContainer->
size() <<
" channel(s) showed saturations." << std::endl;
713 }
715 }
716
717
719
720 return StatusCode::SUCCESS;
721}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Old LArRawChannelContainer
ServiceHandle< StoreGateSvc > & evtStore()
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
size_type size() const noexcept
Returns the number of elements in the collection.
virtual float TimeOffset(const HWIdentifier fId) const =0
virtual float TimeOffset() const =0
LArVectorProxy OFCRef_t
This class defines the interface for accessing Optimal Filtering coefficients for each channel provid...
virtual float pedestal(const HWIdentifier &id, int gain) const =0
LArVectorProxy ShapeRef_t
This class defines the interface for accessing Shape (Nsample variable, Dt = 25 ns fixed) @stereotype...
virtual ShapeRef_t Shape(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
virtual ShapeRef_t ShapeDer(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
value_type get_compact() const
Get the compact id.
const LArVectorProxy ADC2MEV(const HWIdentifier &id, int gain) const
value_type at(size_t i) const
Vector indexing with bounds check.
SG::ReadCondHandleKey< LArADC2MeV > m_adc2mevKey
SG::ReadCondHandleKey< ILArHVScaleCorr > m_offlineHVScaleCorrKey
SG::ReadCondHandleKey< ILArOFC > m_ofcKey
Property: OFC coefficients (conditions input).
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
time(flags, cells_name, *args, **kw)
::StatusCode StatusCode
StatusCode definition for legacy code.
std::string debugPrint(const IDC_Container *container, unsigned numprint=25)
Diagnostic output of Identifiable Containers.
msgSvc
Provide convenience handles for various services.
retrieve(aClass, aKey=None)