266 CLHEP::HepRandomEngine* rngEngine =
nullptr;
282 const int nchMax = 48;
283 for (
int dr = 0; dr < ndrawers; ++dr) {
285 m_tileHWID->get_id(dr, drawer_id, &drawer_context);
290 m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
291 for (
int ch = 0; ch < nchMax; ++ch) {
295 double sigmaHi_Norm = sampleNoise->getHfnNorm(idhash, ch,
TileID::HIGHGAIN);
297 double sigmaLo_Hfn1 = sampleNoise->getHfn1(idhash, ch,
TileID::LOWGAIN);
298 double sigmaLo_Hfn2 = sampleNoise->getHfn2(idhash, ch,
TileID::LOWGAIN);
299 double sigmaLo_Norm = sampleNoise->getHfnNorm(idhash, ch,
TileID::LOWGAIN);
301 <<
" pedHi="<< pedSimHi
302 <<
" pedLo="<< pedSimLo
303 <<
" rmsHi="<< sigmaHi_Hfn1 <<
"," << sigmaHi_Hfn2 <<
"," << sigmaHi_Norm
304 <<
" rmsLo="<< sigmaLo_Hfn1 <<
"," << sigmaLo_Hfn2 <<
"," << sigmaLo_Norm);
337 double echtot_Acc = 0.;
338 double echint_Acc = 0.;
339 double echtot_Cut = 0.;
340 double echint_Cut = 0.;
347 auto digitsContainer = std::make_unique<TileMutableDigitsContainer>(
true,
352 std::unique_ptr<TileMutableDigitsContainer> digitsContainer_DigiHSTruth;
354 digitsContainer_DigiHSTruth = std::make_unique<TileMutableDigitsContainer>(
true,
357 ATH_CHECK( digitsContainer_DigiHSTruth->status() );
360 std::unique_ptr<TileMutableDigitsContainer> filteredContainer;
362 filteredContainer = std::make_unique<TileMutableDigitsContainer>(
true,
366 ATH_CHECK( filteredContainer->status() );
372 const int nchMax = 48;
373 std::vector<int> igain(nchMax, -1);
374 std::vector<int> ntot_ch(nchMax, 0);
375 std::vector<double> ech_tot(nchMax, 0.0);
376 std::vector<double> ech_int(nchMax, 0);
377 std::vector<double> ech_int_DigiHSTruth(nchMax, 0);
378 std::vector<int> over_gain(nchMax, -1);
382 std::vector<float> digitsBufferLo(
m_nSamples);
383 std::vector<float> digitsBuffer_DigiHSTruth(
m_nSamples);
384 std::vector<float> digitsBufferLo_DigiHSTruth(
m_nSamples);
386 std::vector<double> emptyBuffer;
387 std::vector<std::vector<double>> drawerBufferHi(nchMax, std::vector<double>(
m_nSamples));
388 std::vector<std::vector<double>> drawerBufferLo(nchMax, std::vector<double>(
m_nSamples));
390 std::vector<std::vector<double>> drawerBufferHi_DigiHSTruth;
391 std::vector<std::vector<double>> drawerBufferLo_DigiHSTruth;
393 drawerBufferHi_DigiHSTruth.resize(nchMax, std::vector<double>(
m_nSamples));
394 drawerBufferLo_DigiHSTruth.resize(nchMax, std::vector<double>(
m_nSamples));
400 Bool_t coherNoiseHi =
false;
401 Bool_t coherNoiseLo =
false;
402 TMatrixD CorrWeightHi;
403 TMatrixD CorrWeightLo;
404 std::vector<std::unique_ptr<double[]>> CorrRndmVec;
405 std::vector<std::unique_ptr<double[]>> CorrRndmVecLo;
408 CorrRndmVec.push_back(std::make_unique<
double[]>(nchMax));
412 CorrRndmVecLo.push_back(std::make_unique<
double[]>(nchMax));
419 std::unique_ptr<TileMutableDigitsContainer> backgroundDigitContainer{};
421 backgroundDigitContainer = std::make_unique<TileMutableDigitsContainer>(
true,
424 ATH_CHECK( backgroundDigitContainer->status() );
428 TimedDigitContList digitContList;
433 if (digitContList.size() == 0) {
435 return StatusCode::SUCCESS;
438 TimedDigitContList::iterator iTzeroDigitCont(digitContList.begin());
439 for (
const auto* digitCollection : *(iTzeroDigitCont->second)) {
440 for (
const auto* digit : *digitCollection) {
441 auto pDigits = std::make_unique<TileDigits>(*digit);
442 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
448 if (tileDigitsContainerHandle.
isValid()) {
449 for (
const auto* digitCollection : *tileDigitsContainerHandle) {
450 for (
const auto* digit : *digitCollection) {
451 auto pDigits = std::make_unique<TileDigits>(*digit);
452 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
457 ATH_MSG_ERROR(
"ReadHandle to Background Digits is invalid.");
458 return StatusCode::FAILURE;
462 collItrRndm = backgroundDigitContainer->begin();
463 lastCollRndm = backgroundDigitContainer->end();
483 dqStatus = DQstatusHandle.
get();
490 badChannels = badChannelsHandle.
retrieve();
496 if(
m_doDigiTruth) collItr_DigiHSTruth = hitContainer_DigiHSTruth->begin();
510 ATH_MSG_VERBOSE(
"ROS "<< ros <<
" drawer " << drawer <<
" is connected");
516 ++collItr_DigiHSTruth;
521 m_tileHWID->get_hash(drawer_id, idhash, &drawer_context);
522 const std::unique_ptr<HWIdentifier[]>& adc_ids =
m_all_ids[idhash];
530 std::fill(over_gain.begin(), over_gain.end(), -1);
535 std::fill(ech_tot.begin(), ech_tot.end(), 0.0);
536 std::fill(ech_int.begin(), ech_int.end(), 0.0);
537 std::fill(ntot_ch.begin(), ntot_ch.end(), 0);
538 std::fill(igain.begin(), igain.end(), igainch);
540 std::vector<std::reference_wrapper<std::vector<std::vector<double>>>> drawerBuffers{drawerBufferHi, drawerBufferLo};
542 drawerBuffers.push_back(drawerBufferHi_DigiHSTruth);
543 drawerBuffers.push_back(drawerBufferLo_DigiHSTruth);
545 for (std::vector<std::vector<double>>& drawerBuffer : drawerBuffers) {
546 for (std::vector<double>& digitsBuffer : drawerBuffer) {
547 std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0);
554 igain, ros, drawer, drawerIdx, over_gain, *emScale, *sampleNoise, dqStatus, badChannels));
558 std::vector<bool> signal_in_channel(nchMax,
false);
559 std::vector<bool> signal_in_channel_DigiHSTruth(nchMax,
false);
561 igain, over_gain, ech_int, signal_in_channel, *emScale, *samplingFraction, pulse));
564 igain, over_gain, ech_int_DigiHSTruth, signal_in_channel_DigiHSTruth, *emScale, *samplingFraction, pulse));
569 if (
msgLvl(MSG::VERBOSE)) {
570 for (
int ich = 0; ich < nchMax; ++ich) {
571 if (igain[ich] > -1) {
572 std::vector<double>& digitSamplesHi = drawerBufferHi[ich];
573 std::vector<double>& digitSamplesLo = drawerBufferLo[ich];
574 msg(MSG::VERBOSE) <<
"total: ADC " <<
m_tileHWID->to_string(adc_ids[ich],-1) <<
"/" << igain[ich]
575 <<
" nhit=" << ntot_ch[ich]
576 <<
" e_ch=" << ech_tot[ich]
577 <<
" AinTHi=" << digitSamplesHi[
m_iTrig]
600 <<
" drawer " << drawer
601 <<
" with " << nchMax <<
" channels and "
620 double* RndmVec = CorrRndmVec[k].get();
621 RandGaussQ::shootArray(rngEngine, nchMax, RndmVec, 0.0, 1.0);
626 double * RndmVecLo = CorrRndmVecLo[k].get();
627 RandGaussQ::shootArray(rngEngine, nchMax, RndmVecLo, 0.0, 1.0);
634 for (
int ich = 0; ich < nchMax; ++ich) {
645 <<
" PMT " << (pmt_id.
is_valid() ?
m_tileID->to_string(pmt_id,-1) : (signal_in_channel[ich] ?
"fake gap" :
"not connected"))
646 <<
" gain=" << igain[ich]);
655 bool chanLoIsBad =
false;
656 bool chanHiIsBad =
false;
660 chanLoIsBad = statusLo.
isBad();
661 chanHiIsBad = statusHi.
isBad();
665 double pedSimHi(0.), sigmaHi_Hfn1(0.), sigmaHi_Hfn2(0.), sigmaHi_Norm(0.), pedSimLo(0.),
666 sigmaLo_Hfn1(0.), sigmaLo_Hfn2(0.), sigmaLo_Norm(0.);
667 bool good_ch = (over_gain[ich]<9);
670 bool tileNoiseHG(
false),tileNoiseLG(
false);
678 if (pedSimHi == 0.0 && (signal_in_channel[ich] || pmt_id.
is_valid()))
683 if (sigmaHi_Hfn1>0 || sigmaHi_Hfn2) {
684 sigmaHi_Norm = sigmaHi_Hfn1 / (sigmaHi_Hfn1
698 if (pedSimLo == 0.0 && (signal_in_channel[ich] || pmt_id.
is_valid()))
703 if (sigmaLo_Hfn1 > 0 || sigmaLo_Hfn2) {
704 sigmaLo_Norm = sigmaLo_Hfn1 / (sigmaLo_Hfn1
705 + sigmaLo_Hfn2 * sampleNoise->getHfnNorm(idhash, ich,
TileID::LOWGAIN));
714 RandGaussQ::shootArray(rngEngine,
m_nSamples, Rndm, 0.0, 1.0);
715 RandFlat::shootArray(rngEngine, 1, Rndm_dG, 0.0, 1.0);
717 RandGaussQ::shootArray(rngEngine,
m_nSamples, RndmLo, 0.0, 1.0);
718 RandFlat::shootArray(rngEngine, 1, RndmLo_dG, 0.0, 1.0);
722 std::vector<double>& digitSamplesHi = drawerBufferHi[ich];
723 std::vector<double>& digitSamplesLo = drawerBufferLo[ich];
724 std::vector<double>& digitSamplesHi_DigiHSTruth = (
m_doDigiTruth) ? drawerBufferHi_DigiHSTruth[ich] : emptyBuffer;
725 std::vector<double>& digitSamplesLo_DigiHSTruth = (
m_doDigiTruth) ? drawerBufferLo_DigiHSTruth[ich] : emptyBuffer;
727 ATH_MSG_DEBUG(
" Channel " << ros <<
'/' << drawer <<
'/' << ich
728 <<
" sampHi=" << digitSamplesHi[
m_iTrig]
729 <<
" pedHi=" << pedSimHi
730 <<
" sampLo=" << digitSamplesLo[
m_iTrig]
731 <<
" pedLo=" << pedSimLo);
736 digitsBuffer[js] = digitSamplesHi[js] + pedSimHi;
738 digitsBuffer_DigiHSTruth[js] = digitSamplesHi_DigiHSTruth[js] + pedSimHi;
745 std::unique_ptr<double[]>& CorVec = CorrRndmVec[js];
747 for (
int i = 0; i < nchMax; ++i) noiseHi += CorrWeightHi(i, ich) * CorVec[i];
748 }
else if (tileNoiseHG) {
750 if (Rndm_dG[0] < sigmaHi_Norm) noiseHi = sigmaHi_Hfn1 * Rndm[js];
751 else noiseHi = sigmaHi_Hfn2 * Rndm[js];
754 if (digitsBuffer[js] + noiseHi >= 0.0) {
755 digitsBuffer[js] += noiseHi;
758 digitsBuffer[js] -= noiseHi;
764 digitsBuffer[js] = round(digitsBuffer[js]);
765 if(
m_doDigiTruth) digitsBuffer_DigiHSTruth[js] = round(digitsBuffer_DigiHSTruth[js]);
769 digitsBufferLo[js] = digitSamplesLo[js] + pedSimLo;
770 if(
m_doDigiTruth) digitsBufferLo_DigiHSTruth[js] = digitSamplesLo_DigiHSTruth[js] + pedSimLo;
775 std::unique_ptr<double[]>& CorVecLo = CorrRndmVecLo[js];
777 for (
int i = 0; i < nchMax; ++i) noiseLo += CorrWeightLo(i, ich) * CorVecLo[i];
778 }
else if (tileNoiseLG) {
780 if (RndmLo_dG[0] < sigmaLo_Norm) noiseLo = sigmaLo_Hfn1 * RndmLo[js];
781 else noiseLo = sigmaLo_Hfn2 * RndmLo[js];
784 if (digitsBufferLo[js] + noiseLo >= 0.0) {
785 digitsBufferLo[js] += noiseLo;
788 digitsBufferLo[js] -= noiseLo;
793 digitsBufferLo[js] = round(digitsBufferLo[js]);
794 if(
m_doDigiTruth) digitsBufferLo_DigiHSTruth[js] = round(digitsBufferLo_DigiHSTruth[js]);
807 digitsBuffer[js] = digitSamplesLo[js] + pedSimLo;
808 if(
m_doDigiTruth) digitsBuffer_DigiHSTruth[js] = digitSamplesLo_DigiHSTruth[js] + pedSimLo;
813 double* CorVec = CorrRndmVec[js].get();
815 for (
int i = 0; i < nchMax; ++i) noiseLo += CorrWeightLo(i, ich) * CorVec[i];
816 }
else if (tileNoiseLG) {
819 if (Rndm_dG[0] < sigmaLo_Norm) noiseLo = sigmaLo_Hfn1 * Rndm[js];
820 else noiseLo = sigmaLo_Hfn2 * Rndm[js];
823 if (digitsBuffer[js] + noiseLo >= 0.0) {
824 digitsBuffer[js] += noiseLo;
827 digitsBuffer[js] -= noiseLo;
831 if (digitsBuffer[js] >
m_f_ADCmax && good_ch) {
836 digitsBuffer[js] = round(digitsBuffer[js]);
837 if(
m_doDigiTruth) digitsBuffer_DigiHSTruth[js] = round(digitsBuffer_DigiHSTruth[js]);
843 if (
msgLvl(MSG::VERBOSE)) {
844 msg(MSG::VERBOSE) <<
"Channel " << ros <<
'/' << drawer <<
'/' << ich <<
"/" << igain[ich]
845 <<
" Switch to low gain Amp(lo)=" << digitsBuffer[
m_iTrig] <<
endmsg;
847 if (sigmaLo_Norm<1.0) {
848 msg(MSG::VERBOSE) <<
"LG Ped & noise from DB "
849 << pedSimLo <<
" " << sigmaLo_Hfn1 <<
" " << sigmaLo_Hfn2 <<
" " << sigmaLo_Norm
850 << ((Rndm_dG[0] < sigmaLo_Norm)?(
" sig1 used"):(
" sig2 used")) <<
endmsg;
852 msg(MSG::VERBOSE) <<
"LG Ped & noise from DB "
853 << pedSimLo <<
" " << sigmaLo_Hfn1 <<
endmsg;
860 if (
msgLvl(MSG::VERBOSE)) {
862 if (sigmaHi_Norm<1.0) {
863 msg(MSG::VERBOSE) <<
"HG Ped & noise from DB "
864 << pedSimHi <<
" " << sigmaHi_Hfn1 <<
" " << sigmaHi_Hfn2 <<
" " << sigmaHi_Norm
865 << ((Rndm_dG[0] < sigmaHi_Norm)?(
" sig1 used"):(
" sig2 used")) <<
endmsg;
867 msg(MSG::VERBOSE) <<
"HG Ped & noise from DB "
868 << pedSimHi <<
" " << sigmaHi_Hfn1 <<
endmsg;
872 if (sigmaLo_Norm<1.0) {
873 msg(MSG::VERBOSE) <<
"LG Ped & noise from DB "
874 << pedSimLo <<
" " << sigmaLo_Hfn1 <<
" " << sigmaLo_Hfn2 <<
" " << sigmaLo_Norm
875 << ((RndmLo_dG[0] < sigmaLo_Norm)?(
" sig1 used"):(
" sig2 used")) <<
endmsg;
877 msg(MSG::VERBOSE) <<
"LG Ped & noise from DB "
878 << pedSimLo <<
" " << sigmaLo_Hfn1 <<
endmsg;
888 std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(),
m_f_ADCmaskValue);
890 ATH_MSG_DEBUG(
"Masking Channel " << ros <<
'/' << drawer <<
'/' << ich <<
"/1 HG" );
893 auto pDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
894 ATH_CHECK( digitsContainer->push_back(std::move(pDigits)) );
897 auto digits_DigiHSTruth = std::make_unique<TileDigits>(adc_id, digitsBuffer_DigiHSTruth);
898 ATH_CHECK( digitsContainer_DigiHSTruth->push_back(std::move(digits_DigiHSTruth)) );
904 std::fill(digitsBufferLo_DigiHSTruth.begin(), digitsBufferLo_DigiHSTruth.end(),
m_f_ADCmaskValue);
907 ATH_MSG_DEBUG(
"Masking Channel " << ros <<
'/' << drawer <<
'/' << ich <<
"/0 LG");
910 auto pDigitsLo = std::make_unique<TileDigits>(adc_id_lo, digitsBufferLo);
911 ATH_CHECK( digitsContainer->push_back(std::move(pDigitsLo)) );
914 auto pDigitsLo_DigiHSTruth = std::make_unique<TileDigits>(adc_id_lo, digitsBufferLo_DigiHSTruth);
915 ATH_CHECK( digitsContainer_DigiHSTruth->push_back(std::move(pDigitsLo_DigiHSTruth)) );
922 bool isChannelGood =
true;
925 double ampInTime = digitsBuffer[
m_iTrig] - pedSimHi;
927 ampInTime = round(ampInTime);
930 isChannelGood =
false;
933 isChannelGood =
false;
939 echtot_Acc += ech_tot[ich];
940 echint_Acc += fabs(ech_int[ich]);
957 std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(),
m_f_ADCmaskValue);
959 }
else if (good_ch) {
960 ATH_MSG_DEBUG(
"Disconnected Channel " << ros <<
'/' << drawer <<
'/' << ich);
961 std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0.);
963 std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), 0.);
966 ATH_MSG_DEBUG(
"Masking Channel " << ros <<
'/' << drawer <<
'/' << ich <<
"/1 HG");
978 std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(),
m_f_ADCmaskValue);
980 }
else if (good_ch) {
981 ATH_MSG_DEBUG(
"Disconnected Channel " << ros <<
'/' << drawer <<
'/' << ich);
982 std::fill(digitsBuffer.begin(), digitsBuffer.end(), 0.);
984 std::fill(digitsBuffer_DigiHSTruth.begin(), digitsBuffer_DigiHSTruth.end(), 0.);
987 ATH_MSG_DEBUG(
"Masking Channel " << ros <<
'/' << drawer <<
'/' << ich <<
"/0 LG");
991 auto pDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
994 if (filteredContainer)
ATH_CHECK( filteredContainer->push_back(pDigits.get()) );
1002 ATH_CHECK( digitsContainer->push_back(std::move(pDigits)) );
1004 auto pDigits_DigiHSTruth = std::make_unique<TileDigits>(adc_id, digitsBuffer_DigiHSTruth);
1005 ATH_CHECK( digitsContainer_DigiHSTruth->push_back(std::move(pDigits_DigiHSTruth)) );
1008 if (
msgLvl(MSG::VERBOSE)) {
1009 double pedSim = ((hiGain) ? pedSimHi : pedSimLo);
1010 double ampInTime = digitsBuffer[
m_iTrig] - pedSim;
1012 ampInTime = round(ampInTime);
1016 <<
" AinT=" << ampInTime
1017 <<
" ped=" << pedSim
1018 <<
" Ech=" << ech_tot[ich]
1019 <<
" EinT=" << ech_int[ich] <<
endmsg;
1020 msg(MSG::VERBOSE) <<
"digits";
1021 for (
unsigned int i = 0; i < digitsBuffer.size(); ++i)
1022 msg(MSG::VERBOSE) <<
" " << digitsBuffer[i];
1026 echtot_Cut += ech_tot[ich];
1027 echint_Cut += ech_int[ich];
1034 if (
msgLvl(MSG::VERBOSE)) {
1035 double pedSim = ((hiGain) ? pedSimHi : pedSimLo);
1036 double ampInTime = digitsBuffer[
m_iTrig] - pedSim;
1038 ampInTime = round(ampInTime);
1039 msg(MSG::VERBOSE) <<
"Reject. ADC " <<
m_tileHWID->to_string(adc_id)
1040 <<
" AinT=" << ampInTime
1041 <<
" ped=" << pedSim
1042 <<
" Ech=" << ech_tot[ich]
1043 <<
" EinT=" << ech_int[ich] <<
endmsg;
1051 if (
msgLvl(MSG::DEBUG)) {
1052 msg(MSG::DEBUG) <<
"TileDigitsMaker execution completed." <<
endmsg;
1053 msg(MSG::DEBUG) <<
" nCh=" << nChSum
1054 <<
" nChH/L=" << nChHiSum <<
"/" << nChLoSum
1055 <<
" nFltH/L=" << nChHiFlt <<
"/" << nChLoFlt
1056 <<
" Hit=" << HitSum
1057 <<
" Ene=" << EneSum
1058 <<
" RChSum=" << RChSum <<
endmsg;
1060 msg(MSG::DEBUG) <<
" Accepted: nChLo/Hi=" << nChLoAcc <<
"/" << nChHiAcc
1061 <<
" eTot=" << echtot_Acc
1062 <<
" eInT=" << echint_Acc <<
endmsg;
1063 msg(MSG::DEBUG) <<
" Rejected: nChLo/Hi=" << nChLoCut <<
"/" << nChHiCut
1064 <<
" eTot=" << echtot_Cut
1065 <<
" eInT=" << echint_Cut <<
endmsg;
1076 ATH_CHECK( digits_DigiHSTruth.
record(std::move(digitsContainer_DigiHSTruth)) );
1079 if (filteredContainer) {
1081 ATH_CHECK( filteredDigitsContainer.
record(std::move(filteredContainer)) );
1084 return StatusCode::SUCCESS;