6#include "CLHEP/Random/RandGaussZiggurat.h"
16#include "CLHEP/Random/RandomEngine.h"
17#include <CLHEP/Random/Randomize.h>
22using CLHEP::RandGaussZiggurat;
30 return StatusCode::FAILURE;
53 StatusCode
sc =
detStore()->retrieve(caloIdMgr);
55 ATH_MSG_ERROR(
" Unable to retrieve CaloIdManager from DetectoreStore");
56 return StatusCode::FAILURE;
64 ATH_MSG_ERROR(
" Unable to retrieve LArOnlineId from DetectoreStore");
65 return StatusCode::FAILURE;
78 std::array<std::pair<int,std::string>,4> iCaloToStr{{{
EM,
"EM"},{
HEC,
"HEC"},{
FCAL,
"FCAL"},{
EMIW,
"EMIW"}}};
80 for (
int iCalo =
EM; iCalo <=
EMIW; ++iCalo) {
87 return StatusCode::FAILURE;
95 return StatusCode::FAILURE;
99 ATH_MSG_ERROR(
" Calo " << iCaloToStr[iCalo] <<
" configured to have only one gain. This is not supported.");
100 return Status::FAILURE;
104 return Status::FAILURE;
110 return StatusCode::SUCCESS;
122 return StatusCode::FAILURE;
143 autoCorrNoise=*autoCorrNoiseHdl;
156 const LArHitEMap* hitmapPtr_DigiHSTruth =
nullptr;
159 hitmapPtr_DigiHSTruth = hitmap_DigitHSTruth.
cptr();
167 DigitContainer->reserve(nCells);
173 std::unique_ptr<LArDigitContainer> DigitContainer_DigiHSTruth =
nullptr;
175 DigitContainer_DigiHSTruth = std::make_unique<LArDigitContainer>();
176 DigitContainer_DigiHSTruth->reserve(nCells);
179 const std::vector<std::pair<float,float> >* TimeE;
180 const std::vector<std::pair<float,float> >* TimeE_DigiHSTruth =
nullptr;
183 CLHEP::HepRandomEngine * engine = rngWrapper->
getEngine(context);
187 for (
size_t it=0;it<nCells;++it)
194 const auto& hitlist_DigiHSTruth=hitmapPtr_DigiHSTruth->
GetCell(it);
195 TimeE_DigiHSTruth = &(hitlist_DigiHSTruth.getData());
202 bool missing=!(badFebs->
status(febId).good());
210 LArDigit* Digit_DigiHSTruth =
nullptr;
213 Digit_DigiHSTruth, TimeE, digit, engine,
224 ATH_MSG_ERROR(
"LArHitEMapToDigitAlg::execute failed in MakeDigit");
225 delete Digit_DigiHSTruth;
228 DigitContainer->push_back(Digit);
229 if (DigitContainer_DigiHSTruth){
230 DigitContainer_DigiHSTruth->push_back(Digit_DigiHSTruth);
239 ATH_MSG_DEBUG(
" number of created digits = " << DigitContainer->size());
243 if ( DigitContainer_DigiHSTruth ){
245 ATH_CHECK(DigitContainer_DigiHSTruthHandle.
record( std::move(DigitContainer_DigiHSTruth) ) );
249 return StatusCode::SUCCESS;
253 const EventContext& ctx,
259 const std::vector<std::pair<float, float>>* TimeE,
261 CLHEP::HepRandomEngine* engine,
262 const std::vector<std::pair<float, float>>* TimeE_DigiHSTruth,
271 bool createDigit_DigiHSTruth =
true;
276 short Adc_DigiHSTruth;
279 std::vector<short> AdcSample_DigiHSTruth(
m_NSamples);
290 else if (
m_larem_id->is_em_endcap_inner(cellId))
320 ATH_MSG_DEBUG(
" number of hit for this cell " << TimeE->size());
326 bool isDead =
m_bcMask.cellShouldBeMasked(bcCont,ch_id);
330 if( this->
ConvertHits2Samples(cellId,ch_id,initialGain,TimeE, Samples, shape).isFailure() ) {
331 return StatusCode::SUCCESS;
334 if( this->
ConvertHits2Samples(cellId,ch_id,initialGain,TimeE_DigiHSTruth, Samples_DigiHSTruth, shape).isFailure() ) {
335 return StatusCode::SUCCESS;
347 rndmGain= rndmEvtDigit->
gain();
348 auto polynom_adc2mev =adc2MeVs->
ADC2MEV(ch_id,rndmEvtDigit->
gain());
349 if (polynom_adc2mev.size() > 1) {
350 float adc2energy = SF * polynom_adc2mev[1];
351 const std::vector<short> & rndm_digit_samples = rndmEvtDigit->
samples() ;
352 float Pedestal = pedestal->
pedestal(ch_id,rndmEvtDigit->
gain());
354 ATH_MSG_WARNING(
" Pedestal not found in database for this channel offID " << cellId <<
" Use sample 0 for random");
355 Pedestal = rndm_digit_samples[0];
357 ATH_MSG_DEBUG(
" Params for inverting LAr Digitization: pedestal " << Pedestal <<
" adc2energy " << adc2energy);
364 if (larOFC.
cptr() !=
nullptr) {
367 if (ofc_a.size()>0) {
368 for (
unsigned int j=0;j<ofc_a.size();j++) sumOfc += ofc_a.
at(j);
370 if (sumOfc>0) adc0 = polynom_adc2mev[0] * SF /sumOfc;
375 if ((
int)(rndm_digit_samples.size()) <
m_NSamples) {
377 "Less digit Samples than requested in digitization for cell "
378 << ch_id.
get_compact() <<
" Digit has " << rndm_digit_samples.size()
379 <<
" samples. Digitization request " <<
m_NSamples);
380 nmax = rndm_digit_samples.size();
382 for(i=0 ; i<
nmax ; i++)
384 rAdc = (rndm_digit_samples[i] - Pedestal ) * adc2energy + adc0;
385 rndm_energy_samples[i] = rAdc ;
397 return StatusCode::FAILURE;
401 igain=std::max(rndmGain,igain);
406 if (igain != initialGain ){
410 else Samples[i] = 0.;
414 if( this->
ConvertHits2Samples(cellId,ch_id,igain,TimeE, Samples, shape) == StatusCode::FAILURE ) {
415 return StatusCode::SUCCESS;
418 if( this->
ConvertHits2Samples(cellId,ch_id,igain,TimeE_DigiHSTruth, Samples_DigiHSTruth, shape) == StatusCode::FAILURE ) {
419 return StatusCode::SUCCESS;
433 bool addedNoise=
false;
441 SigmaNoise = noise->noise(ch_id, igain);
443 float thisNoise = pedestal->
pedestalRMS(ch_id, igain);
445 SigmaNoise = thisNoise;
450 const std::vector<float>& CorGen =
456 return StatusCode::FAILURE;
459 RandGaussZiggurat::shootArray(engine,
m_NSamples, Rndm, 0., 1.);
464 for (
int j = 0; j <= i; j++) {
466 Noise[i] += Rndm[j] * CorGen[
index];
468 Noise[i] = Noise[i] * SigmaNoise;
481 if (igain > rndmEvtDigit->
gain()) {
482 double SigmaNoiseZB = 0.;
483 double SigmaNoise = 0.;
484 double SigmaExtraNoise = 0.;
486 SigmaNoiseZB = noise->noise(ch_id, rndmEvtDigit->
gain());
487 SigmaNoise = noise->noise(ch_id, igain);
491 SigmaNoiseZB = thisNoise;
496 SigmaNoise = thisNoise;
501 auto polynom_adc2mevZB =
503 auto polynom_adc2mev = adc2MeVs->
ADC2MEV(cellId, igain);
504 if (polynom_adc2mevZB.size() > 1 && polynom_adc2mev.size() > 1) {
505 if (polynom_adc2mev[1] > 0.) {
506 SigmaNoiseZB = SigmaNoiseZB * (polynom_adc2mevZB[1]) /
507 (polynom_adc2mev[1]);
508 if (SigmaNoise > SigmaNoiseZB)
509 SigmaExtraNoise = sqrt(SigmaNoise * SigmaNoise -
510 SigmaNoiseZB * SigmaNoiseZB);
513 RandGaussZiggurat::shootArray(engine,
m_NSamples, Rndm, 0.,
516 Noise[i] = SigmaExtraNoise * Rndm[i];
525 float Pedestal = pedestal->
pedestal(ch_id,igain);
527 ATH_MSG_WARNING(
" pedestal not found for cellId " << cellId <<
" assume 1000" );
530 const auto polynom_adc2mev = adc2MeVs->
ADC2MEV(cellId,igain);
531 if (polynom_adc2mev.size() < 2) {
532 ATH_MSG_WARNING(
" No ramp found for requested gain " << igain <<
" for cell " <<
m_larem_id->show_to_string(cellId) <<
" no digit made...");
533 return StatusCode::SUCCESS;
536 energy2adc=1./(polynom_adc2mev[1])/SF;
543 if (larOFC.
cptr() !=
nullptr) {
546 if (ofc_a.size()>0) {
547 for (
unsigned int j=0;j<ofc_a.size();j++) sumOfc+= ofc_a.
at(j);
549 if ((polynom_adc2mev[1])>0 && sumOfc>0) Pedestal = Pedestal - (polynom_adc2mev[0])/(polynom_adc2mev[1])/sumOfc;
550 ATH_MSG_DEBUG(
" Params for final LAr Digitization gain: " << igain <<
" pedestal: " << Pedestal <<
" energy2adc: " << energy2adc);
556 double xAdc_DigiHSTruth = 0;
559 xAdc = Samples[i]*energy2adc + Noise[i] + Pedestal + 0.5;
561 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Noise[i] + Pedestal + 0.5;
567 float flatRndm = RandFlat::shoot(engine);
568 xAdc = Samples[i]*energy2adc + Pedestal + flatRndm;
570 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Pedestal + flatRndm;
575 xAdc = Samples[i]*energy2adc + Pedestal + 0.5;
577 xAdc_DigiHSTruth = Samples_DigiHSTruth[i]*energy2adc + Pedestal + 0.5;
589 else Adc = (short) xAdc;
594 if (xAdc_DigiHSTruth <0) Adc_DigiHSTruth=0;
596 else Adc_DigiHSTruth = (short) xAdc_DigiHSTruth;
597 AdcSample_DigiHSTruth[i] = Adc_DigiHSTruth;
601 ATH_MSG_DEBUG(
" Sample " << i <<
" Energy= " << Samples[i] <<
" Adc=" << Adc);
610 (*Digit)=
LArDigit(ch_id,igain,std::move(AdcSample));
613 createDigit_DigiHSTruth =
false;
614 Digit_DigiHSTruth =
nullptr;
617 if (Samples_DigiHSTruth[i] != 0)
618 createDigit_DigiHSTruth =
true;
622 new LArDigit(ch_id, igain, std::move(AdcSample_DigiHSTruth));
625 return StatusCode::SUCCESS;
631 const std::vector<std::pair<float,float> > *TimeE,
staticVecDouble_t &sampleList,
647 nsamples = Shape.size();
648 nsamples_der = ShapeDer.size();
652 return StatusCode::FAILURE;
657 for (i=0;i<nsamples;i++)
665for (
const auto& [energy, time] : *TimeE) {
678 int ishift=(int)(rint(time*(1./25.)));
679 double dtime=time-25.*((double)(ishift));
686 if (j >=0 && j < nsamples ) {
687 if (j<nsamples_der && std::abs(ShapeDer[j])<10. )
688 sampleList[i] += (Shape[j]- ShapeDer[j]*dtime)*energy ;
689 else sampleList[i] += Shape[j]*energy ;
699 float timeBinWidth = 25./24.*3.;
707 int ishift = (int)(time*(1./25.));
710 tbin = (int)(fmod(time,25)/timeBinWidth);
716 tbin = (int)(fmod(-time,25)/timeBinWidth);
719 double dtime = time - ( 25.*((float)(ishift)) - timeBinWidth*tbin);
721 Shape = shape->
Shape(ch_id,igain,tbin);
722 ShapeDer = shape->
ShapeDer(ch_id,igain,tbin);
724 nsamples = Shape.size();
725 nsamples_der = ShapeDer.size();
734 if (j >=0 && j < nsamples ) {
735 if (j<nsamples_der && std::abs(ShapeDer[j])<10. )
736 sampleList[i] += (Shape[j]- ShapeDer[j]*dtime)*energy ;
737 else sampleList[i] += Shape[j]*energy ;
744 return StatusCode::SUCCESS;
751 int sampleGainChoice{2};
757 sampleGainChoice -= 1;
768 float Pedestal = pedestal->
pedestal(ch_id, gainChoosingGain);
773 const auto& polynom_adc2mev = adc2MeVs->
ADC2MEV(ch_id, gainChoosingGain);
774 if (polynom_adc2mev.size() < 2) {
775 ATH_MSG_WARNING(
" No ramp found for channel " <<
m_laronline_id->channel_name(ch_id) <<
", gain " << gainChoosingGain <<
", no digit produced...");
778 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.
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
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