267 CLHEP::HepRandomEngine* rngEngine =
nullptr;
283 const int nchMax = 48;
284 for (
int dr = 0;
dr < ndrawers; ++
dr) {
292 for (
int ch = 0;
ch < nchMax; ++
ch) {
302 <<
" pedHi="<< pedSimHi
303 <<
" pedLo="<< pedSimLo
304 <<
" rmsHi="<< sigmaHi_Hfn1 <<
"," << sigmaHi_Hfn2 <<
"," << sigmaHi_Norm
305 <<
" rmsLo="<< sigmaLo_Hfn1 <<
"," << sigmaLo_Hfn2 <<
"," << sigmaLo_Norm);
338 double echtot_Acc = 0.;
339 double echint_Acc = 0.;
340 double echtot_Cut = 0.;
341 double echint_Cut = 0.;
348 auto digitsContainer = std::make_unique<TileMutableDigitsContainer>(
true,
353 std::unique_ptr<TileMutableDigitsContainer> digitsContainer_DigiHSTruth;
355 digitsContainer_DigiHSTruth = std::make_unique<TileMutableDigitsContainer>(
true,
361 std::unique_ptr<TileMutableDigitsContainer> filteredContainer;
363 filteredContainer = std::make_unique<TileMutableDigitsContainer>(
true,
373 const int nchMax = 48;
374 std::vector<int>
igain(nchMax, -1);
375 std::vector<int> ntot_ch(nchMax, 0);
376 std::vector<double> ech_tot(nchMax, 0.0);
377 std::vector<double> ech_int(nchMax, 0);
378 std::vector<double> ech_int_DigiHSTruth(nchMax, 0);
379 std::vector<int> over_gain(nchMax, -1);
383 std::vector<float> digitsBufferLo(
m_nSamples);
384 std::vector<float> digitsBuffer_DigiHSTruth(
m_nSamples);
385 std::vector<float> digitsBufferLo_DigiHSTruth(
m_nSamples);
387 std::vector<double> emptyBuffer;
388 std::vector<std::vector<double>> drawerBufferHi(nchMax, std::vector<double>(
m_nSamples));
389 std::vector<std::vector<double>> drawerBufferLo(nchMax, std::vector<double>(
m_nSamples));
391 std::vector<std::vector<double>> drawerBufferHi_DigiHSTruth;
392 std::vector<std::vector<double>> drawerBufferLo_DigiHSTruth;
394 drawerBufferHi_DigiHSTruth.resize(nchMax, std::vector<double>(
m_nSamples));
395 drawerBufferLo_DigiHSTruth.resize(nchMax, std::vector<double>(
m_nSamples));
401 Bool_t coherNoiseHi =
false;
402 Bool_t coherNoiseLo =
false;
403 TMatrixD CorrWeightHi;
404 TMatrixD CorrWeightLo;
405 std::vector<std::unique_ptr<double[]>> CorrRndmVec;
406 std::vector<std::unique_ptr<double[]>> CorrRndmVecLo;
418 TileMutableDigitsContainer::const_iterator collItrRndm;
419 TileMutableDigitsContainer::const_iterator lastCollRndm;
420 std::unique_ptr<TileMutableDigitsContainer> backgroundDigitContainer{};
422 backgroundDigitContainer = std::make_unique<TileMutableDigitsContainer>(
true,
425 ATH_CHECK( backgroundDigitContainer->status() );
429 TimedDigitContList digitContList;
434 if (digitContList.size() == 0) {
436 return StatusCode::SUCCESS;
440 for (
const auto* digitCollection : *(iTzeroDigitCont->second)) {
441 for (
const auto*
digit : *digitCollection) {
442 auto pDigits = std::make_unique<TileDigits>(*
digit);
443 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
449 if (tileDigitsContainerHandle.isValid()) {
450 for (
const auto* digitCollection : *tileDigitsContainerHandle) {
451 for (
const auto*
digit : *digitCollection) {
452 auto pDigits = std::make_unique<TileDigits>(*
digit);
453 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
458 ATH_MSG_ERROR(
"ReadHandle to Background Digits is invalid.");
459 return StatusCode::FAILURE;
463 collItrRndm = backgroundDigitContainer->begin();
464 lastCollRndm = backgroundDigitContainer->end();
474 pulse = pulseShape.retrieve();
484 dqStatus = DQstatusHandle.get();
490 ATH_CHECK( badChannelsHandle.isValid() );
491 badChannels = badChannelsHandle.retrieve();
517 ++collItr_DigiHSTruth;
523 const std::unique_ptr<HWIdentifier[]>& adc_ids =
m_all_ids[idhash];
531 std::fill(over_gain.begin(), over_gain.end(), -1);
536 std::fill(ech_tot.begin(), ech_tot.end(), 0.0);
537 std::fill(ech_int.begin(), ech_int.end(), 0.0);
538 std::fill(ntot_ch.begin(), ntot_ch.end(), 0);
541 std::vector<std::reference_wrapper<std::vector<std::vector<double>>>> drawerBuffers{drawerBufferHi, drawerBufferLo};
543 drawerBuffers.push_back(drawerBufferHi_DigiHSTruth);
544 drawerBuffers.push_back(drawerBufferLo_DigiHSTruth);
546 for (std::vector<std::vector<double>>& drawerBuffer : drawerBuffers) {
547 for (std::vector<double>& digitsBuffer : drawerBuffer) {
548 std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0);
555 igain,
ros,
drawer, drawerIdx, over_gain, *emScale, *sampleNoise, dqStatus, badChannels));
559 std::vector<bool> signal_in_channel(nchMax,
false);
560 std::vector<bool> signal_in_channel_DigiHSTruth(nchMax,
false);
562 igain, over_gain, ech_int, signal_in_channel, *emScale, *samplingFraction, pulse));
565 igain, over_gain, ech_int_DigiHSTruth, signal_in_channel_DigiHSTruth, *emScale, *samplingFraction, pulse));
571 for (
int ich = 0; ich < nchMax; ++ich) {
572 if (
igain[ich] > -1) {
573 std::vector<double>& digitSamplesHi = drawerBufferHi[ich];
574 std::vector<double>& digitSamplesLo = drawerBufferLo[ich];
576 <<
" nhit=" << ntot_ch[ich]
577 <<
" e_ch=" << ech_tot[ich]
578 <<
" AinTHi=" << digitSamplesHi[
m_iTrig]
602 <<
" with " << nchMax <<
" channels and "
621 double* RndmVec = CorrRndmVec[
k].get();
622 RandGaussQ::shootArray(rngEngine, nchMax, RndmVec, 0.0, 1.0);
627 double * RndmVecLo = CorrRndmVecLo[
k].get();
628 RandGaussQ::shootArray(rngEngine, nchMax, RndmVecLo, 0.0, 1.0);
635 for (
int ich = 0; ich < nchMax; ++ich) {
646 <<
" PMT " << (pmt_id.
is_valid() ?
m_tileID->
to_string(pmt_id,-1) : (signal_in_channel[ich] ?
"fake gap" :
"not connected"))
647 <<
" gain=" <<
igain[ich]);
656 bool chanLoIsBad =
false;
657 bool chanHiIsBad =
false;
661 chanLoIsBad = statusLo.
isBad();
662 chanHiIsBad = statusHi.
isBad();
666 double pedSimHi(0.), sigmaHi_Hfn1(0.), sigmaHi_Hfn2(0.), sigmaHi_Norm(0.), pedSimLo(0.),
667 sigmaLo_Hfn1(0.), sigmaLo_Hfn2(0.), sigmaLo_Norm(0.);
668 bool good_ch = (over_gain[ich]<9);
671 bool tileNoiseHG(
false),tileNoiseLG(
false);
679 if (pedSimHi == 0.0 && (signal_in_channel[ich] || pmt_id.
is_valid()))
684 if (sigmaHi_Hfn1>0 || sigmaHi_Hfn2) {
685 sigmaHi_Norm = sigmaHi_Hfn1 / (sigmaHi_Hfn1
699 if (pedSimLo == 0.0 && (signal_in_channel[ich] || pmt_id.
is_valid()))
704 if (sigmaLo_Hfn1 > 0 || sigmaLo_Hfn2) {
705 sigmaLo_Norm = sigmaLo_Hfn1 / (sigmaLo_Hfn1
706 + sigmaLo_Hfn2 * sampleNoise->getHfnNorm(idhash, ich,
TileID::LOWGAIN));
715 RandGaussQ::shootArray(rngEngine,
m_nSamples, Rndm, 0.0, 1.0);
716 RandFlat::shootArray(rngEngine, 1, Rndm_dG, 0.0, 1.0);
718 RandGaussQ::shootArray(rngEngine,
m_nSamples, RndmLo, 0.0, 1.0);
719 RandFlat::shootArray(rngEngine, 1, RndmLo_dG, 0.0, 1.0);
723 std::vector<double>& digitSamplesHi = drawerBufferHi[ich];
724 std::vector<double>& digitSamplesLo = drawerBufferLo[ich];
725 std::vector<double>& digitSamplesHi_DigiHSTruth = (
m_doDigiTruth) ? drawerBufferHi_DigiHSTruth[ich] : emptyBuffer;
726 std::vector<double>& digitSamplesLo_DigiHSTruth = (
m_doDigiTruth) ? drawerBufferLo_DigiHSTruth[ich] : emptyBuffer;
729 <<
" sampHi=" << digitSamplesHi[
m_iTrig]
730 <<
" pedHi=" << pedSimHi
731 <<
" sampLo=" << digitSamplesLo[
m_iTrig]
732 <<
" pedLo=" << pedSimLo);
737 digitsBuffer[js] = digitSamplesHi[js] + pedSimHi;
739 digitsBuffer_DigiHSTruth[js] = digitSamplesHi_DigiHSTruth[js] + pedSimHi;
746 std::unique_ptr<double[]>& CorVec = CorrRndmVec[js];
748 for (
int i = 0;
i < nchMax; ++
i) noiseHi += CorrWeightHi(
i, ich) * CorVec[
i];
749 }
else if (tileNoiseHG) {
751 if (Rndm_dG[0] < sigmaHi_Norm) noiseHi = sigmaHi_Hfn1 * Rndm[js];
752 else noiseHi = sigmaHi_Hfn2 * Rndm[js];
755 if (digitsBuffer[js] + noiseHi >= 0.0) {
756 digitsBuffer[js] += noiseHi;
759 digitsBuffer[js] -= noiseHi;
765 digitsBuffer[js] =
round(digitsBuffer[js]);
770 digitsBufferLo[js] = digitSamplesLo[js] + pedSimLo;
771 if(
m_doDigiTruth) digitsBufferLo_DigiHSTruth[js] = digitSamplesLo_DigiHSTruth[js] + pedSimLo;
776 std::unique_ptr<double[]>& CorVecLo = CorrRndmVecLo[js];
778 for (
int i = 0;
i < nchMax; ++
i) noiseLo += CorrWeightLo(
i, ich) * CorVecLo[
i];
779 }
else if (tileNoiseLG) {
781 if (RndmLo_dG[0] < sigmaLo_Norm) noiseLo = sigmaLo_Hfn1 * RndmLo[js];
782 else noiseLo = sigmaLo_Hfn2 * RndmLo[js];
785 if (digitsBufferLo[js] + noiseLo >= 0.0) {
786 digitsBufferLo[js] += noiseLo;
789 digitsBufferLo[js] -= noiseLo;
794 digitsBufferLo[js] =
round(digitsBufferLo[js]);
795 if(
m_doDigiTruth) digitsBufferLo_DigiHSTruth[js] =
round(digitsBufferLo_DigiHSTruth[js]);
808 digitsBuffer[js] = digitSamplesLo[js] + pedSimLo;
809 if(
m_doDigiTruth) digitsBuffer_DigiHSTruth[js] = digitSamplesLo_DigiHSTruth[js] + pedSimLo;
814 double* CorVec = CorrRndmVec[js].get();
816 for (
int i = 0;
i < nchMax; ++
i) noiseLo += CorrWeightLo(
i, ich) * CorVec[
i];
817 }
else if (tileNoiseLG) {
820 if (Rndm_dG[0] < sigmaLo_Norm) noiseLo = sigmaLo_Hfn1 * Rndm[js];
821 else noiseLo = sigmaLo_Hfn2 * Rndm[js];
824 if (digitsBuffer[js] + noiseLo >= 0.0) {
825 digitsBuffer[js] += noiseLo;
828 digitsBuffer[js] -= noiseLo;
832 if (digitsBuffer[js] >
m_f_ADCmax && good_ch) {
837 digitsBuffer[js] =
round(digitsBuffer[js]);
846 <<
" Switch to low gain Amp(lo)=" << digitsBuffer[
m_iTrig] <<
endmsg;
848 if (sigmaLo_Norm<1.0) {
850 << pedSimLo <<
" " << sigmaLo_Hfn1 <<
" " << sigmaLo_Hfn2 <<
" " << sigmaLo_Norm
851 << ((Rndm_dG[0] < sigmaLo_Norm)?(
" sig1 used"):(
" sig2 used")) <<
endmsg;
854 << pedSimLo <<
" " << sigmaLo_Hfn1 <<
endmsg;
863 if (sigmaHi_Norm<1.0) {
865 << pedSimHi <<
" " << sigmaHi_Hfn1 <<
" " << sigmaHi_Hfn2 <<
" " << sigmaHi_Norm
866 << ((Rndm_dG[0] < sigmaHi_Norm)?(
" sig1 used"):(
" sig2 used")) <<
endmsg;
869 << pedSimHi <<
" " << sigmaHi_Hfn1 <<
endmsg;
873 if (sigmaLo_Norm<1.0) {
875 << pedSimLo <<
" " << sigmaLo_Hfn1 <<
" " << sigmaLo_Hfn2 <<
" " << sigmaLo_Norm
876 << ((RndmLo_dG[0] < sigmaLo_Norm)?(
" sig1 used"):(
" sig2 used")) <<
endmsg;
879 << pedSimLo <<
" " << sigmaLo_Hfn1 <<
endmsg;
894 auto pDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
895 ATH_CHECK( digitsContainer->push_back(std::move(pDigits)) );
898 auto digits_DigiHSTruth = std::make_unique<TileDigits>(adc_id, digitsBuffer_DigiHSTruth);
911 auto pDigitsLo = std::make_unique<TileDigits>(adc_id_lo, digitsBufferLo);
912 ATH_CHECK( digitsContainer->push_back(std::move(pDigitsLo)) );
915 auto pDigitsLo_DigiHSTruth = std::make_unique<TileDigits>(adc_id_lo, digitsBufferLo_DigiHSTruth);
916 ATH_CHECK( digitsContainer_DigiHSTruth->
push_back(std::move(pDigitsLo_DigiHSTruth)) );
923 bool isChannelGood =
true;
926 double ampInTime = digitsBuffer[
m_iTrig] - pedSimHi;
928 ampInTime =
round(ampInTime);
931 isChannelGood =
false;
934 isChannelGood =
false;
940 echtot_Acc += ech_tot[ich];
941 echint_Acc += fabs(ech_int[ich]);
960 }
else if (good_ch) {
962 std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0.);
964 std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), 0.);
981 }
else if (good_ch) {
983 std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0.);
985 std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), 0.);
992 auto pDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
1003 ATH_CHECK( digitsContainer->push_back(std::move(pDigits)) );
1005 auto pDigits_DigiHSTruth = std::make_unique<TileDigits>(adc_id, digitsBuffer_DigiHSTruth);
1010 double pedSim = ((hiGain) ? pedSimHi : pedSimLo);
1011 double ampInTime = digitsBuffer[
m_iTrig] - pedSim;
1013 ampInTime =
round(ampInTime);
1017 <<
" AinT=" << ampInTime
1018 <<
" ped=" << pedSim
1019 <<
" Ech=" << ech_tot[ich]
1020 <<
" EinT=" << ech_int[ich] <<
endmsg;
1022 for (
unsigned int i = 0;
i < digitsBuffer.size(); ++
i)
1027 echtot_Cut += ech_tot[ich];
1028 echint_Cut += ech_int[ich];
1036 double pedSim = ((hiGain) ? pedSimHi : pedSimLo);
1037 double ampInTime = digitsBuffer[
m_iTrig] - pedSim;
1039 ampInTime =
round(ampInTime);
1041 <<
" AinT=" << ampInTime
1042 <<
" ped=" << pedSim
1043 <<
" Ech=" << ech_tot[ich]
1044 <<
" EinT=" << ech_int[ich] <<
endmsg;
1055 <<
" nChH/L=" << nChHiSum <<
"/" << nChLoSum
1056 <<
" nFltH/L=" << nChHiFlt <<
"/" << nChLoFlt
1058 <<
" Ene=" << EneSum
1059 <<
" RChSum=" << RChSum <<
endmsg;
1061 msg(
MSG::DEBUG) <<
" Accepted: nChLo/Hi=" << nChLoAcc <<
"/" << nChHiAcc
1062 <<
" eTot=" << echtot_Acc
1063 <<
" eInT=" << echint_Acc <<
endmsg;
1064 msg(
MSG::DEBUG) <<
" Rejected: nChLo/Hi=" << nChLoCut <<
"/" << nChHiCut
1065 <<
" eTot=" << echtot_Cut
1066 <<
" eInT=" << echint_Cut <<
endmsg;
1073 ATH_CHECK( digitsCnt.record(std::move(digitsContainer)) );
1077 ATH_CHECK( digits_DigiHSTruth.record(std::move(digitsContainer_DigiHSTruth)) );
1080 if (filteredContainer) {
1082 ATH_CHECK( filteredDigitsContainer.record(std::move(filteredContainer)) );
1085 return StatusCode::SUCCESS;