Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-01 09:06:28

0001 /** @class sipm::SiPMProperties SimSiPM/SimSiPM/SiPMProperties.h
0002  * SiPMDigitalSignal.h
0003  *
0004  *  @brief Class storing all the parameters that describe a SiPM.
0005  *
0006  *  This class stores all the parameters and values used to describe a SiPM
0007  *  sensor or signal. It also allows to switch on or off some noise effects
0008  *  and can set different levels of detail in the evaluation of PDE.
0009  *
0010  *  @author Edoardo Proserpio
0011  *  @date 2020
0012  */
0013 
0014 #ifndef SIPM_SIPMPROPERTIES_H
0015 #define SIPM_SIPMPROPERTIES_H
0016 
0017 #include <cmath>
0018 #include <cstdint>
0019 #include <iostream>
0020 #include <map>
0021 #include <sstream>
0022 #include <string>
0023 #include <vector>
0024 
0025 namespace sipm {
0026 class SiPMProperties {
0027 public:
0028   /** @enum PdeType
0029    * @brief Used to set different methods to evaluate PDE for each photon.
0030    */
0031   enum class PdeType {
0032     kNoPde,      ///< No PDE applied, all photons will turn in photoelectrons
0033     kSimplePde,  ///< Same PDE value used for all photons
0034     kSpectrumPde ///< PDE calculated considering the wavelength of each photon
0035   };
0036   /** @enum HitDistribution
0037    * Used to describe how photoelectrons are distributed on the SiPM surface
0038    */
0039   enum class HitDistribution {
0040     kUniform, ///< Photons uniformly distributed on the sensor surface
0041     kCircle,  ///< 95% of photons are uniformly distributed on a circle
0042     kGaussian ///< 95% of photons have a gaussian distribution
0043   };
0044 
0045   SiPMProperties();
0046 
0047   /// @brief Used to read settings from a json file
0048   static SiPMProperties readSettings(const std::string&);
0049 
0050   /// @brief Returns size of sensor in mm
0051   constexpr uint32_t size() const { return m_Size; }
0052 
0053   /// @brief Returns pitch of cell in um
0054   constexpr uint32_t pitch() const { return m_Pitch; }
0055 
0056   /// @brief Returns total number of cells in the sensor
0057   constexpr uint32_t nCells() const { return m_Ncells; }
0058 
0059   /// @brief Returns number of cells in the side of the sensor
0060   constexpr uint32_t nSideCells() const { return m_SideCells; }
0061 
0062   /// @brief Returns total number of points in the signal
0063   constexpr uint32_t nSignalPoints() const { return m_SignalPoints; }
0064 
0065   /// @brief Returns @ref HitDistribution type of the sensor
0066   constexpr HitDistribution hitDistribution() const { return m_HitDistribution; }
0067 
0068   /// @brief Returns total signal length in ns
0069   constexpr double signalLength() const { return m_SignalLength; }
0070 
0071   /// @brief Returns sampling time considered by the sensor in ns
0072   constexpr double sampling() const { return m_Sampling; }
0073 
0074   /// @brief Returns rising time constant @sa SiPMSensor::signalShape
0075   constexpr double risingTime() const { return m_RiseTime; }
0076 
0077   /// @brief Returns falling time constant @sa SiPMSensor::signalShape
0078   constexpr double fallingTimeFast() const { return m_FallTimeFast; }
0079 
0080   /// @brief Returns falling time constant of slow component @sa
0081   /// SiPMSensor::signalShape
0082   constexpr double fallingTimeSlow() const { return m_FallTimeSlow; }
0083 
0084   /// @brief Returns weight of slow component of the signal @sa
0085   /// SiPMSensor::signalShape.
0086   constexpr double slowComponentFraction() const { return m_SlowComponentFraction; }
0087 
0088   /// @brief Returns recovery time of SiPM cells.
0089   constexpr double recoveryTime() const { return m_RecoveryTime; }
0090 
0091   /// @brief Returns DCR value.
0092   constexpr double dcr() const { return m_Dcr; }
0093 
0094   /// @brief Returns XT value.
0095   constexpr double xt() const { return m_Xt; }
0096 
0097   /// @brief Returns Delayed XT value.
0098   constexpr double dxt() const { return m_DXt; }
0099 
0100   /// @brief Returns Delayed XT tau.
0101   constexpr double dxtTau() const { return m_DXtTau; }
0102 
0103   /// @brief Returns AP value.
0104   constexpr double ap() const { return m_Ap; }
0105 
0106   /// @brief Returns fast time constant for AP.
0107   constexpr double tauApFast() const { return m_TauApFastComponent; }
0108 
0109   /// @brief Returns slow time constant for AP.
0110   constexpr double tauApSlow() const { return m_TauApSlowComponent; }
0111 
0112   /// @brief Returns fraction of AP generated as slow.
0113   constexpr double apSlowFraction() const { return m_ApSlowFraction; }
0114 
0115   /// @brief Returns value of cell-to-cell gain variation.
0116   constexpr float ccgv() const { return m_Ccgv; }
0117 
0118   /// @brief Returns relative gain.
0119   constexpr double gain() const { return m_Gain; }
0120 
0121   /// @brief Returns SNR in dB.
0122   constexpr double snrdB() const { return m_SnrdB; }
0123 
0124   /// @brief Returns RMS of the noise.
0125   constexpr double snrLinear() const { return m_SnrLinear; }
0126 
0127   /// @brief Returns value of PDE if PdeType::kSimplePde is set.
0128   constexpr double pde() const { return m_Pde; }
0129 
0130   /// @brief Returns wavelength-PDE values if PdeType::kSpectrumPde is set
0131   std::map<double, double> pdeSpectrum() const { return m_PdeSpectrum; }
0132 
0133   /// @brief Returns type of PDE calculation used.
0134   constexpr PdeType pdeType() { return m_HasPde; }
0135 
0136   /// @brief Returns true if DCR is considered.
0137   constexpr bool hasDcr() const { return m_HasDcr; }
0138 
0139   /// @brief Returns true if XT is considered.
0140   constexpr bool hasXt() const { return m_HasXt; }
0141 
0142   /// @brief Returns true if Delayes XT is considered.
0143   constexpr bool hasDXt() const { return m_HasDXt; }
0144 
0145   /// @brief Returns true if AP is considered.
0146   constexpr bool hasAp() const { return m_HasAp; }
0147 
0148   /// @brief Returns true if slow component of the signal is considered.
0149   /// @sa SiPMSensor::signalShape
0150   constexpr bool hasSlowComponent() const { return m_HasSlowComponent; }
0151 
0152   /// @brief Sets a property using its name
0153   void setProperty(const std::string&, const double);
0154 
0155   /// @brief Set size of SiPM sensitive area (side in mm)
0156   ///@param x Size of sipm sensor in mm
0157   constexpr void setSize(const double x) {
0158     m_Size = x;
0159     m_SideCells = 1000 * m_Size / m_Pitch;
0160     m_Ncells = m_SideCells * m_SideCells;
0161   }
0162 
0163   /// @brief Set pitch of SiPM cells (side in um)
0164   /// @param x Size of sipm cell in um
0165   constexpr void setPitch(const double x) {
0166     m_Pitch = x;
0167     m_SideCells = 1000 * m_Size / m_Pitch;
0168     m_Ncells = m_SideCells * m_SideCells;
0169   }
0170 
0171   /// @brief Set sampling time of the signal in ns
0172   void setSampling(const double x) {
0173     m_Sampling = x;
0174     m_SignalPoints = m_SignalLength / m_Sampling;
0175   }
0176 
0177   /// @brief Set length of the signa in ns
0178   /// @param x Signal length in ns
0179   constexpr void setSignalLength(const double x) {
0180     m_SignalLength = x;
0181     m_SignalPoints = m_SignalLength / m_Sampling;
0182   }
0183 
0184   /// @brief Set rising time constant of signal @sa SiPMSensor::signalShape
0185   /// @param x Signal risign time constant in ns
0186   constexpr void setRiseTime(const double x) { m_RiseTime = x; }
0187 
0188   /// @brief Set falling time constant of signal @sa SiPMSensor::signalShape
0189   /// @param x Signal falling time constant for fast component in ns
0190   constexpr void setFallTimeFast(const double x) { m_FallTimeFast = x; }
0191 
0192   /// @brief Set falling time constant for the slow component of signal @sa
0193   /// SiPMSensor::signalShape
0194   /// @param x Signal falling time constant for slow component in ns
0195   constexpr void setFallTimeSlow(const double x) {
0196     m_FallTimeSlow = x;
0197     m_HasSlowComponent = true;
0198   }
0199 
0200   /// @brief Set weigth of slow component in the signal
0201   /// @param x Weight of slow component in the signa. Must be a value in range [0,1]
0202   constexpr void setSlowComponentFraction(const double x) {
0203     m_SlowComponentFraction = x;
0204     m_HasSlowComponent = true;
0205   }
0206 
0207   /// @brief Set recovery time of the SiPM cell
0208   /// @param x Recovery time constant of each SiPM cell in ns
0209   constexpr void setRecoveryTime(const double x) { m_RecoveryTime = x; }
0210 
0211   /// @brief Set SNR value in dB
0212   /// @param x Signal to noise ratio in dB
0213   constexpr void setSnr(const double x) {
0214     m_SnrdB = x;
0215     m_SnrLinear = pow(10, -m_SnrdB / 20);
0216   }
0217 
0218   /// @brief Set time constant for the delay of fast afterpulses
0219   /// @param x Time constant of fast component of afterpulses
0220   constexpr void setTauApFastComponent(const double x) { m_TauApFastComponent = x; }
0221 
0222   /// @brief Set time constant for the delay of slow afterpulses
0223   /// @param x Time constant of slow component of afterpulses
0224   constexpr void setTauApSlowComponent(const double x) { m_TauApSlowComponent = x; }
0225 
0226   /// @brief Set probability to have slow afterpulses over fast ones
0227   /// @param x Fraction of afterpulses generated using slow component
0228   constexpr void setApSlowFraction(const double x) { m_ApSlowFraction = x; }
0229 
0230   /// @brief Set cell-to-cell gain variation @sa m_Ccgv
0231   /// @param x Value of ccgv as a fraction of signal
0232   constexpr void setCcgv(const float x) { m_Ccgv = x; }
0233 
0234   /// @brief Set value for PDE (and sets @ref PdeType::kSimplePde)
0235   /// @param x Flat value of PDE to be applied
0236   constexpr void setPde(const double x) {
0237     m_Pde = x;
0238     m_HasPde = PdeType::kSimplePde;
0239   }
0240 
0241   /// @brief Set dark counts rate
0242   /// @param val Dark counts rate in Hz
0243   constexpr void setDcr(const double val) {
0244     m_Dcr = val;
0245     m_HasDcr = true;
0246   }
0247 
0248   /// @brief Set optical crosstalk probability
0249   /// @param val optical crosstalk probability [0-1]
0250   constexpr void setXt(const double val) {
0251     m_Xt = val;
0252     m_HasXt = true;
0253   }
0254 
0255   /// @brief Set delayed optical crosstalk probability as a fraction of total xt probability
0256   /// @param val delayed optical crosstalk probability [0-1]
0257   constexpr void setDXt(const double val) {
0258     m_DXt = val;
0259     m_HasDXt = true;
0260   }
0261 
0262   /// @brief Set tau of delayed optical crosstalk in ns
0263   /// @param val tau of delayed optical crosstalk
0264   constexpr void setDXtTau(const double val) { m_DXtTau = val; }
0265 
0266   /// @brief Set afterpulse probability
0267   /// @param val afterpulse probability [0-1]
0268   constexpr void setAp(const double val) {
0269     m_Ap = val;
0270     m_HasAp = true;
0271   }
0272 
0273   /// @brief Turn off dark counts
0274   constexpr void setDcrOff() { m_HasDcr = false; }
0275   /// @brief Turn off optical crosstalk
0276   constexpr void setXtOff() { m_HasXt = false; }
0277   /// @brief Turn off delayed optical crosstalk
0278   constexpr void setDXtOff() { m_HasXt = false; }
0279   /// @brief Turn off afterpulses
0280   constexpr void setApOff() { m_HasAp = false; }
0281   /// @brief Turns off slow component of the signal
0282   constexpr void setSlowComponentOff() { m_HasSlowComponent = false; }
0283   /// @brief Turn on dark counts
0284   constexpr void setDcrOn() { m_HasDcr = true; }
0285   /// @brief Turn on optical crosstalk
0286   constexpr void setXtOn() { m_HasXt = true; }
0287   /// @brief Turn on delayed optical crosstalk
0288   constexpr void setDXtOn() { m_HasDXt = true; }
0289   /// @brief Turn on afterpulses
0290   constexpr void setApOn() { m_HasAp = true; }
0291   /// @brief Turns on slow component of the signal
0292   constexpr void setSlowComponentOn() { m_HasSlowComponent = true; }
0293   /// @brief Sets a different type of PDE simulation @ref PdeType
0294   constexpr void setPdeType(PdeType val) { m_HasPde = val; }
0295   /// @brief Set a spectral response of the SiPM and sets @ref
0296   /// PdeType::kSpectrumPde
0297   void setPdeSpectrum(const std::vector<double>&, const std::vector<double>&);
0298 
0299   /// @brief Set hit distriution type
0300   constexpr void setHitDistribution(const HitDistribution val) { m_HitDistribution = val; }
0301 
0302   friend std::ostream& operator<<(std::ostream&, const SiPMProperties&);
0303   std::string toString() const {
0304     std::stringstream ss;
0305     ss << *this;
0306     return ss.str();
0307   }
0308 
0309 private:
0310   double m_Size = 1;
0311   double m_Pitch = 25;
0312   uint32_t m_Ncells;
0313   uint32_t m_SideCells;
0314   HitDistribution m_HitDistribution = HitDistribution::kUniform;
0315 
0316   double m_Sampling = 1;
0317   double m_SignalLength = 500;
0318   uint32_t m_SignalPoints = 0;
0319   double m_RiseTime = 1;
0320   double m_FallTimeFast = 50;
0321   double m_FallTimeSlow = 100;
0322   double m_SlowComponentFraction = 0.2;
0323   double m_RecoveryTime = 50;
0324 
0325   double m_Dcr = 200e3;
0326   double m_Xt = 0.05;
0327   double m_DXt = 0.05;
0328   double m_DXtTau = 15;
0329   double m_Ap = 0.03;
0330   double m_TauApFastComponent = 10;
0331   double m_TauApSlowComponent = 80;
0332   double m_ApSlowFraction = 0.5;
0333   float m_Ccgv = 0.05;
0334   double m_SnrdB = 30;
0335   float m_Gain = 1.0;
0336   double m_SnrLinear;
0337 
0338   double m_Pde = 1;
0339   std::map<double, double> m_PdeSpectrum;
0340   PdeType m_HasPde = PdeType::kNoPde;
0341 
0342   bool m_HasDcr = true;
0343   bool m_HasXt = true;
0344   bool m_HasDXt = false;
0345   bool m_HasAp = true;
0346   bool m_HasSlowComponent = false;
0347 };
0348 } // namespace sipm
0349 #endif /* SIPM_SIPMPROPERTIES_H  */