191 {
192
194 ATH_MSG_VERBOSE(
"ATT: RUN1 settings TilePulseForTileMuonReceiver will end now" );
195 return StatusCode::SUCCESS;
196 } else {
198 }
199
200 const EventContext& ctx = Gaudi::Hive::currentContext();
201
202
203
204
205
206#define nEBchan 6
207#define nLBchan 9
208
209 int EBchan[
nEBchan]={17,16,37,38,3,2};
210
211 int LBchan[
nLBchan]={0,13,14,25,24,41,44,39,40};
212
213#if (nEBchan > nLBchan)
214 double pDigitSamplesArray[
nEBchan][7];
215 double pDigitSamplesRndmArray[
nEBchan][7];
216#else
217 double pDigitSamplesArray[
nLBchan][7];
218 double pDigitSamplesRndmArray[
nLBchan][7];
219#endif
220
221
222
223
224
225 double Rndm[16];
226 double Rndm_dG[1];
227
228
229
230 double pedSim = 0.;
231 double sigma_Hfn1 = 0.;
232 double sigma_Hfn2 = 0.;
233 double sigma_Norm = 0.;
234 double sigmaSim(0.0);
235
236
237
238 double muRcv_NoiseSigma;
239 double muRcv_Ped;
240 double muRcv_Calib;
241 double muRcv_Max;
242
243 SG::ReadCondHandle<TileEMScale> emScale(
m_emScaleKey, ctx);
245
246 const TileBadChannels* badChannels = nullptr;
248 SG::ReadCondHandle<TileBadChannels> badChannelsHandle(
m_badChannelsKey, ctx);
249 ATH_CHECK( badChannelsHandle.isValid() );
250 badChannels = *badChannelsHandle;
251 }
252
253 const TilePulse* pulse = nullptr;
257 pulse = pulseShape.retrieve();
258 }
259
260 const TileSampleNoise* sampleNoise = nullptr;
262 SG::ReadCondHandle<TileSampleNoise> sampleNoiseHandle(
m_sampleNoiseKey, ctx);
263 ATH_CHECK( sampleNoiseHandle.isValid() );
264 sampleNoise = sampleNoiseHandle.retrieve();
265 }
266
267
268
271
272
273
274 IdentifierHash idhash;
275 IdContext drawer_context =
m_tileHWID->drawer_context();
276
277
278
279 auto muRcvDigitsContainer = std::make_unique<TileMutableDigitsContainer>(true,
282 ATH_CHECK( muRcvDigitsContainer->status() );
283
284
285
286 auto muRcvRawChannelContainer = std::make_unique<TileMutableRawChannelContainer>(true,
290 ATH_CHECK( muRcvRawChannelContainer->status() );
291
292
293
294 TileDigitsContainer::const_iterator collItrRndm;
295 TileDigitsContainer::const_iterator lastCollRndm;
296 std::unique_ptr<TileMutableDigitsContainer> backgroundDigitContainer{};
297
299
300 ATH_MSG_DEBUG(
"Prepare background container for MC Overlay procedure");
301
302 backgroundDigitContainer = std::make_unique<TileMutableDigitsContainer>(true,
305 ATH_CHECK( backgroundDigitContainer->status() );
306
309 TimedDigitContList digitContList;
312
313 if (digitContList.size() == 0) {
315 return StatusCode::SUCCESS;
316 }
317
318 TimedDigitContList::iterator iTzeroDigitCont(digitContList.begin());
319 for (const auto* digitCollection : *(iTzeroDigitCont->second)) {
320 for (const auto* digit : *digitCollection) {
321 auto pDigits = std::make_unique<TileDigits>(*digit);
322 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
323 }
324 }
325 } else {
327 if (tileDigitsContainerHandle.isValid()) {
328 for (const auto* digitCollection : *tileDigitsContainerHandle) {
329 for (const auto* digit : *digitCollection) {
330 auto pDigits = std::make_unique<TileDigits>(*digit);
331 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
332 }
333 }
334 } else {
335 ATH_MSG_ERROR(
"ReadHandle to Background Digits is invalid.");
336 return StatusCode::FAILURE;
337 }
338 }
339
340 collItrRndm = backgroundDigitContainer->begin();
341 lastCollRndm = backgroundDigitContainer->end();
342 }
343
344
345
347
348
349
350 std::vector<float> digitsBuffer_rndm(
m_nSamples);
351 std::vector<bool> good_bkg( 9 , false );
352
353
354
357
359
360
363
364 for (const TileHitCollection* hitCollection : *hitContainer) {
365
366
367
368 HWIdentifier drawer_id =
m_tileHWID->drawer_id(hitCollection->identify());
374
375 ATH_MSG_VERBOSE(
"(A.00) Looping over all collections for TMDB in the HIT container");
376 memset(pDigitSamplesArray, 0, sizeof(pDigitSamplesArray));
377
378 ATH_MSG_VERBOSE(
"(A.01) Going through collection ROS/DRAWER : "<< ros <<
"/"<< drawer);
379 ATH_MSG_DEBUG(
" Going through collection ROS/DRAWER : "<< ros <<
"/"<< drawer);
380
382 ATH_MSG_VERBOSE(
"(A.02) ROS: "<< ros <<
" drawer: " << drawer <<
" is connected");
383 } else {
384 ATH_MSG_VERBOSE(
"(A.02) ROS: "<< ros <<
" drawer: " << drawer <<
" is NOT connected");
385 continue;
386 }
387
388
389
390 m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
391
392
393
394
395
396
397 memset(pDigitSamplesRndmArray, 0, sizeof(pDigitSamplesRndmArray));
398
400
401 const TileDigitsCollection *bkgDigitCollection(*collItrRndm);
402
403 if (hitCollection->identify() != bkgDigitCollection->identify()) {
404 ATH_MSG_ERROR (
"Frag IDs for hit collection and digits overlay collection do not match "
405 << MSG::hex << hitCollection->identify() << " != " << bkgDigitCollection->identify()
406 << MSG::dec );
407 return StatusCode::FAILURE;
408 }
409
410 ATH_MSG_DEBUG(
"Prepare buffer (digitsBuffer_rndm) for MC Overlay procdure: pileup digits");
411
412 for (const auto* bkgDigit : *bkgDigitCollection) {
413 bool good_channel = true;
414
415 HWIdentifier adc_id_rndm = (*bkgDigit).adc_HWID();
417 ATH_MSG_VERBOSE (
"check channels from adc id in rndm container (TMDB channel): "<< channel );
418
419 digitsBuffer_rndm = (*bkgDigit).samples();
420
421 int nsamp_rndm = digitsBuffer_rndm.size();
424 if (nsamp_rndm>0) {
426 digitsBuffer_rndm[
js] = digitsBuffer_rndm[
js-1];
427 }
428 }
429 }
430
432 pDigitSamplesRndmArray[
channel][j] = digitsBuffer_rndm[j];
433
434
435 if (pDigitSamplesRndmArray[channel][j]==0) good_channel = false;
436 }
437 good_bkg[
channel] = good_channel;
438
439 if (
msgLvl(MSG::VERBOSE)){
440 msg(MSG::VERBOSE) <<
" Digits from pileup background " <<
channel <<
" " <<
ros <<
" " <<
drawer <<
" " <<
m_tileHWID->to_string(adc_id_rndm)<<
" | ";
441 for (
int j=0; j< (
int) digitsBuffer_rndm.size(); j++)
msg(MSG::VERBOSE) << digitsBuffer_rndm[j] <<
" | ";
442 msg(MSG::VERBOSE) <<
"---> | ";
443 for (
int j=0; j< (
int) digitsBuffer_rndm.size(); j++)
msg(MSG::VERBOSE) << pDigitSamplesRndmArray[
channel][j] <<
" | ";
445 }
446 }
447 ++collItrRndm;
448 }
449
451
452
453
454 if ( hitCollection->empty() )
ATH_MSG_DEBUG(
"-- No hits in this drawer! Filling channels with either noise and pedestal or MC pileup overlay. --");
455
456 for (const TileHit* tile_hit : *hitCollection) {
457
458
459
460 Identifier pmt_id = tile_hit->pmt_ID();
461
462
463
464 int tower =
m_tileID->tower(pmt_id);
467
468 ATH_MSG_VERBOSE(
"(B.00) ++ Iterate over all the D layer channels with hits");
469
470
471 int TMDBchan;
472
473 int TILEchan;
474
475 if (eb_ros) {
476
478 TMDBchan = 1 -
m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
479 else
480 TMDBchan =
m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
481
482 TILEchan=EBchan[TMDBchan];
483 } else {
484
485 if (tower == 0) {
486 TMDBchan = 0;
487 } else {
488
490 TMDBchan = 1 -
m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
491 else
492 TMDBchan =
m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
493 }
494
495 TILEchan=LBchan[TMDBchan];
496 }
497
498 double* pDigitSamples = pDigitSamplesArray[TMDBchan];
499
500 if (
msgLvl(MSG::VERBOSE)){
502
503 ATH_MSG_VERBOSE(
"(B.01) Correct pmt being transported in XXchan[]: "<<TMDBchan<<
" "<<TILEchan<<
"=?"
505 <<
" For reference get TMDB adc_id: " <<
m_tileHWID->to_string(adc_id) );
506 ATH_MSG_VERBOSE(
"(B.02) New hit in ROS/DRAWER/PMT "<<ros<<
"/"<<drawer<<
"/"<<TMDBchan<<
" ("<<TILEchan<<
")"
507 <<
" pmt_id "<<
m_tileID->to_string(pmt_id,-1)
508 <<
" adc_id "<<
m_tileHWID->to_string(adc_id) );
509 }
510
511
512
514 double hit_calib = samplingFraction->getSamplingFraction(drawerIdx, channel);
515 hit_calib = std::round(hit_calib * 1000) / 1000;
516
518
520
521
522
523
524 int n_hits = tile_hit->size();
525
527
528 for (int ihit = 0; ihit < n_hits; ++ihit) {
529
530 ATH_MSG_VERBOSE(
"(C.00) ++ Iterating over the hits of channel " << TILEchan <<
": hit " << ihit <<
"/"<< n_hits);
531
532 double e_hit = tile_hit->energy(ihit);
533 double e_pmt = e_hit * hit_calib;
534
535 ATH_MSG_VERBOSE(
"(C.01) Energy in scintillator [MeV]: " << e_hit <<
" true cell energy [MeV]: " << e_pmt);
536
537 double t_hit = tile_hit->time(ihit);
538
540
541
542
547 double shape = 0.0;
548
550
552
558
560
562
564
567 pDigitSamples[
js] += e_pmt * shape;
568
570 << " idx= " << k
571 << " Shape wt. = " << shape
572 << " Amp = " << pDigitSamples[js] << " [MeV]");
573 }
574 } else {
579
581
583
585 << " idx= " << k
587 << " Amp = " << pDigitSamples[js]
588 << "[MeV] Energy: " << e_pmt << " LOGAIN from TileInfo");
589 }
590 }
591 }
592
594 ATH_MSG_DEBUG(
"(C.04) Went over " << n_hits <<
" hits for channel"
595 <<
m_tileHWID->to_string(drawer_id,-2) <<
"/" << TMDBchan <<
" (" << TILEchan <<
")"
596 << " digits [MeV] "<< pDigitSamples[0]
597 << "/" << pDigitSamples[1]
598 << "/" << pDigitSamples[2]
599 << "/" << pDigitSamples[3]
600 << "/" << pDigitSamples[4]
601 << "/" << pDigitSamples[5]
602 << "/" << pDigitSamples[6]);
603 ATH_MSG_VERBOSE(
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
604 }
605
607
609
610
611
612
613
614
615
616
617
618
619 ATH_MSG_VERBOSE(
"++ START filling of channels with background either noise+pedestal or overlay");
620
621 for (int TMDBchan = 0; TMDBchan < upperLim; ++TMDBchan) {
622
623 double* pDigitSamples=pDigitSamplesArray[TMDBchan];
624 int TILEchan = (eb_ros) ? EBchan[TMDBchan] : LBchan[TMDBchan];
625
627
628 ATH_MSG_DEBUG(
"(D.) Going now to channel " <<
" TMDBchan: " << TMDBchan <<
" TILEchan: " << TILEchan);
630 << " TMDBchan: " << TMDBchan << " TILEchan: " << TILEchan
631 << " ROS: " << ros
632 << " drawer: " << drawer
633 << " drawer idx: " << drawerIdx
634 <<
" drawer_id: " <<
m_tileHWID->to_string(drawer_id,-2)
635 <<
" channel: " <<
m_tileHWID->to_string(adc_id,-1));
636
637
640 double mev2ADC_factor = muRcv_Calib / emScale->calibrateChannel(drawerIdx,TILEchan,
TileID::LOWGAIN, 1.
644 << " adc/pCb: "<< muRcv_Calib
645 << " Mev/pCb: "<< emScale->calibrateChannel( drawerIdx,
646 TILEchan,
648 1.,
651 << " final calibration factor adc/MeV: "<< mev2ADC_factor);
652
654 << " " << pDigitSamples[0]
655 << " " << pDigitSamples[1]
656 << " " << pDigitSamples[2]
657 << " " << pDigitSamples[3]
658 << " " << pDigitSamples[4]
659 << " " << pDigitSamples[5]
660 << " " << pDigitSamples[6]
661 << " [All ZERO if there is no hit in channel.] ");
662
663 if ( good_bkg[TMDBchan] ) {
664
665
666
667
669
671
672
673 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E_{Signal} [adc]: "<< pDigitSamples[js] * mev2ADC_factor <<
" -- Overlay");
674 digitsBuffer[
js] = pDigitSamples[
js] * mev2ADC_factor;
675
676
677 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E_{PileUp} [adc]: "<< pDigitSamplesRndmArray[TMDBchan][js] <<
" -- Overlay");
678 digitsBuffer[
js] += pDigitSamplesRndmArray[TMDBchan][
js];
679
680
681 if (digitsBuffer[js] > muRcv_Max) digitsBuffer[
js] = muRcv_Max;
682
683
685 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" calibration [adc/MeV] "<< mev2ADC_factor <<
"-> E_{Signal+PileUp} [adc]: "<< digitsBuffer[js] <<
" -- Overlay");
686 }
687 } else {
688 if (
m_rndmEvtOverlay)
ATH_MSG_INFO(
"At least one digit is zero in background file using the stadart path to fill pedestal and noise in digits");
689
690
691 muRcv_NoiseSigma =
m_tileInfo->MuRcvNoiseSigma(adc_id);
693
695 << " noi " << muRcv_NoiseSigma
696 << " ped " << muRcv_Ped
697 << " cal " << muRcv_Calib
698 << " max " << muRcv_Max);
699
700
701
702
704
705
708
709
710 if (pedSim == 0.0) pedSim = 30.;
711 } else {
712 pedSim = muRcv_Ped;
713 }
714
715
717
718
719 RandGaussQ::shootArray(*rngWrapper,
m_nSamples, Rndm, 0.0, 1.0);
720 RandFlat::shootArray(*rngWrapper, 1, Rndm_dG, 0.0, 1.0);
723 if (sigma_Hfn1 > 0 || sigma_Hfn2) {
725 } else {
727 sigma_Norm = 1.;
728 }
729 if (Rndm_dG[0] < sigma_Norm) sigmaSim = sigma_Hfn1;
730 else sigmaSim = sigma_Hfn2;
731 } else {
732 sigmaSim = muRcv_NoiseSigma;
733 }
734
735
737
738
739 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E [MeV]: "<< pDigitSamples[js]);
740 digitsBuffer[
js] = pDigitSamples[
js] * mev2ADC_factor;
741 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" calibration [adc/MeV] "<< mev2ADC_factor <<
"-> E [adc]: "<< digitsBuffer[js]);
742
743
744 digitsBuffer[
js] += pedSim;
745 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" adding pedestal "<< pedSim <<
"-> E [adc]: "<< digitsBuffer[js]);
746
747
749 digitsBuffer[
js] += sigmaSim * Rndm[
js];
750 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" adding noise "<< sigmaSim * Rndm[js] <<
"-> E [adc]: "<< digitsBuffer[js]);
751 }
752
753
754 if (digitsBuffer[js] > muRcv_Max) digitsBuffer[
js] = muRcv_Max;
755
756
758 }
759 }
760
761
762
763 bool chanIsBad = false;
764
767 chanIsBad =
status.isBad();
768 }
769
770 if (chanIsBad) {
772 digitsBuffer[
js] = 255;
773 }
774 ATH_MSG_VERBOSE(
"(D.03) Masking Channel: "<< ros <<
'/' << drawer <<
'/' << TILEchan <<
" ("<< TMDBchan <<
") LowGain" );
775 } else {
776 ATH_MSG_VERBOSE(
"(D.03) Good Channel : "<< ros <<
'/' << drawer <<
'/' << TILEchan <<
" ("<< TMDBchan <<
") LowGain" );
777 }
778
779 ATH_MSG_VERBOSE(
"++ Changed to TMDB adc_id: " <<
m_tileHWID->to_string(adc_id) <<
" and save a TileDigits object into a container." );
780 std::unique_ptr<TileDigits> muonReceiverDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
781 ATH_MSG_VERBOSE(
"++ Create a TileRawChannelObject object and set it into a container " );
782 TileRawChannel* muRcvRawChannel =
m_MuRcvBuildTool->rawChannel(muonReceiverDigits.get(), ctx);
783 ATH_CHECK( muRcvDigitsContainer->push_back(std::move(muonReceiverDigits)) );
784 ATH_CHECK( muRcvRawChannelContainer->push_back(muRcvRawChannel) );
787 << " Digitized pulse [ADC] "<< digitsBuffer[0]
788 << "/" << digitsBuffer[1]
789 << "/" << digitsBuffer[2]
790 << "/" << digitsBuffer[3]
791 << "/" << digitsBuffer[4]
792 << "/" << digitsBuffer[5]
793 << "/" << digitsBuffer[6] );
795 <<
" E [ADC]: "<< muRcvRawChannel->
amplitude()
796 <<
" Time [ns]: "<< muRcvRawChannel->
time()
797 <<
" Qf: "<< muRcvRawChannel->
quality() );
798 }
799 }
800 }
801 if (
msgLvl(MSG::VERBOSE)) muRcvDigitsContainer->print();
802
804
805
806
807 ATH_MSG_VERBOSE (
"(A.05) Send to event store all collected objects " );
808
810 ATH_CHECK( muRcvDigitsCnt.record(std::move(muRcvDigitsContainer)) );
811
813 ATH_CHECK( muRcvRawChannelCnt.record(std::move(muRcvRawChannelContainer)) );
814
816
817 return StatusCode::SUCCESS;
818}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
bool msgLvl(const MSG::Level lvl) const
const TileBchStatus & getAdcStatus(const HWIdentifier adc_id) const
Return Tile ADC status.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
Gaudi::Property< bool > m_useCoolPulseShapes
std::string m_inputDigitContainerName
Gaudi::Property< bool > m_maskBadChannels
SG::WriteHandleKey< TileDigitsContainer > m_muRcvDigitsContainerKey
SG::ReadHandleKey< TileHitContainer > m_hitContainerKey
Gaudi::Property< bool > m_integerDigits
ServiceHandle< PileUpMergeSvc > m_mergeSvc
SG::ReadCondHandleKey< TilePulse > m_pulseShapeKey
Name of TilePulseShape in condition store.
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service to use.
SG::WriteHandleKey< TileRawChannelContainer > m_muRcvRawChannelContainerKey
Gaudi::Property< bool > m_rndmEvtOverlay
ToolHandle< TileRawChannelBuilderMF > m_MuRcvBuildTool
SG::ReadCondHandleKey< TileBadChannels > m_badChannelsKey
Name of TileBadChannels in condition store.
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
Gaudi::Property< bool > m_tileNoise
Gaudi::Property< bool > m_tilePedestal
Gaudi::Property< std::string > m_randomStreamName
Random Stream Name.
Gaudi::Property< bool > m_onlyUseContainerName
SG::ReadHandleKey< TileDigitsContainer > m_inputDigitContainerKey
SG::ReadCondHandleKey< TileSamplingFraction > m_samplingFractionKey
Name of TileSamplingFraction in condition store.
SG::ReadCondHandleKey< TileSampleNoise > m_sampleNoiseKey
Name of TileSampleNoise in condition store.
std::vector< double > m_shapeMuonReceiver
Muon receiver pulse shape.
bool getPulseShapeYDY(unsigned int drawerIdx, unsigned int channel, unsigned int adc, float time, float &y, float &dy) const
float time(int ind=0) const
float quality(int ind=0) const
float amplitude(int ind=0) const
float getPed(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
float getHfn2(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
float getHfn1(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
float getHfn(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
float getHfnNorm(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
float round(const float toRound, const unsigned int decimals)
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
std::list< value_t > type
type of the collection of timed data object