Commit 24bad95e authored by Volker Friese's avatar Volker Friese Committed by Pierre-Alain Loizeau
Browse files

Enabled setting parameters for single STS ASICs. Expanded ASIC parameter...

Enabled setting parameters for single STS ASICs. Expanded ASIC parameter container by time offset and coefficients for walk correction.
parent 2b32df7e
......@@ -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)
......@@ -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 */
/* 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)
/* 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