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,
186 DigitContainer->push_back(Digit);
187 if (DigitContainer_DigiHSTruth){
188 DigitContainer_DigiHSTruth->push_back(Digit_DigiHSTruth);
197 ATH_MSG_DEBUG(
" number of created digits = " << DigitContainer->size());
201 if ( DigitContainer_DigiHSTruth ){
203 ATH_CHECK(DigitContainer_DigiHSTruthHandle.
record( std::move(DigitContainer_DigiHSTruth) ) );
207 return StatusCode::SUCCESS;
211 const EventContext& ctx,
217 const std::vector<std::pair<float, float>>* TimeE,
219 CLHEP::HepRandomEngine* engine,
220 const std::vector<std::pair<float, float>>* TimeE_DigiHSTruth)
const {
221 bool createDigit_DigiHSTruth =
true;
226 short Adc_DigiHSTruth;
229 std::vector<short> AdcSample_DigiHSTruth(
m_NSamples);
254 autoCorrNoise=*autoCorrNoiseHdl;
266 else if (
m_larem_id->is_em_endcap_inner(cellId))
296 ATH_MSG_DEBUG(
" number of hit for this cell " << TimeE->size());
302 bool isDead =
m_bcMask.cellShouldBeMasked(bcCont,ch_id);
306 if( this->
ConvertHits2Samples(ctx, cellId,ch_id,initialGain,TimeE, Samples).isFailure() ) {
307 return StatusCode::SUCCESS;
310 if( this->
ConvertHits2Samples(ctx, cellId,ch_id,initialGain,TimeE_DigiHSTruth, Samples_DigiHSTruth).isFailure() ) {
311 return StatusCode::SUCCESS;
323 rndmGain= rndmEvtDigit->
gain();
324 auto polynom_adc2mev =adc2MeVs->
ADC2MEV(ch_id,rndmEvtDigit->
gain());
325 if (polynom_adc2mev.size() > 1) {
326 float adc2energy = SF * polynom_adc2mev[1];
327 const std::vector<short> & rndm_digit_samples = rndmEvtDigit->
samples() ;
328 float Pedestal = pedestal->
pedestal(ch_id,rndmEvtDigit->
gain());
330 ATH_MSG_WARNING(
" Pedestal not found in database for this channel offID " << cellId <<
" Use sample 0 for random");
331 Pedestal = rndm_digit_samples[0];
333 ATH_MSG_DEBUG(
" Params for inverting LAr Digitization: pedestal " << Pedestal <<
" adc2energy " << adc2energy);
340 if (larOFC.
cptr() !=
nullptr) {
343 if (ofc_a.size()>0) {
344 for (
unsigned int j=0;j<ofc_a.size();j++) sumOfc += ofc_a.
at(j);
346 if (sumOfc>0) adc0 = polynom_adc2mev[0] * SF /sumOfc;
351 if ((
int)(rndm_digit_samples.size()) <
m_NSamples) {
353 "Less digit Samples than requested in digitization for cell "
354 << ch_id.
get_compact() <<
" Digit has " << rndm_digit_samples.size()
355 <<
" samples. Digitization request " <<
m_NSamples);
356 nmax = rndm_digit_samples.size();
358 for(i=0 ; i<
nmax ; i++)
360 rAdc = (rndm_digit_samples[i] - Pedestal ) * adc2energy + adc0;
361 rndm_energy_samples[i] = rAdc ;
373 return StatusCode::FAILURE;
377 igain=std::max(rndmGain,igain);
382 if (igain != initialGain ){
386 else Samples[i] = 0.;
390 if( this->
ConvertHits2Samples(ctx, cellId,ch_id,igain,TimeE, Samples) == StatusCode::FAILURE ) {
391 return StatusCode::SUCCESS;
394 if( this->
ConvertHits2Samples(ctx, cellId,ch_id,igain,TimeE_DigiHSTruth, Samples_DigiHSTruth) == StatusCode::FAILURE ) {
395 return StatusCode::SUCCESS;
409 bool addedNoise=
false;
417 SigmaNoise = noise->noise(ch_id, igain);
426 const std::vector<float>& CorGen =
432 return StatusCode::FAILURE;
435 RandGaussZiggurat::shootArray(engine,
m_NSamples, Rndm, 0., 1.);
440 for (
int j = 0; j <= i; j++) {
442 Noise[i] += Rndm[j] * CorGen[
index];
444 Noise[i] = Noise[i] * SigmaNoise;
457 if (igain > rndmEvtDigit->
gain()) {
458 double SigmaNoiseZB = 0.;
459 double SigmaNoise = 0.;
460 double SigmaExtraNoise = 0.;
462 SigmaNoiseZB = noise->noise(ch_id, rndmEvtDigit->
gain());
463 SigmaNoise = noise->noise(ch_id, igain);
467 SigmaNoiseZB = noise;
477 auto polynom_adc2mevZB =
479 auto polynom_adc2mev = adc2MeVs->
ADC2MEV(cellId, igain);
480 if (polynom_adc2mevZB.size() > 1 && polynom_adc2mev.size() > 1) {
481 if (polynom_adc2mev[1] > 0.) {
482 SigmaNoiseZB = SigmaNoiseZB * (polynom_adc2mevZB[1]) /
483 (polynom_adc2mev[1]);
484 if (SigmaNoise > SigmaNoiseZB)
485 SigmaExtraNoise = sqrt(SigmaNoise * SigmaNoise -
486 SigmaNoiseZB * SigmaNoiseZB);
489 RandGaussZiggurat::shootArray(engine,
m_NSamples, Rndm, 0.,
492 Noise[i] = SigmaExtraNoise * Rndm[i];
501 float Pedestal = pedestal->
pedestal(ch_id,igain);
503 ATH_MSG_WARNING(
" pedestal not found for cellId " << cellId <<
" assume 1000" );
506 const auto polynom_adc2mev = adc2MeVs->
ADC2MEV(cellId,igain);
507 if (polynom_adc2mev.size() < 2) {
508 ATH_MSG_WARNING(
" No ramp found for requested gain " << igain <<
" for cell " <<
m_larem_id->show_to_string(cellId) <<
" no digit made...");
509 return StatusCode::SUCCESS;
512 energy2adc=1./(polynom_adc2mev[1])/SF;
519 if (larOFC.
cptr() !=
nullptr) {
522 if (ofc_a.size()>0) {
523 for (
unsigned int j=0;j<ofc_a.size();j++) sumOfc+= ofc_a.
at(j);
525 if ((polynom_adc2mev[1])>0 && sumOfc>0) Pedestal = Pedestal - (polynom_adc2mev[0])/(polynom_adc2mev[1])/sumOfc;
526 ATH_MSG_DEBUG(
" Params for final LAr Digitization gain: " << igain <<
" pedestal: " << Pedestal <<
" energy2adc: " << energy2adc);
532 double xAdc_DigiHSTruth = 0;
535 xAdc = Samples[i]*energy2adc + Noise[i] + Pedestal + 0.5;
537 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Noise[i] + Pedestal + 0.5;
543 float flatRndm = RandFlat::shoot(engine);
544 xAdc = Samples[i]*energy2adc + Pedestal + flatRndm;
546 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Pedestal + flatRndm;
551 xAdc = Samples[i]*energy2adc + Pedestal + 0.5;
553 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Pedestal + 0.5;
565 else Adc = (short) xAdc;
570 if (xAdc_DigiHSTruth <0) Adc_DigiHSTruth=0;
572 else Adc_DigiHSTruth = (short) xAdc_DigiHSTruth;
573 AdcSample_DigiHSTruth[i] = Adc_DigiHSTruth;
577 ATH_MSG_DEBUG(
" Sample " << i <<
" Energy= " << Samples[i] <<
" Adc=" << Adc);
586 (*Digit)=
LArDigit(ch_id,igain,std::move(AdcSample));
589 createDigit_DigiHSTruth =
false;
590 Digit_DigiHSTruth =
nullptr;
593 if (Samples_DigiHSTruth[i] != 0)
594 createDigit_DigiHSTruth =
true;
598 new LArDigit(ch_id, igain, std::move(AdcSample_DigiHSTruth));
601 return StatusCode::SUCCESS;
608 const std::vector<std::pair<float,float> > *TimeE,
staticVecDouble_t &sampleList)
const
627 nsamples = Shape.size();
628 nsamples_der = ShapeDer.size();
632 return StatusCode::FAILURE;
637 for (i=0;i<nsamples;i++)
645for (
const auto& [energy, time] : *TimeE) {
658 int ishift=(int)(rint(time*(1./25.)));
659 double dtime=time-25.*((double)(ishift));
666 if (j >=0 && j < nsamples ) {
667 if (j<nsamples_der && std::abs(ShapeDer[j])<10. )
668 sampleList[i] += (Shape[j]- ShapeDer[j]*dtime)*energy ;
669 else sampleList[i] += Shape[j]*energy ;
679 float timeBinWidth = 25./24.*3.;
687 int ishift = (int)(time*(1./25.));
690 tbin = (int)(fmod(time,25)/timeBinWidth);
696 tbin = (int)(fmod(-time,25)/timeBinWidth);
699 double dtime = time - ( 25.*((float)(ishift)) - timeBinWidth*tbin);
701 Shape = shape->
Shape(ch_id,igain,tbin);
702 ShapeDer = shape->
ShapeDer(ch_id,igain,tbin);
704 nsamples = Shape.size();
705 nsamples_der = ShapeDer.size();
714 if (j >=0 && j < nsamples ) {
715 if (j<nsamples_der && std::abs(ShapeDer[j])<10. )
716 sampleList[i] += (Shape[j]- ShapeDer[j]*dtime)*energy ;
717 else sampleList[i] += Shape[j]*energy ;
724 return StatusCode::SUCCESS;
731 int sampleGainChoice{2};
737 sampleGainChoice -= 1;
748 float Pedestal = pedestal->
pedestal(ch_id, gainChoosingGain);
753 const auto& polynom_adc2mev = adc2MeVs->
ADC2MEV(ch_id, gainChoosingGain);
754 if (polynom_adc2mev.size() < 2) {
755 ATH_MSG_WARNING(
" No ramp found for channel " <<
m_laronline_id->channel_name(ch_id) <<
", gain " << gainChoosingGain <<
", no digit produced...");
758 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