6#include "CLHEP/Random/RandGaussZiggurat.h"
16#include "CLHEP/Random/RandomEngine.h"
17#include <CLHEP/Random/Randomize.h>
21using CLHEP::RandGaussZiggurat;
29 return StatusCode::FAILURE;
52 StatusCode
sc =
detStore()->retrieve(caloIdMgr);
54 ATH_MSG_ERROR(
" Unable to retrieve CaloIdManager from DetectoreStore");
55 return StatusCode::FAILURE;
63 ATH_MSG_ERROR(
" Unable to retrieve LArOnlineId from DetectoreStore");
64 return StatusCode::FAILURE;
77 std::array<std::pair<int,std::string>,4> iCaloToStr{{{
EM,
"EM"},{
HEC,
"HEC"},{
FCAL,
"FCAL"},{
EMIW,
"EMIW"}}};
79 for (
int iCalo =
EM; iCalo <=
EMIW; ++iCalo) {
86 return StatusCode::FAILURE;
94 return StatusCode::FAILURE;
98 ATH_MSG_ERROR(
" Calo " << iCaloToStr[iCalo] <<
" configured to have only one gain. This is not supported.");
99 return Status::FAILURE;
103 return Status::FAILURE;
109 return StatusCode::SUCCESS;
121 return StatusCode::FAILURE;
127 const LArHitEMap* hitmapPtr_DigiHSTruth =
nullptr;
130 hitmapPtr_DigiHSTruth = hitmap_DigitHSTruth.
cptr();
138 DigitContainer->reserve(nCells);
144 std::unique_ptr<LArDigitContainer> DigitContainer_DigiHSTruth =
nullptr;
146 DigitContainer_DigiHSTruth = std::make_unique<LArDigitContainer>();
147 DigitContainer_DigiHSTruth->reserve(nCells);
150 const std::vector<std::pair<float,float> >* TimeE;
151 const std::vector<std::pair<float,float> >* TimeE_DigiHSTruth =
nullptr;
154 CLHEP::HepRandomEngine * engine = rngWrapper->
getEngine(context);
158 for (
size_t it=0;it<nCells;++it)
165 const auto& hitlist_DigiHSTruth=hitmapPtr_DigiHSTruth->
GetCell(it);
166 TimeE_DigiHSTruth = &(hitlist_DigiHSTruth.getData());
173 bool missing=!(badFebs->
status(febId).good());
181 LArDigit* Digit_DigiHSTruth =
nullptr;
184 Digit_DigiHSTruth, TimeE, digit, engine,
187 ATH_MSG_ERROR(
"LArHitEMapToDigitAlg::execute failed in MakeDigit");
188 delete Digit_DigiHSTruth;
191 DigitContainer->push_back(Digit);
192 if (DigitContainer_DigiHSTruth){
193 DigitContainer_DigiHSTruth->push_back(Digit_DigiHSTruth);
202 ATH_MSG_DEBUG(
" number of created digits = " << DigitContainer->size());
206 if ( DigitContainer_DigiHSTruth ){
208 ATH_CHECK(DigitContainer_DigiHSTruthHandle.
record( std::move(DigitContainer_DigiHSTruth) ) );
212 return StatusCode::SUCCESS;
216 const EventContext& ctx,
222 const std::vector<std::pair<float, float>>* TimeE,
224 CLHEP::HepRandomEngine* engine,
225 const std::vector<std::pair<float, float>>* TimeE_DigiHSTruth)
const {
226 bool createDigit_DigiHSTruth =
true;
231 short Adc_DigiHSTruth;
234 std::vector<short> AdcSample_DigiHSTruth(
m_NSamples);
259 autoCorrNoise=*autoCorrNoiseHdl;
271 else if (
m_larem_id->is_em_endcap_inner(cellId))
301 ATH_MSG_DEBUG(
" number of hit for this cell " << TimeE->size());
307 bool isDead =
m_bcMask.cellShouldBeMasked(bcCont,ch_id);
311 if( this->
ConvertHits2Samples(ctx, cellId,ch_id,initialGain,TimeE, Samples).isFailure() ) {
312 return StatusCode::SUCCESS;
315 if( this->
ConvertHits2Samples(ctx, cellId,ch_id,initialGain,TimeE_DigiHSTruth, Samples_DigiHSTruth).isFailure() ) {
316 return StatusCode::SUCCESS;
328 rndmGain= rndmEvtDigit->
gain();
329 auto polynom_adc2mev =adc2MeVs->
ADC2MEV(ch_id,rndmEvtDigit->
gain());
330 if (polynom_adc2mev.size() > 1) {
331 float adc2energy = SF * polynom_adc2mev[1];
332 const std::vector<short> & rndm_digit_samples = rndmEvtDigit->
samples() ;
333 float Pedestal = pedestal->
pedestal(ch_id,rndmEvtDigit->
gain());
335 ATH_MSG_WARNING(
" Pedestal not found in database for this channel offID " << cellId <<
" Use sample 0 for random");
336 Pedestal = rndm_digit_samples[0];
338 ATH_MSG_DEBUG(
" Params for inverting LAr Digitization: pedestal " << Pedestal <<
" adc2energy " << adc2energy);
345 if (larOFC.
cptr() !=
nullptr) {
348 if (ofc_a.size()>0) {
349 for (
unsigned int j=0;j<ofc_a.size();j++) sumOfc += ofc_a.
at(j);
351 if (sumOfc>0) adc0 = polynom_adc2mev[0] * SF /sumOfc;
356 if ((
int)(rndm_digit_samples.size()) <
m_NSamples) {
358 "Less digit Samples than requested in digitization for cell "
359 << ch_id.
get_compact() <<
" Digit has " << rndm_digit_samples.size()
360 <<
" samples. Digitization request " <<
m_NSamples);
361 nmax = rndm_digit_samples.size();
363 for(i=0 ; i<
nmax ; i++)
365 rAdc = (rndm_digit_samples[i] - Pedestal ) * adc2energy + adc0;
366 rndm_energy_samples[i] = rAdc ;
378 return StatusCode::FAILURE;
382 igain=std::max(rndmGain,igain);
387 if (igain != initialGain ){
391 else Samples[i] = 0.;
395 if( this->
ConvertHits2Samples(ctx, cellId,ch_id,igain,TimeE, Samples) == StatusCode::FAILURE ) {
396 return StatusCode::SUCCESS;
399 if( this->
ConvertHits2Samples(ctx, cellId,ch_id,igain,TimeE_DigiHSTruth, Samples_DigiHSTruth) == StatusCode::FAILURE ) {
400 return StatusCode::SUCCESS;
414 bool addedNoise=
false;
422 SigmaNoise = noise->noise(ch_id, igain);
431 const std::vector<float>& CorGen =
437 return StatusCode::FAILURE;
440 RandGaussZiggurat::shootArray(engine,
m_NSamples, Rndm, 0., 1.);
445 for (
int j = 0; j <= i; j++) {
447 Noise[i] += Rndm[j] * CorGen[
index];
449 Noise[i] = Noise[i] * SigmaNoise;
462 if (igain > rndmEvtDigit->
gain()) {
463 double SigmaNoiseZB = 0.;
464 double SigmaNoise = 0.;
465 double SigmaExtraNoise = 0.;
467 SigmaNoiseZB = noise->noise(ch_id, rndmEvtDigit->
gain());
468 SigmaNoise = noise->noise(ch_id, igain);
472 SigmaNoiseZB = noise;
482 auto polynom_adc2mevZB =
484 auto polynom_adc2mev = adc2MeVs->
ADC2MEV(cellId, igain);
485 if (polynom_adc2mevZB.size() > 1 && polynom_adc2mev.size() > 1) {
486 if (polynom_adc2mev[1] > 0.) {
487 SigmaNoiseZB = SigmaNoiseZB * (polynom_adc2mevZB[1]) /
488 (polynom_adc2mev[1]);
489 if (SigmaNoise > SigmaNoiseZB)
490 SigmaExtraNoise = sqrt(SigmaNoise * SigmaNoise -
491 SigmaNoiseZB * SigmaNoiseZB);
494 RandGaussZiggurat::shootArray(engine,
m_NSamples, Rndm, 0.,
497 Noise[i] = SigmaExtraNoise * Rndm[i];
506 float Pedestal = pedestal->
pedestal(ch_id,igain);
508 ATH_MSG_WARNING(
" pedestal not found for cellId " << cellId <<
" assume 1000" );
511 const auto polynom_adc2mev = adc2MeVs->
ADC2MEV(cellId,igain);
512 if (polynom_adc2mev.size() < 2) {
513 ATH_MSG_WARNING(
" No ramp found for requested gain " << igain <<
" for cell " <<
m_larem_id->show_to_string(cellId) <<
" no digit made...");
514 return StatusCode::SUCCESS;
517 energy2adc=1./(polynom_adc2mev[1])/SF;
524 if (larOFC.
cptr() !=
nullptr) {
527 if (ofc_a.size()>0) {
528 for (
unsigned int j=0;j<ofc_a.size();j++) sumOfc+= ofc_a.
at(j);
530 if ((polynom_adc2mev[1])>0 && sumOfc>0) Pedestal = Pedestal - (polynom_adc2mev[0])/(polynom_adc2mev[1])/sumOfc;
531 ATH_MSG_DEBUG(
" Params for final LAr Digitization gain: " << igain <<
" pedestal: " << Pedestal <<
" energy2adc: " << energy2adc);
537 double xAdc_DigiHSTruth = 0;
540 xAdc = Samples[i]*energy2adc + Noise[i] + Pedestal + 0.5;
542 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Noise[i] + Pedestal + 0.5;
548 float flatRndm = RandFlat::shoot(engine);
549 xAdc = Samples[i]*energy2adc + Pedestal + flatRndm;
551 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Pedestal + flatRndm;
556 xAdc = Samples[i]*energy2adc + Pedestal + 0.5;
558 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Pedestal + 0.5;
570 else Adc = (short) xAdc;
575 if (xAdc_DigiHSTruth <0) Adc_DigiHSTruth=0;
577 else Adc_DigiHSTruth = (short) xAdc_DigiHSTruth;
578 AdcSample_DigiHSTruth[i] = Adc_DigiHSTruth;
582 ATH_MSG_DEBUG(
" Sample " << i <<
" Energy= " << Samples[i] <<
" Adc=" << Adc);
591 (*Digit)=
LArDigit(ch_id,igain,std::move(AdcSample));
594 createDigit_DigiHSTruth =
false;
595 Digit_DigiHSTruth =
nullptr;
598 if (Samples_DigiHSTruth[i] != 0)
599 createDigit_DigiHSTruth =
true;
603 new LArDigit(ch_id, igain, std::move(AdcSample_DigiHSTruth));
606 return StatusCode::SUCCESS;
613 const std::vector<std::pair<float,float> > *TimeE,
staticVecDouble_t &sampleList)
const
632 nsamples = Shape.size();
633 nsamples_der = ShapeDer.size();
637 return StatusCode::FAILURE;
642 for (i=0;i<nsamples;i++)
650for (
const auto& [energy, time] : *TimeE) {
663 int ishift=(int)(rint(time*(1./25.)));
664 double dtime=time-25.*((double)(ishift));
671 if (j >=0 && j < nsamples ) {
672 if (j<nsamples_der && std::abs(ShapeDer[j])<10. )
673 sampleList[i] += (Shape[j]- ShapeDer[j]*dtime)*energy ;
674 else sampleList[i] += Shape[j]*energy ;
684 float timeBinWidth = 25./24.*3.;
692 int ishift = (int)(time*(1./25.));
695 tbin = (int)(fmod(time,25)/timeBinWidth);
701 tbin = (int)(fmod(-time,25)/timeBinWidth);
704 double dtime = time - ( 25.*((float)(ishift)) - timeBinWidth*tbin);
706 Shape = shape->
Shape(ch_id,igain,tbin);
707 ShapeDer = shape->
ShapeDer(ch_id,igain,tbin);
709 nsamples = Shape.size();
710 nsamples_der = ShapeDer.size();
719 if (j >=0 && j < nsamples ) {
720 if (j<nsamples_der && std::abs(ShapeDer[j])<10. )
721 sampleList[i] += (Shape[j]- ShapeDer[j]*dtime)*energy ;
722 else sampleList[i] += Shape[j]*energy ;
729 return StatusCode::SUCCESS;
736 int sampleGainChoice{2};
742 sampleGainChoice -= 1;
753 float Pedestal = pedestal->
pedestal(ch_id, gainChoosingGain);
758 const auto& polynom_adc2mev = adc2MeVs->
ADC2MEV(ch_id, gainChoosingGain);
759 if (polynom_adc2mev.size() < 2) {
760 ATH_MSG_WARNING(
" No ramp found for channel " <<
m_laronline_id->channel_name(ch_id) <<
", gain " << gainChoosingGain <<
", no digit produced...");
763 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
A wrapper class for event-slot-local random engines.
SeedingOptionType
Options for seeding option=0 is setSeed as in MC20 option=1 is setSeedLegacy as in MC16 option=2 is s...
void setSeedLegacy(const std::string &algName, size_t slot, uint64_t ev, uint64_t run, uint64_t offset, SeedingOptionType seeding, EventContext::ContextEvt_t evt=EventContext::INVALID_CONTEXT_EVT)
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.
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
This is a "hash" representation of an Identifier.
value_type get_compact() const
Get the compact id.
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
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=nullptr) 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
StatusCode ConvertHits2Samples(const EventContext &ctx, const Identifier &cellId, HWIdentifier ch_id, CaloGain::CaloGain igain, const std::vector< std::pair< float, float > > *TimeE, staticVecDouble_t &sampleList) const
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