6#include "CLHEP/Random/RandGaussZiggurat.h"
16#include "CLHEP/Random/RandomEngine.h"
17#include <CLHEP/Random/Randomize.h>
18#include <GaudiKernel/StatusCode.h>
23using CLHEP::RandGaussZiggurat;
31 return StatusCode::FAILURE;
54 StatusCode
sc =
detStore()->retrieve(caloIdMgr);
56 ATH_MSG_ERROR(
" Unable to retrieve CaloIdManager from DetectoreStore");
57 return StatusCode::FAILURE;
65 ATH_MSG_ERROR(
" Unable to retrieve LArOnlineId from DetectoreStore");
66 return StatusCode::FAILURE;
79 std::array<std::pair<int,std::string>,4> iCaloToStr{{{
EM,
"EM"},{
HEC,
"HEC"},{
FCAL,
"FCAL"},{
EMIW,
"EMIW"}}};
81 for (
int iCalo =
EM; iCalo <=
EMIW; ++iCalo) {
88 return StatusCode::FAILURE;
96 return StatusCode::FAILURE;
100 ATH_MSG_ERROR(
" Calo " << iCaloToStr[iCalo] <<
" configured to have only one gain. This is not supported.");
101 return Status::FAILURE;
105 return Status::FAILURE;
111 return StatusCode::SUCCESS;
123 return StatusCode::FAILURE;
144 autoCorrNoise=*autoCorrNoiseHdl;
157 const LArHitEMap* hitmapPtr_DigiHSTruth =
nullptr;
160 hitmapPtr_DigiHSTruth = hitmap_DigitHSTruth.
cptr();
168 DigitContainer->reserve(nCells);
174 std::unique_ptr<LArDigitContainer> DigitContainer_DigiHSTruth =
nullptr;
176 DigitContainer_DigiHSTruth = std::make_unique<LArDigitContainer>();
177 DigitContainer_DigiHSTruth->reserve(nCells);
180 const std::vector<std::pair<float,float> >* TimeE;
181 const std::vector<std::pair<float,float> >* TimeE_DigiHSTruth =
nullptr;
184 CLHEP::HepRandomEngine * engine = rngWrapper->
getEngine(context);
188 for (
size_t it=0;it<nCells;++it)
195 const auto& hitlist_DigiHSTruth=hitmapPtr_DigiHSTruth->
GetCell(it);
196 TimeE_DigiHSTruth = &(hitlist_DigiHSTruth.getData());
203 bool missing=!(badFebs->
status(febId).good());
211 LArDigit* Digit_DigiHSTruth =
nullptr;
214 Digit_DigiHSTruth, TimeE, digit, engine,
225 ATH_MSG_ERROR(
"LArHitEMapToDigitAlg::execute failed in MakeDigit");
226 delete Digit_DigiHSTruth;
229 DigitContainer->push_back(Digit);
230 if (DigitContainer_DigiHSTruth){
231 DigitContainer_DigiHSTruth->push_back(Digit_DigiHSTruth);
240 ATH_MSG_DEBUG(
" number of created digits = " << DigitContainer->size());
244 if ( DigitContainer_DigiHSTruth ){
246 ATH_CHECK(DigitContainer_DigiHSTruthHandle.
record( std::move(DigitContainer_DigiHSTruth) ) );
250 return StatusCode::SUCCESS;
254 const EventContext& ctx,
260 const std::vector<std::pair<float, float>>* TimeE,
262 CLHEP::HepRandomEngine* engine,
263 const std::vector<std::pair<float, float>>* TimeE_DigiHSTruth,
272 bool createDigit_DigiHSTruth =
true;
277 short Adc_DigiHSTruth;
280 std::vector<short> AdcSample_DigiHSTruth(
m_NSamples);
291 else if (
m_larem_id->is_em_endcap_inner(cellId))
321 ATH_MSG_DEBUG(
" number of hit for this cell " << TimeE->size());
327 bool isDead =
m_bcMask.cellShouldBeMasked(bcCont,ch_id);
331 if( this->
ConvertHits2Samples(cellId,ch_id,initialGain,TimeE, Samples, shape).isFailure() ) {
332 return StatusCode::SUCCESS;
335 if( this->
ConvertHits2Samples(cellId,ch_id,initialGain,TimeE_DigiHSTruth, Samples_DigiHSTruth, shape).isFailure() ) {
336 return StatusCode::SUCCESS;
348 rndmGain= rndmEvtDigit->
gain();
349 auto polynom_adc2mev =adc2MeVs->
ADC2MEV(ch_id,rndmEvtDigit->
gain());
350 if (polynom_adc2mev.size() > 1) {
351 float adc2energy = SF * polynom_adc2mev[1];
352 const std::vector<short> & rndm_digit_samples = rndmEvtDigit->
samples() ;
353 float Pedestal = pedestal->
pedestal(ch_id,rndmEvtDigit->
gain());
355 ATH_MSG_WARNING(
" Pedestal not found in database for this channel offID " << cellId <<
" Use sample 0 for random");
356 Pedestal = rndm_digit_samples[0];
358 ATH_MSG_DEBUG(
" Params for inverting LAr Digitization: pedestal " << Pedestal <<
" adc2energy " << adc2energy);
365 if (larOFC.
cptr() !=
nullptr) {
368 if (ofc_a.size()>0) {
369 for (
unsigned int j=0;j<ofc_a.size();j++) sumOfc += ofc_a.
at(j);
371 if (sumOfc>0) adc0 = polynom_adc2mev[0] * SF /sumOfc;
376 if ((
int)(rndm_digit_samples.size()) <
m_NSamples) {
378 "Less digit Samples than requested in digitization for cell "
379 << ch_id.
get_compact() <<
" Digit has " << rndm_digit_samples.size()
380 <<
" samples. Digitization request " <<
m_NSamples);
381 nmax = rndm_digit_samples.size();
383 for(i=0 ; i<
nmax ; i++)
385 rAdc = (rndm_digit_samples[i] - Pedestal ) * adc2energy + adc0;
386 rndm_energy_samples[i] = rAdc ;
391 ATH_MSG_ERROR(
" No ramp found for this random cell " <<
m_larem_id->show_to_string(cellId) <<
" for gain " << rndmEvtDigit->
gain());
392 if (adc2MeVs->
nGains()<=(
int)rndmEvtDigit->
gain()) {
393 ATH_MSG_ERROR(
"Found ramp for only " << adc2MeVs->
nGains() <<
" gains. Are you trying to overlay of Run 3 random with run 4 signal?");
395 return StatusCode::FAILURE;
402 return StatusCode::FAILURE;
406 igain=std::max(rndmGain,igain);
411 if (igain != initialGain ){
415 else Samples[i] = 0.;
419 if( this->
ConvertHits2Samples(cellId,ch_id,igain,TimeE, Samples, shape) == StatusCode::FAILURE ) {
420 return StatusCode::SUCCESS;
423 if( this->
ConvertHits2Samples(cellId,ch_id,igain,TimeE_DigiHSTruth, Samples_DigiHSTruth, shape) == StatusCode::FAILURE ) {
424 return StatusCode::SUCCESS;
438 bool addedNoise=
false;
446 SigmaNoise = noise->noise(ch_id, igain);
448 float thisNoise = pedestal->
pedestalRMS(ch_id, igain);
450 SigmaNoise = thisNoise;
455 const std::vector<float>& CorGen =
461 return StatusCode::FAILURE;
464 RandGaussZiggurat::shootArray(engine,
m_NSamples, Rndm, 0., 1.);
469 for (
int j = 0; j <= i; j++) {
471 Noise[i] += Rndm[j] * CorGen[
index];
473 Noise[i] = Noise[i] * SigmaNoise;
486 if (igain > rndmEvtDigit->
gain()) {
487 double SigmaNoiseZB = 0.;
488 double SigmaNoise = 0.;
489 double SigmaExtraNoise = 0.;
491 SigmaNoiseZB = noise->noise(ch_id, rndmEvtDigit->
gain());
492 SigmaNoise = noise->noise(ch_id, igain);
496 SigmaNoiseZB = thisNoise;
501 SigmaNoise = thisNoise;
506 auto polynom_adc2mevZB =
508 auto polynom_adc2mev = adc2MeVs->
ADC2MEV(cellId, igain);
509 if (polynom_adc2mevZB.size() > 1 && polynom_adc2mev.size() > 1) {
510 if (polynom_adc2mev[1] > 0.) {
511 SigmaNoiseZB = SigmaNoiseZB * (polynom_adc2mevZB[1]) /
512 (polynom_adc2mev[1]);
513 if (SigmaNoise > SigmaNoiseZB)
514 SigmaExtraNoise = sqrt(SigmaNoise * SigmaNoise -
515 SigmaNoiseZB * SigmaNoiseZB);
518 RandGaussZiggurat::shootArray(engine,
m_NSamples, Rndm, 0.,
521 Noise[i] = SigmaExtraNoise * Rndm[i];
530 float Pedestal = pedestal->
pedestal(ch_id,igain);
532 ATH_MSG_WARNING(
" pedestal not found for cellId " << cellId <<
" assume 1000" );
535 const auto polynom_adc2mev = adc2MeVs->
ADC2MEV(cellId,igain);
536 if (polynom_adc2mev.size() < 2) {
537 ATH_MSG_WARNING(
" No ramp found for requested gain " << igain <<
" for cell " <<
m_larem_id->show_to_string(cellId) <<
" no digit made...");
538 return StatusCode::SUCCESS;
541 energy2adc=1./(polynom_adc2mev[1])/SF;
548 if (larOFC.
cptr() !=
nullptr) {
551 if (ofc_a.size()>0) {
552 for (
unsigned int j=0;j<ofc_a.size();j++) sumOfc+= ofc_a.
at(j);
554 if ((polynom_adc2mev[1])>0 && sumOfc>0) Pedestal = Pedestal - (polynom_adc2mev[0])/(polynom_adc2mev[1])/sumOfc;
555 ATH_MSG_DEBUG(
" Params for final LAr Digitization gain: " << igain <<
" pedestal: " << Pedestal <<
" energy2adc: " << energy2adc);
561 double xAdc_DigiHSTruth = 0;
564 xAdc = Samples[i]*energy2adc + Noise[i] + Pedestal + 0.5;
566 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Noise[i] + Pedestal + 0.5;
572 float flatRndm = RandFlat::shoot(engine);
573 xAdc = Samples[i]*energy2adc + Pedestal + flatRndm;
575 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Pedestal + flatRndm;
580 xAdc = Samples[i]*energy2adc + Pedestal + 0.5;
582 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Pedestal + 0.5;
598 ", energy2adc=" << energy2adc <<
", E[0]= " << (TimeE->size()>0 ? std::format(
"{}",TimeE->at(0).first) :
"No value"));
607 if (xAdc_DigiHSTruth <0) Adc_DigiHSTruth=0;
609 else Adc_DigiHSTruth = (short) xAdc_DigiHSTruth;
610 AdcSample_DigiHSTruth[i] = Adc_DigiHSTruth;
614 ATH_MSG_DEBUG(
" Sample " << i <<
" Energy= " << Samples[i] <<
" Adc=" << Adc);
623 (*Digit)=
LArDigit(ch_id,igain,std::move(AdcSample));
626 createDigit_DigiHSTruth =
false;
627 Digit_DigiHSTruth =
nullptr;
630 if (Samples_DigiHSTruth[i] != 0)
631 createDigit_DigiHSTruth =
true;
635 new LArDigit(ch_id, igain, std::move(AdcSample_DigiHSTruth));
638 return StatusCode::SUCCESS;
644 const std::vector<std::pair<float,float> > *TimeE,
staticVecDouble_t &sampleList,
660 nsamples = Shape.size();
661 nsamples_der = ShapeDer.size();
665 return StatusCode::FAILURE;
670 for (i=0;i<nsamples;i++)
672 msg() << MSG::DEBUG << Shape[i] <<
" ";
679for (
const auto& [energy, time] : *TimeE) {
692 int ishift=(int)(rint(time*(1./25.)));
693 double dtime=time-25.*((double)(ishift));
698 msg() << MSG::DEBUG <<
" time/i/j " << time <<
" "<< i <<
" " << j;
700 if (j >=0 && j < nsamples ) {
701 if (j<nsamples_der && std::abs(ShapeDer[j])<10. )
702 sampleList[i] += (Shape[j]- ShapeDer[j]*dtime)*energy ;
703 else sampleList[i] += Shape[j]*energy ;
714 float timeBinWidth = 25./24.*3.;
722 int ishift = (int)(time*(1./25.));
725 tbin = (int)(fmod(time,25)/timeBinWidth);
731 tbin = (int)(fmod(-time,25)/timeBinWidth);
734 double dtime = time - ( 25.*((float)(ishift)) - timeBinWidth*tbin);
736 Shape = shape->
Shape(ch_id,igain,tbin);
737 ShapeDer = shape->
ShapeDer(ch_id,igain,tbin);
739 nsamples = Shape.size();
740 nsamples_der = ShapeDer.size();
749 if (j >=0 && j < nsamples ) {
750 if (j<nsamples_der && std::abs(ShapeDer[j])<10. )
751 sampleList[i] += (Shape[j]- ShapeDer[j]*dtime)*energy ;
752 else sampleList[i] += Shape[j]*energy ;
759 return StatusCode::SUCCESS;
768 int sampleGainChoice{2};
774 sampleGainChoice -= 1;
784 float Pedestal = pedestal->
pedestal(ch_id, gainChoosingGain);
789 const auto& polynom_adc2mev = adc2MeVs->
ADC2MEV(ch_id, gainChoosingGain);
790 if (polynom_adc2mev.size() < 2) {
791 ATH_MSG_WARNING(
" No ramp found for channel " <<
m_laronline_id->channel_name(ch_id) <<
", gain " << gainChoosingGain <<
", gain choice failed...");
794 const float pseudoADC3 = samples[sampleGainChoice] / (polynom_adc2mev[1]) / SF + Pedestal;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Definition of CaloDetDescrManager.
interface to a tool that returns the time offset of the current trigger.
LArBadXCont< LArBadFeb > LArBadFebCont
LArBadXCont< LArBadChannel > LArBadChannelCont
Handle class for recording to StoreGate.
A wrapper class for event-slot-local random engines.
void setSeedLegacy(const std::string &algName, const EventContext &ctx, uint32_t offset, SeedingOptionType seeding, EventContext::ContextEvt_t evt=EventContext::INVALID_CONTEXT_EVT)
Set the random seed using a string (e.g.
SeedingOptionType
Options for seeding.
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
const ServiceHandle< StoreGateSvc > & detStore() const
This class initializes the Calo (LAr and Tile) offline identifiers.
const LArHEC_ID * getHEC_ID(void) const
const LArFCAL_ID * getFCAL_ID(void) const
const LArEM_ID * getEM_ID(void) const
a typed memory pool that saves time spent allocation small object.
void reserve(unsigned int size)
Set the desired capacity.
pointer nextElementPtr()
obtain the next available element in pool by pointer pool is resized if its limit has been reached On...
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
virtual float pedestalRMS(const HWIdentifier &id, int gain) const =0
access to RMS of Pedestal index by Identifier, and gain setting
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
virtual const float & FSAMPL(const HWIdentifier &id) const =0
value_type get_compact() const
Get the compact id.
This is a "hash" representation of an Identifier.
value_type get_compact() const
Get the compact id.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
const LArVectorProxy ADC2MEV(const HWIdentifier &id, int gain) const
const std::vector< float > & autoCorrSqrt(const HWIdentifier &id, int gain) const
LArBC_t status(const HWIdentifier channel) const
Query the status of a particular channel or FEB This is the main client access method.
Liquid Argon digit base class.
CaloGain::CaloGain gain() const
const std::vector< short > & samples() const
Gaudi::Property< bool > m_usePhase
Gaudi::Property< bool > m_isMcOverlay
const LArHEC_ID * m_larhec_id
Gaudi::Property< std::vector< std::string > > m_problemsToMask
static constexpr int s_MaxNSamples
Gaudi::Property< bool > m_NoiseInEMEC
Gaudi::Property< bool > m_doDigiTruth
SG::ReadHandleKey< LArHitEMap > m_hitMapKey
SG::ReadCondHandleKey< LArADC2MeV > m_adc2mevKey
StatusCode ConvertHits2Samples(const Identifier &cellId, HWIdentifier ch_id, CaloGain::CaloGain igain, const std::vector< std::pair< float, float > > *TimeE, staticVecDouble_t &sampleList, const ILArShape *shape) const
const CaloCell_ID * m_calocell_id
Gaudi::Property< bool > m_pedestalNoise
Gaudi::Property< bool > m_roundingNoNoise
SG::ReadHandleKey< LArHitEMap > m_hitMapKey_DigiHSTruth
StatusCode MakeDigit(const EventContext &ctx, const Identifier &cellId, const HWIdentifier &ch_id, LArDigit *&Digit, DataPool< LArDigit > &dataItemsPool, LArDigit *&Digit_DigiHSTruth, const std::vector< std::pair< float, float > > *TimeE, const LArDigit *rndm_digit, CLHEP::HepRandomEngine *engine, const std::vector< std::pair< float, float > > *TimeE_DigiHSTruth, const LArADC2MeV *adc2MeVs, const ILArfSampl *fSampl, const ILArPedestal *pedestal, const ILArNoise *noise, const LArAutoCorrNoise *autoCorrNoise, const LArBadChannelCont *bcCont, const ILArShape *shape) const
std::array< Gaudi::Property< std::pair< int, int > >, 4 > m_gainRange
virtual StatusCode execute(const EventContext &context) const
Gaudi::Property< uint32_t > m_randomSeedOffset
Gaudi::Property< bool > m_NoiseInEMB
SG::ReadCondHandleKey< LArBadChannelCont > m_bcContKey
Gaudi::Property< int > m_firstSample
SG::WriteHandleKey< LArDigitContainer > m_DigitContainerName_DigiHSTruth
const LArOnlineID * m_laronline_id
Gaudi::Property< bool > m_NoiseInHEC
boost::container::static_vector< double, s_MaxNSamples > staticVecDouble_t
Gaudi::Property< bool > m_useLegacyRandomSeeds
const LArFCAL_ID * m_larfcal_id
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
std::array< Gaudi::Property< double >, 4 > m_LowGainThresh
virtual StatusCode initialize()
SG::ReadCondHandleKey< ILArPedestal > m_pedestalKey
const LArEM_ID * m_larem_id
SG::ReadCondHandleKey< ILArNoise > m_noiseKey
CaloGain::CaloGain chooseGain(const staticVecDouble_t &samples, const HWIdentifier id, const CaloNum iCalo, const ILArPedestal *ped, const LArADC2MeV *ramp, const float SF) const
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Gaudi::Property< bool > m_Windows
LArBadChannelMask m_bcMask
Gaudi::Property< bool > m_NoiseOnOff
std::array< Gaudi::Property< double >, 4 > m_HighGainThresh
boost::container::static_vector< float, s_MaxNSamples > staticVecFloat_t
Gaudi::Property< bool > m_RndmEvtOverlay
Gaudi::Property< int > m_NSamples
SG::ReadCondHandleKey< ILArOFC > m_OFCKey
ServiceHandle< IAthRNGSvc > m_rndmGenSvc
SG::ReadCondHandleKey< LArAutoCorrNoise > m_autoCorrNoiseKey
const T * pointerFromKey(const EventContext &context, const SG::ReadCondHandleKey< T > &key) const
Gaudi::Property< bool > m_NoiseInFCAL
SG::ReadCondHandleKey< LArBadFebCont > m_badFebKey
SG::ReadCondHandleKey< ILArfSampl > m_fSamplKey
Gaudi::Property< unsigned > m_maxADC
SG::WriteHandleKey< LArDigitContainer > m_DigitContainerName
SG::ReadCondHandleKey< ILArShape > m_shapeKey
Gaudi::Property< std::string > m_randomStreamName
size_t GetNbCells(void) const
const LArHitList & GetCell(const unsigned int index) const
const LArDigit * GetDigit(unsigned int index) const
const LARLIST & getData() const
value_type at(size_t i) const
Vector indexing with bounds check.
const_pointer_type cptr()
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts