diff --git a/core/detectors/sts/CbmStsParAsic.cxx b/core/detectors/sts/CbmStsParAsic.cxx index 67b0408493d9aaff89b1790d3e695297a33d27e3..99fb1d292ef8e017ac4b3bf52c7c4e963ac00a1d 100644 --- a/core/detectors/sts/CbmStsParAsic.cxx +++ b/core/detectors/sts/CbmStsParAsic.cxx @@ -16,11 +16,10 @@ #include <assert.h> // for assert -ClassImp(CbmStsParAsic) - // ----- Constructor --------------------------------------------------- - CbmStsParAsic::CbmStsParAsic(UShort_t nChannels, UShort_t nAdc, Double_t dynRange, Double_t threshold, - Double_t timeResol, Double_t deadTime, Double_t noise, Double_t znr) +// ----- Constructor --------------------------------------------------- +CbmStsParAsic::CbmStsParAsic(UShort_t nChannels, UShort_t nAdc, double dynRange, double threshold, double timeResol, + double deadTime, double noise, double znr) { Set(nChannels, nAdc, dynRange, threshold, timeResol, deadTime, noise, znr); } @@ -32,6 +31,8 @@ CbmStsParAsic::CbmStsParAsic(const CbmStsParAsic& other) { Set(other.fNofChannels, other.fNofAdc, other.fDynRange, other.fThreshold, other.fTimeResolution, other.fDeadTime, other.fNoise, other.fZeroNoiseRate); + SetTimeOffset(other.fTimeOffset); + SetWalkCoef(other.fWalkCoef); } // ------------------------------------------------------------------------- @@ -41,6 +42,8 @@ CbmStsParAsic& CbmStsParAsic::operator=(const CbmStsParAsic& other) { Set(other.fNofChannels, other.fNofAdc, other.fDynRange, other.fThreshold, other.fTimeResolution, other.fDeadTime, other.fNoise, other.fZeroNoiseRate); + SetTimeOffset(other.fTimeOffset); + SetWalkCoef(other.fWalkCoef); return *this; } // ------------------------------------------------------------------------- @@ -55,23 +58,23 @@ CbmStsParAsic::~CbmStsParAsic() // ----- ADC channel from charge ---------------------------------------- -Short_t CbmStsParAsic::ChargeToAdc(Double_t charge) const +int16_t CbmStsParAsic::ChargeToAdc(double charge) const { if (charge < fThreshold) return -1; // Underflow if (charge >= fThreshold + fDynRange) return fNofAdc - 1; // Overflow - return Short_t((charge - fThreshold) / fDynRange * Double_t(fNofAdc)); + return int16_t((charge - fThreshold) / fDynRange * double(fNofAdc)); } // ------------------------------------------------------------------------- // ----- Deactivate channels ------------------------------------------- -UInt_t CbmStsParAsic::DeactivateRandomChannels(Double_t fraction) +uint16_t CbmStsParAsic::DeactivateRandomChannels(double fraction) { if (fraction < 0.) return 0; // --- Average number of dead channels - Double_t meanDead = fraction * Double_t(fNofChannels); + double meanDead = fraction * double(fNofChannels); if (meanDead > fNofChannels) meanDead = fNofChannels; // --- Sample actual number of dead channels from Poissonian @@ -94,17 +97,17 @@ UInt_t CbmStsParAsic::DeactivateRandomChannels(Double_t fraction) // ----- Single-channel noise rate ------------------------------------- -Double_t CbmStsParAsic::GetNoiseRate() const +double CbmStsParAsic::GetNoiseRate() const { if (fNoise == 0.) return 0.; - Double_t ratio = fThreshold / fNoise; + double ratio = fThreshold / fNoise; return 0.5 * fZeroNoiseRate * TMath::Exp(-0.5 * ratio * ratio); } // ------------------------------------------------------------------------- // ----- Random charge of a noise signal ------------------------------- -Double_t CbmStsParAsic::GetRandomNoiseCharge() const +double CbmStsParAsic::GetRandomNoiseCharge() const { assert(fIsInit); return fNoiseCharge->GetRandom(); @@ -112,7 +115,7 @@ Double_t CbmStsParAsic::GetRandomNoiseCharge() const // ------------------------------------------------------------------------- -// ----- Intialise the noise charge distribution ----------------------- +// ----- Initialise the noise charge distribution ---------------------- void CbmStsParAsic::Init() { if (fNoiseCharge) delete fNoiseCharge; @@ -124,8 +127,8 @@ void CbmStsParAsic::Init() // ----- Set the parameters --------------------------------------------- -void CbmStsParAsic::Set(UShort_t nChannels, UShort_t nAdc, Double_t dynRange, Double_t threshold, Double_t timeResol, - Double_t deadTime, Double_t noise, Double_t zeroNoiseRate, std::set<UShort_t> deadChannels) +void CbmStsParAsic::Set(UShort_t nChannels, UShort_t nAdc, double dynRange, double threshold, double timeResol, + double deadTime, double noise, double zeroNoiseRate, std::set<UShort_t> deadChannels) { // Assert validity of parameters @@ -161,3 +164,6 @@ std::string CbmStsParAsic::ToString() const return ss.str(); } // -------------------------------------------------------------------------- + + +ClassImp(CbmStsParAsic) diff --git a/core/detectors/sts/CbmStsParAsic.h b/core/detectors/sts/CbmStsParAsic.h index 9b06d9d93a18f6295752abf75cad02bc590475d7..7721d226aef202597cf8d9f1b593c7b7a4ec19b4 100644 --- a/core/detectors/sts/CbmStsParAsic.h +++ b/core/detectors/sts/CbmStsParAsic.h @@ -2,17 +2,12 @@ SPDX-License-Identifier: GPL-3.0-only Authors: Volker Friese [committer] */ -/** @file CbmStsParAsic.h - ** @author Volker Friese <v.friese@gsi.de> - ** @date 23.03.2020 - **/ - #ifndef CBMSTSPARASIC_H #define CBMSTSPARASIC_H 1 -#include <Rtypes.h> // for THashConsistencyHolder, ClassDefNV -#include <RtypesCore.h> // for Double_t, UShort_t, Bool_t, Short_t, kFALSE +#include <Rtypes.h> // for THashConsistencyHolder, ClassDefNV +#include <array> #include <set> #include <string> // for string @@ -23,8 +18,7 @@ class TF1; ** @author Volker Friese <v.friese@gsi.de> ** @since 23.03.2020 ** - ** This class represents the configuration parameters of a - ** readout ASIC of the STS (STSXYTER). + ** This class represents the configuration parameters of a readout ASIC of the STS (STSXYTER). **/ class CbmStsParAsic { @@ -35,16 +29,16 @@ public: /** @brief Constructor with parameters ** @param nChannels Number of readout channels - ** @param nAdc Number of ADC channels - ** @param dynRange Dynamic range of ADC [e] - ** @param threshold ADC threshold [e] - ** @param timeResol Time resolution [ns] - ** @param deadTime Single-channel dead time [ns] - ** @param noise Noise RMS [e] - ** @param znr Zero-crossing noise rate [1/ns] - **/ - CbmStsParAsic(UShort_t nChannels, UShort_t nAdc, Double_t dynRange, Double_t threshold, Double_t timeResol, - Double_t deadTime, Double_t noise, Double_t znr); + ** @param nAdc Number of ADC channels + ** @param dynRange Dynamic range of ADC [e] + ** @param threshold ADC threshold [e] + ** @param timeResol Time resolution [ns] + ** @param deadTime Single-channel dead time [ns] + ** @param noise Noise RMS [e] + ** @param znr Zero-crossing noise rate [1/ns] + **/ + CbmStsParAsic(uint16_t nChannels, uint16_t nAdc, double dynRange, double threshold, double timeResol, double deadTime, + double noise, double znr); /** @brief Copy constructor (disabled) **/ @@ -68,146 +62,158 @@ public: /** @brief Charge from ADC channel (mean) - ** @param adc ADC channel - ** @return Mean charge in ADC channel [e] - */ - Double_t AdcToCharge(UShort_t adc) const - { - return fThreshold + fDynRange / Double_t(fNofAdc) * (Double_t(adc) + 0.5); - } + ** @param adc ADC channel + ** @return Mean charge in ADC channel [e] + */ + double AdcToCharge(uint16_t adc) const { return fThreshold + fDynRange / double(fNofAdc) * (double(adc) + 0.5); } /** @brief Randomly deactivate a fraction of the channels ** @param fraction Fraction of channels to deactivate ** @return Number of deactivated channels **/ - UInt_t DeactivateRandomChannels(Double_t fraction); + uint16_t DeactivateRandomChannels(double fraction); /** @brief ADC channel for a given charge - ** @param charge Charge [e] - ** @return ADC channel number - ** - ** Returns -1 for charge below threshold. - **/ - Short_t ChargeToAdc(Double_t charge) const; + ** @param charge Charge [e] + ** @return ADC channel number + ** + ** Returns -1 for charge below threshold. + **/ + int16_t ChargeToAdc(double charge) const; /** @brief Single-channel dead time - ** @return Dead time [ns] - **/ - Double_t GetDeadTime() const { return fDeadTime; } + ** @return Dead time [ns] + **/ + double GetDeadTime() const { return fDeadTime; } /** @brief Dynamic range of ADC - ** @return Dynamic range [e] - **/ - Double_t GetDynRange() const { return fDynRange; } + ** @return Dynamic range [e] + **/ + double GetDynRange() const { return fDynRange; } /** @brief Number of ADC channels - ** @return Number of ADC channels - **/ - UShort_t GetNofAdc() const { return fNofAdc; } + ** @return Number of ADC channels + **/ + uint16_t GetNofAdc() const { return fNofAdc; } /** @brief Number of readout channels - ** @return Number of readout channels - **/ - UShort_t GetNofChannels() const { return fNofChannels; } + ** @return Number of readout channels + **/ + uint16_t GetNofChannels() const { return fNofChannels; } /** @brief Electronic noise RMS - ** @return Noise RMS [e] - **/ - Double_t GetNoise() const { return fNoise; } + ** @return Noise RMS [e] + **/ + double GetNoise() const { return fNoise; } /** @brief Single-channel noise rate - ** @return Noise rate [1/s] - **/ - Double_t GetNoiseRate() const; + ** @return Noise rate [1/s] + **/ + double GetNoiseRate() const; /** @brief Random noise charge - ** @return Charge of a random noise signal [e] - ** - ** The noise charge is samples from a Gaussian with zero mean - ** and width equal to the noise RMS, starting from threshold - ** and up to 10 times the noise RMS. - **/ - Double_t GetRandomNoiseCharge() const; + ** @return Charge of a random noise signal [e] + ** + ** The noise charge is samples from a Gaussian with zero mean + ** and width equal to the noise RMS, starting from threshold + ** and up to 10 times the noise RMS. + **/ + double GetRandomNoiseCharge() const; /** @brief ADC Threshold - ** @return Threshold [e] - **/ - Double_t GetThreshold() const { return fThreshold; } + ** @return Threshold [e] + **/ + double GetThreshold() const { return fThreshold; } /** @brief Time resolution - ** @return Time resolution [ns] - **/ - Double_t GetTimeResol() const { return fTimeResolution; } + ** @return Time resolution [ns] + **/ + double GetTimeResol() const { return fTimeResolution; } /** @brief Zero-crossing noise rate - ** @return Zero-crossing noise rate [1/ns] - **/ - Double_t GetZeroNoiseRate() const { return fZeroNoiseRate; } + ** @return Zero-crossing noise rate [1/ns] + **/ + double GetZeroNoiseRate() const { return fZeroNoiseRate; } /** @brief Initialisation - ** - ** Calculates the noise charge distribution. - **/ + ** + ** Calculates the noise charge distribution. + **/ void Init(); /** @brief Check for a channel being active - ** @param channel Channel number within ASIC - ** @return True if the channel is active - **/ - Bool_t IsChannelActive(UShort_t channel) const { return fDeadChannels.find(channel) == fDeadChannels.end(); } + ** @param channel Channel number within ASIC + ** @return True if the channel is active + **/ + Bool_t IsChannelActive(uint16_t channel) const { return fDeadChannels.find(channel) == fDeadChannels.end(); } /** @brief Set parameters ** @param nChannels Number of readout channels - ** @param nAdc Number of ADC channels - ** @param dynRange Dynamic range [e] - ** @param threshold Threshold [e] - ** @param timeResol Time resolution [ns] - ** @param deadTime Channel dead time [ns] - ** @param noise Noise RMS - ** @param zeroNoiseRate Zero-crossing noise rate - ** @param deadChannels Set of dead channels - **/ - void Set(UShort_t nChannels, UShort_t nAdc, Double_t dynRange, Double_t threshold, Double_t timeResol, - Double_t deadTime, Double_t noise, Double_t zeroNoiseRate, std::set<UShort_t> deadChannels = {}); + ** @param nAdc Number of ADC channels + ** @param dynRange Dynamic range [e] + ** @param threshold Threshold [e] + ** @param timeResol Time resolution [ns] + ** @param deadTime Channel dead time [ns] + ** @param noise Noise RMS + ** @param zeroNoiseRate Zero-crossing noise rate + ** @param deadChannels Set of dead channels + **/ + void Set(uint16_t nChannels, uint16_t nAdc, double dynRange, double threshold, double timeResol, double deadTime, + double noise, double zeroNoiseRate, std::set<uint16_t> deadChannels = {}); + + + /** @brief Set time offset + ** @param offset Time offset for this ASIC [ns] + ** + ** The time offset will be subtracted from the message at the unpacking stage. + */ + void SetTimeOffset(double offset) { fTimeOffset = offset; } + /** @brief Set coefficients for walk correction + ** @param par Array of correction parameters + **/ + void SetWalkCoef(std::array<double, 4> par) { fWalkCoef = par; } + /** @brief Info to string **/ std::string ToString() const; private: - UShort_t fNofChannels = 0; ///< Number of readout channels - UShort_t fNofAdc = 0; ///< Number of ADC channels - Double_t fDynRange = 0.; ///< Dynamic range [e] - Double_t fThreshold = 0.; ///< Threshold [e] - Double_t fTimeResolution = 0.; ///< Time resolution [ns] - Double_t fDeadTime = 0.; ///< Channel dead time [ns] - Double_t fNoise = 0.; ///< RMS of noise [e] - Double_t fZeroNoiseRate = 0.; ///< Zero-crossing noise rate [1/ns] - std::set<UShort_t> fDeadChannels {}; ///< Map of dead channels - - Bool_t fIsInit = kFALSE; //! Flag for being initialised + uint16_t fNofChannels = 0; ///< Number of readout channels + uint16_t fNofAdc = 0; ///< Number of ADC channels + double fDynRange = 0.; ///< Dynamic range [e] + double fThreshold = 0.; ///< Threshold [e] + double fTimeResolution = 0.; ///< Time resolution [ns] + double fDeadTime = 0.; ///< Channel dead time [ns] + double fNoise = 0.; ///< RMS of noise [e] + double fZeroNoiseRate = 0.; ///< Zero-crossing noise rate [1/ns] + double fTimeOffset = 0.; ///< Time offset [ns] + std::array<double, 4> fWalkCoef = {{0., 0., 0., 0.}}; ///< Parameters for correction of walk effect + std::set<uint16_t> fDeadChannels {}; ///< Map of dead channels + + bool fIsInit = kFALSE; //! Flag for being initialised /** @brief Noise charge distribution. Is instantiated by the Init - ** method in order to avoid frequent re-calculation. **/ + ** method in order to avoid frequent re-calculation. **/ TF1* fNoiseCharge = nullptr; //! - ClassDefNV(CbmStsParAsic, 3); + ClassDefNV(CbmStsParAsic, 4); }; #endif /* CBMSTSPARASIC_H */ diff --git a/core/detectors/sts/CbmStsParModule.cxx b/core/detectors/sts/CbmStsParModule.cxx index 6c703cb992b3b7d16048fe968f0b8256fd884b89..7221c976bc131d09cbe408877fffc25368eb0196 100644 --- a/core/detectors/sts/CbmStsParModule.cxx +++ b/core/detectors/sts/CbmStsParModule.cxx @@ -1,11 +1,8 @@ -/* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Volker Friese [committer] */ -/** @file CbmStsParModule.cxx - ** @author Volker Friese <v.friese@gsi.de> - ** @date 28.06.2014 - **/ + #include "CbmStsParModule.h" #include <cassert> // for assert @@ -16,25 +13,23 @@ using std::string; using std::stringstream; -ClassImp(CbmStsParModule) - - // ----- Constructor --------------------------------------------------- - CbmStsParModule::CbmStsParModule(UInt_t nChannels, UInt_t nAsicChannels) +// ----- Constructor --------------------------------------------------- +CbmStsParModule::CbmStsParModule(uint32_t nChannels, uint32_t nAsicChannels) : fNofChannels(nChannels) , fNofAsicChannels(nAsicChannels) { - UInt_t nAsics = (nChannels % nAsicChannels ? nChannels / nAsicChannels + 1 : nChannels / nAsicChannels); + uint32_t nAsics = (nChannels % nAsicChannels ? nChannels / nAsicChannels + 1 : nChannels / nAsicChannels); fAsicPars.resize(nAsics); } // ------------------------------------------------------------------------- // ----- Randomly deactivate channels ---------------------------------- -UInt_t CbmStsParModule::DeactivateRandomChannels(Double_t fraction) +uint32_t CbmStsParModule::DeactivateRandomChannels(Double_t fraction) { if (fraction <= 0.) return 0; - UInt_t nDeactivated = 0; + uint32_t nDeactivated = 0; for (auto& asic : fAsicPars) { nDeactivated += asic.DeactivateRandomChannels(fraction); } @@ -44,11 +39,11 @@ UInt_t CbmStsParModule::DeactivateRandomChannels(Double_t fraction) // ----- Get ASIC parameters ------------------------------------------- -const CbmStsParAsic& CbmStsParModule::GetParAsic(UInt_t channel) const +const CbmStsParAsic& CbmStsParModule::GetParAsic(uint32_t channel) const { assert(!fAsicPars.empty()); assert(channel < fNofChannels); - UInt_t nAsic = channel / fNofAsicChannels; + uint32_t nAsic = channel / fNofAsicChannels; assert(nAsic < GetNofAsics()); return fAsicPars[nAsic]; } @@ -56,10 +51,10 @@ const CbmStsParAsic& CbmStsParModule::GetParAsic(UInt_t channel) const // ----- Check for a channel being active ------------------------------ -Bool_t CbmStsParModule::IsChannelActive(UInt_t channel) const +Bool_t CbmStsParModule::IsChannelActive(uint32_t channel) const { const CbmStsParAsic& parAsic = GetParAsic(channel); - UShort_t asicChannel = channel % fNofAsicChannels; + uint32_t asicChannel = channel % fNofAsicChannels; return parAsic.IsChannelActive(asicChannel); } // ------------------------------------------------------------------------- @@ -77,6 +72,15 @@ void CbmStsParModule::SetAllAsics(const CbmStsParAsic& asicPar) // ------------------------------------------------------------------------- +// ----- Set parameters for one ASIC ----------------------------------- +void CbmStsParModule::SetAsic(uint32_t asicNr, const CbmStsParAsic& asicPar) +{ + assert(asicNr < fAsicPars.size()); + fAsicPars[asicNr] = asicPar; +} +// ------------------------------------------------------------------------- + + // ----- String output ------------------------------------------------- string CbmStsParModule::ToString() const { @@ -85,3 +89,6 @@ string CbmStsParModule::ToString() const return ss.str(); } // ------------------------------------------------------------------------- + + +ClassImp(CbmStsParModule) diff --git a/core/detectors/sts/CbmStsParModule.h b/core/detectors/sts/CbmStsParModule.h index b13c4cd9a5ab88d536817534765236580caa3a72..c50da9fd293400b940a580f083a9e1b9fec1900b 100644 --- a/core/detectors/sts/CbmStsParModule.h +++ b/core/detectors/sts/CbmStsParModule.h @@ -1,19 +1,14 @@ -/* Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2014-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Volker Friese [committer] */ -/** @file CbmStsParModule.h - ** @author Volker Friese <v.friese@gsi.de> - ** @date 31.03.2020 - **/ #ifndef CBMSTSPARMODULE_H #define CBMSTSPARMODULE_H 1 #include "CbmStsParAsic.h" // for CbmStsParAsic -#include <Rtypes.h> // for THashConsistencyHolder, ClassDefNV -#include <RtypesCore.h> // for UInt_t +#include <Rtypes.h> // for THashConsistencyHolder, ClassDefNV #include <string> // for string #include <vector> // for vector @@ -37,10 +32,10 @@ public: /** @brief Standard constructor - ** @param nChannels Number of readout channels - ** @param nAsics Number of readout channels per ASIC - **/ - CbmStsParModule(UInt_t nChannels, UInt_t nAsicChannels); + ** @param nChannels Number of readout channels + ** @param nAsics Number of readout channels per ASIC + **/ + CbmStsParModule(uint32_t nChannels, uint32_t nAsicChannels); /** @brief Destructor **/ @@ -51,64 +46,70 @@ public: ** @param fraction Fraction of channels to deactivate ** @return Number of deactivated channels **/ - UInt_t DeactivateRandomChannels(Double_t fraction); + uint32_t DeactivateRandomChannels(double fraction); /** @brief ASIC parameters for a given channel - ** @param channel Channel number - ** @return ASIC parameters - **/ - const CbmStsParAsic& GetParAsic(UInt_t channel) const; + ** @param channel Channel number + ** @return ASIC parameters + **/ + const CbmStsParAsic& GetParAsic(uint32_t channel) const; /** @brief All ASIC parameters - ** @return Vector of ASIC parameters - **/ + ** @return Vector of ASIC parameters + **/ const std::vector<CbmStsParAsic>& GetAsicParams() const { return fAsicPars; } /** @brief Number of channels per ASIC - ** @return Number of channels per ASIC - **/ - UInt_t GetNofAsicChannels() const { return fNofAsicChannels; } + ** @return Number of channels per ASIC + **/ + uint32_t GetNofAsicChannels() const { return fNofAsicChannels; } /** @brief Number of ASICs - ** @return Number of ASICs - **/ - UInt_t GetNofAsics() const { return fAsicPars.size(); } + ** @return Number of ASICs + **/ + uint32_t GetNofAsics() const { return fAsicPars.size(); } /** @brief Number of channels - ** @return Number of channels - **/ - UInt_t GetNofChannels() const { return fNofChannels; } + ** @return Number of channels + **/ + uint32_t GetNofChannels() const { return fNofChannels; } /** @brief Check for a channel being active - ** @param channel Channel number - ** @return True if the channel is active - **/ - Bool_t IsChannelActive(UInt_t channel) const; + ** @param channel Channel number + ** @return True if the channel is active + **/ + bool IsChannelActive(uint32_t channel) const; /** @brief Set all ASICs with the same parameter set - ** @param asicPar Parameters for all ASICs - **/ + ** @param asicPar Parameters for all ASICs + **/ void SetAllAsics(const CbmStsParAsic& asicPar); + /** @brief Set parameters for a single ASIC + ** @param asicPar ASIC parameter set + **/ + void SetAsic(uint32_t asicNr, const CbmStsParAsic& asicPar); + + /** @brief String output **/ std::string ToString() const; private: - UInt_t fNofChannels = 0; ///< Number of readout channels - UInt_t fNofAsicChannels = 0.; ///< Number of channels per ASIC + uint32_t fNofChannels = 0; ///< Number of readout channels + uint32_t fNofAsicChannels = 0.; ///< Number of channels per ASIC std::vector<CbmStsParAsic> fAsicPars {}; ///< ASIC parameters - ClassDefNV(CbmStsParModule, 1); + ClassDefNV(CbmStsParModule, 2); }; #endif /* CBMSTSPARMODULE_H */