Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-11-07 23:58:26

0001 #ifndef _hgcfeelectronics_h_
0002 #define _hgcfeelectronics_h_
0003 
0004 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 
0007 #include "CLHEP/Random/RandGauss.h"
0008 #include "CLHEP/Random/RandGaussQ.h"
0009 #include "CLHEP/Random/RandFlat.h"
0010 #include "SimCalorimetry/HGCalSimProducers/interface/HGCDigitizerTypes.h"
0011 
0012 /**
0013    @class HGCFEElectronics
0014    @short models the behavior of the front-end electronics
0015  */
0016 
0017 namespace hgc = hgc_digi;
0018 
0019 namespace hgc_digi {
0020   typedef std::array<float, 6> FEADCPulseShape;
0021 }
0022 
0023 template <class DFr>
0024 class HGCFEElectronics {
0025 public:
0026   enum HGCFEElectronicsFirmwareVersion { TRIVIAL, SIMPLE, WITHTOT };
0027   enum HGCFEElectronicsTOTMode { WEIGHTEDBYE, SIMPLETHRESHOLD };
0028 
0029   /**
0030      @short CTOR
0031    */
0032   HGCFEElectronics(const edm::ParameterSet& ps);
0033 
0034   /**
0035      @short switches according to the firmware version
0036    */
0037   inline void runShaper(DFr& dataFrame,
0038                         hgc::HGCSimHitData& chargeColl,
0039                         hgc::HGCSimHitData& toa,
0040                         const hgc_digi::FEADCPulseShape& adcPulse,
0041                         CLHEP::HepRandomEngine* engine,
0042                         uint32_t thrADC = 0,
0043                         float lsbADC = -1,
0044                         uint32_t gainIdx = 0,
0045                         float maxADC = -1,
0046                         int thickness = 1,
0047                         float tdcOnsetAuto = -1) {
0048     switch (fwVersion_) {
0049       case SIMPLE: {
0050         runSimpleShaper(dataFrame, chargeColl, thrADC, lsbADC, gainIdx, maxADC, adcPulse);
0051         break;
0052       }
0053       case WITHTOT: {
0054         runShaperWithToT(
0055             dataFrame, chargeColl, toa, engine, thrADC, lsbADC, gainIdx, maxADC, thickness, tdcOnsetAuto, adcPulse);
0056         break;
0057       }
0058       default: {
0059         runTrivialShaper(dataFrame, chargeColl, thrADC, lsbADC, gainIdx, maxADC);
0060         break;
0061       }
0062     }
0063   }
0064   inline void runShaper(DFr& dataFrame,
0065                         hgc::HGCSimHitData& chargeColl,
0066                         hgc::HGCSimHitData& toa,
0067                         CLHEP::HepRandomEngine* engine,
0068                         uint32_t thrADC = 0,
0069                         float lsbADC = -1,
0070                         uint32_t gainIdx = 0,
0071                         float maxADC = -1,
0072                         int thickness = 1) {
0073     runShaper(dataFrame, chargeColl, toa, adcPulse_, engine, thrADC, lsbADC, gainIdx, maxADC, thickness);
0074   }
0075 
0076   void SetNoiseValues(const std::vector<float>& noise_fC) {
0077     noise_fC_.insert(noise_fC_.end(), noise_fC.begin(), noise_fC.end());
0078   };
0079 
0080   float getTimeJitter(float totalCharge, int thickness) {
0081     float A2 = jitterNoise2_ns_.at(thickness - 1);
0082     float C2 = jitterConstant2_ns_.at(thickness - 1);
0083     float X2 = pow((totalCharge / noise_fC_.at(thickness - 1)), 2.);
0084     float jitter2 = A2 / X2 + C2;
0085     return sqrt(jitter2);
0086   };
0087 
0088   /**
0089      @short returns the LSB currently configured
0090   */
0091   float getADClsb() { return adcLSB_fC_; }
0092   float getTDClsb() { return tdcLSB_fC_; }
0093   int getTargetMipValue() { return targetMIPvalue_ADC_; }
0094   float getADCThreshold() { return adcThreshold_fC_; }
0095   float getMaxADC() { return adcSaturation_fC_; }
0096   float getMaxTDC() { return tdcSaturation_fC_; }
0097   float getTDCOnset() { return tdcOnset_fC_; }
0098   std::array<float, 3> getTDCForToAOnset() { return tdcForToAOnset_fC_; }
0099   void setADClsb(float newLSB) { adcLSB_fC_ = newLSB; }
0100   void setTDCfsc(float newTDCfsc) {
0101     tdcSaturation_fC_ = newTDCfsc;
0102     tdcLSB_fC_ = tdcSaturation_fC_ / pow(2., tdcNbits_);
0103     // lower tdcSaturation_fC_ by one part in a million
0104     // to ensure largest charge converted in bits is 0xfff and not 0x000
0105     tdcSaturation_fC_ *= (1. - 1e-6);
0106   }
0107 
0108   /**
0109      @short converts charge to digis without pulse shape
0110    */
0111   void runTrivialShaper(
0112       DFr& dataFrame, hgc::HGCSimHitData& chargeColl, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC);
0113 
0114   /**
0115      @short applies a shape to each time sample and propagates the tails to the subsequent time samples
0116    */
0117   void runSimpleShaper(DFr& dataFrame,
0118                        hgc::HGCSimHitData& chargeColl,
0119                        uint32_t thrADC,
0120                        float lsbADC,
0121                        uint32_t gainIdx,
0122                        float maxADC,
0123                        const hgc_digi::FEADCPulseShape& adcPulse);
0124   void runSimpleShaper(
0125       DFr& dataFrame, hgc::HGCSimHitData& chargeColl, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC) {
0126     runSimpleShaper(dataFrame, chargeColl, thrADC, lsbADC, gainIdx, maxADC, adcPulse_);
0127   }
0128 
0129   /**
0130      @short implements pulse shape and switch to time over threshold including deadtime
0131    */
0132   void runShaperWithToT(DFr& dataFrame,
0133                         hgc::HGCSimHitData& chargeColl,
0134                         hgc::HGCSimHitData& toa,
0135                         CLHEP::HepRandomEngine* engine,
0136                         uint32_t thrADC,
0137                         float lsbADC,
0138                         uint32_t gainIdx,
0139                         float maxADC,
0140                         int thickness,
0141                         float tdcOnsetAuto,
0142                         const hgc_digi::FEADCPulseShape& adcPulse);
0143   void runShaperWithToT(DFr& dataFrame,
0144                         hgc::HGCSimHitData& chargeColl,
0145                         hgc::HGCSimHitData& toa,
0146                         CLHEP::HepRandomEngine* engine,
0147                         uint32_t thrADC,
0148                         float lsbADC,
0149                         uint32_t gainIdx,
0150                         float maxADC,
0151                         int thickness,
0152                         float tdcOnsetAuto) {
0153     runShaperWithToT(
0154         dataFrame, chargeColl, toa, engine, thrADC, lsbADC, gainIdx, maxADC, thickness, tdcOnsetAuto, adcPulse_);
0155   }
0156 
0157   /**
0158      @short returns how ToT will be computed
0159    */
0160   uint32_t toaMode() const { return toaMode_; }
0161 
0162   /**
0163      @short getter for the default ADC pulse configured by python
0164    */
0165   hgc_digi::FEADCPulseShape& getDefaultADCPulse() { return adcPulse_; }
0166 
0167   /**
0168      @short DTOR
0169    */
0170   ~HGCFEElectronics() {}
0171 
0172 private:
0173   //private members
0174   uint32_t fwVersion_;
0175   hgc_digi::FEADCPulseShape adcPulse_, pulseAvgT_;
0176   std::array<float, 3> tdcForToAOnset_fC_;
0177   std::vector<float> tdcChargeDrainParameterisation_;
0178   float adcSaturation_fC_, adcLSB_fC_, tdcLSB_fC_, tdcSaturation_fC_, adcThreshold_fC_, tdcOnset_fC_, toaLSB_ns_,
0179       tdcResolutionInNs_;
0180   uint32_t targetMIPvalue_ADC_;
0181   std::array<float, 3> jitterNoise2_ns_, jitterConstant2_ns_;
0182   std::vector<float> noise_fC_;
0183   uint32_t toaMode_;
0184   uint32_t tdcNbits_;
0185   bool thresholdFollowsMIP_;
0186   //caches
0187   std::array<bool, hgc::nSamples> busyFlags, totFlags, toaFlags;
0188   hgc::HGCSimHitData newCharge, toaFromToT;
0189 };
0190 
0191 #endif