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 CLHEP::HepRandomEngine* rndmEngine = rngWrapper->
getEngine(ctx);
358
360
361
364
365 for (const TileHitCollection* hitCollection : *hitContainer) {
366
367
368
369 HWIdentifier drawer_id =
m_tileHWID->drawer_id(hitCollection->identify());
375
376 ATH_MSG_VERBOSE(
"(A.00) Looping over all collections for TMDB in the HIT container");
377 memset(pDigitSamplesArray, 0, sizeof(pDigitSamplesArray));
378
379 ATH_MSG_VERBOSE(
"(A.01) Going through collection ROS/DRAWER : "<< ros <<
"/"<< drawer);
380 ATH_MSG_DEBUG(
" Going through collection ROS/DRAWER : "<< ros <<
"/"<< drawer);
381
383 ATH_MSG_VERBOSE(
"(A.02) ROS: "<< ros <<
" drawer: " << drawer <<
" is connected");
384 } else {
385 ATH_MSG_VERBOSE(
"(A.02) ROS: "<< ros <<
" drawer: " << drawer <<
" is NOT connected");
386 continue;
387 }
388
389
390
391 m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
392
393
394
395
396
397
398 memset(pDigitSamplesRndmArray, 0, sizeof(pDigitSamplesRndmArray));
399
401
402 const TileDigitsCollection *bkgDigitCollection(*collItrRndm);
403
404 if (hitCollection->identify() != bkgDigitCollection->identify()) {
405 ATH_MSG_ERROR (
"Frag IDs for hit collection and digits overlay collection do not match "
406 << MSG::hex << hitCollection->identify() << " != " << bkgDigitCollection->identify()
407 << MSG::dec );
408 return StatusCode::FAILURE;
409 }
410
411 ATH_MSG_DEBUG(
"Prepare buffer (digitsBuffer_rndm) for MC Overlay procdure: pileup digits");
412
413 for (const auto* bkgDigit : *bkgDigitCollection) {
414 bool good_channel = true;
415
416 HWIdentifier adc_id_rndm = (*bkgDigit).adc_HWID();
418 ATH_MSG_VERBOSE (
"check channels from adc id in rndm container (TMDB channel): "<< channel );
419
420 digitsBuffer_rndm = (*bkgDigit).samples();
421
422 int nsamp_rndm = digitsBuffer_rndm.size();
425 if (nsamp_rndm>0) {
427 digitsBuffer_rndm[
js] = digitsBuffer_rndm[
js-1];
428 }
429 }
430 }
431
433 pDigitSamplesRndmArray[
channel][
j] = digitsBuffer_rndm[
j];
434
435
436 if (pDigitSamplesRndmArray[channel][j]==0) good_channel = false;
437 }
438 good_bkg[
channel] = good_channel;
439
440 if (
msgLvl(MSG::VERBOSE)){
441 msg(MSG::VERBOSE) <<
" Digits from pileup background " <<
channel <<
" " <<
ros <<
" " <<
drawer <<
" " <<
m_tileHWID->to_string(adc_id_rndm)<<
" | ";
442 for (
int j=0;
j< (
int) digitsBuffer_rndm.size();
j++)
msg(MSG::VERBOSE) << digitsBuffer_rndm[
j] <<
" | ";
443 msg(MSG::VERBOSE) <<
"---> | ";
444 for (
int j=0;
j< (
int) digitsBuffer_rndm.size();
j++)
msg(MSG::VERBOSE) << pDigitSamplesRndmArray[
channel][
j] <<
" | ";
446 }
447 }
448 ++collItrRndm;
449 }
450
452
453
454
455 if ( hitCollection->empty() )
ATH_MSG_DEBUG(
"-- No hits in this drawer! Filling channels with either noise and pedestal or MC pileup overlay. --");
456
457 for (const TileHit* tile_hit : *hitCollection) {
458
459
460
461 Identifier pmt_id = tile_hit->pmt_ID();
462
463
464
465 int tower =
m_tileID->tower(pmt_id);
468
469 ATH_MSG_VERBOSE(
"(B.00) ++ Iterate over all the D layer channels with hits");
470
471
472 int TMDBchan;
473
474 int TILEchan;
475
476 if (eb_ros) {
477
479 TMDBchan = 1 -
m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
480 else
481 TMDBchan =
m_tileID->pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
482
483 TILEchan=EBchan[TMDBchan];
484 } else {
485
486 if (tower == 0) {
487 TMDBchan = 0;
488 } else {
489
491 TMDBchan = 1 -
m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
492 else
493 TMDBchan =
m_tileID->pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
494 }
495
496 TILEchan=LBchan[TMDBchan];
497 }
498
499 double* pDigitSamples = pDigitSamplesArray[TMDBchan];
500
501 if (
msgLvl(MSG::VERBOSE)){
503
504 ATH_MSG_VERBOSE(
"(B.01) Correct pmt being transported in XXchan[]: "<<TMDBchan<<
" "<<TILEchan<<
"=?"
506 <<
" For reference get TMDB adc_id: " <<
m_tileHWID->to_string(adc_id) );
507 ATH_MSG_VERBOSE(
"(B.02) New hit in ROS/DRAWER/PMT "<<ros<<
"/"<<drawer<<
"/"<<TMDBchan<<
" ("<<TILEchan<<
")"
508 <<
" pmt_id "<<
m_tileID->to_string(pmt_id,-1)
509 <<
" adc_id "<<
m_tileHWID->to_string(adc_id) );
510 }
511
512
513
515 double hit_calib = samplingFraction->getSamplingFraction(drawerIdx, channel);
516 hit_calib = std::round(hit_calib * 1000) / 1000;
517
519
521
522
523
524
525 int n_hits = tile_hit->size();
526
528
529 for (int ihit = 0; ihit < n_hits; ++ihit) {
530
531 ATH_MSG_VERBOSE(
"(C.00) ++ Iterating over the hits of channel " << TILEchan <<
": hit " << ihit <<
"/"<< n_hits);
532
533 double e_hit = tile_hit->energy(ihit);
534 double e_pmt = e_hit * hit_calib;
535
536 ATH_MSG_VERBOSE(
"(C.01) Energy in scintillator [MeV]: " << e_hit <<
" true cell energy [MeV]: " << e_pmt);
537
538 double t_hit = tile_hit->time(ihit);
539
541
542
543
548 double shape = 0.0;
549
551
553
559
561
563
565
568 pDigitSamples[
js] += e_pmt * shape;
569
571 << " idx= " << k
572 << " Shape wt. = " << shape
573 << " Amp = " << pDigitSamples[js] << " [MeV]");
574 }
575 } else {
580
582
584
586 << " idx= " << k
588 << " Amp = " << pDigitSamples[js]
589 << "[MeV] Energy: " << e_pmt << " LOGAIN from TileInfo");
590 }
591 }
592 }
593
595 ATH_MSG_DEBUG(
"(C.04) Went over " << n_hits <<
" hits for channel"
596 <<
m_tileHWID->to_string(drawer_id,-2) <<
"/" << TMDBchan <<
" (" << TILEchan <<
")"
597 << " digits [MeV] "<< pDigitSamples[0]
598 << "/" << pDigitSamples[1]
599 << "/" << pDigitSamples[2]
600 << "/" << pDigitSamples[3]
601 << "/" << pDigitSamples[4]
602 << "/" << pDigitSamples[5]
603 << "/" << pDigitSamples[6]);
604 ATH_MSG_VERBOSE(
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
605 }
606
608
610
611
612
613
614
615
616
617
618
619
620 ATH_MSG_VERBOSE(
"++ START filling of channels with background either noise+pedestal or overlay");
621
622 for (int TMDBchan = 0; TMDBchan < upperLim; ++TMDBchan) {
623
624 double* pDigitSamples=pDigitSamplesArray[TMDBchan];
625 int TILEchan = (eb_ros) ? EBchan[TMDBchan] : LBchan[TMDBchan];
626
628
629 ATH_MSG_DEBUG(
"(D.) Going now to channel " <<
" TMDBchan: " << TMDBchan <<
" TILEchan: " << TILEchan);
631 << " TMDBchan: " << TMDBchan << " TILEchan: " << TILEchan
632 << " ROS: " << ros
633 << " drawer: " << drawer
634 << " drawer idx: " << drawerIdx
635 <<
" drawer_id: " <<
m_tileHWID->to_string(drawer_id,-2)
636 <<
" channel: " <<
m_tileHWID->to_string(adc_id,-1));
637
638
641 double mev2ADC_factor = muRcv_Calib / emScale->calibrateChannel(drawerIdx,TILEchan,
TileID::LOWGAIN, 1.
645 << " adc/pCb: "<< muRcv_Calib
646 << " Mev/pCb: "<< emScale->calibrateChannel( drawerIdx,
647 TILEchan,
649 1.,
652 << " final calibration factor adc/MeV: "<< mev2ADC_factor);
653
655 << " " << pDigitSamples[0]
656 << " " << pDigitSamples[1]
657 << " " << pDigitSamples[2]
658 << " " << pDigitSamples[3]
659 << " " << pDigitSamples[4]
660 << " " << pDigitSamples[5]
661 << " " << pDigitSamples[6]
662 << " [All ZERO if there is no hit in channel.] ");
663
664 if ( good_bkg[TMDBchan] ) {
665
666
667
668
670
672
673
674 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E_{Signal} [adc]: "<< pDigitSamples[js] * mev2ADC_factor <<
" -- Overlay");
675 digitsBuffer[
js] = pDigitSamples[
js] * mev2ADC_factor;
676
677
678 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E_{PileUp} [adc]: "<< pDigitSamplesRndmArray[TMDBchan][js] <<
" -- Overlay");
679 digitsBuffer[
js] += pDigitSamplesRndmArray[TMDBchan][
js];
680
681
682 if (digitsBuffer[js] > muRcv_Max) digitsBuffer[
js] = muRcv_Max;
683
684
686 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" calibration [adc/MeV] "<< mev2ADC_factor <<
"-> E_{Signal+PileUp} [adc]: "<< digitsBuffer[js] <<
" -- Overlay");
687 }
688 } else {
689 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");
690
691
692 muRcv_NoiseSigma =
m_tileInfo->MuRcvNoiseSigma(adc_id);
694
696 << " noi " << muRcv_NoiseSigma
697 << " ped " << muRcv_Ped
698 << " cal " << muRcv_Calib
699 << " max " << muRcv_Max);
700
701
702
703
705
706
709
710
711 if (pedSim == 0.0) pedSim = 30.;
712 } else {
713 pedSim = muRcv_Ped;
714 }
715
716
718
719
720 RandGaussQ::shootArray(rndmEngine,
m_nSamples, Rndm, 0.0, 1.0);
721 RandFlat::shootArray(rndmEngine, 1, Rndm_dG, 0.0, 1.0);
724 if (sigma_Hfn1 > 0 || sigma_Hfn2) {
726 } else {
728 sigma_Norm = 1.;
729 }
730 if (Rndm_dG[0] < sigma_Norm) sigmaSim = sigma_Hfn1;
731 else sigmaSim = sigma_Hfn2;
732 } else {
733 sigmaSim = muRcv_NoiseSigma;
734 }
735
736
738
739
740 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E [MeV]: "<< pDigitSamples[js]);
741 digitsBuffer[
js] = pDigitSamples[
js] * mev2ADC_factor;
742 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" calibration [adc/MeV] "<< mev2ADC_factor <<
"-> E [adc]: "<< digitsBuffer[js]);
743
744
745 digitsBuffer[
js] += pedSim;
746 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" adding pedestal "<< pedSim <<
"-> E [adc]: "<< digitsBuffer[js]);
747
748
750 digitsBuffer[
js] += sigmaSim * Rndm[
js];
751 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" adding noise "<< sigmaSim * Rndm[js] <<
"-> E [adc]: "<< digitsBuffer[js]);
752 }
753
754
755 if (digitsBuffer[js] > muRcv_Max) digitsBuffer[
js] = muRcv_Max;
756
757
759 }
760 }
761
762
763
764 bool chanIsBad = false;
765
768 chanIsBad =
status.isBad();
769 }
770
771 if (chanIsBad) {
773 digitsBuffer[
js] = 255;
774 }
775 ATH_MSG_VERBOSE(
"(D.03) Masking Channel: "<< ros <<
'/' << drawer <<
'/' << TILEchan <<
" ("<< TMDBchan <<
") LowGain" );
776 } else {
777 ATH_MSG_VERBOSE(
"(D.03) Good Channel : "<< ros <<
'/' << drawer <<
'/' << TILEchan <<
" ("<< TMDBchan <<
") LowGain" );
778 }
779
780 ATH_MSG_VERBOSE(
"++ Changed to TMDB adc_id: " <<
m_tileHWID->to_string(adc_id) <<
" and save a TileDigits object into a container." );
781 std::unique_ptr<TileDigits> muonReceiverDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
782 ATH_MSG_VERBOSE(
"++ Create a TileRawChannelObject object and set it into a container " );
783 TileRawChannel* muRcvRawChannel =
m_MuRcvBuildTool->rawChannel(muonReceiverDigits.get(), ctx);
784 ATH_CHECK( muRcvDigitsContainer->push_back(std::move(muonReceiverDigits)) );
785 ATH_CHECK( muRcvRawChannelContainer->push_back(muRcvRawChannel) );
788 << " Digitized pulse [ADC] "<< digitsBuffer[0]
789 << "/" << digitsBuffer[1]
790 << "/" << digitsBuffer[2]
791 << "/" << digitsBuffer[3]
792 << "/" << digitsBuffer[4]
793 << "/" << digitsBuffer[5]
794 << "/" << digitsBuffer[6] );
796 <<
" E [ADC]: "<< muRcvRawChannel->
amplitude()
797 <<
" Time [ns]: "<< muRcvRawChannel->
time()
798 <<
" Qf: "<< muRcvRawChannel->
quality() );
799 }
800 }
801 }
802 if (
msgLvl(MSG::VERBOSE)) muRcvDigitsContainer->print();
803
805
806
807
808 ATH_MSG_VERBOSE (
"(A.05) Send to event store all collected objects " );
809
811 ATH_CHECK( muRcvDigitsCnt.record(std::move(muRcvDigitsContainer)) );
812
814 ATH_CHECK( muRcvRawChannelCnt.record(std::move(muRcvRawChannelContainer)) );
815
817
818 return StatusCode::SUCCESS;
819}
#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.
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
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
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
std::list< value_t > type
type of the collection of timed data object