ATLAS Offline Software
Loading...
Searching...
No Matches
ZDCPulseAnalyzer Class Reference

#include <ZDCPulseAnalyzer.h>

Public Types

enum  {
  PulseBit = 0 , LowGainBit = 1 , FailBit = 2 , HGOverflowBit = 3 ,
  HGUnderflowBit = 4 , PSHGOverUnderflowBit = 5 , LGOverflowBit = 6 , LGUnderflowBit = 7 ,
  PrePulseBit = 8 , PostPulseBit = 9 , FitFailedBit = 10 , BadChisqBit = 11 ,
  BadT0Bit = 12 , ExcludeEarlyLGBit = 13 , ExcludeLateLGBit = 14 , preExpTailBit = 15 ,
  FitMinAmpBit = 16 , RepassPulseBit = 17 , ArmSumIncludeBit = 18 , FailSigCutBit = 19 ,
  UnderFlowExclusionBit = 20 , N_STATUS_BITS
}
enum  LowGainMode { LGModeNormal = 0 , LGModeForceLG , LGModeRefitLG }
enum  TimingCorrMode { NoTimingCorr = 0 , TimingCorrLin , TimingCorrLog }
using JSON = ZDCJSONConfig::JSON

Public Member Functions

 ZDCPulseAnalyzer (ZDCMsg::MessageFunctionPtr msgFunc_p, const std::string &tag, int Nsample, float deltaTSample, size_t preSampleIdx, int pedestal, const std::string &fitFunction, int peak2ndDerivMinSample, float peak2DerivMinThreshHG, float peak2DerivMinThreshLG)
 ZDCPulseAnalyzer (ZDCMsg::MessageFunctionPtr msgFunc_p, const JSON &configJSON)
 ~ZDCPulseAnalyzer ()
void setFitOPtions (const std::string &fitOptions)
void saveFitFunc (bool save)
bool quietFits () const
void setQuietFits ()
void setUnquietFits ()
void enableDelayed (float deltaT, float pedestalShift, bool fixedBaseline=false)
void enableRepass (float peak2ndDerivMinRepassHG, float peak2ndDerivMinRepassLG)
void enableTimeSigCut (bool AND, float sigCut, const std::string &TF1String, const std::vector< double > &parsHG, const std::vector< double > &parsLG)
void enablePreExclusion (unsigned int maxSamplesExcl, unsigned int HGADCThresh, unsigned int LGADCThresh)
void enablePostExclusion (unsigned int maxSamplesExcl, unsigned int HGADCThresh, unsigned int LGADCThresh)
void SetPeak2ndDerivMinTolerance (size_t tolerance)
void setPerSampleNoiseSigmas (const std::vector< float > &sigmaHG, const std::vector< float > &sigmaLG)
void setLGMode (unsigned int mode)
unsigned int getLGMode () const
void set2ndDerivStep (size_t step)
void SetCutValues (float chisqDivAmpCutHG, float chisqDivAmpCutLG, float deltaT0MinHG, float deltaT0MaxHG, float deltaT0MinLG, float deltaT0MaxLG)
void SetTimeCuts (float deltaT0MinHG, float deltaT0MaxHG, float deltaT0MinLG, float deltaT0MaxLG)
void SetChisqCuts (float chisqDivAmpCutHG, float chisqDivAmpScaleHG, float chisqDivAmpOffsetHG, float chisqDivAmpPowerHG, float chisqDivAmpCutLG, float chisqDivAmpScaleLG, float chisqDivAmpOffsetLG, float chisqDivAmpPowerLG)
void SetNoiseSigmas (float noiseSigHG, float noiseSigLG)
void SetGainFactorsHGLG (float gainFactorHG, float gainFactorLG)
void SetFitMinMaxAmp (float minAmpHG, float minAmpLG, float maxAmpHG, float maxAmpLG)
void setMinimumSignificance (float sigMinHG, float sigMinLG)
void SetTauT0Values (bool fixTau1, bool fixTau2, float tau1, float tau2, float t0HG, float t0LG)
void enablePostPulseCheck (unsigned int postPulseSampleDelta, float postPulseDerivMinSig, float postPulseAbsDer2ndMinSig, float minMainDer2ndRatio)
void disablePostPulseCheck ()
void SetADCOverUnderflowValues (int HGOverflowADC, int HGUnderflowADC, int LGOverflowADC)
void SetTimingCorrParams (TimingCorrMode mode, float refADC, float refScale, const std::vector< float > &HGT0CorrParams, const std::vector< float > &LGT0CorrParams)
void SetFitTimeMax (float tmax)
void SetNonlinCorrParams (float refADC, float refScale, const std::vector< float > &paramsHG, const std::vector< float > &paramsLG)
void enableFADCCorrections (bool correctPerSample, std::unique_ptr< const TH1 > &correHistHG, std::unique_ptr< const TH1 > &correHistLG)
void disableFADCCorrections ()
bool LoadAndAnalyzeData (const std::vector< float > &ADCSamplesHG, const std::vector< float > &ADCSamplesLG)
bool LoadAndAnalyzeData (const std::vector< float > &ADCSamplesHG, const std::vector< float > &ADCSamplesLG, const std::vector< float > &ADCSamplesHGDelayed, const std::vector< float > &ADCSamplesLGDelayed)
bool ReanalyzeData ()
bool HaveData () const
bool havePulse () const
bool useLowGain () const
bool failed () const
bool HGOverflow () const
bool HGUnderflow () const
bool PSHGOverUnderflow () const
bool LGOverflow () const
bool LGUnderflow () const
bool prePulse () const
bool postPulse () const
bool fitFailed () const
bool badChisq () const
bool badT0 () const
bool excludeEarlyLG () const
bool excludeLateLG () const
bool preExpTail () const
bool fitMinimumAmplitude () const
bool repassPulse () const
bool armSumInclude () const
bool failSigCut () const
bool underflowExclusion () const
float GetFitAmplitude () const
float GetFitT0 () const
float GetT0Sub () const
float GetT0Corr () const
float getTimeSig () const
float GetChisq () const
float GetChisqRatio () const
float GetFitTau1 () const
float GetFitTau2 () const
float GetFitPreT0 () const
float GetFitPreAmp () const
float GetFitPostT0 () const
float GetFitPostAmp () const
float GetFitExpAmp () const
float GetAmpNoNonLin () const
float GetAmplitude () const
float GetAmpError () const
float GetPreExpAmp () const
const std::vector< float > & GetShapeParameters () const
float getRefitLGAmp () const
float getRefitLGFitAmp () const
float getRefitLGAmpCorr () const
float getRefitLGChisq () const
float getRefitLGChisqRatio () const
float getRefitLGTime () const
float getRefitLGTimeSub () const
float getPresample () const
float getMaxADCHG () const
float getMaxADCLG () const
float getMinADCHG () const
float getMinADCLG () const
float getMaxADCSub () const
float getMinADCSub () const
int getMaxADCSampleHG () const
int getMinADCSampleHG () const
int getMaxADCSampleLG () const
int getMinADCSampleLG () const
float getADCPeakHG () const
float getADCPeakLG () const
float GetMaxDelta () const
float GetMinDelta () const
float GetFitTMax () const
float GetFitTMin () const
float GetdelayBS () const
float GetMinDeriv2nd () const
float GetMinDeriv2ndIndex () const
unsigned int GetStatusMask () const
float GetPreSampleAmp () const
float GetBkgdMaxFraction () const
float GetDelayedBaselineShiftFit () const
float GetDelayedBaselineCorr () const
const TH1 * GetHistogramPtr (bool refitLG=false)
std::shared_ptr< TGraphErrors > GetCombinedGraph (bool forceLG=false)
std::shared_ptr< TGraphErrors > GetGraph (bool forceLG=false)
std::vector< float > GetFitPulls (bool forceLG=false) const
void dump () const
void dumpConfiguration () const
void dumpTF1 (const TF1 *) const
const std::vector< float > & GetSamplesSub () const
const std::vector< float > & GetSamplesDeriv2nd () const

Static Public Attributes

static const ZDCJSONConfig::JSONParamList JSONConfigParams

Private Types

typedef std::vector< float >::const_iterator SampleCIter
using ChisqCutLambdatype = std::function<bool(float,float,float, float&)>

Private Member Functions

void initialize ()
void reset (bool reanalyze=false)
void setDefaults ()
std::pair< bool, std::string > ValidateJSONConfig (const JSON &config)
std::pair< bool, std::string > ConfigFromJSON (const JSON &config)
void SetupFitFunctions ()
bool DoAnalysis (bool repass)
bool ScanAndSubtractSamples ()
bool AnalyzeData (size_t nSamples, size_t preSample, const std::vector< float > &samples, const std::vector< float > &samplesNoise, const std::vector< bool > &useSamples, float peak2ndDerivMinThresh, const std::vector< float > &toCorrParams, ChisqCutLambdatype chisqCutLambda, float minT0Corr, float maxT0Corr)
double getAmplitudeCorrection (bool highGain)
void prepareLGRefit (const std::vector< float > &samplesLG, const std::vector< float > &samplesNoise, const std::vector< bool > &useSamples)
void FillHistogram (bool refitLG)
void checkTF1Limits (TF1 *func)
void DoFit (bool refitLG=false)
void DoFitCombined (bool refitLG=false)
void UpdateFitterTimeLimits (TFitter *fitter, ZDCFitWrapper *wrapper, bool prePulse)

Static Private Member Functions

static std::vector< float > calculate2ndDerivative (const std::vector< float > &inputData, unsigned int step)
static std::pair< std::vector< float >, std::vector< float > > calculate2ndDerivative (const std::vector< float > &inputData, const std::vector< float > &inputNoise, unsigned int step)
static std::vector< float > calculateDerivative (const std::vector< float > &inputData, unsigned int step)
static float obtainDelayedBaselineCorr (const std::vector< float > &samples)
static std::unique_ptr< TFitter > MakeCombinedFitter (TF1 *func)
static void CombinedPulsesFCN (int &numParam, double *, double &f, double *par, int flag)

Private Attributes

ZDCMsg::MessageFunctionPtr m_msgFunc_p {}
std::string m_tag {}
unsigned int m_Nsample {}
unsigned int m_preSampleIdx {}
float m_freqMHz {}
float m_deltaTSample {}
int m_pedestal {}
unsigned int m_LGMode {LGModeNormal}
float m_tmin {}
float m_tmax {}
bool m_quietFits {true}
bool m_saveFitFunc {false}
std::string m_fitFunction
size_t m_2ndDerivStep {1}
size_t m_peak2ndDerivMinSample {}
size_t m_peak2ndDerivMinTolerance {1}
float m_peak2ndDerivMinThreshLG {}
float m_peak2ndDerivMinThreshHG {}
bool m_useDelayed {false}
bool m_enableRepass {false}
float m_peak2ndDerivMinRepassLG {}
float m_peak2ndDerivMinRepassHG {}
float m_gainFactorHG {}
float m_gainFactorLG {}
float m_noiseSigHG {}
float m_noiseSigLG {}
bool m_havePerSampleNoiseHG {false}
bool m_havePerSampleNoiseLG {false}
std::vector< float > m_setPerSampleNoiseHG
std::vector< float > m_setPerSampleNoiseLG
std::string m_fitOptions {}
int m_HGOverflowADC {}
int m_HGUnderflowADC {}
int m_LGOverflowADC {}
float m_nominalT0HG {}
float m_nominalT0LG {}
float m_nominalTau1 {}
float m_nominalTau2 {}
bool m_fixTau1 {}
bool m_fixTau2 {}
float m_defaultFitTMax {}
float m_defaultFitTMin {}
float m_chisqDivAmpCutLG {}
float m_chisqDivAmpCutHG {}
float m_chisqDivAmpScaleLG {}
float m_chisqDivAmpScaleHG {}
float m_chisqDivAmpOffsetLG {}
float m_chisqDivAmpOffsetHG {}
float m_chisqDivAmpPowerLG {}
float m_chisqDivAmpPowerHG {}
float m_T0CutLowLG {}
float m_T0CutHighLG {}
float m_T0CutLowHG {}
float m_T0CutHighHG {}
std::unique_ptr< const TF1 > m_timeResFuncHG_p {}
std::unique_ptr< const TF1 > m_timeResFuncLG_p {}
float m_t0CutSig {}
unsigned int m_timeCutMode {0}
float m_defaultT0Max {}
float m_defaultT0Min {}
float m_fitAmpMinHG {}
float m_fitAmpMinLG {}
float m_fitAmpMaxHG {}
float m_fitAmpMaxLG {}
bool m_haveSignifCuts {false}
float m_sigMinHG {}
float m_sigMinLG {}
bool m_doPrePulseCheck {false}
bool m_doPostPulseCheck {false}
unsigned int m_postPulseDelta {0}
float m_postPulseDerivMinSig {}
float m_postPulseAbsDer2ndMinSig {}
float m_postPulseMainMinDer2ndRatio {}
unsigned int m_prePulseDelta {0}
bool m_enablePreExcl {false}
unsigned int m_maxSamplesPreExcl {0}
unsigned int m_preExclHGADCThresh {0}
unsigned int m_preExclLGADCThresh {0}
bool m_enablePostExcl {false}
unsigned int m_postExclHGADCThresh {0}
unsigned int m_postExclLGADCThresh {0}
unsigned int m_maxSamplesPostExcl {0}
bool m_enableUnderflowExclHG {false}
bool m_enableUnderflowExclLG {false}
unsigned int m_underFlowExclSamplesPreHG {0}
unsigned int m_underFlowExclSamplesPostHG {0}
unsigned int m_underFlowExclSamplesPreLG {0}
unsigned int m_underFlowExclSamplesPostLG {0}
unsigned int m_timingCorrMode {NoTimingCorr}
float m_timingCorrRefADC {500}
float m_timingCorrScale {100}
std::vector< float > m_LGT0CorrParams {}
std::vector< float > m_HGT0CorrParams {}
bool m_haveNonlinCorr {false}
float m_nonLinCorrRefADC {500}
float m_nonLinCorrRefScale {100}
std::vector< float > m_nonLinCorrParamsHG {}
std::vector< float > m_nonLinCorrParamsLG {}
bool m_haveFADCCorrections {false}
std::string m_fadcCorrFileName
bool m_FADCCorrPerSample {false}
std::unique_ptr< const TH1 > m_FADCCorrHG {}
std::unique_ptr< const TH1 > m_FADCCorrLG {}
std::unique_ptr< TH1 > m_fitHist {}
std::unique_ptr< TH1 > m_fitHistLGRefit {}
bool m_initialized {false}
bool m_initializedFits {false}
std::unique_ptr< ZDCFitWrapper > m_defaultFitWrapper {}
std::unique_ptr< ZDCPrePulseFitWrapper > m_prePulseFitWrapper {}
std::unique_ptr< ZDCPreExpFitWrapper > m_preExpFitWrapper {}
bool m_adjTimeRangeEvent {false}
unsigned int m_minSampleEvt {}
unsigned int m_maxSampleEvt {}
bool m_useFixedBaseline {}
float m_delayedDeltaT {}
float m_delayedPedestalDiff {}
std::unique_ptr< TH1 > m_delayedHist {}
std::unique_ptr< TH1 > m_delayedHistLGRefit {}
std::unique_ptr< TFitter > m_prePulseCombinedFitter {}
std::unique_ptr< TFitter > m_defaultCombinedFitter {}
bool m_haveData {false}
bool m_havePulse {false}
bool m_useLowGain {false}
bool m_fail {false}
bool m_HGOverflow {false}
bool m_HGUnderflow {false}
bool m_PSHGOverUnderflow {false}
bool m_LGOverflow {false}
bool m_LGUnderflow {false}
bool m_prePulse {false}
bool m_postPulse {false}
bool m_fitFailed {false}
bool m_badChisq {false}
bool m_badT0 {false}
bool m_ExcludeEarly {false}
bool m_ExcludeLate {false}
bool m_preExpTail {false}
bool m_fixPrePulse {false}
bool m_fitMinAmp {false}
bool m_repassPulse {false}
bool m_failSigCut {false}
bool m_underflowExclusion {false}
bool m_backToHG_pre {false}
float m_baselineCorr {}
int m_usedPresampIdx {}
float m_preSample {}
float m_minADCHG {}
float m_maxADCHG {}
int m_minADCSampleHG
int m_maxADCSampleHG
float m_maxADCLG {}
float m_minADCLG {}
int m_minADCSampleLG
int m_maxADCSampleLG
float m_ADCPeakHG {}
float m_ADCPeakLG {}
float m_maxDelta {}
float m_minDelta {}
float m_initialExpAmp {}
float m_minDeriv2nd {}
int m_minDeriv2ndIndex {}
float m_fitTMax {}
float m_fitTMin {}
float m_fitPostT0lo {}
float m_minDeriv2ndSig
float m_preExpSig
float m_prePulseSig
float m_initialPrePulseT0 {}
float m_initialPrePulseAmp {}
float m_initialPostPulseT0 {}
float m_fitAmplitude {}
float m_fitAmpError {}
float m_fitTime {}
float m_fitTimeSub {}
float m_fitTimeCorr {}
float m_timeSig {}
float m_fitTCorr2nd {}
float m_fitTau1 {}
float m_fitTau2 {}
float m_fitChisq {}
float m_chisqRatio {}
float m_fitNDoF {}
float m_fitPreT0 {}
float m_fitPreAmp {}
float m_fitPostT0 {}
float m_fitPostAmp {}
float m_fitExpAmp {}
float m_amplitude {}
float m_ampNoNonLin {}
float m_ampError {}
float m_preSampleAmp {}
float m_preAmplitude {}
float m_postAmplitude {}
float m_expAmplitude {}
float m_bkgdMaxFraction {}
float m_delayedBaselineShift {}
std::vector< float > m_shapeParameters
bool m_evtLGRefit {false}
float m_refitLGAmpl {0}
float m_refitLGFitAmpl {0}
float m_refitLGAmplCorr {0}
float m_refitLGAmpError {0}
float m_refitLGChisq {0}
float m_refitLGChisqRatio {0}
float m_refitLGTime {0}
float m_refitLGTimeSub {0}
int m_lastHGOverFlowSample {-1}
int m_firstHGOverFlowSample {-1}
unsigned int m_NSamplesAna {0}
std::vector< float > m_ADCSamplesHG
std::vector< float > m_ADCSamplesLG
std::vector< float > m_ADCSamplesHGSub
std::vector< float > m_ADCSamplesLGSub
std::vector< float > m_sampleNoiseHG
std::vector< float > m_sampleNoiseLG
std::vector< bool > m_useSampleLG
std::vector< bool > m_useSampleHG
std::vector< float > m_ADCSSampNoiseHG
std::vector< float > m_ADCSSampNoiseLG
std::vector< float > m_samplesSub
std::vector< float > m_samplesNoise
std::vector< float > m_samplesLGRefit
std::vector< float > m_samplesNoiseLGRefit
std::vector< float > m_samplesDeriv2nd
std::vector< float > m_samplesDeriv2ndErr
std::vector< float > m_fitPulls

Static Private Attributes

static TH1 * s_undelayedFitHist = nullptr
static TH1 * s_delayedFitHist = nullptr
static TF1 * s_combinedFitFunc = nullptr
static float s_combinedFitTMax = 1000
static float s_combinedFitTMin = -0.5
static std::vector< float > s_pullValues

Detailed Description

Definition at line 23 of file ZDCPulseAnalyzer.h.

Member Typedef Documentation

◆ ChisqCutLambdatype

using ZDCPulseAnalyzer::ChisqCutLambdatype = std::function<bool(float,float,float, float&)>
private

Definition at line 428 of file ZDCPulseAnalyzer.h.

◆ JSON

Definition at line 26 of file ZDCPulseAnalyzer.h.

◆ SampleCIter

typedef std::vector<float>::const_iterator ZDCPulseAnalyzer::SampleCIter
private

Definition at line 74 of file ZDCPulseAnalyzer.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
PulseBit 
LowGainBit 
FailBit 
HGOverflowBit 
HGUnderflowBit 
PSHGOverUnderflowBit 
LGOverflowBit 
LGUnderflowBit 
PrePulseBit 
PostPulseBit 
FitFailedBit 
BadChisqBit 
BadT0Bit 
ExcludeEarlyLGBit 
ExcludeLateLGBit 
preExpTailBit 
FitMinAmpBit 
RepassPulseBit 
ArmSumIncludeBit 
FailSigCutBit 
UnderFlowExclusionBit 
N_STATUS_BITS 

Definition at line 28 of file ZDCPulseAnalyzer.h.

28 {PulseBit = 0, // &1
29 LowGainBit = 1, // &2
30 FailBit = 2, // &4
31 HGOverflowBit = 3, // &8
32 // -------------------------
33 HGUnderflowBit = 4, // &16
34 PSHGOverUnderflowBit = 5, // &32
35 LGOverflowBit = 6, // &64
36 LGUnderflowBit = 7, // &128
37 // -------------------------
38 PrePulseBit = 8, // &256
39 PostPulseBit = 9, // &512
40 FitFailedBit = 10, // &1024
41 BadChisqBit = 11, // &2048
42 // -------------------------
43 BadT0Bit = 12, // &4096
44 ExcludeEarlyLGBit = 13, // &8192
45 ExcludeLateLGBit = 14, // &16384
46 preExpTailBit = 15, // &32768
47 //
48 FitMinAmpBit = 16, // 0x10000
49 RepassPulseBit = 17, // 0x20000
50 ArmSumIncludeBit = 18, // 0x40000
51 FailSigCutBit = 19, // 0x80000
52 UnderFlowExclusionBit = 20, // 0x100000
54 };

◆ LowGainMode

Enumerator
LGModeNormal 
LGModeForceLG 
LGModeRefitLG 

Definition at line 56 of file ZDCPulseAnalyzer.h.

◆ TimingCorrMode

Enumerator
NoTimingCorr 
TimingCorrLin 
TimingCorrLog 

Definition at line 62 of file ZDCPulseAnalyzer.h.

Constructor & Destructor Documentation

◆ ZDCPulseAnalyzer() [1/2]

ZDCPulseAnalyzer::ZDCPulseAnalyzer ( ZDCMsg::MessageFunctionPtr msgFunc_p,
const std::string & tag,
int Nsample,
float deltaTSample,
size_t preSampleIdx,
int pedestal,
const std::string & fitFunction,
int peak2ndDerivMinSample,
float peak2DerivMinThreshHG,
float peak2DerivMinThreshLG )

Definition at line 160 of file ZDCPulseAnalyzer.cxx.

162 :
163 m_msgFunc_p(std::move(msgFunc_p)),
164 m_tag(tag), m_Nsample(Nsample),
165 m_preSampleIdx(preSampleIdx),
166 m_deltaTSample(deltaTSample),
167 m_pedestal(pedestal), m_fitFunction(fitFunction),
168 m_peak2ndDerivMinSample(peak2ndDerivMinSample),
169 m_peak2ndDerivMinThreshLG(std::abs(peak2ndDerivMinThreshLG)),
170 m_peak2ndDerivMinThreshHG(std::abs(peak2ndDerivMinThreshHG))
171{
172 // Create the histogram used for fitting
173 //
174 m_tmin = -deltaTSample / 2;
175 m_tmax = m_tmin + ((float) Nsample) * deltaTSample;
178
179 std::string histName = "ZDCFitHist" + tag;
180 std::string histNameLGRefit = "ZDCFitHist" + tag + "_LGRefit";
181
182 m_fitHist = std::make_unique<TH1F>(histName.c_str(), "", m_Nsample, m_tmin, m_tmax);
183 m_fitHistLGRefit = std::make_unique<TH1F>(histNameLGRefit.c_str(), "", m_Nsample, m_tmin, m_tmax);
184
185 m_fitHist->SetDirectory(0);
186 m_fitHistLGRefit->SetDirectory(0);
187
188 setDefaults();
189 reset();
190}
std::string m_fitFunction
unsigned int m_preSampleIdx
unsigned int m_Nsample
std::unique_ptr< TH1 > m_fitHistLGRefit
std::unique_ptr< TH1 > m_fitHist
ZDCMsg::MessageFunctionPtr m_msgFunc_p
const std::string reset

◆ ZDCPulseAnalyzer() [2/2]

ZDCPulseAnalyzer::ZDCPulseAnalyzer ( ZDCMsg::MessageFunctionPtr msgFunc_p,
const JSON & configJSON )

Definition at line 192 of file ZDCPulseAnalyzer.cxx.

192 :
193 m_msgFunc_p(std::move(msgFunc_p))
194{
195 setDefaults();
196
197 // auto [result, resultString] = ValidateJSONConfig(configJSON);
198 // (*m_msgFunc_p)(ZDCMsg::Debug, "ValidateJSON produced result: " + resultString);
199
200 auto [result2, resultString2] = ConfigFromJSON(configJSON);
201 (*m_msgFunc_p)(ZDCMsg::Debug, "ConfigFromJSON produced result: "+ resultString2);
202
204
205 // Create the histogram used for fitting
206 //
207 if (m_freqMHz >1.e-6) m_deltaTSample = 1000./m_freqMHz;
208 m_tmin = -m_deltaTSample / 2;
211
212 std::string histName = "ZDCFitHist" + m_tag;
213 std::string histNameLGRefit = "ZDCFitHist" + m_tag + "_LGRefit";
214
215 m_fitHist = std::make_unique<TH1F>(histName.c_str(), "", m_Nsample, m_tmin, m_tmax);
216 m_fitHistLGRefit = std::make_unique<TH1F>(histNameLGRefit.c_str(), "", m_Nsample, m_tmin, m_tmax);
217
218 m_fitHist->SetDirectory(0);
219 m_fitHistLGRefit->SetDirectory(0);
220
221 if(m_useDelayed) {
223 }
224
225 reset();
226}
void dumpConfiguration() const
std::pair< bool, std::string > ConfigFromJSON(const JSON &config)
void enableDelayed(float deltaT, float pedestalShift, bool fixedBaseline=false)
@ Debug
Definition ZDCMsg.h:19

◆ ~ZDCPulseAnalyzer()

ZDCPulseAnalyzer::~ZDCPulseAnalyzer ( )
inline

Definition at line 519 of file ZDCPulseAnalyzer.h.

519{}

Member Function Documentation

◆ AnalyzeData()

bool ZDCPulseAnalyzer::AnalyzeData ( size_t nSamples,
size_t preSample,
const std::vector< float > & samples,
const std::vector< float > & samplesNoise,
const std::vector< bool > & useSamples,
float peak2ndDerivMinThresh,
const std::vector< float > & toCorrParams,
ChisqCutLambdatype chisqCutLambda,
float minT0Corr,
float maxT0Corr )
private

Definition at line 1297 of file ZDCPulseAnalyzer.cxx.

1306{
1307
1308 // We keep track of which sample we used to do the subtraction sepaate from m_minSampleEvt
1309 // because the corresponding time is the reference time we provide to the fit function when
1310 // we have pre-pulses and in case we change the m_minSampleEvt after doing the subtraction
1311 //
1312 // e.g. our refit when the chisquare cuts fails
1313 //
1314
1315 // Find the first used sample in the event
1316 //
1317 bool haveFirst = false;
1318 unsigned int lastUsed = 0;
1319
1320 for (unsigned int sample = preSampleIdx; sample < nSamples; sample++) {
1321 if (useSample[sample]) {
1322 //
1323 // We're going to use this sample in the analysis, update bookeeping
1324 //
1325 if (!haveFirst) {
1326 if (sample > m_minSampleEvt) m_minSampleEvt = sample;
1327 haveFirst = true;
1328 }
1329 else {
1330 lastUsed = sample;
1331 }
1332 }
1333 }
1334
1335 if (lastUsed < m_maxSampleEvt) m_maxSampleEvt = lastUsed;
1336
1337 // Check to see whether we've changed the range of samples used in the analysis
1338 //
1339 // Should be obseleted with reworking of the fitting using Root::Fit package
1340 //
1341 if (m_minSampleEvt > preSampleIdx) {
1342 m_ExcludeEarly = true;
1343 m_adjTimeRangeEvent = true;
1344 }
1345
1346 if (m_maxSampleEvt < nSamples - 1) {
1347 m_adjTimeRangeEvent = true;
1348 m_ExcludeLate = true;
1349 }
1350
1351 // Prepare for subtraction
1352 //
1354 m_preSample = samples[m_usedPresampIdx];
1355
1356 // std::ostringstream pedMessage;
1357 // pedMessage << "Pedestal index = " << m_usedPresampIdx << ", value = " << m_preSample;
1358 // (*m_msgFunc_p)(ZDCMsg::Verbose, pedMessage.str().c_str());
1359
1360 m_samplesSub = samples;
1361 m_samplesNoise = samplesNoise;
1362
1363 //
1364 // When we are combinig delayed and undelayed samples we have to deal with the fact that
1365 // the two readouts can have different noise and thus different baselines. Which is a huge
1366 // headache.
1367 //
1368 if (m_useDelayed) {
1369 if (m_useFixedBaseline) {
1371 }
1372 else {
1373 //
1374 // Use much-improved method to match delayed and undelayed baselines
1375 //
1377 std::ostringstream baselineMsg;
1378 baselineMsg << "Delayed samples baseline correction = " << m_baselineCorr << std::endl;
1379 (*m_msgFunc_p)(ZDCMsg::Debug, baselineMsg.str().c_str());
1380 }
1381
1382 // Now apply the baseline correction to align ADC values for delayed and undelayed samples
1383 //
1384 for (size_t isample = 0; isample < nSamples; isample++) {
1385 if (isample % 2) m_samplesSub[isample] -= m_baselineCorr;
1386 }
1387
1388 // If we use one of the delayed samples for presample, we have to adjust the presample value as well
1389 //
1391 }
1392
1393 // Do the presample subtraction
1394 //
1395 std::for_each(m_samplesSub.begin(), m_samplesSub.end(), [psval = m_preSample] (float & adcUnsub) {return adcUnsub -= psval;} );
1396
1397 // Calculate the second derivatives using step size m_2ndDerivStep
1398 //
1400 m_samplesDeriv2nd = deriv2ndResult.first;
1401 m_samplesDeriv2ndErr = deriv2ndResult.second;
1402
1403 // Find the sample which has the lowest 2nd derivative. We loop over the range defined by the
1404 // tolerance on the position of the minimum second derivative. Note: the +1 in the upper iterator is because
1405 // that's where the loop terminates, not the last element.
1406 //
1407 SampleCIter minDeriv2ndIter;
1408
1409 int upperDelta = std::min(m_peak2ndDerivMinSample + m_peak2ndDerivMinTolerance + 1, nSamples);
1410
1411 minDeriv2ndIter = std::min_element(m_samplesDeriv2nd.begin() + m_peak2ndDerivMinSample - m_peak2ndDerivMinTolerance, m_samplesDeriv2nd.begin() + upperDelta);
1412
1413 m_minDeriv2nd = *minDeriv2ndIter;
1414 m_minDeriv2ndIndex = std::distance(m_samplesDeriv2nd.cbegin(), minDeriv2ndIter);
1416
1417 m_havePulse = false;
1418
1419 // If the second derivative is greater than the threshold, we may have a pulse
1420 //
1421 if (std::abs(m_minDeriv2nd) >= peak2ndDerivMinThresh) {
1422 //
1423 // Check that we have found a real maximum
1424 //
1429
1430 if ((deltaLeft2 > 0 || deltaLeft > 0) && (deltaRight2 > 0 || deltaRight > 0)) {
1431 m_havePulse = true;
1432 }
1433 else {
1434 // In the case that a fluctuation made the most negative 2nd derivative not at the real peak
1435 // check the 2nd derivative at the nominal peak position.
1436 //
1437 if (std::abs(m_samplesDeriv2nd[m_peak2ndDerivMinSample]) > peak2ndDerivMinThresh) {
1439
1440 // Now we re-do the check
1441 //
1446
1447 if ((deltaLeft2 > 0 || deltaLeft > 0) && (deltaRight2 > 0 || deltaRight > 0)) {
1448 m_havePulse = true;
1449 }
1450 }
1451 else {
1452 (*m_msgFunc_p)(ZDCMsg::Info, ("ZDCPulseAnalyzer for " + m_tag + " found a fake maximum at sample " + std::to_string(m_minDeriv2ndIndex) ));
1453 }
1454 }
1455 }
1456
1457 // save the low and high gain ADC values at the peak -- if we have a pulse, at m_minDeriv2ndIndex
1458 // otherwise at m_peak2ndDerivMinSample
1459 //
1460 if (m_havePulse) {
1463 }
1464 else {
1467 }
1468
1469 // Now decide whether we have a preceeding pulse or not. There are two possible kinds of preceeding pulses:
1470 // 1) exponential tail from a preceeding pulse
1471 // 2) peaked pulse before the main pulse
1472 //
1473 // we can, of course, have both
1474 //
1475
1476 // To check for exponential tail, test the slope determined by the minimum ADC value (and pre-sample)
1477 // **beware** this can cause trouble in 2015 data where the pulses had overshoot due to the transformers
1478 //
1479
1480 // Implement a much simpler test for presence of an exponential tail from an OOT pulse
1481 // namely if the slope evaluated at the presample is significantly negative, then
1482 // we have a preceeding pulse.
1483 //
1484 // Note that we don't have to subtract the FADC value corresponding to the presample because
1485 // that subtraction has already been done.
1486 //
1487 if (m_havePulse) {
1488 if (m_doPrePulseCheck) {
1489 // If we've alreday excluded early samples, we have almost by construction have negative exponential tail
1490 //
1491 if (m_ExcludeEarly) m_preExpTail = true;
1492
1493 //
1494 // The subtracted ADC value at m_usedPresampIdx is, by construction, zero
1495 // The next sample has had the pre-sample subtracted, so it represents the initial derivative
1496 //
1497 float derivPresampleErr = std::sqrt(Sqr(m_samplesNoise[m_usedPresampIdx]) + Sqr(m_samplesNoise[m_usedPresampIdx+1]));
1498 float derivPresampleSig = m_samplesSub[m_usedPresampIdx+1]/derivPresampleErr;
1499 if (derivPresampleSig < -5) {
1500 m_preExpTail = true;
1501 m_preExpSig = derivPresampleSig;
1502 }
1503
1504 for (unsigned int isample = m_usedPresampIdx; isample <= m_minDeriv2ndIndex - m_prePulseDelta; isample++) {
1505 if (!useSample[isample]) continue;
1506
1507 float sampleSig = -m_samplesSub[isample]/m_samplesNoise[isample];
1508
1509 // Compare the derivative significant to the 2nd derivative significance,
1510 // so we don't waste time dealing with small perturbations on large signals
1511 //
1512 if ((sampleSig > 5 && sampleSig > 0.02*m_minDeriv2ndSig) || sampleSig > 0.5*m_minDeriv2ndSig) {
1513 m_preExpTail = true;
1514
1515 if (sampleSig > m_preExpSig) m_preExpSig = sampleSig;
1516 }
1517 }
1518
1519 // Now we search for maxima before the main pulse
1520 //
1521 int loopLimit = (m_havePulse ? m_minDeriv2ndIndex - 2 : m_peak2ndDerivMinSample - 2);
1522 int loopStart = m_minSampleEvt == 0 ? 1 : m_minSampleEvt;
1523
1524 float maxPrepulseSig = 0;
1525 unsigned int maxPrepulseSample = 0;
1526
1527 for (int isample = loopStart; isample <= loopLimit; isample++) {
1528 if (!useSample[isample]) continue;
1529
1530 //
1531 // If any of the second derivatives prior to the peak are significantly negative, we have a an extra pulse
1532 // prior to the main one -- as opposed to just an expnential tail
1533 //
1534 double prePulseSig = -m_samplesDeriv2nd[isample]/(1e-6 + m_samplesDeriv2ndErr[isample]);
1535 //
1536 // apply a cut on the significance (as above) but without using division
1537 //
1538 if ((prePulseSig > 6 && m_samplesDeriv2nd[isample] < 0.05 * m_minDeriv2nd) ||
1539 m_samplesDeriv2nd[isample] < 0.5*m_minDeriv2nd)
1540 {
1541 m_prePulse = true;
1542 if (prePulseSig > maxPrepulseSig) {
1543 maxPrepulseSig = prePulseSig;
1544 maxPrepulseSample = isample;
1545 }
1546 }
1547 }
1548
1549 if (m_prePulse) {
1550 m_prePulseSig = maxPrepulseSig;
1551
1552 if (m_preExpTail) {
1553 //
1554 // We have a prepulse. If we already indicated an negative exponential,
1555 // if the prepulse has greater significance, we override the negative exponential
1556 //
1557 if (m_prePulseSig > m_preExpSig) {
1558 m_preExpTail = false;
1559 }
1560 else {
1561 m_prePulse = false;
1562 }
1563 }
1564
1565 m_initialPrePulseAmp = m_samplesSub[maxPrepulseSample];
1566 m_initialPrePulseT0 = m_deltaTSample * (maxPrepulseSample);
1567 }
1568 }
1569
1570 // -----------------------------------------------------
1571 // Post pulse detection
1572 //
1573 if (m_doPostPulseCheck) {
1574 for (int isample = m_minDeriv2ndIndex + m_postPulseDelta; isample < (int) nSamples - 1; isample++) {
1575 if (!useSample[isample] || !useSample[isample +1]) continue;
1576
1577 float deriv = m_samplesSub[isample + 1] - m_samplesSub[isample];
1578 float derivErr = std::sqrt(Sqr(m_samplesNoise[isample + 1]) + Sqr(m_samplesNoise[isample]));
1579
1580 float deriv2nd = m_samplesDeriv2nd[isample];
1581 float deriv2ndErr = m_samplesDeriv2ndErr[isample];
1582
1583 if (deriv > m_postPulseDerivMinSig*derivErr && std::abs(deriv2nd) > m_postPulseAbsDer2ndMinSig*deriv2ndErr) {
1584 m_postPulse = true;
1585
1586 // The place to apply the cut on samples depends on whether we have found a "minimum" or a "maximum"
1587 // The -m_2ndDerivStep for the minimum accounts for the shift between 2nd derivative and the samples
1588 // if we find a maximum we cut one sample lower
1589 //
1590 unsigned int delta = deriv2nd < 0 ? m_2ndDerivStep : m_2ndDerivStep - 1;
1591 m_maxSampleEvt = std::min<int>(isample - delta, m_maxSampleEvt);
1592
1593 std::ostringstream msg;
1594 msg << "ZDCPulseAnalyzer for " << m_tag << " Found a post pulse at sample " << isample
1595 << " deriv = " << deriv << ", derivErr = " << derivErr
1596 << " deriv2nd = " << deriv2nd << ", deriv2ndErr = " << deriv2nd;
1597 (*m_msgFunc_p)(ZDCMsg::Debug, msg.str());
1598 m_adjTimeRangeEvent = true;
1599
1600 break;
1601 }
1602 }
1603 }
1604 }
1605
1606
1607 // -----------------------------------------------------
1608
1609 // Stop now if we have no pulse or we've detected a failure
1610 //
1611 if (m_fail || !m_havePulse) return false;
1612
1613 if (!m_useDelayed) DoFit();
1614 else DoFitCombined();
1615
1616 if (fitFailed()) {
1617 m_fail = true;
1618 }
1619 else {
1620 std::ostringstream ostrm;
1621 // ostrm << "Pulse fit successful with chisquare = " << m_fitChisq;
1622 // (*m_msgFunc_p)(ZDCMsg::Debug, ostrm.str());
1623
1625
1627 //
1628 // We correct relative to the m_timingCorrRefADC using m_timingCorrScale to scale
1629 //
1630 double t0CorrFact = (m_fitAmplitude - m_timingCorrRefADC) / m_timingCorrScale;
1631 if (m_timingCorrMode == TimingCorrLog) t0CorrFact = std::log(t0CorrFact);
1632
1633 // Calculate the correction using a polynomial of power determined by the size of the vector.
1634 // For historical reasons we include here a constant term, though it is degenerate with
1635 // the nominal t0 and/or timing calibrations.
1636 //
1637 float correction = 0;
1638
1639 for (unsigned int ipow = 0; ipow < t0CorrParams.size(); ipow++) {
1640 correction += t0CorrParams[ipow]*std::pow(t0CorrFact, double(ipow));
1641 }
1642
1643 // The correction represents the offset of the timing value from zero so we subtract the result
1644 //
1646 }
1647
1648 bool failFixedCut = m_fitTimeCorr < minT0Corr || m_fitTimeCorr > maxT0Corr;
1649
1650 // Calculate the timing significance. Note this implementation breaks the model for
1651 // how DoAnalysis is currently used by explicitly testing m_useLowGain, but that model
1652 // needs adjustment anyway ... (one step at a time)
1653 //
1654 // Note that to avoid coupling non-linear corrections to the amplitude and the
1655 // timing significance we evaluate the time resolution using the fit amplitude
1656 //
1657 if (m_timeCutMode != 0) {
1658 double timeResolution = 0;
1659 if (m_useLowGain) timeResolution = m_timeResFuncLG_p->Eval(m_fitAmplitude);
1660 else timeResolution = m_timeResFuncHG_p->Eval(m_fitAmplitude);
1661
1662 m_timeSig = m_fitTimeCorr/timeResolution;
1663 if (std::abs(m_timeSig) > m_t0CutSig) {
1664 //
1665 // We've failed the significance cut. In OR mode (1) we mark the time
1666 // as bad if we've lso failed the fixed cut. In AND mode, we mark it
1667 // as bad regardless of the fixed cut.
1668 //
1669 if (m_timeCutMode == 1) {
1670 if (failFixedCut) m_badT0 = true;
1671 }
1672 else m_badT0 = true;
1673 }
1674 else if (m_timeCutMode == 2 && failFixedCut) m_badT0 = failFixedCut;
1675 }
1676 else {
1677 m_timeSig = -1;
1678 m_badT0 = failFixedCut;
1679 }
1680
1681 // Now check for valid chisq using lambda function
1682 //
1683 // if (m_fitChisq/m_fitNDoF > 2 && m_fitChisq / (m_fitAmplitude + 1.0e-6) > maxChisqDivAmp) m_badChisq = true;
1684 if (!chisqCutLambda(m_fitChisq, m_fitAmplitude, m_fitNDoF, m_chisqRatio)) m_badChisq = true; }
1685
1686 return !m_fitFailed;
1687}
T Sqr(T in)
std::unique_ptr< const TF1 > m_timeResFuncHG_p
unsigned int m_timeCutMode
size_t m_peak2ndDerivMinTolerance
std::unique_ptr< const TF1 > m_timeResFuncLG_p
static std::vector< float > calculate2ndDerivative(const std::vector< float > &inputData, unsigned int step)
std::vector< float > m_samplesNoise
unsigned int m_prePulseDelta
unsigned int m_timingCorrMode
unsigned int m_maxSampleEvt
bool fitFailed() const
std::vector< float > m_ADCSamplesLG
static float obtainDelayedBaselineCorr(const std::vector< float > &samples)
void DoFit(bool refitLG=false)
std::vector< float > m_samplesSub
unsigned int m_postPulseDelta
std::vector< float > m_ADCSamplesHG
unsigned int m_minSampleEvt
std::vector< float > m_samplesDeriv2ndErr
std::vector< float >::const_iterator SampleCIter
std::vector< float > m_samplesDeriv2nd
void DoFitCombined(bool refitLG=false)
@ Info
Definition ZDCMsg.h:20
correction(mu, runmode, campaign, run=None)
Definition zlumi_mc_cf.py:4
MsgStream & msg
Definition testRead.cxx:32

◆ armSumInclude()

bool ZDCPulseAnalyzer::armSumInclude ( ) const
inline

Definition at line 673 of file ZDCPulseAnalyzer.h.

673{return havePulse() && !(failed() || fitFailed() || badChisq() || badT0() || fitMinimumAmplitude() || LGOverflow() || LGUnderflow() || failSigCut());}
bool LGOverflow() const
bool fitMinimumAmplitude() const
bool havePulse() const
bool failSigCut() const
bool badChisq() const
bool LGUnderflow() const

◆ badChisq()

bool ZDCPulseAnalyzer::badChisq ( ) const
inline

Definition at line 665 of file ZDCPulseAnalyzer.h.

665{return m_badChisq;}

◆ badT0()

bool ZDCPulseAnalyzer::badT0 ( ) const
inline

Definition at line 667 of file ZDCPulseAnalyzer.h.

667{return m_badT0;}

◆ calculate2ndDerivative() [1/2]

std::pair< std::vector< float >, std::vector< float > > ZDCPulseAnalyzer::calculate2ndDerivative ( const std::vector< float > & inputData,
const std::vector< float > & inputNoise,
unsigned int step )
staticprivate

Definition at line 2554 of file ZDCPulseAnalyzer.cxx.

2555{
2556 unsigned int nSamples = inputData.size();
2557
2558 // We start with two zero entries for which we can't calculate the double-step derivative
2559 // and would pad with two zero entries at the end. Start by initializing
2560 //
2561 unsigned int vecSize = 2*step + nSamples - step - 1;
2562 std::vector<float> results(vecSize, 0);
2563 std::vector<float> resultsErr(vecSize, 0);
2564
2565 unsigned int fillIndex = step;
2566 for (unsigned int sample = step; sample < nSamples - step; sample++) {
2567 float deriv2nd = inputData[sample + step] + inputData[sample - step] - 2*inputData[sample];
2568 float deriv2ndErr = std::sqrt(Sqr(inputNoise[sample + step]) + Sqr(inputNoise[sample - step]) + 2*Sqr(inputNoise[sample]));
2569
2570 results[fillIndex] = deriv2nd;
2571 resultsErr[fillIndex++] = deriv2ndErr;
2572 }
2573
2574 return {results, resultsErr};
2575}

◆ calculate2ndDerivative() [2/2]

std::vector< float > ZDCPulseAnalyzer::calculate2ndDerivative ( const std::vector< float > & inputData,
unsigned int step )
staticprivate

Definition at line 2534 of file ZDCPulseAnalyzer.cxx.

2535{
2536 unsigned int nSamples = inputData.size();
2537
2538 // We start with two zero entries for which we can't calculate the double-step derivative
2539 // and would pad with two zero entries at the end. Start by initializing
2540 //
2541 unsigned int vecSize = 2*step + nSamples - step - 1;
2542 std::vector<float> results(vecSize, 0);
2543
2544 unsigned int fillIndex = step;
2545 for (unsigned int sample = step; sample < nSamples - step; sample++) {
2546 auto deriv2nd = inputData[sample + step] + inputData[sample - step] - 2*inputData[sample];
2547 results.at(fillIndex++) = deriv2nd;
2548 }
2549
2550 return results;
2551}

◆ calculateDerivative()

std::vector< float > ZDCPulseAnalyzer::calculateDerivative ( const std::vector< float > & inputData,
unsigned int step )
staticprivate

Definition at line 2513 of file ZDCPulseAnalyzer.cxx.

2514{
2515 unsigned int nSamples = inputData.size();
2516
2517 // So we pad at the beginning and end based on step (i.e. with step - 1 zeros). Fill out the fill vector with zeros initially
2518 //
2519 unsigned int vecSize = 2*(step - 1) + nSamples - step - 1;
2520 std::vector<float> results(vecSize, 0);
2521
2522 // Now fill out the values
2523 //
2524 unsigned int fillIdx = step - 1;
2525
2526 for (unsigned int sample = 0; sample < nSamples - step; sample++) {
2527 int deriv = inputData[sample + step] - inputData[sample];
2528 results.at(fillIdx++) = deriv;
2529 }
2530
2531 return results;
2532}

◆ checkTF1Limits()

void ZDCPulseAnalyzer::checkTF1Limits ( TF1 * func)
private

Definition at line 2185 of file ZDCPulseAnalyzer.cxx.

2186{
2187 for (int ipar = 0; ipar < func->GetNpar(); ipar++) {
2188 double parLimitLow, parLimitHigh;
2189
2190 func->GetParLimits(ipar, parLimitLow, parLimitHigh);
2191
2192 (*m_msgFunc_p)(ZDCMsg::Debug, (
2193 "ZDCPulseAnalyzer name=" + std::string(func->GetName())
2194 + " ipar=" + std::to_string(ipar)
2195 + " parLimitLow=" + std::to_string(parLimitLow)
2196 + " parLimitHigh="+ std::to_string(parLimitHigh)
2197 )
2198 );
2199
2200 if (std::abs(parLimitHigh - parLimitLow) > (1e-6)*std::abs(parLimitLow)) {
2201 double value = func->GetParameter(ipar);
2202 if (value >= parLimitHigh) {
2203 value = parLimitHigh * 0.9;
2204 }
2205 else if (value <= parLimitLow) {
2206 value = parLimitLow + 0.1*std::abs(parLimitLow);
2207 }
2208 func->SetParameter(ipar, value);
2209 }
2210 }
2211}

◆ CombinedPulsesFCN()

void ZDCPulseAnalyzer::CombinedPulsesFCN ( int & numParam,
double * ,
double & f,
double * par,
int flag )
staticprivate

Definition at line 106 of file ZDCPulseAnalyzer.cxx.

107{
108 // The first parameter is a correction factor to account for decrease in beam intensity between x
109 // and y scan. It is applied here and not passed to the actual fit function
110 //
111 int nSamples = s_undelayedFitHist->GetNbinsX();
112
113 if (flag == 3) {
114 s_pullValues.assign(nSamples * 2, 0);
115 }
116
117 double chiSquare = 0;
118
119 float delayBaselineAdjust = par[0];
120
121 // undelayed
122 //
123 for (int isample = 0; isample < nSamples; isample++) {
124 double histValue = s_undelayedFitHist->GetBinContent(isample + 1);
125 double histError = std::max(s_undelayedFitHist->GetBinError(isample + 1), 1.0);
126 double t = s_undelayedFitHist->GetBinCenter(isample + 1);
127
128 if (t > s_combinedFitTMax) break;
129 if (t < s_combinedFitTMin) continue;
130
131 double funcVal = s_combinedFitFunc->EvalPar(&t, &par[1]);
132
133 double pull = (histValue - funcVal) / histError;
134
135 if (flag == 3) s_pullValues[2 * isample] = pull;
136 chiSquare += pull * pull;
137 }
138
139 // delayed
140 //
141 for (int isample = 0; isample < nSamples; isample++) {
142 double histValue = s_delayedFitHist->GetBinContent(isample + 1);
143 double histError = std::max(s_delayedFitHist->GetBinError(isample + 1), 1.0);
144 double t = s_delayedFitHist->GetBinCenter(isample + 1);
145
146 if (t > s_combinedFitTMax) break;
147 if (t < s_combinedFitTMin) continue;
148
149 double funcVal = s_combinedFitFunc->EvalPar(&t, &par[1]) + delayBaselineAdjust;
150 double pull = (histValue - funcVal) / histError;
151
152 if (flag == 3) s_pullValues[2 * isample + 1] = pull;
153 chiSquare += pull * pull;
154 }
155
156 f = chiSquare;
157}
static TF1 * s_combinedFitFunc
static std::vector< float > s_pullValues
static TH1 * s_undelayedFitHist
static float s_combinedFitTMin
static float s_combinedFitTMax
static TH1 * s_delayedFitHist

◆ ConfigFromJSON()

std::pair< bool, std::string > ZDCPulseAnalyzer::ConfigFromJSON ( const JSON & config)
private

Definition at line 2706 of file ZDCPulseAnalyzer.cxx.

2707{
2708 bool result = true;
2709 std::string resultString = "success";
2710
2711 for (auto [key, value] : config.items()) {
2712 //
2713 // Big if statement to process configuration parameters
2714 //
2715 if (key == "Nsample") m_Nsample = value;
2716 else if (key == "tag") m_tag = value;
2717 else if (key == "LGMode") m_LGMode = value;
2718 else if (key == "Nsample") m_Nsample = value;
2719 else if (key == "useDelayed") m_useDelayed = value;
2720 else if (key == "preSampleIdx") m_preSampleIdx = value;
2721 else if (key == "FADCFreqMHz") m_freqMHz = value;
2722 else if (key == "nominalPedestal") m_pedestal = value;
2723 else if (key == "fitFunction") m_fitFunction = value;
2724 else if (key == "peakSample") m_peak2ndDerivMinSample = value;
2725 else if (key == "peakTolerance") m_peak2ndDerivMinTolerance = value;
2726 else if (key == "2ndDerivThreshHG") m_peak2ndDerivMinThreshHG = value;
2727 else if (key == "2ndDerivThreshLG") m_peak2ndDerivMinThreshLG = value;
2728 else if (key == "2ndDerivStep") m_2ndDerivStep = value;
2729 else if (key == "HGOverflowADC") m_HGOverflowADC = value;
2730 else if (key == "HGUnderflowADC") m_HGUnderflowADC = value;
2731 else if (key == "LGOverflowADC") m_LGOverflowADC = value;
2732 else if (key == "nominalT0HG") m_nominalT0HG = value;
2733 else if (key == "nominalT0LG") m_nominalT0LG = value;
2734 else if (key == "nominalTau1") m_nominalTau1 = value;
2735 else if (key == "nominalTau2") m_nominalTau2 = value;
2736 else if (key == "fixTau1") m_fixTau1 = value;
2737 else if (key == "fixTau2") m_fixTau2 = value;
2738 else if (key == "T0CutsHG") {
2739 m_T0CutLowHG = value[0];
2740 m_T0CutHighHG = value[1];
2741 }
2742 else if (key == "T0CutsLG") {
2743 m_T0CutLowLG = value[0];
2744 m_T0CutHighLG = value[1];
2745 m_initializedFits = false;
2746 }
2747 else if (key == "chisqDivAmpCutHG") m_chisqDivAmpCutHG = value;
2748 else if (key == "chisqDivAmpCutLG") m_chisqDivAmpCutLG = value;
2749 else if (key == "chisqDivAmpOffsetHG") m_chisqDivAmpOffsetHG = value;
2750 else if (key == "chisqDivAmpScaleLG") m_chisqDivAmpScaleLG = value;
2751 else if (key == "chisqDivAmpScaleHG") m_chisqDivAmpScaleHG = value;
2752 else if (key == "chisqDivAmpOffsetLG") m_chisqDivAmpOffsetLG = value;
2753 else if (key == "chisqDivAmpPowerHG") m_chisqDivAmpPowerHG = value;
2754 else if (key == "chisqDivAmpPowerLG") m_chisqDivAmpPowerLG = value;
2755 else if (key == "gainFactorHG") m_gainFactorHG = value;
2756 else if (key == "gainFactorLG") m_gainFactorLG = value;
2757 else if (key == "noiseSigmaHG") m_noiseSigHG = value;
2758 else if (key == "noiseSigmaLG") m_noiseSigLG = value;
2759 else if (key == "perSampleNoiseSigmaHG") {
2762 }
2763 else if (key == "perSampleNoiseSigmaLG") {
2766 // m_setPerSampleNoiseLG.clear();
2767
2768 // for (auto elem : value) {
2769 // m_setPerSampleNoiseLG.push_back(elem);
2770 // }
2771 }
2772 else if (key == "fitTimeMax") {
2773 SetFitTimeMax(static_cast<float>(value));
2774 }
2775 else if (key == "enableRepass") m_enableRepass = value;
2776 else if (key == "Repass2ndDerivThreshHG") m_peak2ndDerivMinRepassHG = value;
2777 else if (key == "Repass2ndDerivThreshLG") m_peak2ndDerivMinRepassLG = value;
2778 else if (key == "fitAmpMinMaxHG") {
2779 m_fitAmpMinHG = value[0];
2780 m_fitAmpMaxHG = value[1];
2781 }
2782 else if (key == "fitAmpMinMaxLG") {
2783 m_fitAmpMinLG = value[0];
2784 m_fitAmpMaxLG = value[1];
2785 }
2786 else if (key == "quietFits") {
2788 }
2789 else if (key == "enablePreExclusion") {
2790 m_enablePreExcl = true;
2794 }
2795 else if (key == "enablePostExclusion") {
2796 m_enablePostExcl = true;
2800 }
2801 else if (key == "enableUnderflowExclusionHG") {
2805 }
2806 else if (key == "enableUnderflowExclusionLG") {
2810 }
2811 else if (key == "enablePrePulseDetection") {
2813 }
2814 else if (key == "enablePostPulseDetection") {
2816 }
2817 else if (key == "ampMinSignifHGLG") {
2818 m_haveSignifCuts = true;
2819 m_sigMinHG = value[0];
2820 m_sigMinLG = value[1];
2821 }
2822 else if (key == "enableFADCCorrections") {
2823 auto fileNameJson = value["filename"];
2824 auto doPerSampleCorrJson = value["doPerSampleCorr"];
2825
2826 if (fileNameJson.is_null() || doPerSampleCorrJson.is_null()) {
2827 result = false;
2828 resultString = "failure processing enableFADCCorrections object";
2829 break;
2830 }
2831
2832 m_haveFADCCorrections = true;
2833 m_FADCCorrPerSample = doPerSampleCorrJson;
2834 m_fadcCorrFileName = fileNameJson;
2835 }
2836 else if(key =="useDelayed"){
2837 if(value){
2838 m_useDelayed = true;
2839 }
2840 }
2841 else if (key == "delayDeltaT") m_delayedDeltaT = value;
2842 else if (key == "delayDefaultPedestalShift") m_delayedPedestalDiff = value;
2843 else if (key == "enableTimingCorrection") {
2847 }
2848 else if(key == "timeCorrCoeffHG"){
2849 for(int i = 0;auto coeff:value){
2850 m_HGT0CorrParams.at(i) = coeff;
2851 i++;
2852 }
2853 }
2854 else if(key == "timeCorrCoeffLG"){
2855 for(int i = 0;auto coeff:value){
2856 m_LGT0CorrParams.at(i) = coeff;
2857 i++;
2858 }
2859 }
2860 else if(key == "enableNLCorrection"){
2861 m_haveNonlinCorr = true;
2864 (*m_msgFunc_p)(
2865 ZDCMsg::Debug, ("Setting non-linear parameters"
2866 ", reference ADC = " + std::to_string(m_nonLinCorrRefADC) +
2867 ", reference scale = " + std::to_string(m_nonLinCorrRefScale)));
2868 }
2869 else if(key == "HGNLCorrCoeffs"){
2870 std::string HGParamsStr = "HG coefficients = ";
2871 for (auto coeff : value) {
2872 m_nonLinCorrParamsHG.push_back(coeff);
2873 HGParamsStr += std::to_string(m_nonLinCorrParamsHG.back()) + " ";
2874 }
2875 (*m_msgFunc_p)(ZDCMsg::Debug, std::move(HGParamsStr));
2876 }
2877 else if(key == "LGNLCorrCoeffs"){
2878 std::string LGParamsStr = "LG coefficients = ";
2879 for(auto coeff:value){
2880 m_nonLinCorrParamsLG.push_back(coeff);
2881 LGParamsStr += std::to_string(m_nonLinCorrParamsLG.back()) + " ";
2882 }
2883 (*m_msgFunc_p)(ZDCMsg::Debug, std::move(LGParamsStr));
2884 }
2885 else {
2886 result = false;
2887 resultString = "unprocessed parameter";
2888 break;
2889 }
2890 }
2891
2892 return {result, resultString};
2893}
std::vector< float > m_setPerSampleNoiseHG
std::vector< float > m_nonLinCorrParamsLG
std::vector< float > m_LGT0CorrParams
unsigned int m_preExclLGADCThresh
unsigned int m_postExclLGADCThresh
unsigned int m_maxSamplesPreExcl
std::vector< float > m_setPerSampleNoiseLG
unsigned int m_underFlowExclSamplesPreLG
std::vector< float > m_nonLinCorrParamsHG
unsigned int m_underFlowExclSamplesPostHG
unsigned int m_maxSamplesPostExcl
unsigned int m_underFlowExclSamplesPreHG
void SetFitTimeMax(float tmax)
unsigned int m_underFlowExclSamplesPostLG
std::vector< float > m_HGT0CorrParams
unsigned int m_preExclHGADCThresh
unsigned int m_postExclHGADCThresh
std::string m_fadcCorrFileName
unsigned int m_LGMode

◆ disableFADCCorrections()

void ZDCPulseAnalyzer::disableFADCCorrections ( )
inline

Definition at line 638 of file ZDCPulseAnalyzer.h.

638{m_haveFADCCorrections = false;}

◆ disablePostPulseCheck()

void ZDCPulseAnalyzer::disablePostPulseCheck ( )
inline

Definition at line 595 of file ZDCPulseAnalyzer.h.

595{m_doPostPulseCheck = false;}

◆ DoAnalysis()

bool ZDCPulseAnalyzer::DoAnalysis ( bool repass)
private

Definition at line 1166 of file ZDCPulseAnalyzer.cxx.

1167{
1168 float deriv2ndThreshHG = 0;
1169 float deriv2ndThreshLG = 0;
1170
1171 if (!repass) {
1173
1174 deriv2ndThreshHG = m_peak2ndDerivMinThreshHG;
1175 deriv2ndThreshLG = m_peak2ndDerivMinThreshLG;
1176 }
1177 else {
1178 deriv2ndThreshHG = m_peak2ndDerivMinRepassHG;
1179 deriv2ndThreshLG = m_peak2ndDerivMinRepassLG;
1180 }
1181
1183 if (m_useLowGain) {
1184 // (*m_msgFunc_p)(ZDCMsg::Verbose, "ZDCPulseAnalyzer:: " + m_tag + " using low gain data ");
1185
1186 auto chisqCutLambda = [cut = m_chisqDivAmpCutLG,
1189 power = m_chisqDivAmpPowerLG]
1190 (float chisq, float amp, unsigned int fitNDoF, float& ratio)->bool
1191 {
1192 // Avoid a spurious FPE from clang.
1194 if (amp < 1e-6) return true;
1195 ratio = chisq /(offset + scale* (std::pow(amp/1000, power)));
1196 if (chisq/fitNDoF > 2 && ratio > cut) return false;
1197 else return true;
1198 };
1199
1201 deriv2ndThreshLG, m_LGT0CorrParams, chisqCutLambda, m_T0CutLowLG, m_T0CutHighLG);
1202 if (result) {
1203 //
1204 // +++BAC
1205 //
1206 // I have removed some code that attempted a refit in case of failure of the chi-square cut
1207 // Instead, we should implement an analysis of the failure with possible re-fit afterwards
1208 // with possible change of the pre- or post-pulse condition
1209 //
1210 // --BAC
1211 //
1212
1213 double amplCorrFactor = getAmplitudeCorrection(false);
1214
1215 //
1216 // Multiply amplitude by gain factor
1217 //
1219 m_amplitude = m_fitAmplitude * amplCorrFactor * m_gainFactorLG;
1220 m_ampError = m_fitAmpError * amplCorrFactor * m_gainFactorLG;
1225
1226 // BAC: also scale up the 2nd derivative by the gain factor so low and high gain can be treated on the same footing
1227 //
1229 }
1230
1231 return result;
1232 }
1233 else {
1234 // (*m_msgFunc_p)(ZDCMsg::Verbose, "ZDCPulseAnalyzer:: " + m_tag + " using high gain data ");
1235 auto chisqCutLambda = [cut = m_chisqDivAmpCutHG,
1238 power = m_chisqDivAmpPowerHG, tag = m_tag]
1239 (float chisq, float amp, unsigned int fitNDoF, float& ratio)->bool
1240 {
1241 // Avoid a spurious FPE from clang.
1243 if (amp < 1e-6) return true;
1244 ratio = chisq /(offset + scale*(std::pow(amp/1000, power)));
1245 if (chisq/float(fitNDoF) > 2 && ratio > cut) return false;
1246 else return true;
1247 };
1248
1250 deriv2ndThreshHG, m_HGT0CorrParams, chisqCutLambda, m_T0CutLowHG, m_T0CutHighHG);
1251 if (result) {
1252 // +++BAC
1253 //
1254 // I have removed some code that attempted a refit in case of failure of the chi-square cut
1255 // Instead, we should implement an analysis of the failure with possible re-fit afterwards
1256 // with possible change of the pre- or post-pulse condition
1257 //
1258 // --BAC
1259
1267
1269
1270 // If we have a non-linear correction, apply it here
1271 //
1272 // We apply it as an inverse correction - i.e. we divide by a correction
1273 // term tha is a sum of coefficients times the ADC minus a reference
1274 // to a power. The lowest power is 1, the highest is deteremined by
1275 // the number of provided coefficients
1276 //
1277 double amplCorrFactor = getAmplitudeCorrection(true);
1278
1279 m_amplitude *= amplCorrFactor;
1280 m_ampError *= amplCorrFactor;
1281 }
1282
1283 // If LG refit has been requested, do it now
1284 //
1287 DoFit(true);
1288
1289 double amplCorrFactor = getAmplitudeCorrection(false);
1290 m_refitLGAmplCorr = m_refitLGAmpl*amplCorrFactor;
1291 }
1292
1293 return result;
1294 }
1295}
std::vector< bool > m_useSampleHG
unsigned int m_NSamplesAna
std::vector< float > m_sampleNoiseLG
std::vector< float > m_ADCSamplesHGSub
void prepareLGRefit(const std::vector< float > &samplesLG, const std::vector< float > &samplesNoise, const std::vector< bool > &useSamples)
double getAmplitudeCorrection(bool highGain)
std::vector< float > m_ADCSamplesLGSub
std::vector< bool > m_useSampleLG
bool AnalyzeData(size_t nSamples, size_t preSample, const std::vector< float > &samples, const std::vector< float > &samplesNoise, const std::vector< bool > &useSamples, float peak2ndDerivMinThresh, const std::vector< float > &toCorrParams, ChisqCutLambdatype chisqCutLambda, float minT0Corr, float maxT0Corr)
std::vector< float > m_sampleNoiseHG
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24

◆ DoFit()

void ZDCPulseAnalyzer::DoFit ( bool refitLG = false)
private

Definition at line 1712 of file ZDCPulseAnalyzer.cxx.

1713{
1714 bool fitLG = m_useLowGain || refitLG;
1715
1716 TH1* hist_p = nullptr;
1717 FillHistogram(refitLG);
1718
1719 // Set the initial values
1720 //
1721 float ampInitial, fitAmpMin, fitAmpMax, t0Initial;
1722
1723 if (fitLG) {
1724 fitAmpMin = m_fitAmpMinLG;
1725 fitAmpMax = m_fitAmpMaxLG;
1726 t0Initial = m_nominalT0LG;
1727 ampInitial = m_ADCPeakLG;
1728 }
1729 else {
1730 ampInitial = m_ADCPeakHG;
1731 fitAmpMin = m_fitAmpMinHG;
1732 fitAmpMax = m_fitAmpMaxHG;
1733 t0Initial = m_nominalT0HG;
1734 }
1735
1736 if (refitLG) {
1737 hist_p = m_fitHistLGRefit.get();
1738 }
1739 else {
1740 hist_p = m_fitHist.get();
1741 }
1742 if (ampInitial < fitAmpMin) ampInitial = fitAmpMin * 1.5;
1743
1744
1745 ZDCFitWrapper* fitWrapper = m_defaultFitWrapper.get();
1746 if (preExpTail()) {
1747 fitWrapper = m_preExpFitWrapper.get();
1748 (static_cast<ZDCPreExpFitWrapper*>(m_preExpFitWrapper.get()))->SetInitialExpPulse(m_initialExpAmp);
1749 }
1750 else if (prePulse()) {
1751 fitWrapper = m_prePulseFitWrapper.get();
1752 (static_cast<ZDCPrePulseFitWrapper*>(fitWrapper))->SetInitialPrePulse(m_initialPrePulseAmp, m_initialPrePulseT0,0,25);
1753 }
1754
1755 if (m_adjTimeRangeEvent) {
1758
1759 float fitTReference = m_deltaTSample * m_usedPresampIdx;
1760
1761 fitWrapper->Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax, m_fitTMin, m_fitTMax, fitTReference);
1762 }
1763 else {
1764 fitWrapper->Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
1765 }
1766
1767 // Now perform the fit
1768 //
1769 std::string options = m_fitOptions + "Ns";
1770 if (m_quietFits) {
1771 options += "Q";
1772 }
1773
1774 bool fitFailed = false;
1775
1776 // dumpTF1(fitWrapper->GetWrapperTF1RawPtr());
1777 checkTF1Limits(fitWrapper->GetWrapperTF1RawPtr());
1778
1779 //
1780 // Fit the data with the function provided by the fit wrapper
1781 //
1782 TFitResultPtr result_ptr = hist_p->Fit(fitWrapper->GetWrapperTF1RawPtr(), options.c_str(), "", m_fitTMin, m_fitTMax);
1783 int fitStatus = result_ptr;
1784
1785 //
1786 // If the first fit failed, also check the EDM. If sufficiently small, the failure is almost surely due
1787 // to parameter limits and we just accept the result
1788 //
1789 if (fitStatus != 0 && result_ptr->Edm() > 0.001)
1790 {
1791 //
1792 // We contstrain the fit and try again
1793 //
1794 fitWrapper->ConstrainFit();
1795
1796 TFitResultPtr constrFitResult_ptr = hist_p->Fit(fitWrapper->GetWrapperTF1RawPtr(), options.c_str(), "", m_fitTMin, m_fitTMax);
1797 fitWrapper->UnconstrainFit();
1798
1799 if ((int) constrFitResult_ptr != 0) {
1800 //
1801 // Even the constrained fit failed, so we quit.
1802 //
1803 fitFailed = true;
1804 }
1805 else {
1806 // Now we try the fit again with the constraint removed
1807 //
1808 TFitResultPtr unconstrFitResult_ptr = hist_p->Fit(fitWrapper->GetWrapperTF1RawPtr(), options.c_str(), "", m_fitTMin, m_fitTMax);
1809 if ((int) unconstrFitResult_ptr != 0) {
1810 //
1811 // The unconstrained fit failed again, so we redo the constrained fit
1812 //
1813 fitWrapper->ConstrainFit();
1814
1815 TFitResultPtr constrFit2Result_ptr = hist_p->Fit(fitWrapper->GetWrapperTF1RawPtr(), options.c_str(), "", m_fitTMin, m_fitTMax);
1816 if ((int) constrFit2Result_ptr != 0) {
1817 //
1818 // Even the constrained fit failed the second time, so we quit.
1819 //
1820 fitFailed = true;
1821 }
1822
1823 result_ptr = constrFit2Result_ptr;
1824 fitWrapper->UnconstrainFit();
1825 }
1826 else {
1827 result_ptr = unconstrFitResult_ptr;
1828 }
1829 }
1830 }
1831
1832 // At this point we're don varying function parameters
1833 //
1834 fitWrapper->Finalize();
1835
1836 if (!m_fitFailed && m_saveFitFunc) {
1837 hist_p->GetListOfFunctions()->Clear();
1838
1839 TF1* func = fitWrapper->GetWrapperTF1RawPtr();
1840 std::string name = func->GetName();
1841
1842 TF1* copyFunc = static_cast<TF1*>(func->Clone((name + "_copy").c_str()));
1843 hist_p->GetListOfFunctions()->Add(copyFunc);
1844 }
1845
1846 if (!refitLG) {
1848 m_bkgdMaxFraction = fitWrapper->GetBkgdMaxFraction();
1849 m_fitAmplitude = fitWrapper->GetAmplitude();
1850 m_fitAmpError = fitWrapper->GetAmpError();
1851
1852 if (preExpTail()) {
1853 m_fitExpAmp = (static_cast<ZDCPreExpFitWrapper*>(m_preExpFitWrapper.get()))->GetExpAmp();
1854 }
1855 else {
1856 m_fitExpAmp = 0;
1857 }
1858
1859 m_fitTime = fitWrapper->GetTime();
1860 m_fitTimeSub = m_fitTime - t0Initial;
1861
1862 m_fitChisq = result_ptr->Chi2();
1863 m_fitNDoF = result_ptr->Ndf();
1864
1865 m_fitTau1 = fitWrapper->GetTau1();
1866 m_fitTau2 = fitWrapper->GetTau2();
1867
1868 // Here we need to check if the fit amplitude is small (close) enough to fitAmpMin.
1869 // with "< 1+epsilon" where epsilon ~ 1%
1870 if (m_fitAmplitude < fitAmpMin * 1.01) {
1871 m_fitMinAmp = true;
1872 }
1873
1874 if (m_haveSignifCuts) {
1875 float sigMinCut = fitLG ? m_sigMinLG : m_sigMinHG;
1876
1877 if (m_fitAmpError > 1e-6) {
1878 if (m_fitAmplitude/m_fitAmpError < sigMinCut) m_failSigCut = true;
1879 }
1880 }
1881
1882 if (!m_fitFailed) {
1883 unsigned int numPars = fitWrapper->GetNumShapeParameters();
1884 m_shapeParameters.assign(numPars, 0);
1885
1886 for (size_t ipar = 0; ipar < numPars; ipar++) {
1887 m_shapeParameters[ipar] = fitWrapper->GetShapeParameter(ipar);
1888 }
1889 }
1890 }
1891 else {
1892 m_evtLGRefit = true;
1893 m_refitLGFitAmpl = fitWrapper->GetAmplitude();
1894 m_refitLGAmpl = fitWrapper->GetAmplitude() * m_gainFactorLG;
1896 m_refitLGChisq = result_ptr->Chi2();
1897 m_refitLGTime = fitWrapper->GetTime();
1898 m_refitLGTimeSub = m_refitLGTime - t0Initial;
1899 }
1900}
virtual float GetTau1() const =0
void Initialize(float initialAmp, float initialT0, float ampMin, float ampMax)
virtual float GetBkgdMaxFraction() const =0
virtual void ConstrainFit()=0
virtual TF1 * GetWrapperTF1RawPtr() const
virtual float GetAmpError() const =0
virtual void UnconstrainFit()=0
virtual float GetTime() const =0
virtual float GetShapeParameter(size_t index) const =0
virtual float GetTau2() const =0
virtual void Finalize()
virtual float GetAmplitude() const =0
virtual unsigned int GetNumShapeParameters() const =0
std::unique_ptr< ZDCFitWrapper > m_defaultFitWrapper
bool prePulse() const
std::vector< float > m_shapeParameters
std::string m_fitOptions
std::unique_ptr< ZDCPrePulseFitWrapper > m_prePulseFitWrapper
void checkTF1Limits(TF1 *func)
bool preExpTail() const
std::unique_ptr< ZDCPreExpFitWrapper > m_preExpFitWrapper
void FillHistogram(bool refitLG)

◆ DoFitCombined()

void ZDCPulseAnalyzer::DoFitCombined ( bool refitLG = false)
private

Definition at line 1902 of file ZDCPulseAnalyzer.cxx.

1903{
1904 bool fitLG = refitLG || m_useLowGain;
1905 TH1* hist_p = nullptr, *delayedHist_p = nullptr;
1906
1907 FillHistogram(refitLG);
1908 if (refitLG) {
1909 hist_p = m_fitHistLGRefit.get();
1910 delayedHist_p = m_delayedHistLGRefit.get();
1911 }
1912 else {
1913 hist_p = m_fitHist.get();
1914 delayedHist_p = m_delayedHist.get();
1915 }
1916
1917 float fitAmpMin, fitAmpMax, t0Initial, ampInitial;
1918 if (fitLG) {
1919 ampInitial = m_ADCPeakLG;
1920 fitAmpMin = m_fitAmpMinLG;
1921 fitAmpMax = m_fitAmpMaxLG;
1922 t0Initial = m_nominalT0LG;
1923 }
1924 else {
1925 ampInitial = m_ADCPeakHG;
1926 fitAmpMin = m_fitAmpMinHG;
1927 fitAmpMax = m_fitAmpMaxHG;
1928 t0Initial = m_nominalT0HG;
1929 }
1930
1931 // Set the initial values
1932 //
1933 if (ampInitial < fitAmpMin) ampInitial = fitAmpMin * 1.5;
1934
1935 ZDCFitWrapper* fitWrapper = m_defaultFitWrapper.get();
1936 //if (prePulse()) fitWrapper = fitWrapper = m_preExpFitWrapper.get();
1937
1938 if (preExpTail()) {
1939 fitWrapper = m_preExpFitWrapper.get();
1940 (static_cast<ZDCPreExpFitWrapper*>(m_preExpFitWrapper.get()))->SetInitialExpPulse(m_initialExpAmp);
1941 }
1942 else if (prePulse()) {
1943 fitWrapper = m_prePulseFitWrapper.get();
1944 (static_cast<ZDCPrePulseFitWrapper*>(fitWrapper))->SetInitialPrePulse(m_initialPrePulseAmp, m_initialPrePulseT0,0,25);
1945 }
1946
1947 // Initialize the fit wrapper for this event, specifying a
1948 // per-event fit range if necessary
1949 //
1950 if (m_adjTimeRangeEvent) {
1953
1954 float fitTReference = m_deltaTSample * m_usedPresampIdx;
1955
1956 fitWrapper->Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax, m_fitTMin, m_fitTMax, fitTReference);
1957 }
1958 else {
1959 fitWrapper->Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
1960 }
1961
1962 // Set up the virtual fitter
1963 //
1964 TFitter* theFitter = nullptr;
1965
1966 if (prePulse()) {
1968
1969 theFitter = m_prePulseCombinedFitter.get();
1970 }
1971 else {
1973
1974 theFitter = m_defaultCombinedFitter.get();
1975 }
1976
1977 // dumpTF1(fitWrapper->GetWrapperTF1RawPtr());
1978
1979 // Set the static pointers to histograms and function for use in FCN
1980 //
1981 s_undelayedFitHist = hist_p;
1982 s_delayedFitHist = delayedHist_p;
1983 s_combinedFitFunc = fitWrapper->GetWrapperTF1RawPtr();
1986
1987
1988 size_t numFitPar = theFitter->GetNumberTotalParameters();
1989
1990 theFitter->GetMinuit()->fISW[4] = -1;
1991
1992 // Now perform the fit
1993 //
1994 if (m_quietFits) {
1995 theFitter->GetMinuit()->fISW[4] = -1;
1996
1997 int ierr= 0;
1998 theFitter->GetMinuit()->mnexcm("SET NOWarnings",nullptr,0,ierr);
1999 }
2000 else theFitter->GetMinuit()->fISW[4] = 0;
2001
2002 // Only include baseline shift in fit for pre-pulses. Otherwise baseline matching should work
2003 //
2004 if (prePulse()) {
2005 theFitter->SetParameter(0, "delayBaselineAdjust", 0, 0.01, -100, 100);
2006 theFitter->ReleaseParameter(0);
2007 }
2008 else {
2009 theFitter->SetParameter(0, "delayBaselineAdjust", 0, 0.01, -100, 100);
2010 theFitter->FixParameter(0);
2011 }
2012
2013
2014 double arglist[100];
2015 arglist[0] = 5000; // number of function calls
2016 arglist[1] = 0.01; // tolerance
2017 int status = theFitter->ExecuteCommand("MIGRAD", arglist, 2);
2018
2019 double fitAmp = theFitter->GetParameter(1);
2020
2021 // Capture the chi-square etc.
2022 //
2023 double chi2, edm, errdef;
2024 int nvpar, nparx;
2025
2026 theFitter->GetStats(chi2, edm, errdef, nvpar, nparx);
2027
2028 // Here we need to check if fitAmp is small (close) enough to fitAmpMin.
2029 // with "< 1+epsilon" where epsilon ~ 1%
2030 //
2031 if (status || fitAmp < fitAmpMin * 1.01 || edm > 0.01){
2032
2033 //
2034 // We first retry the fit with no baseline adjust
2035 //
2036 theFitter->SetParameter(0, "delayBaselineAdjust", 0, 0.01, -100, 100);
2037 theFitter->FixParameter(0);
2038
2039 // Here we need to check if fitAmp is small (close) enough to fitAmpMin.
2040 // with "< 1+epsilon" where epsilon ~ 1%
2041 if (fitAmp < fitAmpMin * 1.01) {
2042 if (m_adjTimeRangeEvent) {
2043 float fitTReference = m_deltaTSample * m_usedPresampIdx;
2044 fitWrapper->Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax, m_fitTMin, m_fitTMax, fitTReference);
2045 }
2046 else {
2047 fitWrapper->Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
2048 }
2049 }
2050
2051 status = theFitter->ExecuteCommand("MIGRAD", arglist, 2);
2052 if (status != 0) {
2053 //
2054 // Fit failed event with no baseline adust, so be it
2055 //
2056 theFitter->ReleaseParameter(0);
2057 m_fitFailed = true;
2058 }
2059 else {
2060 //
2061 // The fit succeeded with no baseline adjust, re-fit allowing for baseline adjust using
2062 // the parameters from previous fit as the starting point
2063 //
2064 theFitter->ReleaseParameter(0);
2065 status = theFitter->ExecuteCommand("MIGRAD", arglist, 2);
2066
2067 if (status) {
2068 // Since we know the fit can succeed without the baseline adjust, go back to it
2069 //
2070 theFitter->SetParameter(0, "delayBaselineAdjust", 0, 0.01, -100, 100);
2071 theFitter->FixParameter(0);
2072 status = theFitter->ExecuteCommand("MIGRAD", arglist, 2);
2073 }
2074 }
2075 }
2076 else m_fitFailed = false;
2077
2078 // Check to see if the fit forced the amplitude to the minimum, if so set the corresponding status bit
2079 //
2080 fitAmp = theFitter->GetParameter(1);
2081
2082 // Here we need to check if fitAmp is small (close) enough to fitAmpMin.
2083 // with "< 1+epsilon" where epsilon ~ 1%
2084 if (fitAmp < fitAmpMin * 1.01) {
2085 m_fitMinAmp = true;
2086 }
2087
2088 // Check that the amplitude passes minimum significance requirement
2089 //
2090 float sigMinCut = fitLG ? m_sigMinLG : m_sigMinHG;
2091 if (m_fitAmpError > 1e-6) {
2092 if (m_fitAmplitude/m_fitAmpError < sigMinCut) m_failSigCut = true;
2093 }
2094
2095 if (!m_quietFits) theFitter->GetMinuit()->fISW[4] = -1;
2096
2097 std::vector<double> funcParams(numFitPar - 1);
2098 std::vector<double> funcParamErrs(numFitPar - 1);
2099
2100 // Save the baseline shift between delayed and undelayed samples
2101 //
2102 m_delayedBaselineShift = theFitter->GetParameter(0);
2103
2104 // Capture and store the fit function parameteds and errors
2105 //
2106 for (size_t ipar = 1; ipar < numFitPar; ipar++) {
2107 funcParams[ipar - 1] = theFitter->GetParameter(ipar);
2108 funcParamErrs[ipar - 1] = theFitter->GetParError(ipar);
2109 }
2110
2111 s_combinedFitFunc->SetParameters(&funcParams[0]);
2112 s_combinedFitFunc->SetParErrors(&funcParamErrs[0]);
2113
2114 // Capture the chi-square etc.
2115 //
2116 theFitter->GetStats(chi2, edm, errdef, nvpar, nparx);
2117
2118 int ndf = 2 * m_Nsample - nvpar;
2119
2120 s_combinedFitFunc->SetChisquare(chi2);
2121 s_combinedFitFunc->SetNDF(ndf);
2122
2123 // add to list of functions
2124 if (m_saveFitFunc) {
2125 s_undelayedFitHist->GetListOfFunctions()->Clear();
2126 s_undelayedFitHist->GetListOfFunctions()->Add(s_combinedFitFunc);
2127
2128 s_delayedFitHist->GetListOfFunctions()->Clear();
2129 s_delayedFitHist->GetListOfFunctions()->Add(s_combinedFitFunc);
2130 }
2131
2132 if (!refitLG) {
2133 // Save the pull values from the last call to FCN
2134 //
2135 arglist[0] = 3; // number of function calls
2136 theFitter->ExecuteCommand("Cal1fcn", arglist, 1);
2138
2139 m_fitAmplitude = fitWrapper->GetAmplitude();
2140 m_fitTime = fitWrapper->GetTime();
2141 if (prePulse()) {
2142 m_fitPreT0 = (static_cast<ZDCPrePulseFitWrapper*>(m_prePulseFitWrapper.get()))->GetPreT0();
2143 m_fitPreAmp = (static_cast<ZDCPrePulseFitWrapper*>(m_prePulseFitWrapper.get()))->GetPreAmp();
2144 m_fitPostT0 = (static_cast<ZDCPrePulseFitWrapper*>(m_prePulseFitWrapper.get()))->GetPostT0();
2145 m_fitPostAmp = (static_cast<ZDCPrePulseFitWrapper*>(m_prePulseFitWrapper.get()))->GetPostAmp();
2146 }
2147
2148 if (preExpTail()) {
2149 m_fitExpAmp = (static_cast<ZDCPreExpFitWrapper*>(m_preExpFitWrapper.get()))->GetExpAmp();
2150 }
2151 else {
2152 m_fitExpAmp = 0;
2153 }
2154
2155 m_fitTimeSub = m_fitTime - t0Initial;
2156 m_fitChisq = chi2;
2157 m_fitNDoF = ndf;
2158
2159 m_fitTau1 = fitWrapper->GetTau1();
2160 m_fitTau2 = fitWrapper->GetTau2();
2161
2162 m_fitAmpError = fitWrapper->GetAmpError();
2163 m_bkgdMaxFraction = fitWrapper->GetBkgdMaxFraction();
2164
2165 if (!m_fitFailed) {
2166 unsigned int numPars = fitWrapper->GetNumShapeParameters();
2167 m_shapeParameters.assign(numPars, 0);
2168
2169 for (size_t ipar = 0; ipar < numPars; ipar++) {
2170 m_shapeParameters[ipar] = fitWrapper->GetShapeParameter(ipar);
2171 }
2172 }
2173 }
2174 else {
2175 m_evtLGRefit = true;
2176 m_refitLGFitAmpl = fitWrapper->GetAmplitude();
2177 m_refitLGAmpl = fitWrapper->GetAmplitude() * m_gainFactorLG;
2180 m_refitLGTime = fitWrapper->GetTime();
2181 m_refitLGTimeSub = m_refitLGTime - t0Initial;
2182 }
2183}
std::unique_ptr< TFitter > m_prePulseCombinedFitter
std::vector< float > m_fitPulls
static std::unique_ptr< TFitter > MakeCombinedFitter(TF1 *func)
std::unique_ptr< TH1 > m_delayedHistLGRefit
std::unique_ptr< TH1 > m_delayedHist
std::unique_ptr< TFitter > m_defaultCombinedFitter
double chi2(TH1 *h0, TH1 *h1)
status
Definition merge.py:16

◆ dump()

void ZDCPulseAnalyzer::dump ( ) const

Definition at line 2268 of file ZDCPulseAnalyzer.cxx.

2269{
2270 (*m_msgFunc_p)(ZDCMsg::Info, ("ZDCPulseAnalyzer dump for tag = " + m_tag));
2271
2272 (*m_msgFunc_p)(ZDCMsg::Info, ("Presample index, value = " + std::to_string(m_preSampleIdx) + ", " + std::to_string(m_preSample)));
2273
2274 if (m_useDelayed) {
2275 (*m_msgFunc_p)(ZDCMsg::Info, ("using delayed samples with delta T = " + std::to_string(m_delayedDeltaT) + ", and pedestalDiff == " +
2276 std::to_string(m_delayedPedestalDiff)));
2277 }
2278
2279 std::ostringstream message1;
2280 message1 << "samplesSub ";
2281 for (size_t sample = 0; sample < m_samplesSub.size(); sample++) {
2282 message1 << ", [" << sample << "] = " << m_samplesSub[sample];
2283 }
2284 (*m_msgFunc_p)(ZDCMsg::Info, message1.str());
2285
2286 std::ostringstream message3;
2287 message3 << "samplesDeriv2nd ";
2288 for (size_t sample = 0; sample < m_samplesDeriv2nd.size(); sample++) {
2289 message3 << ", [" << sample << "] = " << m_samplesDeriv2nd[sample];
2290 }
2291 (*m_msgFunc_p)(ZDCMsg::Info, message3.str());
2292
2293 (*m_msgFunc_p)(ZDCMsg::Info, ("minimum 2nd deriv sample, value = " + std::to_string(m_minDeriv2ndIndex) + ", " + std::to_string(m_minDeriv2nd)));
2294}

◆ dumpConfiguration()

void ZDCPulseAnalyzer::dumpConfiguration ( ) const

Definition at line 2315 of file ZDCPulseAnalyzer.cxx.

2316{
2317 std::ostringstream ostrStream;
2318 (*m_msgFunc_p)(ZDCMsg::Info, ("\n ZDCPulserAnalyzer:: ======================================================================="));
2319 (*m_msgFunc_p)(ZDCMsg::Info, ("ZDCPulserAnalyzer:: settings for instance: " + m_tag));
2320
2321 ostrStream << "Nsample = " << m_Nsample << " at frequency " << m_freqMHz << " MHz, preSample index = "
2322 << m_preSampleIdx << ", nominal pedestal = " << m_pedestal;
2323
2324 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2325
2326 ostrStream << "LG mode = " << m_LGMode << ", gainFactor HG = " << m_gainFactorHG << ", gainFactor LG = " << m_gainFactorLG << ", noise sigma HG = " << m_noiseSigHG << ", noiseSigLG = " << m_noiseSigLG;
2327 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2328
2330 ostrStream << "Using per-sample noise sigmas for high gain, values = ";
2331 for (auto sig : m_setPerSampleNoiseHG) {ostrStream << sig << ", ";}
2332 ostrStream << "end";
2333 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2334 }
2335
2337 ostrStream << "Using per-sample noise sigmas for low gain, values = ";
2338 for (auto sig : m_setPerSampleNoiseLG) {ostrStream << sig << ", ";}
2339 ostrStream << "end";
2340 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2341 }
2342
2343 ostrStream << "peak sample = " << m_peak2ndDerivMinSample << ", tolerance = " << m_peak2ndDerivMinTolerance
2344 << ", 2ndDerivThresh HG, LG = " << m_peak2ndDerivMinThreshHG << ", " << m_peak2ndDerivMinThreshLG
2345 << ", 2nd deriv step = " << m_2ndDerivStep;
2346 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2347
2348 if (m_useDelayed) {
2349 ostrStream << "using delayed samples with delta T = " << m_delayedDeltaT << ", and default pedestalDiff == "
2351 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2352 }
2353
2354 ostrStream <<"Fit function = " << m_fitFunction << "fixTau1 = " << m_fixTau1 << ", fixTau2 = " << m_fixTau2
2355 << ", nominalTau1 = " << m_nominalTau1 << ", nominalTau2 = " << m_nominalTau2 << "\n"
2356 << ", nominalT0HG = " << m_nominalT0HG << ", nominalT0LG = " << m_nominalT0LG
2357 << ", t0Cuts HG = [" << m_T0CutLowHG << ", " << m_T0CutHighHG << "], t0Cuts LG = ["
2358 << m_T0CutLowLG << ", " << m_T0CutHighLG << "]";
2359 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2360
2361 ostrStream << "HGOverflowADC = " << m_HGOverflowADC << ", HGUnderflowADC = " << m_HGUnderflowADC
2362 << ", LGOverflowADC = "<< m_LGOverflowADC;
2363 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2364
2365 ostrStream << "chisqDivAmpCutHG = " << m_chisqDivAmpCutHG << ", chisqDivAmpCutLG=" << m_chisqDivAmpCutLG
2366 << ", chisqDivAmpOffsetHG = " << m_chisqDivAmpOffsetHG << ", chisqDivAmpOffsetLG = " << m_chisqDivAmpOffsetLG
2367 << ", chisqDivAmpPowerHG = " << m_chisqDivAmpPowerHG << ", chisqDivAmpPowerLG = " << m_chisqDivAmpPowerLG;
2368 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2369
2370 if ( m_enableRepass) {
2371 ostrStream << "Repass enabled with peak2ndDerivMinRepassHG = " << m_peak2ndDerivMinRepassHG << ", peak2ndDerivMinRepassLG = " << m_peak2ndDerivMinRepassLG;
2372 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2373 }
2374
2375 if (!m_doPrePulseCheck) {
2376 (*m_msgFunc_p)(ZDCMsg::Info, "Pre-pulse and negative exponential pulse checking disabled");
2377 }
2378 if (!m_doPostPulseCheck) {
2379 (*m_msgFunc_p)(ZDCMsg::Info, "Post-pulse checking disabled");
2380 }
2381
2382 if (m_enablePreExcl) {
2383 ostrStream << "Pre-exclusion enabled for up to " << m_maxSamplesPreExcl << ", samples with ADC threshold HG = "
2384 << m_preExclHGADCThresh << ", LG = " << m_preExclLGADCThresh;
2385 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2386 }
2387 if (m_enablePostExcl) {
2388 ostrStream << "Post-exclusion enabled for up to " << m_maxSamplesPostExcl << ", samples with ADC threshold HG = "
2390 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2391 }
2392
2394 ostrStream << "High gain Underflow pre- and post-exclusion enabled for up to " << m_underFlowExclSamplesPreHG
2395 << ", and " << m_underFlowExclSamplesPostHG << " samples, respectively";
2396 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2397 }
2399 ostrStream << "Low gain Underflow pre- and post-exclusion enabled for up to " << m_underFlowExclSamplesPreLG
2400 << ", and " << m_underFlowExclSamplesPostLG << " samples, respectively";
2401 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2402 }
2403 if (m_haveSignifCuts) {
2404 ostrStream << "Minimum significance cuts applied: HG min. sig. = " << m_sigMinHG << ", LG min. sig. " << m_sigMinLG;
2405 (*m_msgFunc_p)(ZDCMsg::Info, ostrStream.str()); ostrStream.str(""); ostrStream.clear();
2406 }
2407
2408}

◆ dumpTF1()

void ZDCPulseAnalyzer::dumpTF1 ( const TF1 * func) const

Definition at line 2296 of file ZDCPulseAnalyzer.cxx.

2297{
2298 std::string message = "Dump of TF1: " + std::string(func->GetName());
2299 bool continueDump = (*m_msgFunc_p)(ZDCMsg::Verbose, std::move(message));
2300 if (!continueDump) return;
2301
2302 unsigned int npar = func->GetNpar();
2303 for (unsigned int ipar = 0; ipar < npar; ipar++) {
2304 std::ostringstream msgstr;
2305
2306 double parMin = 0, parMax = 0;
2307 func->GetParLimits(ipar, parMin, parMax);
2308
2309 msgstr << "Parameter " << ipar << ", value = " << func->GetParameter(ipar) << ", error = "
2310 << func->GetParError(ipar) << ", min = " << parMin << ", max = " << parMax;
2311 (*m_msgFunc_p)(ZDCMsg::Verbose, msgstr.str());
2312 }
2313}
@ Verbose
Definition ZDCMsg.h:18

◆ enableDelayed()

void ZDCPulseAnalyzer::enableDelayed ( float deltaT,
float pedestalShift,
bool fixedBaseline = false )

Definition at line 228 of file ZDCPulseAnalyzer.cxx.

229{
230 m_useDelayed = true;
231 m_useFixedBaseline = fixedBaseline;
232
233 m_delayedDeltaT = deltaT;
234 m_delayedPedestalDiff = pedestalShift;
235
236 m_deltaTSample /= 2.;
237
238 std::string delayedHGName = std::string(m_fitHist->GetName()) + "delayed";
239 std::string delayedLGName = std::string(m_fitHistLGRefit->GetName()) + "delayed";
240
241 m_delayedHist = std::make_unique<TH1F>(delayedHGName.c_str(), "", m_Nsample, m_tmin + m_delayedDeltaT, m_tmax + m_delayedDeltaT);
242 m_delayedHist->SetDirectory(0);
243
244 m_delayedHistLGRefit = std::make_unique<TH1F>(delayedLGName.c_str(), "", m_Nsample, m_tmin + m_delayedDeltaT, m_tmax + m_delayedDeltaT);
245 m_delayedHistLGRefit->SetDirectory(0);
246}

◆ enableFADCCorrections()

void ZDCPulseAnalyzer::enableFADCCorrections ( bool correctPerSample,
std::unique_ptr< const TH1 > & correHistHG,
std::unique_ptr< const TH1 > & correHistLG )

Definition at line 647 of file ZDCPulseAnalyzer.cxx.

648{
650 m_FADCCorrPerSample = correctPerSample;
651
652 // check for appropriate limits
653 //
654 auto getXmin=[](const TH1 * pH){
655 return pH->GetXaxis()->GetXmin();
656 };
657 auto getXmax=[](const TH1 * pH){
658 return pH->GetXaxis()->GetXmax();
659 };
660 auto xmin= getXmin(correHistHG.get());
661 auto xmax= getXmax(correHistHG.get());
662 if (std::abs(xmin+0.5) > 1e-3 || std::abs(xmax - 4095.5) > 1e-3) {
663 (*m_msgFunc_p)(ZDCMsg::Error, "ZDCPulseAnalyzer::enableFADCCorrections:: invalid high gain correction histogram range: xmin, xmax = " +
664 std::to_string(xmin ) + ", " + std::to_string(xmax) );
665 }
666 else {
667 m_FADCCorrHG = std::move(correHistHG);
668 }
669 xmin= getXmin(correHistLG.get());
670 xmax= getXmax(correHistLG.get());
671 if (std::abs(xmin+0.5) > 1e-3 ||
672 std::abs(xmax - 4095.5) > 1e-3) {
673 (*m_msgFunc_p)(ZDCMsg::Error, "ZDCPulseAnalyzer::enableFADCCorrections:: invalid low gain correction histogram range: xmin, xmax = " +
674 std::to_string(xmin) + ", " + std::to_string(xmax) );
675 }
676 else {
677 m_FADCCorrLG = std::move(correHistLG);
678 }
679}
std::unique_ptr< const TH1 > m_FADCCorrLG
std::unique_ptr< const TH1 > m_FADCCorrHG
double xmax
Definition listroot.cxx:61
double xmin
Definition listroot.cxx:60
@ Error
Definition ZDCMsg.h:22

◆ enablePostExclusion()

void ZDCPulseAnalyzer::enablePostExclusion ( unsigned int maxSamplesExcl,
unsigned int HGADCThresh,
unsigned int LGADCThresh )
inline

Definition at line 544 of file ZDCPulseAnalyzer.h.

545 {
546 m_enablePostExcl = true;
547 m_maxSamplesPostExcl = maxSamplesExcl;
548 m_postExclHGADCThresh = HGADCThresh;
549 m_postExclLGADCThresh = LGADCThresh;
550 }

◆ enablePostPulseCheck()

void ZDCPulseAnalyzer::enablePostPulseCheck ( unsigned int postPulseSampleDelta,
float postPulseDerivMinSig,
float postPulseAbsDer2ndMinSig,
float minMainDer2ndRatio )

Definition at line 255 of file ZDCPulseAnalyzer.cxx.

256{
257 m_doPostPulseCheck = true;
258 m_postPulseDelta = postPulseSampleDelta;
259 m_postPulseDerivMinSig = postPulseDerivMinSig;
260 m_postPulseAbsDer2ndMinSig = postPulseAbsDer2ndMinSig;
261 m_postPulseMainMinDer2ndRatio = minMainDer2ndRatio;
262}
float m_postPulseMainMinDer2ndRatio

◆ enablePreExclusion()

void ZDCPulseAnalyzer::enablePreExclusion ( unsigned int maxSamplesExcl,
unsigned int HGADCThresh,
unsigned int LGADCThresh )
inline

Definition at line 536 of file ZDCPulseAnalyzer.h.

537 {
538 m_enablePreExcl = true;
539 m_maxSamplesPreExcl = maxSamplesExcl;
540 m_preExclHGADCThresh = HGADCThresh;
541 m_preExclLGADCThresh = LGADCThresh;
542 }

◆ enableRepass()

void ZDCPulseAnalyzer::enableRepass ( float peak2ndDerivMinRepassHG,
float peak2ndDerivMinRepassLG )

Definition at line 248 of file ZDCPulseAnalyzer.cxx.

249{
250 m_enableRepass = true;
251 m_peak2ndDerivMinRepassHG = peak2ndDerivMinRepassHG;
252 m_peak2ndDerivMinRepassLG = peak2ndDerivMinRepassLG;
253}

◆ enableTimeSigCut()

void ZDCPulseAnalyzer::enableTimeSigCut ( bool AND,
float sigCut,
const std::string & TF1String,
const std::vector< double > & parsHG,
const std::vector< double > & parsLG )

Definition at line 618 of file ZDCPulseAnalyzer.cxx.

621{
622 m_timeCutMode = AND ? 2 : 1;
623 m_t0CutSig = sigCut;
624
625 // Make the TF1's that provide the resolution
626 //
627 std::string timeResHGName = "TimeResFuncHG_" + m_tag;
628 std::string timeResLGName = "TimeResFuncLG_" + m_tag;
629
630 TF1* funcHG_p = new TF1(timeResHGName.c_str(), TF1String.c_str(), 0, m_HGOverflowADC);
631 TF1* funcLG_p = new TF1(timeResLGName.c_str(), TF1String.c_str(), 0, m_LGOverflowADC);
632
633 if (parsHG.size() != static_cast<unsigned int>(funcHG_p->GetNpar()) ||
634 parsLG.size() != static_cast<unsigned int>(funcLG_p->GetNpar())) {
635 //
636 // generate an error message
637 }
638
639 funcHG_p->SetParameters(&parsHG[0]);
640 funcLG_p->SetParameters(&parsLG[0]);
641
642 m_timeResFuncHG_p.reset(funcHG_p);
643 m_timeResFuncLG_p.reset(funcLG_p);
644
645}

◆ excludeEarlyLG()

bool ZDCPulseAnalyzer::excludeEarlyLG ( ) const
inline

Definition at line 668 of file ZDCPulseAnalyzer.h.

668{return m_ExcludeEarly;}

◆ excludeLateLG()

bool ZDCPulseAnalyzer::excludeLateLG ( ) const
inline

Definition at line 669 of file ZDCPulseAnalyzer.h.

669{return m_ExcludeLate;}

◆ failed()

bool ZDCPulseAnalyzer::failed ( ) const
inline

Definition at line 654 of file ZDCPulseAnalyzer.h.

654{return m_fail;}

◆ failSigCut()

bool ZDCPulseAnalyzer::failSigCut ( ) const
inline

Definition at line 674 of file ZDCPulseAnalyzer.h.

674{return m_failSigCut;}

◆ FillHistogram()

void ZDCPulseAnalyzer::FillHistogram ( bool refitLG)
inlineprivate

Definition at line 454 of file ZDCPulseAnalyzer.h.

455 {
456 if (!m_useDelayed) {
457 if (!refitLG) {
458 // Set the data and errors in the histogram object
459 //
460 for (size_t isample = 0; isample < m_NSamplesAna; isample++) {
461 m_fitHist->SetBinContent(isample + 1, m_samplesSub[isample]);
462 m_fitHist->SetBinError(isample + 1, m_samplesNoise[isample]);
463 }
464 }
465 else {
466 for (size_t isample = 0; isample < m_NSamplesAna; isample++) {
467 m_fitHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample]);
468 m_fitHistLGRefit->SetBinError(isample + 1, m_samplesNoiseLGRefit[isample]);
469 }
470 }
471 }
472 else {
473 if (!refitLG) {
474 // Set the data and errors in the histogram object
475 //
476 for (size_t isample = 0; isample < m_Nsample; isample++) {
477 m_fitHist->SetBinContent(isample + 1, m_samplesSub[isample * 2]);
478 m_delayedHist->SetBinContent(isample + 1, m_samplesSub[isample * 2 + 1]);
479
480 m_fitHist->SetBinError(isample + 1, m_samplesNoise[isample]);
481 m_delayedHist->SetBinError(isample + 1, m_samplesNoise[isample]);
482 }
483 }
484 else {
485 // Set the data and errors in the histogram object
486 //
487 for (size_t isample = 0; isample < m_Nsample; isample++) {
488 m_fitHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample * 2]);
489 m_delayedHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample * 2 + 1]);
490
491 m_fitHistLGRefit->SetBinError(isample + 1, m_samplesNoiseLGRefit[isample]);
492 m_delayedHistLGRefit->SetBinError(isample + 1, m_samplesNoiseLGRefit[isample]);
493 }
494 }
495 }
496 }
std::vector< float > m_samplesNoiseLGRefit
std::vector< float > m_samplesLGRefit

◆ fitFailed()

bool ZDCPulseAnalyzer::fitFailed ( ) const
inline

Definition at line 664 of file ZDCPulseAnalyzer.h.

664{return m_fitFailed;}

◆ fitMinimumAmplitude()

bool ZDCPulseAnalyzer::fitMinimumAmplitude ( ) const
inline

Definition at line 671 of file ZDCPulseAnalyzer.h.

671{return m_fitMinAmp;}

◆ getADCPeakHG()

float ZDCPulseAnalyzer::getADCPeakHG ( ) const
inline

Definition at line 770 of file ZDCPulseAnalyzer.h.

770{return m_ADCPeakHG;}

◆ getADCPeakLG()

float ZDCPulseAnalyzer::getADCPeakLG ( ) const
inline

Definition at line 771 of file ZDCPulseAnalyzer.h.

771{return m_ADCPeakLG;}

◆ GetAmpError()

float ZDCPulseAnalyzer::GetAmpError ( ) const
inline

Definition at line 701 of file ZDCPulseAnalyzer.h.

701{return m_ampError;}

◆ GetAmplitude()

float ZDCPulseAnalyzer::GetAmplitude ( ) const
inline

Definition at line 700 of file ZDCPulseAnalyzer.h.

700{return m_amplitude;}

◆ getAmplitudeCorrection()

double ZDCPulseAnalyzer::getAmplitudeCorrection ( bool highGain)
private

Definition at line 718 of file ZDCPulseAnalyzer.cxx.

719{
720 double amplCorrFactor = 1;
721
722 // If we have FADC correction and we aren't applying it per-sample, do so here
723 //
725 double fadcCorr = highGain ? m_FADCCorrHG->Interpolate(m_fitAmplitude) : m_FADCCorrLG->Interpolate(m_fitAmplitude);
726 amplCorrFactor *= fadcCorr;
727 }
728
729 double amplCorr = m_fitAmplitude * amplCorrFactor;
730
731 // If we have a non-linear correction, apply it here
732 // We apply it as an inverse correction - i.e. we divide by a correction
733 // term tha is a sum of coefficients times the ADC minus a reference
734 // to a power. The lowest power is 1, the highest is deteremined by
735 // the number of provided coefficients
736
737 if (m_haveNonlinCorr) {
738 float invNLCorr = 1.0;
739 float nlPolyArg = (amplCorr - m_nonLinCorrRefADC) / m_nonLinCorrRefScale;
740
741 if (highGain) {
742 for (size_t power = 1; power <= m_nonLinCorrParamsHG.size(); power++) {
743 invNLCorr += m_nonLinCorrParamsHG[power - 1]*pow(nlPolyArg, power);
744 }
745 }
746 else {
747 for (size_t power = 1; power <= m_nonLinCorrParamsLG.size(); power++) {
748 invNLCorr += m_nonLinCorrParamsLG[power - 1]*pow(nlPolyArg, power);
749 }
750 }
751
752 amplCorrFactor /= invNLCorr;
753 }
754
755 return amplCorrFactor;
756}
constexpr int pow(int x)
Definition conifer.h:27

◆ GetAmpNoNonLin()

float ZDCPulseAnalyzer::GetAmpNoNonLin ( ) const
inline

Definition at line 699 of file ZDCPulseAnalyzer.h.

699{return m_ampNoNonLin;}

◆ GetBkgdMaxFraction()

float ZDCPulseAnalyzer::GetBkgdMaxFraction ( ) const
inline

Definition at line 787 of file ZDCPulseAnalyzer.h.

787{return m_bkgdMaxFraction;}

◆ GetChisq()

float ZDCPulseAnalyzer::GetChisq ( ) const
inline

Definition at line 688 of file ZDCPulseAnalyzer.h.

688{return m_fitChisq;}

◆ GetChisqRatio()

float ZDCPulseAnalyzer::GetChisqRatio ( ) const
inline

Definition at line 689 of file ZDCPulseAnalyzer.h.

689{return m_chisqRatio;}

◆ GetCombinedGraph()

std::shared_ptr< TGraphErrors > ZDCPulseAnalyzer::GetCombinedGraph ( bool forceLG = false)

Definition at line 2442 of file ZDCPulseAnalyzer.cxx.

2443{
2444 //
2445 // We defer filling the histogram if we don't have a pulse until the histogram is requested
2446 //
2447 GetHistogramPtr(LGRefit);
2448
2449 TH1* hist_p = nullptr, *delayedHist_p = nullptr;
2450 if (LGRefit) {
2451 hist_p = m_fitHistLGRefit.get();
2452 delayedHist_p = m_delayedHistLGRefit.get();
2453 }
2454 else {
2455 hist_p = m_fitHist.get();
2456 delayedHist_p = m_delayedHist.get();
2457 }
2458
2459 std::shared_ptr<TGraphErrors> theGraph = std::make_shared<TGraphErrors>(TGraphErrors(2 * m_Nsample));
2460 size_t npts = 0;
2461
2462 for (int ipt = 0; ipt < hist_p->GetNbinsX(); ipt++) {
2463 theGraph->SetPoint(npts, hist_p->GetBinCenter(ipt + 1), hist_p->GetBinContent(ipt + 1));
2464 theGraph->SetPointError(npts++, 0, hist_p->GetBinError(ipt + 1));
2465 }
2466
2467 for (int iDelayPt = 0; iDelayPt < delayedHist_p->GetNbinsX(); iDelayPt++) {
2468 theGraph->SetPoint(npts, delayedHist_p->GetBinCenter(iDelayPt + 1), delayedHist_p->GetBinContent(iDelayPt + 1) - m_delayedBaselineShift);
2469 theGraph->SetPointError(npts++, 0, delayedHist_p->GetBinError(iDelayPt + 1));
2470 }
2471 if (m_havePulse) {
2472 TF1* func_p = static_cast<TF1*>(hist_p->GetListOfFunctions()->Last());
2473 if (func_p) {
2474 theGraph->GetListOfFunctions()->Add(new TF1(*func_p));
2475 hist_p->GetListOfFunctions()->SetOwner (false);
2476 }
2477 }
2478 theGraph->SetName(( std::string(hist_p->GetName()) + "combinaed").c_str());
2479
2480 theGraph->SetMarkerStyle(20);
2481 theGraph->SetMarkerColor(1);
2482
2483 return theGraph;
2484}
const TH1 * GetHistogramPtr(bool refitLG=false)

◆ GetdelayBS()

float ZDCPulseAnalyzer::GetdelayBS ( ) const
inline

Definition at line 779 of file ZDCPulseAnalyzer.h.

◆ GetDelayedBaselineCorr()

float ZDCPulseAnalyzer::GetDelayedBaselineCorr ( ) const
inline

Definition at line 790 of file ZDCPulseAnalyzer.h.

790{return m_baselineCorr;}

◆ GetDelayedBaselineShiftFit()

float ZDCPulseAnalyzer::GetDelayedBaselineShiftFit ( ) const
inline

Definition at line 789 of file ZDCPulseAnalyzer.h.

◆ GetFitAmplitude()

float ZDCPulseAnalyzer::GetFitAmplitude ( ) const
inline

Definition at line 683 of file ZDCPulseAnalyzer.h.

683{return m_fitAmplitude;}

◆ GetFitExpAmp()

float ZDCPulseAnalyzer::GetFitExpAmp ( ) const
inline

Definition at line 696 of file ZDCPulseAnalyzer.h.

696{return m_fitExpAmp;}

◆ GetFitPostAmp()

float ZDCPulseAnalyzer::GetFitPostAmp ( ) const
inline

Definition at line 695 of file ZDCPulseAnalyzer.h.

695{return m_postAmplitude;}

◆ GetFitPostT0()

float ZDCPulseAnalyzer::GetFitPostT0 ( ) const
inline

Definition at line 694 of file ZDCPulseAnalyzer.h.

694{return m_fitPostT0;}

◆ GetFitPreAmp()

float ZDCPulseAnalyzer::GetFitPreAmp ( ) const
inline

Definition at line 693 of file ZDCPulseAnalyzer.h.

693{return m_preAmplitude;}

◆ GetFitPreT0()

float ZDCPulseAnalyzer::GetFitPreT0 ( ) const
inline

Definition at line 692 of file ZDCPulseAnalyzer.h.

692{return m_fitPreT0;}

◆ GetFitPulls()

std::vector< float > ZDCPulseAnalyzer::GetFitPulls ( bool forceLG = false) const

Definition at line 681 of file ZDCPulseAnalyzer.cxx.

682{
683 //
684 // If there was no pulse for this event, return an empty vector (see reset() method)
685 //
686 if (!m_havePulse) {
687 return m_fitPulls;
688 }
689
690 //
691 // The combined (delayed+undelayed) pulse fitting fills out m_fitPulls directly
692 //
693 if (m_useDelayed) {
694 return m_fitPulls;
695 }
696 else {
697 //
698 // When not using combined fitting, We don't have the pre-calculated pulls. Calculate them on the fly.
699 //
700 std::vector<float> pulls(m_Nsample, -100);
701
702 const TH1* dataHist_p = refitLG ? m_fitHistLGRefit.get() : m_fitHist.get();
703 const TF1* fit_p = static_cast<const TF1*>(dataHist_p->GetListOfFunctions()->Last());
704
705 for (size_t ibin = 0; ibin < m_Nsample ; ibin++) {
706 float t = dataHist_p->GetBinCenter(ibin + 1);
707 float fitVal = fit_p->Eval(t);
708 float histVal = dataHist_p->GetBinContent(ibin + 1);
709 float histErr = dataHist_p->GetBinError(ibin + 1);
710 float pull = (histVal - fitVal)/histErr;
711 pulls[ibin] = pull;
712 }
713
714 return pulls;
715 }
716}

◆ GetFitT0()

float ZDCPulseAnalyzer::GetFitT0 ( ) const
inline

Definition at line 684 of file ZDCPulseAnalyzer.h.

684{return m_fitTime;}

◆ GetFitTau1()

float ZDCPulseAnalyzer::GetFitTau1 ( ) const
inline

Definition at line 690 of file ZDCPulseAnalyzer.h.

690{return m_fitTau1;}

◆ GetFitTau2()

float ZDCPulseAnalyzer::GetFitTau2 ( ) const
inline

Definition at line 691 of file ZDCPulseAnalyzer.h.

691{return m_fitTau2;}

◆ GetFitTMax()

float ZDCPulseAnalyzer::GetFitTMax ( ) const
inline

Definition at line 776 of file ZDCPulseAnalyzer.h.

776{return m_fitTMax;}

◆ GetFitTMin()

float ZDCPulseAnalyzer::GetFitTMin ( ) const
inline

Definition at line 777 of file ZDCPulseAnalyzer.h.

777{return m_fitTMin;}

◆ GetGraph()

std::shared_ptr< TGraphErrors > ZDCPulseAnalyzer::GetGraph ( bool forceLG = false)

Definition at line 2487 of file ZDCPulseAnalyzer.cxx.

2488{
2489 //
2490 // We defer filling the histogram if we don't have a pulse until the histogram is requested
2491 //
2492 const TH1* hist_p = GetHistogramPtr(forceLG);
2493
2494 std::shared_ptr<TGraphErrors> theGraph = std::make_shared<TGraphErrors>(TGraphErrors(m_Nsample));
2495 size_t npts = 0;
2496
2497 for (int ipt = 0; ipt < hist_p->GetNbinsX(); ipt++) {
2498 theGraph->SetPoint(npts, hist_p->GetBinCenter(ipt + 1), hist_p->GetBinContent(ipt + 1));
2499 theGraph->SetPointError(npts++, 0, hist_p->GetBinError(ipt + 1));
2500 }
2501
2502 TF1* func_p = static_cast<TF1*>(hist_p->GetListOfFunctions()->Last());
2503 theGraph->GetListOfFunctions()->Add(func_p);
2504 theGraph->SetName(( std::string(hist_p->GetName()) + "not_combinaed").c_str());
2505
2506 theGraph->SetMarkerStyle(20);
2507 theGraph->SetMarkerColor(1);
2508
2509 return theGraph;
2510}

◆ GetHistogramPtr()

const TH1 * ZDCPulseAnalyzer::GetHistogramPtr ( bool refitLG = false)
inline

Definition at line 792 of file ZDCPulseAnalyzer.h.

793 {
794 //
795 // We defer filling the histogram if we don't have a pulse until the histogram is requested
796 //
797 if (!m_havePulse) {
798 FillHistogram(refitLG);
799 }
800
801 return refitLG ? m_fitHistLGRefit.get() : m_fitHist.get();
802 }

◆ getLGMode()

unsigned int ZDCPulseAnalyzer::getLGMode ( ) const
inline

Definition at line 566 of file ZDCPulseAnalyzer.h.

566{return m_LGMode;}

◆ getMaxADCHG()

float ZDCPulseAnalyzer::getMaxADCHG ( ) const
inline

Definition at line 749 of file ZDCPulseAnalyzer.h.

749{return m_maxADCHG;}

◆ getMaxADCLG()

float ZDCPulseAnalyzer::getMaxADCLG ( ) const
inline

Definition at line 750 of file ZDCPulseAnalyzer.h.

750{return m_maxADCLG;}

◆ getMaxADCSampleHG()

int ZDCPulseAnalyzer::getMaxADCSampleHG ( ) const
inline

Definition at line 764 of file ZDCPulseAnalyzer.h.

◆ getMaxADCSampleLG()

int ZDCPulseAnalyzer::getMaxADCSampleLG ( ) const
inline

Definition at line 767 of file ZDCPulseAnalyzer.h.

◆ getMaxADCSub()

float ZDCPulseAnalyzer::getMaxADCSub ( ) const
inline

Definition at line 754 of file ZDCPulseAnalyzer.h.

754 {
755 float maxADCNosub = m_useLowGain ? m_maxADCLG : m_maxADCHG;
756 return maxADCNosub - m_pedestal - m_preSample;
757 }

◆ GetMaxDelta()

float ZDCPulseAnalyzer::GetMaxDelta ( ) const
inline

Definition at line 773 of file ZDCPulseAnalyzer.h.

773{return m_maxDelta;}

◆ getMinADCHG()

float ZDCPulseAnalyzer::getMinADCHG ( ) const
inline

Definition at line 751 of file ZDCPulseAnalyzer.h.

751{return m_minADCHG;}

◆ getMinADCLG()

float ZDCPulseAnalyzer::getMinADCLG ( ) const
inline

Definition at line 752 of file ZDCPulseAnalyzer.h.

752{return m_minADCLG;}

◆ getMinADCSampleHG()

int ZDCPulseAnalyzer::getMinADCSampleHG ( ) const
inline

Definition at line 765 of file ZDCPulseAnalyzer.h.

◆ getMinADCSampleLG()

int ZDCPulseAnalyzer::getMinADCSampleLG ( ) const
inline

Definition at line 768 of file ZDCPulseAnalyzer.h.

◆ getMinADCSub()

float ZDCPulseAnalyzer::getMinADCSub ( ) const
inline

Definition at line 759 of file ZDCPulseAnalyzer.h.

759 {
760 float minADCNosub = m_useLowGain ? m_minADCLG : m_minADCHG;
761 return minADCNosub - m_pedestal - m_preSample;
762 }

◆ GetMinDelta()

float ZDCPulseAnalyzer::GetMinDelta ( ) const
inline

Definition at line 774 of file ZDCPulseAnalyzer.h.

774{return m_minDelta;}

◆ GetMinDeriv2nd()

float ZDCPulseAnalyzer::GetMinDeriv2nd ( ) const
inline

Definition at line 781 of file ZDCPulseAnalyzer.h.

781{return m_minDeriv2nd;}

◆ GetMinDeriv2ndIndex()

float ZDCPulseAnalyzer::GetMinDeriv2ndIndex ( ) const
inline

Definition at line 782 of file ZDCPulseAnalyzer.h.

782{return m_minDeriv2ndIndex;}

◆ GetPreExpAmp()

float ZDCPulseAnalyzer::GetPreExpAmp ( ) const
inline

Definition at line 702 of file ZDCPulseAnalyzer.h.

702{return m_expAmplitude;}

◆ getPresample()

float ZDCPulseAnalyzer::getPresample ( ) const
inline

Definition at line 748 of file ZDCPulseAnalyzer.h.

748{return m_preSample;}

◆ GetPreSampleAmp()

float ZDCPulseAnalyzer::GetPreSampleAmp ( ) const
inline

Definition at line 786 of file ZDCPulseAnalyzer.h.

786{return m_preSampleAmp;}

◆ getRefitLGAmp()

float ZDCPulseAnalyzer::getRefitLGAmp ( ) const
inline

Definition at line 706 of file ZDCPulseAnalyzer.h.

707 {
708 if (m_evtLGRefit) return m_refitLGAmpl;
709 else return 0;
710 }

◆ getRefitLGAmpCorr()

float ZDCPulseAnalyzer::getRefitLGAmpCorr ( ) const
inline

Definition at line 718 of file ZDCPulseAnalyzer.h.

719 {
721 else return 0;
722 }

◆ getRefitLGChisq()

float ZDCPulseAnalyzer::getRefitLGChisq ( ) const
inline

Definition at line 724 of file ZDCPulseAnalyzer.h.

725 {
726 if (m_evtLGRefit) return m_refitLGChisq;
727 else return 0;
728 }

◆ getRefitLGChisqRatio()

float ZDCPulseAnalyzer::getRefitLGChisqRatio ( ) const
inline

Definition at line 730 of file ZDCPulseAnalyzer.h.

731 {
733 else return 0;
734 }

◆ getRefitLGFitAmp()

float ZDCPulseAnalyzer::getRefitLGFitAmp ( ) const
inline

Definition at line 712 of file ZDCPulseAnalyzer.h.

713 {
714 if (m_evtLGRefit) return m_refitLGFitAmpl;
715 else return 0;
716 }

◆ getRefitLGTime()

float ZDCPulseAnalyzer::getRefitLGTime ( ) const
inline

Definition at line 736 of file ZDCPulseAnalyzer.h.

737 {
738 if (m_evtLGRefit) return m_refitLGTime;
739 else return 0;
740 }

◆ getRefitLGTimeSub()

float ZDCPulseAnalyzer::getRefitLGTimeSub ( ) const
inline

Definition at line 742 of file ZDCPulseAnalyzer.h.

743 {
744 if (m_evtLGRefit) return m_refitLGTimeSub;
745 else return 0;
746 }

◆ GetSamplesDeriv2nd()

const std::vector< float > & ZDCPulseAnalyzer::GetSamplesDeriv2nd ( ) const
inline

Definition at line 814 of file ZDCPulseAnalyzer.h.

814{return m_samplesDeriv2nd;}

◆ GetSamplesSub()

const std::vector< float > & ZDCPulseAnalyzer::GetSamplesSub ( ) const
inline

Definition at line 813 of file ZDCPulseAnalyzer.h.

813{return m_samplesSub;}

◆ GetShapeParameters()

const std::vector< float > & ZDCPulseAnalyzer::GetShapeParameters ( ) const
inline

Definition at line 704 of file ZDCPulseAnalyzer.h.

704{return m_shapeParameters;}

◆ GetStatusMask()

unsigned int ZDCPulseAnalyzer::GetStatusMask ( ) const

Definition at line 2410 of file ZDCPulseAnalyzer.cxx.

2411{
2412 unsigned int statusMask = 0;
2413
2414 if (havePulse()) statusMask |= 1 << PulseBit;
2415 if (useLowGain()) statusMask |= 1 << LowGainBit;
2416 if (failed()) statusMask |= 1 << FailBit;
2417 if (HGOverflow()) statusMask |= 1 << HGOverflowBit;
2418
2419 if (HGUnderflow()) statusMask |= 1 << HGUnderflowBit;
2420 if (PSHGOverUnderflow()) statusMask |= 1 << PSHGOverUnderflowBit;
2421 if (LGOverflow()) statusMask |= 1 << LGOverflowBit;
2422 if (LGUnderflow()) statusMask |= 1 << LGUnderflowBit;
2423
2424 if (prePulse()) statusMask |= 1 << PrePulseBit;
2425 if (postPulse()) statusMask |= 1 << PostPulseBit;
2426 if (fitFailed()) statusMask |= 1 << FitFailedBit;
2427 if (badChisq()) statusMask |= 1 << BadChisqBit;
2428
2429 if (badT0()) statusMask |= 1 << BadT0Bit;
2430 if (excludeEarlyLG()) statusMask |= 1 << ExcludeEarlyLGBit;
2431 if (excludeLateLG()) statusMask |= 1 << ExcludeLateLGBit;
2432 if (preExpTail()) statusMask |= 1 << preExpTailBit;
2433 if (fitMinimumAmplitude()) statusMask |= 1 << FitMinAmpBit;
2434 if (repassPulse()) statusMask |= 1 << RepassPulseBit;
2435 if (armSumInclude()) statusMask |= 1 << ArmSumIncludeBit;
2436 if (failSigCut()) statusMask |= 1 << FailSigCutBit;
2437 if (underflowExclusion()) statusMask |= 1<<UnderFlowExclusionBit;
2438
2439 return statusMask;
2440}
bool HGOverflow() const
bool underflowExclusion() const
bool excludeEarlyLG() const
bool useLowGain() const
bool HGUnderflow() const
bool armSumInclude() const
bool PSHGOverUnderflow() const
bool postPulse() const
bool repassPulse() const
bool excludeLateLG() const

◆ GetT0Corr()

float ZDCPulseAnalyzer::GetT0Corr ( ) const
inline

Definition at line 686 of file ZDCPulseAnalyzer.h.

686{return m_fitTimeCorr;}

◆ GetT0Sub()

float ZDCPulseAnalyzer::GetT0Sub ( ) const
inline

Definition at line 685 of file ZDCPulseAnalyzer.h.

685{return m_fitTimeSub;}

◆ getTimeSig()

float ZDCPulseAnalyzer::getTimeSig ( ) const
inline

Definition at line 687 of file ZDCPulseAnalyzer.h.

687{return m_timeSig;}

◆ HaveData()

bool ZDCPulseAnalyzer::HaveData ( ) const
inline

Definition at line 647 of file ZDCPulseAnalyzer.h.

647{return m_haveData;}

◆ havePulse()

bool ZDCPulseAnalyzer::havePulse ( ) const
inline

Definition at line 652 of file ZDCPulseAnalyzer.h.

652{return m_havePulse;}

◆ HGOverflow()

bool ZDCPulseAnalyzer::HGOverflow ( ) const
inline

Definition at line 655 of file ZDCPulseAnalyzer.h.

655{return m_HGOverflow;}

◆ HGUnderflow()

bool ZDCPulseAnalyzer::HGUnderflow ( ) const
inline

Definition at line 657 of file ZDCPulseAnalyzer.h.

657{return m_HGUnderflow;}

◆ initialize()

void ZDCPulseAnalyzer::initialize ( )
private

Definition at line 348 of file ZDCPulseAnalyzer.cxx.

349{
351
358
359 m_initialized = true;
360}
std::vector< float > m_ADCSSampNoiseLG
std::vector< float > m_ADCSSampNoiseHG

◆ LGOverflow()

bool ZDCPulseAnalyzer::LGOverflow ( ) const
inline

Definition at line 659 of file ZDCPulseAnalyzer.h.

659{return m_LGOverflow;}

◆ LGUnderflow()

bool ZDCPulseAnalyzer::LGUnderflow ( ) const
inline

Definition at line 660 of file ZDCPulseAnalyzer.h.

660{return m_LGUnderflow;}

◆ LoadAndAnalyzeData() [1/2]

bool ZDCPulseAnalyzer::LoadAndAnalyzeData ( const std::vector< float > & ADCSamplesHG,
const std::vector< float > & ADCSamplesLG )

Definition at line 863 of file ZDCPulseAnalyzer.cxx.

864{
865 if (m_useDelayed) {
866 (*m_msgFunc_p)(ZDCMsg::Fatal, "ZDCPulseAnalyzer::LoadAndAnalyzeData:: Wrong LoadAndAnalyzeData called -- expecting both delayed and undelayed samples");
867 }
868
871
872 // Clear any transient data
873 //
874 reset(false);
875
876 // Make sure we have the right number of samples. Should never fail. necessry?
877 //
878 if (ADCSamplesHG.size() != m_Nsample || ADCSamplesLG.size() != m_Nsample) {
879 m_fail = true;
880 return false;
881 }
882
883 m_ADCSamplesHG = ADCSamplesHG;
884 m_ADCSamplesLG = ADCSamplesLG;
885
886 return DoAnalysis(false);
887}
bool DoAnalysis(bool repass)
@ Fatal
Definition ZDCMsg.h:23

◆ LoadAndAnalyzeData() [2/2]

bool ZDCPulseAnalyzer::LoadAndAnalyzeData ( const std::vector< float > & ADCSamplesHG,
const std::vector< float > & ADCSamplesLG,
const std::vector< float > & ADCSamplesHGDelayed,
const std::vector< float > & ADCSamplesLGDelayed )

Definition at line 889 of file ZDCPulseAnalyzer.cxx.

891{
892 if (!m_useDelayed) {
893 (*m_msgFunc_p)(ZDCMsg::Fatal, "ZDCPulseAnalyzer::LoadAndAnalyzeData:: Wrong LoadAndAnalyzeData called -- expecting only undelayed samples");
894 }
895
898
899 // Clear any transient data
900 //
901 reset();
902
903 // Make sure we have the right number of samples. Should never fail. necessry?
904 //
905 if (ADCSamplesHG.size() != m_Nsample || ADCSamplesLG.size() != m_Nsample ||
906 ADCSamplesHGDelayed.size() != m_Nsample || ADCSamplesLGDelayed.size() != m_Nsample) {
907 m_fail = true;
908 return false;
909 }
910
911 // +++ BAC Mar 22, 2026
912 // Trying to rationalize the initialization/handling of transient data. These line should not be necessary. Thus commented
913 // ---
914 //
915 // m_ADCSamplesHG.reserve(m_Nsample*2);
916 // m_ADCSamplesLG.reserve(m_Nsample*2);
917
918 // Now do pedestal subtraction and check for overflows
919 //
920 for (size_t isample = 0; isample < m_Nsample; isample++) {
921 float ADCHG = ADCSamplesHG[isample];
922 float ADCLG = ADCSamplesLG[isample];
923
924 float ADCHGDelay = ADCSamplesHGDelayed[isample] - m_delayedPedestalDiff;
925 float ADCLGDelay = ADCSamplesLGDelayed[isample] - m_delayedPedestalDiff;
926
927 if (m_delayedDeltaT > 0) {
928 m_ADCSamplesHG.push_back(ADCHG);
929 m_ADCSamplesHG.push_back(ADCHGDelay);
930
931 m_ADCSamplesLG.push_back(ADCLG);
932 m_ADCSamplesLG.push_back(ADCLGDelay);
933 }
934 else {
935 m_ADCSamplesHG.push_back(ADCHGDelay);
936 m_ADCSamplesHG.push_back(ADCHG);
937
938 m_ADCSamplesLG.push_back(ADCLGDelay);
939 m_ADCSamplesLG.push_back(ADCLG);
940 }
941 }
942
943 return DoAnalysis(false);
944}

◆ MakeCombinedFitter()

std::unique_ptr< TFitter > ZDCPulseAnalyzer::MakeCombinedFitter ( TF1 * func)
staticprivate

Definition at line 2213 of file ZDCPulseAnalyzer.cxx.

2214{
2215 TVirtualFitter::SetDefaultFitter("Minuit");
2216
2217 size_t nFitParams = func->GetNpar() + 1;
2218 std::unique_ptr<TFitter> fitter = std::make_unique<TFitter>(nFitParams);
2219
2220 fitter->GetMinuit()->fISW[4] = -1;
2221 fitter->SetParameter(0, "delayBaselineAdjust", 0, 0.01, -100, 100);
2222
2223 for (size_t ipar = 0; ipar < nFitParams - 1; ipar++) {
2224 double parLimitLow, parLimitHigh;
2225
2226 func->GetParLimits(ipar, parLimitLow, parLimitHigh);
2227 if (std::abs(parLimitHigh - parLimitLow) < (1e-6)*std::abs(parLimitLow)) {
2228 double value = func->GetParameter(ipar);
2229 double lowLim = std::min(value * 0.99, value * 1.01);
2230 double highLim = std::max(value * 0.99, value * 1.01);
2231
2232 fitter->SetParameter(ipar + 1, func->GetParName(ipar), func->GetParameter(ipar), 0.01, lowLim, highLim);
2233 fitter->FixParameter(ipar + 1);
2234 }
2235 else {
2236 double value = func->GetParameter(ipar);
2237 if (value >= parLimitHigh) value = parLimitHigh * 0.99;
2238 else if (value <= parLimitLow) value = parLimitLow * 1.01;
2239
2240 double step = std::min((parLimitHigh - parLimitLow)/100., (value - parLimitLow)/100.);
2241
2242 fitter->SetParameter(ipar + 1, func->GetParName(ipar), value, step, parLimitLow, parLimitHigh);
2243 }
2244 }
2245
2247
2248 return fitter;
2249}
static void CombinedPulsesFCN(int &numParam, double *, double &f, double *par, int flag)
const ShapeFitter * fitter

◆ obtainDelayedBaselineCorr()

float ZDCPulseAnalyzer::obtainDelayedBaselineCorr ( const std::vector< float > & samples)
staticprivate

Definition at line 2590 of file ZDCPulseAnalyzer.cxx.

2591{
2592 const unsigned int nsamples = samples.size();
2593
2594 std::vector<float> derivVec = calculateDerivative(samples, 2);
2595 std::vector<float> deriv2ndVec = calculate2ndDerivative(samples, 2);
2596
2597 // Now step through and check even and odd samples values for 2nd derivative and derivative
2598 // we start with index 2 since the 2nd derivative calculation has 2 initial zeros with nstep = 2
2599 //
2600 float minScore = 1.0e9;
2601 unsigned int minIndex = 0;
2602
2603 for (unsigned int idx = 2; idx < nsamples - 1; idx++) {
2604 float deriv = derivVec[idx];
2605 float prevDeriv = derivVec[idx - 1];
2606
2607 float derivDiff = deriv - prevDeriv;
2608
2609 float deriv2nd = deriv2ndVec[idx];
2610 if (idx > nsamples - 2) deriv2nd = deriv2ndVec[idx - 1];
2611
2612 // Calculate a score based on the actual derivatives (squared) and 2nd derivatives (squared)
2613 // and the slope differences (squared). The relative weights are not adjustable for now
2614 //
2615 float score = (deriv*deriv + 2*derivDiff*derivDiff +
2616 0.5*deriv2nd*deriv2nd);
2617
2618 if (score < minScore) {
2619 minScore = score;
2620 minIndex = idx;
2621 }
2622 }
2623
2624 // We use four samples, two each of "even" and "odd".
2625 // Because of the way the above analysis is done, we can always
2626 // Go back one even and one odd sample and forward one odd sample.
2627 //
2628 //if minIndex is < 2 or >samples.size() the result is undefined; prevent this:
2629 if (minIndex<2 or (minIndex+1) >=nsamples){
2630 throw std::out_of_range("minIndex out of range in ZDCPulseAnalyzer::obtainDelayedBaselineCorr");
2631 }
2632 float sample0 = samples[minIndex - 2];
2633 float sample1 = samples[minIndex - 1];
2634 float sample2 = samples[minIndex];
2635 float sample3 = samples[minIndex + 1];
2636
2637 // Possibility -- implement logarithmic interpolation for large 2nd derivative?
2638 //
2639 float baselineCorr = (0.5 * (sample1 - sample0 + sample3 - sample2) -
2640 0.25 * (sample3 - sample1 + sample2 - sample0));
2641
2642 if (minIndex % 2 != 0) baselineCorr =-baselineCorr;
2643
2644 return baselineCorr;
2645}
static std::vector< float > calculateDerivative(const std::vector< float > &inputData, unsigned int step)

◆ postPulse()

bool ZDCPulseAnalyzer::postPulse ( ) const
inline

Definition at line 663 of file ZDCPulseAnalyzer.h.

663{return m_postPulse;}

◆ preExpTail()

bool ZDCPulseAnalyzer::preExpTail ( ) const
inline

Definition at line 670 of file ZDCPulseAnalyzer.h.

670{return m_preExpTail;}

◆ prepareLGRefit()

void ZDCPulseAnalyzer::prepareLGRefit ( const std::vector< float > & samplesLG,
const std::vector< float > & samplesNoise,
const std::vector< bool > & useSamples )
private

Definition at line 1689 of file ZDCPulseAnalyzer.cxx.

1691{
1692 m_samplesLGRefit.clear();
1693 m_samplesNoiseLGRefit.clear();
1694
1695 float presampleLG = m_ADCSamplesLGSub[m_usedPresampIdx];
1696
1697 // Do the presample subtraction
1698 //
1699 for (unsigned int idx = 0; idx < samplesLG.size(); idx++) {
1700 m_samplesLGRefit.push_back(samplesLG[idx] - presampleLG);
1701
1702 if (useSamples[idx]) {
1703 m_samplesNoiseLGRefit.push_back(samplesNoise[idx]);
1704 }
1705 else {
1706 m_samplesNoiseLGRefit.push_back(0);
1707 }
1708 }
1709}

◆ prePulse()

bool ZDCPulseAnalyzer::prePulse ( ) const
inline

Definition at line 662 of file ZDCPulseAnalyzer.h.

662{return m_prePulse;}

◆ PSHGOverUnderflow()

bool ZDCPulseAnalyzer::PSHGOverUnderflow ( ) const
inline

Definition at line 658 of file ZDCPulseAnalyzer.h.

◆ quietFits()

bool ZDCPulseAnalyzer::quietFits ( ) const
inline

Definition at line 524 of file ZDCPulseAnalyzer.h.

524{return m_quietFits;}

◆ ReanalyzeData()

bool ZDCPulseAnalyzer::ReanalyzeData ( )

Definition at line 946 of file ZDCPulseAnalyzer.cxx.

947{
948 reset(true);
949
950 bool result = DoAnalysis(true);
951 if (result && havePulse()) {
952 m_repassPulse = true;
953 }
954
955 return result;
956}

◆ repassPulse()

bool ZDCPulseAnalyzer::repassPulse ( ) const
inline

Definition at line 672 of file ZDCPulseAnalyzer.h.

672{return m_repassPulse;}

◆ reset()

void ZDCPulseAnalyzer::reset ( bool reanalyze = false)
private

Definition at line 362 of file ZDCPulseAnalyzer.cxx.

363{
364 if (!repass) {
365 m_haveData = false;
366
367 m_useLowGain = false;
368 m_fail = false;
369 m_HGOverflow = false;
370
371 m_HGUnderflow = false;
372 m_PSHGOverUnderflow = false;
373 m_LGOverflow = false;
374 m_LGUnderflow = false;
375
376 m_ExcludeEarly = false;
377 m_ExcludeLate = false;
378
379 m_adjTimeRangeEvent = false;
380 m_backToHG_pre = false;
381 m_fixPrePulse = false;
382 m_underflowExclusion = false;
383
384 m_minADCLG = -1;
385 m_maxADCLG = -1;
386 m_minADCHG = -1;
387 m_maxADCHG = -1;
388
389 m_minADCSampleHG = -1;
390 m_maxADCSampleHG = -1;
391 m_minADCSampleLG = -1;
392 m_maxADCSampleLG = -1;
393
394 m_ADCPeakHG = -1;
395 m_ADCPeakLG = -1;
396
399
400 m_useSampleHG.assign(m_NSamplesAna, true);
401 m_useSampleLG.assign(m_NSamplesAna, true);
402
405 }
406 else {
408 }
409
412 }
413 else {
415 }
416
417 m_minSampleEvt = 0;
419
421
424
427
428 m_fitPulls.assign(m_NSamplesAna, 0);
429 }
430
431
434
435 if (m_initializedFits) {
439 }
440
441 // -----------------------
442 // Statuses
443 //
444 m_havePulse = false;
445
446 m_prePulse = false;
447 m_postPulse = false;
448 m_fitFailed = false;
449 m_badChisq = false;
450
451 m_badT0 = false;
452 m_preExpTail = false;
453 m_repassPulse = false;
454
455 m_fitMinAmp = false;
456 m_evtLGRefit = false;
457 m_failSigCut = false;
458
459 // -----------------------
460
462
463 m_fitAmplitude = 0;
464 m_ampNoNonLin = 0;
465 m_fitTime = -100;
466 m_fitTimeSub = -100;
467 m_fitTimeCorr = -100;
468 m_fitTCorr2nd = -100;
469
470 m_fitPreT0 = -100;
471 m_fitPreAmp = -100;
472 m_fitPostT0 = -100;
473 m_fitPostAmp = -100;
474 m_fitExpAmp = -100;
475
476 m_minDeriv2ndSig = -10;
477 m_preExpSig = -10;
478 m_prePulseSig = -10;
479
480 m_fitChisq = 0;
481 m_chisqRatio = 0;
482
483 m_amplitude = 0;
484 m_ampError = 0;
485 m_preSampleAmp = 0;
486 m_preAmplitude = 0;
487 m_postAmplitude = 0;
488 m_expAmplitude = 0;
490
491 m_refitLGAmpl = 0;
493 m_refitLGChisq = 0;
494 m_refitLGTime = -100;
495 m_refitLGTimeSub = -100;
496
499
501
502 m_initialExpAmp = 0;
503 m_fitPostT0lo = 0;
504
505 m_fitPulls.clear();
506
507 m_samplesSub.clear();
508 m_samplesDeriv2nd.clear();
509}

◆ saveFitFunc()

void ZDCPulseAnalyzer::saveFitFunc ( bool save)
inline

Definition at line 522 of file ZDCPulseAnalyzer.h.

save(self, fileName="./columbo.out")
Definition checkTP.py:176

◆ ScanAndSubtractSamples()

bool ZDCPulseAnalyzer::ScanAndSubtractSamples ( )
private

Definition at line 958 of file ZDCPulseAnalyzer.cxx.

959{
960 //
961 // Dump samples to verbose output
962 //
963 bool doDump = (*m_msgFunc_p)(ZDCMsg::Verbose, "Dumping all samples before subtraction: ");
964 if (doDump) {
965 std::ostringstream dumpStringHG;
966 dumpStringHG << "HG: ";
967 for (auto val : m_ADCSamplesHG) {
968 dumpStringHG << std::setw(4) << val << " ";
969 }
970
971 (*m_msgFunc_p)(ZDCMsg::Verbose, dumpStringHG.str().c_str());
972
973
974 // Now low gain
975 //
976 std::ostringstream dumpStringLG;
977 dumpStringLG << "LG: " << std::setw(4) << std::setfill(' ');
978 for (auto val : m_ADCSamplesLG) {
979 dumpStringLG << std::setw(4) << val << " ";
980 }
981
982 (*m_msgFunc_p)(ZDCMsg::Verbose, dumpStringLG.str().c_str());
983 }
984
985 // Now do pedestal subtraction and check for overflows
986 //
989
990 m_maxADCHG = 0;
991 m_maxADCLG = 0;
992
993 for (size_t isample = 0; isample < m_NSamplesAna; isample++) {
994 float ADCHG = m_ADCSamplesHG[isample];
995 float ADCLG = m_ADCSamplesLG[isample];
996
997 //
998 // We always pedestal subtract even if the sample isn't going to be used in analysis
999 // basically for diagnostics
1000 //
1001 m_ADCSamplesHGSub[isample] = ADCHG - m_pedestal;
1002 m_ADCSamplesLGSub[isample] = ADCLG - m_pedestal;
1003
1004
1005 // If we have the per-sample FADC correction, we apply it after pedestal correction
1006 // since we analyze the FADC response after baseline (~ same as pedestal) subtraction
1007 //
1009 double fadcCorrHG = m_FADCCorrHG->Interpolate(m_ADCSamplesHGSub[isample]);
1010 double fadcCorrLG = m_FADCCorrLG->Interpolate(m_ADCSamplesLGSub[isample]);
1011
1012 m_ADCSamplesHGSub[isample] *= fadcCorrHG;
1013 m_ADCSamplesLGSub[isample] *= fadcCorrLG;
1014
1015 // if (doDump) {
1016 // std::ostringstream dumpString;
1017 // dumpString << "After FADC correction, sample " << isample << ", HG ADC = " << m_ADCSamplesHGSub[isample]
1018 // << ", LG ADC = " << m_ADCSamplesLGSub[isample] << std::endl;
1019 // (*m_msgFunc_p)(ZDCMsg::Verbose, dumpString.str().c_str());
1020 // }
1021 }
1022
1023 if (ADCHG > m_maxADCHG) {
1024 m_maxADCHG = ADCHG;
1025 m_maxADCSampleHG = isample;
1026 }
1027 else if (ADCHG < m_minADCHG) {
1028 m_minADCHG = ADCHG;
1029 m_minADCSampleHG = isample;
1030 }
1031
1032 if (ADCLG > m_maxADCLG) {
1033 m_maxADCLG = ADCLG;
1034 m_maxADCSampleLG = isample;
1035 }
1036 else if (ADCLG < m_minADCLG) {
1037 m_minADCLG = ADCLG;
1038 m_minADCSampleLG = isample;
1039 }
1040
1041 if (m_useSampleHG[isample]) {
1042 if (m_enablePreExcl) {
1043 if (ADCHG > m_preExclHGADCThresh && isample < m_maxSamplesPreExcl) {
1044 m_useSampleHG[isample] = false;
1045 continue;
1046 }
1047 }
1048
1049 if (m_enablePostExcl) {
1050 if (ADCHG > m_postExclHGADCThresh && isample >= m_NSamplesAna - m_maxSamplesPostExcl) {
1051 m_useSampleHG[isample] = false;
1052 continue;
1053 }
1054 }
1055
1056 // If we get here, we've passed the above filters on the sample
1057 //
1058 if (ADCHG > m_HGOverflowADC) {
1059 m_HGOverflow = true;
1060
1061 if (isample == m_preSampleIdx) m_PSHGOverUnderflow = true;
1062
1063 // Note: the implementation of the explicit pre- and post- sample exclusion should make this
1064 // code obselete but before removing it we first need to validate the pre- and post-exclusion
1065 //
1066 if ((int) isample > m_lastHGOverFlowSample) m_lastHGOverFlowSample = isample;
1067 if ((int) isample < m_firstHGOverFlowSample) m_firstHGOverFlowSample = isample;
1068 }
1069 else if (ADCHG < m_HGUnderflowADC) {
1072 m_useSampleHG[isample] = false;
1073 m_underflowExclusion = true;
1074 }
1075 else {
1076 m_HGUnderflow = true;
1077
1078 if (isample == m_preSampleIdx) m_PSHGOverUnderflow = true;
1079 }
1080 }
1081 }
1082
1083 // Now the low gain sample
1084 //
1085 if (m_useSampleLG[isample]) {
1086 if (m_enablePreExcl) {
1087 if (ADCLG > m_preExclLGADCThresh && isample <= m_maxSamplesPreExcl) {
1088 m_useSampleLG[isample] = false;
1089 continue;
1090 }
1091 }
1092
1093 if (m_enablePostExcl) {
1094 if (ADCLG > m_postExclLGADCThresh && isample >= m_NSamplesAna - m_maxSamplesPostExcl) {
1095 m_useSampleLG[isample] = false;
1096 m_ExcludeLate = true;
1097 continue;
1098 }
1099 }
1100
1101 if (ADCLG > m_LGOverflowADC) {
1102 m_LGOverflow = true;
1103 m_fail = true;
1104 m_amplitude = m_LGOverflowADC * m_gainFactorLG; // Give a vale here even though we know it's wrong because
1105 // the user may not check the return value and we know that
1106 // amplitude is bigger than this
1107 }
1108
1109 if (ADCLG == 0) {
1112 m_underflowExclusion = true;
1113 m_useSampleLG[isample] = false;
1114 }
1115 else {
1116 m_LGUnderflow = true;
1117 m_fail = true;
1118 }
1119 }
1120 }
1121 }
1122
1123 // if (doDump) {
1124 // (*m_msgFunc_p)(ZDCMsg::Verbose, "Dump of useSamples: ");
1125
1126 // std::ostringstream dumpStringUseHG;
1127 // dumpStringUseHG << "HG: ";
1128 // for (auto val : m_useSampleHG) {
1129 // dumpStringUseHG << val << " ";
1130 // }
1131 // (*m_msgFunc_p)(ZDCMsg::Verbose, dumpStringUseHG.str().c_str());
1132
1133 // std::ostringstream dumpStringUseLG;
1134 // dumpStringUseLG << "LG: ";
1135 // for (auto val : m_useSampleLG) {
1136 // dumpStringUseLG << val << " ";
1137 // }
1138 // (*m_msgFunc_p)(ZDCMsg::Verbose, dumpStringUseLG.str().c_str());
1139 // }
1140
1141 // This ugly code should be obseleted by the introduction of the better, pre- and post-sample exclusion but
1142 // that code still has to be fully validated.
1143 //
1144 // See if we can still use high gain even in the case of HG overflow if the overflow results from
1145 // the first few samples or the last few samples
1146 //
1147 if (m_HGOverflow && !m_HGUnderflow) {
1149 m_HGOverflow = false;
1151 m_adjTimeRangeEvent = true;
1152 m_backToHG_pre = true;
1153 m_ExcludeEarly = true;
1154 }
1155 else if (m_firstHGOverFlowSample < static_cast<int>(m_NSamplesAna) && m_firstHGOverFlowSample >= static_cast<int>(m_NSamplesAna - 2) ) {
1157 m_HGOverflow = false;
1158 m_adjTimeRangeEvent = true;
1159 m_ExcludeLate = true;
1160 }
1161 }
1162
1163 return true;
1164}

◆ set2ndDerivStep()

void ZDCPulseAnalyzer::set2ndDerivStep ( size_t step)
inline

Definition at line 568 of file ZDCPulseAnalyzer.h.

◆ SetADCOverUnderflowValues()

void ZDCPulseAnalyzer::SetADCOverUnderflowValues ( int HGOverflowADC,
int HGUnderflowADC,
int LGOverflowADC )

Definition at line 564 of file ZDCPulseAnalyzer.cxx.

565{
566 m_HGOverflowADC = HGOverflowADC;
567 m_LGOverflowADC = LGOverflowADC;
568 m_HGUnderflowADC = HGUnderflowADC;
569}

◆ SetChisqCuts()

void ZDCPulseAnalyzer::SetChisqCuts ( float chisqDivAmpCutHG,
float chisqDivAmpScaleHG,
float chisqDivAmpOffsetHG,
float chisqDivAmpPowerHG,
float chisqDivAmpCutLG,
float chisqDivAmpScaleLG,
float chisqDivAmpOffsetLG,
float chisqDivAmpPowerLG )

Definition at line 604 of file ZDCPulseAnalyzer.cxx.

606{
607 m_chisqDivAmpCutHG = chisqDivAmpCutHG;
608 m_chisqDivAmpScaleHG = chisqDivAmpScaleHG;
609 m_chisqDivAmpOffsetHG = chisqDivAmpOffsetHG;
610 m_chisqDivAmpPowerHG = chisqDivAmpPowerHG;
611
612 m_chisqDivAmpCutLG = chisqDivAmpCutLG;
613 m_chisqDivAmpScaleLG = chisqDivAmpScaleLG;
614 m_chisqDivAmpOffsetLG = chisqDivAmpOffsetLG;
615 m_chisqDivAmpPowerLG = chisqDivAmpPowerLG;
616}

◆ SetCutValues()

void ZDCPulseAnalyzer::SetCutValues ( float chisqDivAmpCutHG,
float chisqDivAmpCutLG,
float deltaT0MinHG,
float deltaT0MaxHG,
float deltaT0MinLG,
float deltaT0MaxLG )

Definition at line 571 of file ZDCPulseAnalyzer.cxx.

574{
575 m_chisqDivAmpCutHG = chisqDivAmpCutHG;
576 m_chisqDivAmpCutLG = chisqDivAmpCutLG;
577
580
583
586
587 m_T0CutLowHG = deltaT0MinHG;
588 m_T0CutLowLG = deltaT0MinLG;
589
590 m_T0CutHighHG = deltaT0MaxHG;
591 m_T0CutHighLG = deltaT0MaxLG;
592}

◆ setDefaults()

void ZDCPulseAnalyzer::setDefaults ( )
private

Definition at line 264 of file ZDCPulseAnalyzer.cxx.

265{
267
268 m_nominalTau1 = 1.5;
269 m_nominalTau2 = 5;
270
271 m_fixTau1 = false;
272 m_fixTau2 = false;
273
274 m_HGOverflowADC = 3500;
276 m_LGOverflowADC = 3900;
277
278 // Default values for the gain factors uswed to match low and high gain
279 //
280 m_gainFactorLG = 10;
281 m_gainFactorHG = 1;
282
283 m_2ndDerivStep = 1;
284
285 m_noiseSigHG = 1;
286 m_noiseSigLG = 1;
287
288 m_sigMinLG = 0;
289 m_sigMinHG = 0;
290
291 m_timeCutMode = 0;
292 m_chisqDivAmpCutLG = 100;
293 m_chisqDivAmpCutHG = 100;
294
297
300
303
304 m_LGT0CorrParams.assign(6, 0);
305 m_HGT0CorrParams.assign(6, 0);
306
307 // m_defaultFitTMax = m_tmax;
308 // m_defaultFitTMin = m_tmin;
309
310 m_fitAmpMinHG = 1;
311 m_fitAmpMinLG = 1;
312
313 m_fitAmpMaxHG = 1500;
314 m_fitAmpMaxLG = 1500;
315
316 m_haveSignifCuts = false;
317
319
320 m_doPostPulseCheck = true;
325
326 m_doPrePulseCheck = true;
327 m_prePulseDelta = 2;
328
331
333
334 m_initialExpAmp = 0;
335 m_fitPostT0lo = 0;
336
337 m_useDelayed = false;
338 m_enablePreExcl = false;
339 m_enablePostExcl = false;
340
342 m_haveNonlinCorr = false;
343 m_quietFits = true;
344 m_saveFitFunc = false;
345 m_fitOptions = "s";
346}

◆ SetFitMinMaxAmp()

void ZDCPulseAnalyzer::SetFitMinMaxAmp ( float minAmpHG,
float minAmpLG,
float maxAmpHG,
float maxAmpLG )

Definition at line 525 of file ZDCPulseAnalyzer.cxx.

526{
527 m_fitAmpMinHG = minAmpHG;
528 m_fitAmpMinLG = minAmpLG;
529
530 m_fitAmpMaxHG = maxAmpHG;
531 m_fitAmpMaxLG = maxAmpLG;
532}

◆ setFitOPtions()

void ZDCPulseAnalyzer::setFitOPtions ( const std::string & fitOptions)
inline

Definition at line 521 of file ZDCPulseAnalyzer.h.

521{ m_fitOptions = fitOptions;}

◆ SetFitTimeMax()

void ZDCPulseAnalyzer::SetFitTimeMax ( float tmax)

Definition at line 552 of file ZDCPulseAnalyzer.cxx.

553{
554 if (tmax < m_tmin) {
555 (*m_msgFunc_p)(ZDCMsg::Error, ("ZDCPulseAnalyzer::SetFitTimeMax:: invalid FitTimeMax: " + std::to_string(tmax)));
556 return;
557 }
558
559 m_defaultFitTMax = std::min(tmax, m_defaultFitTMax);
560
562}

◆ SetGainFactorsHGLG()

void ZDCPulseAnalyzer::SetGainFactorsHGLG ( float gainFactorHG,
float gainFactorLG )

Definition at line 519 of file ZDCPulseAnalyzer.cxx.

520{
521 m_gainFactorHG = gainFactorHG;
522 m_gainFactorLG = gainFactorLG;
523}

◆ setLGMode()

void ZDCPulseAnalyzer::setLGMode ( unsigned int mode)
inline

Definition at line 565 of file ZDCPulseAnalyzer.h.

◆ setMinimumSignificance()

void ZDCPulseAnalyzer::setMinimumSignificance ( float sigMinHG,
float sigMinLG )

Definition at line 512 of file ZDCPulseAnalyzer.cxx.

513{
514 m_haveSignifCuts = true;
515 m_sigMinHG = sigMinHG;
516 m_sigMinLG = sigMinLG;
517}

◆ SetNoiseSigmas()

void ZDCPulseAnalyzer::SetNoiseSigmas ( float noiseSigHG,
float noiseSigLG )
inline

Definition at line 580 of file ZDCPulseAnalyzer.h.

581 {
582 m_noiseSigHG = noiseSigHG;
583 m_noiseSigLG = noiseSigLG;
584 }

◆ SetNonlinCorrParams()

void ZDCPulseAnalyzer::SetNonlinCorrParams ( float refADC,
float refScale,
const std::vector< float > & paramsHG,
const std::vector< float > & paramsLG )
inline

Definition at line 614 of file ZDCPulseAnalyzer.h.

615 {
616 std::string HGParamsStr = "HG coefficients = ", LGParamsStr = "LG coefficients = ";
617
618 for (auto val : paramsHG) {HGParamsStr += std::to_string(val) + " ";}
619 for (auto val : paramsLG) {LGParamsStr += std::to_string(val) + " ";}
620
621 (*m_msgFunc_p)(ZDCMsg::Info, ("Setting non-linear parameters for module: " + m_tag + ", reference ADC = " +
622 std::to_string(refADC) + ", reference scale = " + std::to_string(refScale)));
623
624 (*m_msgFunc_p)(ZDCMsg::Info, std::move(HGParamsStr));
625 (*m_msgFunc_p)(ZDCMsg::Info, std::move(LGParamsStr));
626
627 m_nonLinCorrRefADC = refADC;
628 m_nonLinCorrRefScale = refScale;
629 m_nonLinCorrParamsHG = paramsHG;
630 m_nonLinCorrParamsLG = paramsLG;
631 m_haveNonlinCorr = true;
632 }

◆ SetPeak2ndDerivMinTolerance()

void ZDCPulseAnalyzer::SetPeak2ndDerivMinTolerance ( size_t tolerance)
inline

Definition at line 552 of file ZDCPulseAnalyzer.h.

552 {
554 m_initializedFits = false;
555 }
constexpr double tolerance

◆ setPerSampleNoiseSigmas()

void ZDCPulseAnalyzer::setPerSampleNoiseSigmas ( const std::vector< float > & sigmaHG,
const std::vector< float > & sigmaLG )
inline

Definition at line 557 of file ZDCPulseAnalyzer.h.

558 {
559 m_setPerSampleNoiseHG = sigmaHG;
560 m_setPerSampleNoiseLG = sigmaLG;
563 }

◆ setQuietFits()

void ZDCPulseAnalyzer::setQuietFits ( )
inline

Definition at line 525 of file ZDCPulseAnalyzer.h.

525{m_quietFits = true;}

◆ SetTauT0Values()

void ZDCPulseAnalyzer::SetTauT0Values ( bool fixTau1,
bool fixTau2,
float tau1,
float tau2,
float t0HG,
float t0LG )

Definition at line 534 of file ZDCPulseAnalyzer.cxx.

535{
536 m_fixTau1 = fixTau1;
537 m_fixTau2 = fixTau2;
538 m_nominalTau1 = tau1;
539 m_nominalTau2 = tau2;
540
541 m_nominalT0HG = t0HG;
542 m_nominalT0LG = t0LG;
543
544 std::ostringstream ostrm;
545 ostrm << "ZDCPulseAnalyzer::SetTauT0Values:: m_fixTau1=" << m_fixTau1 << " m_fixTau2=" << m_fixTau2 << " m_nominalTau1=" << m_nominalTau1 << " m_nominalTau2=" << m_nominalTau2 << " m_nominalT0HG=" << m_nominalT0HG << " m_nominalT0LG=" << m_nominalT0LG;
546
547 (*m_msgFunc_p)(ZDCMsg::Info, ostrm.str());
548
549 m_initializedFits = false;
550}

◆ SetTimeCuts()

void ZDCPulseAnalyzer::SetTimeCuts ( float deltaT0MinHG,
float deltaT0MaxHG,
float deltaT0MinLG,
float deltaT0MaxLG )

Definition at line 594 of file ZDCPulseAnalyzer.cxx.

596{
597 m_T0CutLowHG = deltaT0MinHG;
598 m_T0CutLowLG = deltaT0MinLG;
599
600 m_T0CutHighHG = deltaT0MaxHG;
601 m_T0CutHighLG = deltaT0MaxLG;
602}

◆ SetTimingCorrParams()

void ZDCPulseAnalyzer::SetTimingCorrParams ( TimingCorrMode mode,
float refADC,
float refScale,
const std::vector< float > & HGT0CorrParams,
const std::vector< float > & LGT0CorrParams )
inline

Definition at line 599 of file ZDCPulseAnalyzer.h.

601 {
603 if (mode != NoTimingCorr) {
604 m_timingCorrRefADC = refADC;
605 m_timingCorrScale = refScale;
606
607 m_HGT0CorrParams = HGT0CorrParams;
608 m_LGT0CorrParams = LGT0CorrParams;
609 }
610 }

◆ setUnquietFits()

void ZDCPulseAnalyzer::setUnquietFits ( )
inline

Definition at line 526 of file ZDCPulseAnalyzer.h.

526{m_quietFits = false;}

◆ SetupFitFunctions()

void ZDCPulseAnalyzer::SetupFitFunctions ( )
private

Definition at line 758 of file ZDCPulseAnalyzer.cxx.

759{
760 float prePulseTMin = 0;
761 float prePulseTMax = prePulseTMin + m_deltaTSample * (m_peak2ndDerivMinSample - m_peak2ndDerivMinTolerance);
762
763 if (m_fitFunction == "FermiExp") {
764 if (!m_fixTau1 || !m_fixTau2) {
765 //
766 // Use the variable tau version of the expFermiFit
767 //
768 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiVariableTaus(m_tag, m_tmin, m_tmax, m_fixTau1, m_fixTau2, m_nominalTau1, m_nominalTau2));
769 }
770 else {
771 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiFixedTaus(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
772 }
773
774 m_preExpFitWrapper = std::unique_ptr<ZDCFitExpFermiPreExp>(new ZDCFitExpFermiPreExp(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2, m_nominalTau2, false));
775 m_prePulseFitWrapper = std::unique_ptr<ZDCPrePulseFitWrapper>(new ZDCFitExpFermiPrePulse(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
776 }
777 else if (m_fitFunction == "FermiExpRun3") {
778 if (!m_fixTau1 || !m_fixTau2) {
779 //
780 // Use the variable tau version of the expFermiFit
781 //
782 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiVariableTausRun3(m_tag, m_tmin, m_tmax, m_fixTau1, m_fixTau2, m_nominalTau1, m_nominalTau2));
783 }
784 else {
785 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiFixedTaus(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
786 }
787
788 m_preExpFitWrapper = std::unique_ptr<ZDCFitExpFermiPreExp>(new ZDCFitExpFermiPreExp(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2, 6, false));
789 m_prePulseFitWrapper = std::unique_ptr<ZDCPrePulseFitWrapper>(new ZDCFitExpFermiPrePulse(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
790 }
791 else if (m_fitFunction == "FermiExpLHCf") {
792 //
793 // Use the variable tau version of the expFermiFit
794 //
795 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiVariableTausLHCf(m_tag, m_tmin, m_tmax, m_fixTau1, m_fixTau2,
797
798 m_preExpFitWrapper = std::unique_ptr<ZDCFitExpFermiLHCfPreExp>(new ZDCFitExpFermiLHCfPreExp(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2, 6, false));
799
800 m_prePulseFitWrapper = std::unique_ptr<ZDCPrePulseFitWrapper>(new ZDCFitExpFermiLHCfPrePulse(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
801 }
802 else if (m_fitFunction == "FermiExpInduct") {
803 //
804 // Use the variable tau version of the expFermiFit
805 //
806 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiVariableTausInduct(m_tag, m_tmin, m_tmax, m_fixTau1, m_fixTau2,
808 m_preExpFitWrapper = std::unique_ptr<ZDCFitExpFermiInductPreExp>(new ZDCFitExpFermiInductPreExp(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2, 6, false));
809
810 // We still have to implement the pre-pulse version of the new induct function For now, using old ("LHCf") version
811 //
812 m_prePulseFitWrapper = std::unique_ptr<ZDCPrePulseFitWrapper>(new ZDCFitExpFermiLHCfPrePulse(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
813 }
814 else if (m_fitFunction == "FermiExpLinear") {
815 if (!m_fixTau1 || !m_fixTau2) {
816 //
817 // Use the variable tau version of the expFermiFit
818 //
819 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiVariableTaus(m_tag, m_tmin, m_tmax, m_fixTau1, m_fixTau2, m_nominalTau1, m_nominalTau2));
820 }
821 else {
822 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiLinearFixedTaus(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
823 }
824
825 m_preExpFitWrapper = std::unique_ptr<ZDCFitExpFermiPreExp>(new ZDCFitExpFermiPreExp(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2, 6, false));
826 m_prePulseFitWrapper = std::unique_ptr<ZDCPrePulseFitWrapper>(new ZDCFitExpFermiLinearPrePulse(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
827 }
828 else if (m_fitFunction == "ComplexPrePulse") {
829 if (!m_fixTau1 || !m_fixTau2) {
830 //
831 // Use the variable tau version of the expFermiFit
832 //
833 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiVariableTaus(m_tag, m_tmin, m_tmax, m_fixTau1, m_fixTau2, m_nominalTau1, m_nominalTau2));
834 }
835 else {
836 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiLinearFixedTaus(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
837 }
838
839 m_prePulseFitWrapper = std::unique_ptr<ZDCPrePulseFitWrapper>(new ZDCFitComplexPrePulse(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
840 }
841 else if (m_fitFunction == "GeneralPulse") {
842 if (!m_fixTau1 || !m_fixTau2) {
843 //
844 // Use the variable tau version of the expFermiFit
845 //
846 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiVariableTaus(m_tag, m_tmin, m_tmax, m_fixTau1, m_fixTau2, m_nominalTau1, m_nominalTau2));
847 }
848 else {
849 m_defaultFitWrapper = std::unique_ptr<ZDCFitWrapper>(new ZDCFitExpFermiLinearFixedTaus(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
850 }
851
852 m_prePulseFitWrapper = std::unique_ptr<ZDCPrePulseFitWrapper>(new ZDCFitGeneralPulse(m_tag, m_tmin, m_tmax, m_nominalTau1, m_nominalTau2));
853 }
854 else {
855 (*m_msgFunc_p)(ZDCMsg::Fatal, "Wrong fit function type: " + m_fitFunction);
856 }
857
858 m_prePulseFitWrapper->SetPrePulseT0Range(prePulseTMin, prePulseTMax);
859
860 m_initializedFits = true;
861}

◆ underflowExclusion()

bool ZDCPulseAnalyzer::underflowExclusion ( ) const
inline

Definition at line 675 of file ZDCPulseAnalyzer.h.

675{return m_underflowExclusion;}

◆ UpdateFitterTimeLimits()

void ZDCPulseAnalyzer::UpdateFitterTimeLimits ( TFitter * fitter,
ZDCFitWrapper * wrapper,
bool prePulse )
private

Definition at line 2251 of file ZDCPulseAnalyzer.cxx.

2252{
2253 double parLimitLow, parLimitHigh;
2254
2255 auto func_p = wrapper->GetWrapperTF1();
2256 func_p->GetParLimits(1, parLimitLow, parLimitHigh);
2257
2258 fitter->SetParameter(2, func_p->GetParName(1), func_p->GetParameter(1), 0.01, parLimitLow, parLimitHigh);
2259
2260 if (prePulse) {
2261 unsigned int parIndex = static_cast<ZDCPrePulseFitWrapper*>(wrapper)->GetPreT0ParIndex();
2262
2263 func_p->GetParLimits(parIndex, parLimitLow, parLimitHigh);
2264 fitter->SetParameter(parIndex + 1, func_p->GetParName(parIndex), func_p->GetParameter(parIndex), 0.01, parLimitLow, parLimitHigh);
2265 }
2266}
virtual std::shared_ptr< TF1 > GetWrapperTF1()

◆ useLowGain()

bool ZDCPulseAnalyzer::useLowGain ( ) const
inline

Definition at line 653 of file ZDCPulseAnalyzer.h.

653{return m_useLowGain;}

◆ ValidateJSONConfig()

std::pair< bool, std::string > ZDCPulseAnalyzer::ValidateJSONConfig ( const JSON & config)
private

Definition at line 2647 of file ZDCPulseAnalyzer.cxx.

2648{
2649 bool result = true;
2650 std::string resultString = "success";
2651
2652 for (auto [key, descr] : JSONConfigParams) {
2653 auto iter = config.find(key);
2654 if (iter != config.end()) {
2655 //
2656 // Check type consistency
2657 //
2658 auto jsonType = iter.value().type();
2659 auto paramType = std::get<0>(descr);
2660 if (jsonType != paramType) {
2661 result = false;
2662 resultString = "Bad type for parameter " + key + ", type in JSON = " + std::to_string((unsigned int) jsonType) ;
2663 break;
2664 }
2665
2666 size_t paramSize = std::get<1>(descr);
2667 size_t jsonSize = iter.value().size();
2668 if (jsonSize != paramSize) {
2669 result = false;
2670 resultString = "Bad length for parameter " + key + ", length in JSON = " + std::to_string(jsonSize) ;
2671 break;
2672 }
2673 }
2674 else {
2675 bool required = std::get<2>(descr);
2676 if (required) {
2677 result = false;
2678 resultString = "Missing required parameter " + key;
2679 break;
2680 }
2681 }
2682 }
2683
2684 if (result) {
2685 //
2686 // Now check that the parameters in the JSON object are in the master list of parameters
2687 //
2688 for (auto [key, value] : config.items()) {
2689 //
2690 // Look for this key in the list of allowed parameters. Yes, it's a slow
2691 // search but we only do it once at configuration time.
2692 //
2693 // bool found = false;
2694 auto iter = JSONConfigParams.find(key);
2695 if (iter == JSONConfigParams.end()) {
2696 result = false;
2697 resultString = "Unknown parameter, key = " + key;
2698 break;
2699 }
2700 }
2701 }
2702
2703 return {result, resultString};
2704}
static const ZDCJSONConfig::JSONParamList JSONConfigParams

Member Data Documentation

◆ JSONConfigParams

const ZDCJSONConfig::JSONParamList ZDCPulseAnalyzer::JSONConfigParams
static

Definition at line 33 of file ZDCPulseAnalyzer.h.

56 {
57 LGModeNormal = 0,
60 };
61
63
64 //
65 // List of allowed JSON configuration parameters
66 //
67 // For each parameter we have name, JSON value type, whether it can be set per channel, and whether it is required
68 //
69 // if the type is -1, then there's no value, the presence of the parameter itself is a boolean -- i.e. enabling
70 //
71
73private:
74 typedef std::vector<float>::const_iterator SampleCIter;
75
76 // Static data
77 //
78
79 static TH1* s_undelayedFitHist;
80 static TH1* s_delayedFitHist;
81 static TF1* s_combinedFitFunc;
82 static float s_combinedFitTMax;
83 static float s_combinedFitTMin;
84 static std::vector<float> s_pullValues;
85
86 // Quantities provided/set in the constructor
87 //
89 std::string m_tag{};
90 unsigned int m_Nsample{};
91 unsigned int m_preSampleIdx{};
92 float m_freqMHz{};
93 float m_deltaTSample{};
94 int m_pedestal{};
95 unsigned int m_LGMode{LGModeNormal};
96 float m_tmin{};
97 float m_tmax{};
std::map< std::string, JSONParamDescr > JSONParamList
std::shared_ptr< MessageFunction > MessageFunctionPtr
Definition ZDCMsg.h:14

◆ m_2ndDerivStep

size_t ZDCPulseAnalyzer::m_2ndDerivStep {1}
private

Definition at line 103 of file ZDCPulseAnalyzer.h.

103{1};

◆ m_ADCPeakHG

float ZDCPulseAnalyzer::m_ADCPeakHG {}
private

Definition at line 317 of file ZDCPulseAnalyzer.h.

317{};

◆ m_ADCPeakLG

float ZDCPulseAnalyzer::m_ADCPeakLG {}
private

Definition at line 318 of file ZDCPulseAnalyzer.h.

318{};

◆ m_ADCSamplesHG

std::vector<float> ZDCPulseAnalyzer::m_ADCSamplesHG
private

Definition at line 384 of file ZDCPulseAnalyzer.h.

◆ m_ADCSamplesHGSub

std::vector<float> ZDCPulseAnalyzer::m_ADCSamplesHGSub
private

Definition at line 386 of file ZDCPulseAnalyzer.h.

◆ m_ADCSamplesLG

std::vector<float> ZDCPulseAnalyzer::m_ADCSamplesLG
private

Definition at line 385 of file ZDCPulseAnalyzer.h.

◆ m_ADCSamplesLGSub

std::vector<float> ZDCPulseAnalyzer::m_ADCSamplesLGSub
private

Definition at line 387 of file ZDCPulseAnalyzer.h.

◆ m_ADCSSampNoiseHG

std::vector<float> ZDCPulseAnalyzer::m_ADCSSampNoiseHG
private

Definition at line 394 of file ZDCPulseAnalyzer.h.

◆ m_ADCSSampNoiseLG

std::vector<float> ZDCPulseAnalyzer::m_ADCSSampNoiseLG
private

Definition at line 395 of file ZDCPulseAnalyzer.h.

◆ m_adjTimeRangeEvent

bool ZDCPulseAnalyzer::m_adjTimeRangeEvent {false}
private

Definition at line 247 of file ZDCPulseAnalyzer.h.

247{false}; // indicates whether we adjust the time range for this specific event

◆ m_ampError

float ZDCPulseAnalyzer::m_ampError {}
private

Definition at line 360 of file ZDCPulseAnalyzer.h.

360{};

◆ m_amplitude

float ZDCPulseAnalyzer::m_amplitude {}
private

Definition at line 358 of file ZDCPulseAnalyzer.h.

358{};

◆ m_ampNoNonLin

float ZDCPulseAnalyzer::m_ampNoNonLin {}
private

Definition at line 359 of file ZDCPulseAnalyzer.h.

359{};

◆ m_backToHG_pre

bool ZDCPulseAnalyzer::m_backToHG_pre {false}
private

Definition at line 299 of file ZDCPulseAnalyzer.h.

299{false};

◆ m_badChisq

bool ZDCPulseAnalyzer::m_badChisq {false}
private

Definition at line 284 of file ZDCPulseAnalyzer.h.

284{false};

◆ m_badT0

bool ZDCPulseAnalyzer::m_badT0 {false}
private

Definition at line 286 of file ZDCPulseAnalyzer.h.

286{false};

◆ m_baselineCorr

float ZDCPulseAnalyzer::m_baselineCorr {}
private

Definition at line 300 of file ZDCPulseAnalyzer.h.

300{};

◆ m_bkgdMaxFraction

float ZDCPulseAnalyzer::m_bkgdMaxFraction {}
private

Definition at line 365 of file ZDCPulseAnalyzer.h.

365{};

◆ m_chisqDivAmpCutHG

float ZDCPulseAnalyzer::m_chisqDivAmpCutHG {}
private

Definition at line 150 of file ZDCPulseAnalyzer.h.

150{}; // maximum good HG chisq / amplitude

◆ m_chisqDivAmpCutLG

float ZDCPulseAnalyzer::m_chisqDivAmpCutLG {}
private

Definition at line 149 of file ZDCPulseAnalyzer.h.

149{}; // maximum good LG chisq / amplitude

◆ m_chisqDivAmpOffsetHG

float ZDCPulseAnalyzer::m_chisqDivAmpOffsetHG {}
private

Definition at line 154 of file ZDCPulseAnalyzer.h.

154{}; // maximum good HG chisq / amplitude

◆ m_chisqDivAmpOffsetLG

float ZDCPulseAnalyzer::m_chisqDivAmpOffsetLG {}
private

Definition at line 153 of file ZDCPulseAnalyzer.h.

153{}; // maximum good LG chisq / amplitude

◆ m_chisqDivAmpPowerHG

float ZDCPulseAnalyzer::m_chisqDivAmpPowerHG {}
private

Definition at line 156 of file ZDCPulseAnalyzer.h.

156{}; // maximum good HG chisq / amplitude

◆ m_chisqDivAmpPowerLG

float ZDCPulseAnalyzer::m_chisqDivAmpPowerLG {}
private

Definition at line 155 of file ZDCPulseAnalyzer.h.

155{}; // maximum good LG chisq / amplitude

◆ m_chisqDivAmpScaleHG

float ZDCPulseAnalyzer::m_chisqDivAmpScaleHG {}
private

Definition at line 152 of file ZDCPulseAnalyzer.h.

152{}; // maximum good HG chisq / amplitude

◆ m_chisqDivAmpScaleLG

float ZDCPulseAnalyzer::m_chisqDivAmpScaleLG {}
private

Definition at line 151 of file ZDCPulseAnalyzer.h.

151{}; // maximum good LG chisq / amplitude

◆ m_chisqRatio

float ZDCPulseAnalyzer::m_chisqRatio {}
private

Definition at line 351 of file ZDCPulseAnalyzer.h.

351{};

◆ m_defaultCombinedFitter

std::unique_ptr<TFitter> ZDCPulseAnalyzer::m_defaultCombinedFitter {}
private

Definition at line 261 of file ZDCPulseAnalyzer.h.

261{};

◆ m_defaultFitTMax

float ZDCPulseAnalyzer::m_defaultFitTMax {}
private

Definition at line 146 of file ZDCPulseAnalyzer.h.

146{}; // user-provided upper limit on samples to be included in fit

◆ m_defaultFitTMin

float ZDCPulseAnalyzer::m_defaultFitTMin {}
private

Definition at line 147 of file ZDCPulseAnalyzer.h.

147{}; // user-provided upper limit on samples to be included in fit

◆ m_defaultFitWrapper

std::unique_ptr<ZDCFitWrapper> ZDCPulseAnalyzer::m_defaultFitWrapper {}
private

Definition at line 241 of file ZDCPulseAnalyzer.h.

241{};

◆ m_defaultT0Max

float ZDCPulseAnalyzer::m_defaultT0Max {}
private

Definition at line 169 of file ZDCPulseAnalyzer.h.

169{}; // Upper limit on pulse t0

◆ m_defaultT0Min

float ZDCPulseAnalyzer::m_defaultT0Min {}
private

Definition at line 170 of file ZDCPulseAnalyzer.h.

170{}; // Lower limit on pulse t0

◆ m_delayedBaselineShift

float ZDCPulseAnalyzer::m_delayedBaselineShift {}
private

Definition at line 366 of file ZDCPulseAnalyzer.h.

366{};

◆ m_delayedDeltaT

float ZDCPulseAnalyzer::m_delayedDeltaT {}
private

Definition at line 255 of file ZDCPulseAnalyzer.h.

255{};

◆ m_delayedHist

std::unique_ptr<TH1> ZDCPulseAnalyzer::m_delayedHist {}
private

Definition at line 257 of file ZDCPulseAnalyzer.h.

257{};

◆ m_delayedHistLGRefit

std::unique_ptr<TH1> ZDCPulseAnalyzer::m_delayedHistLGRefit {}
private

Definition at line 258 of file ZDCPulseAnalyzer.h.

258{};

◆ m_delayedPedestalDiff

float ZDCPulseAnalyzer::m_delayedPedestalDiff {}
private

Definition at line 256 of file ZDCPulseAnalyzer.h.

256{};

◆ m_deltaTSample

float ZDCPulseAnalyzer::m_deltaTSample {}
private

Definition at line 93 of file ZDCPulseAnalyzer.h.

93{};

◆ m_doPostPulseCheck

bool ZDCPulseAnalyzer::m_doPostPulseCheck {false}
private

Definition at line 188 of file ZDCPulseAnalyzer.h.

188{false};

◆ m_doPrePulseCheck

bool ZDCPulseAnalyzer::m_doPrePulseCheck {false}
private

Definition at line 184 of file ZDCPulseAnalyzer.h.

184{false};

◆ m_enablePostExcl

bool ZDCPulseAnalyzer::m_enablePostExcl {false}
private

Definition at line 203 of file ZDCPulseAnalyzer.h.

203{false};

◆ m_enablePreExcl

bool ZDCPulseAnalyzer::m_enablePreExcl {false}
private

Definition at line 198 of file ZDCPulseAnalyzer.h.

198{false};

◆ m_enableRepass

bool ZDCPulseAnalyzer::m_enableRepass {false}
private

Definition at line 111 of file ZDCPulseAnalyzer.h.

111{false};

◆ m_enableUnderflowExclHG

bool ZDCPulseAnalyzer::m_enableUnderflowExclHG {false}
private

Definition at line 208 of file ZDCPulseAnalyzer.h.

208{false};

◆ m_enableUnderflowExclLG

bool ZDCPulseAnalyzer::m_enableUnderflowExclLG {false}
private

Definition at line 209 of file ZDCPulseAnalyzer.h.

209{false};

◆ m_evtLGRefit

bool ZDCPulseAnalyzer::m_evtLGRefit {false}
private

Definition at line 370 of file ZDCPulseAnalyzer.h.

370{false};

◆ m_ExcludeEarly

bool ZDCPulseAnalyzer::m_ExcludeEarly {false}
private

Definition at line 287 of file ZDCPulseAnalyzer.h.

287{false};

◆ m_ExcludeLate

bool ZDCPulseAnalyzer::m_ExcludeLate {false}
private

Definition at line 288 of file ZDCPulseAnalyzer.h.

288{false};

◆ m_expAmplitude

float ZDCPulseAnalyzer::m_expAmplitude {}
private

Definition at line 364 of file ZDCPulseAnalyzer.h.

364{};

◆ m_fadcCorrFileName

std::string ZDCPulseAnalyzer::m_fadcCorrFileName
private

Definition at line 229 of file ZDCPulseAnalyzer.h.

◆ m_FADCCorrHG

std::unique_ptr<const TH1> ZDCPulseAnalyzer::m_FADCCorrHG {}
private

Definition at line 231 of file ZDCPulseAnalyzer.h.

231{};

◆ m_FADCCorrLG

std::unique_ptr<const TH1> ZDCPulseAnalyzer::m_FADCCorrLG {}
private

Definition at line 232 of file ZDCPulseAnalyzer.h.

232{};

◆ m_FADCCorrPerSample

bool ZDCPulseAnalyzer::m_FADCCorrPerSample {false}
private

Definition at line 230 of file ZDCPulseAnalyzer.h.

230{false};

◆ m_fail

bool ZDCPulseAnalyzer::m_fail {false}
private

Definition at line 273 of file ZDCPulseAnalyzer.h.

273{false};

◆ m_failSigCut

bool ZDCPulseAnalyzer::m_failSigCut {false}
private

Definition at line 294 of file ZDCPulseAnalyzer.h.

294{false};

◆ m_firstHGOverFlowSample

int ZDCPulseAnalyzer::m_firstHGOverFlowSample {-1}
private

Definition at line 381 of file ZDCPulseAnalyzer.h.

381{-1};

◆ m_fitAmpError

float ZDCPulseAnalyzer::m_fitAmpError {}
private

Definition at line 342 of file ZDCPulseAnalyzer.h.

342{};

◆ m_fitAmplitude

float ZDCPulseAnalyzer::m_fitAmplitude {}
private

Definition at line 341 of file ZDCPulseAnalyzer.h.

341{};

◆ m_fitAmpMaxHG

float ZDCPulseAnalyzer::m_fitAmpMaxHG {}
private

Definition at line 175 of file ZDCPulseAnalyzer.h.

175{}; // Minimum am`plitude in the fit

◆ m_fitAmpMaxLG

float ZDCPulseAnalyzer::m_fitAmpMaxLG {}
private

Definition at line 176 of file ZDCPulseAnalyzer.h.

176{}; // Minimum amplitude in the fit

◆ m_fitAmpMinHG

float ZDCPulseAnalyzer::m_fitAmpMinHG {}
private

Definition at line 172 of file ZDCPulseAnalyzer.h.

172{}; // Minimum amplitude in the fit

◆ m_fitAmpMinLG

float ZDCPulseAnalyzer::m_fitAmpMinLG {}
private

Definition at line 173 of file ZDCPulseAnalyzer.h.

173{}; // Minimum amplitude in the fit

◆ m_fitChisq

float ZDCPulseAnalyzer::m_fitChisq {}
private

Definition at line 350 of file ZDCPulseAnalyzer.h.

350{};

◆ m_fitExpAmp

float ZDCPulseAnalyzer::m_fitExpAmp {}
private

Definition at line 357 of file ZDCPulseAnalyzer.h.

357{};

◆ m_fitFailed

bool ZDCPulseAnalyzer::m_fitFailed {false}
private

Definition at line 283 of file ZDCPulseAnalyzer.h.

283{false};

◆ m_fitFunction

std::string ZDCPulseAnalyzer::m_fitFunction
private

Definition at line 102 of file ZDCPulseAnalyzer.h.

◆ m_fitHist

std::unique_ptr<TH1> ZDCPulseAnalyzer::m_fitHist {}
private

Definition at line 236 of file ZDCPulseAnalyzer.h.

236{};

◆ m_fitHistLGRefit

std::unique_ptr<TH1> ZDCPulseAnalyzer::m_fitHistLGRefit {}
private

Definition at line 237 of file ZDCPulseAnalyzer.h.

237{};

◆ m_fitMinAmp

bool ZDCPulseAnalyzer::m_fitMinAmp {false}
private

Definition at line 292 of file ZDCPulseAnalyzer.h.

292{false};

◆ m_fitNDoF

float ZDCPulseAnalyzer::m_fitNDoF {}
private

Definition at line 352 of file ZDCPulseAnalyzer.h.

352{};

◆ m_fitOptions

std::string ZDCPulseAnalyzer::m_fitOptions {}
private

Definition at line 132 of file ZDCPulseAnalyzer.h.

132{};

◆ m_fitPostAmp

float ZDCPulseAnalyzer::m_fitPostAmp {}
private

Definition at line 356 of file ZDCPulseAnalyzer.h.

356{};

◆ m_fitPostT0

float ZDCPulseAnalyzer::m_fitPostT0 {}
private

Definition at line 355 of file ZDCPulseAnalyzer.h.

355{};

◆ m_fitPostT0lo

float ZDCPulseAnalyzer::m_fitPostT0lo {}
private

Definition at line 330 of file ZDCPulseAnalyzer.h.

330{}; // use to assign lower bound of post pulse T0

◆ m_fitPreAmp

float ZDCPulseAnalyzer::m_fitPreAmp {}
private

Definition at line 354 of file ZDCPulseAnalyzer.h.

354{};

◆ m_fitPreT0

float ZDCPulseAnalyzer::m_fitPreT0 {}
private

Definition at line 353 of file ZDCPulseAnalyzer.h.

353{};

◆ m_fitPulls

std::vector<float> ZDCPulseAnalyzer::m_fitPulls
private

Definition at line 411 of file ZDCPulseAnalyzer.h.

◆ m_fitTau1

float ZDCPulseAnalyzer::m_fitTau1 {}
private

Definition at line 348 of file ZDCPulseAnalyzer.h.

348{};

◆ m_fitTau2

float ZDCPulseAnalyzer::m_fitTau2 {}
private

Definition at line 349 of file ZDCPulseAnalyzer.h.

349{};

◆ m_fitTCorr2nd

float ZDCPulseAnalyzer::m_fitTCorr2nd {}
private

Definition at line 347 of file ZDCPulseAnalyzer.h.

347{};

◆ m_fitTime

float ZDCPulseAnalyzer::m_fitTime {}
private

Definition at line 343 of file ZDCPulseAnalyzer.h.

343{};

◆ m_fitTimeCorr

float ZDCPulseAnalyzer::m_fitTimeCorr {}
private

Definition at line 345 of file ZDCPulseAnalyzer.h.

345{};

◆ m_fitTimeSub

float ZDCPulseAnalyzer::m_fitTimeSub {}
private

Definition at line 344 of file ZDCPulseAnalyzer.h.

344{};

◆ m_fitTMax

float ZDCPulseAnalyzer::m_fitTMax {}
private

Definition at line 327 of file ZDCPulseAnalyzer.h.

327{}; // event-by-event specified fit tmax

◆ m_fitTMin

float ZDCPulseAnalyzer::m_fitTMin {}
private

Definition at line 328 of file ZDCPulseAnalyzer.h.

328{}; // event-by-event specified fit tmin

◆ m_fixPrePulse

bool ZDCPulseAnalyzer::m_fixPrePulse {false}
private

Definition at line 291 of file ZDCPulseAnalyzer.h.

291{false};

◆ m_fixTau1

bool ZDCPulseAnalyzer::m_fixTau1 {}
private

Definition at line 143 of file ZDCPulseAnalyzer.h.

143{};

◆ m_fixTau2

bool ZDCPulseAnalyzer::m_fixTau2 {}
private

Definition at line 144 of file ZDCPulseAnalyzer.h.

144{};

◆ m_freqMHz

float ZDCPulseAnalyzer::m_freqMHz {}
private

Definition at line 92 of file ZDCPulseAnalyzer.h.

92{};

◆ m_gainFactorHG

float ZDCPulseAnalyzer::m_gainFactorHG {}
private

Definition at line 117 of file ZDCPulseAnalyzer.h.

117{};

◆ m_gainFactorLG

float ZDCPulseAnalyzer::m_gainFactorLG {}
private

Definition at line 118 of file ZDCPulseAnalyzer.h.

118{};

◆ m_haveData

bool ZDCPulseAnalyzer::m_haveData {false}
private

Definition at line 269 of file ZDCPulseAnalyzer.h.

269{false};

◆ m_haveFADCCorrections

bool ZDCPulseAnalyzer::m_haveFADCCorrections {false}
private

Definition at line 228 of file ZDCPulseAnalyzer.h.

228{false};

◆ m_haveNonlinCorr

bool ZDCPulseAnalyzer::m_haveNonlinCorr {false}
private

Definition at line 222 of file ZDCPulseAnalyzer.h.

222{false};

◆ m_havePerSampleNoiseHG

bool ZDCPulseAnalyzer::m_havePerSampleNoiseHG {false}
private

Definition at line 125 of file ZDCPulseAnalyzer.h.

125{false};

◆ m_havePerSampleNoiseLG

bool ZDCPulseAnalyzer::m_havePerSampleNoiseLG {false}
private

Definition at line 126 of file ZDCPulseAnalyzer.h.

126{false};

◆ m_havePulse

bool ZDCPulseAnalyzer::m_havePulse {false}
private

Definition at line 271 of file ZDCPulseAnalyzer.h.

271{false};

◆ m_haveSignifCuts

bool ZDCPulseAnalyzer::m_haveSignifCuts {false}
private

Definition at line 178 of file ZDCPulseAnalyzer.h.

178{false};

◆ m_HGOverflow

bool ZDCPulseAnalyzer::m_HGOverflow {false}
private

Definition at line 274 of file ZDCPulseAnalyzer.h.

274{false};

◆ m_HGOverflowADC

int ZDCPulseAnalyzer::m_HGOverflowADC {}
private

Definition at line 133 of file ZDCPulseAnalyzer.h.

133{};

◆ m_HGT0CorrParams

std::vector<float> ZDCPulseAnalyzer::m_HGT0CorrParams {}
private

Definition at line 220 of file ZDCPulseAnalyzer.h.

220{}; // Parameters used to correct the fit HG times

◆ m_HGUnderflow

bool ZDCPulseAnalyzer::m_HGUnderflow {false}
private

Definition at line 276 of file ZDCPulseAnalyzer.h.

276{false};

◆ m_HGUnderflowADC

int ZDCPulseAnalyzer::m_HGUnderflowADC {}
private

Definition at line 134 of file ZDCPulseAnalyzer.h.

134{};

◆ m_initialExpAmp

float ZDCPulseAnalyzer::m_initialExpAmp {}
private

Definition at line 323 of file ZDCPulseAnalyzer.h.

323{};

◆ m_initialized

bool ZDCPulseAnalyzer::m_initialized {false}
private

Definition at line 239 of file ZDCPulseAnalyzer.h.

239{false};

◆ m_initializedFits

bool ZDCPulseAnalyzer::m_initializedFits {false}
private

Definition at line 240 of file ZDCPulseAnalyzer.h.

240{false};

◆ m_initialPostPulseT0

float ZDCPulseAnalyzer::m_initialPostPulseT0 {}
private

Definition at line 339 of file ZDCPulseAnalyzer.h.

339{};

◆ m_initialPrePulseAmp

float ZDCPulseAnalyzer::m_initialPrePulseAmp {}
private

Definition at line 337 of file ZDCPulseAnalyzer.h.

337{};

◆ m_initialPrePulseT0

float ZDCPulseAnalyzer::m_initialPrePulseT0 {}
private

Definition at line 336 of file ZDCPulseAnalyzer.h.

336{};

◆ m_lastHGOverFlowSample

int ZDCPulseAnalyzer::m_lastHGOverFlowSample {-1}
private

Definition at line 380 of file ZDCPulseAnalyzer.h.

380{-1};

◆ m_LGMode

unsigned int ZDCPulseAnalyzer::m_LGMode {LGModeNormal}
private

Definition at line 95 of file ZDCPulseAnalyzer.h.

◆ m_LGOverflow

bool ZDCPulseAnalyzer::m_LGOverflow {false}
private

Definition at line 278 of file ZDCPulseAnalyzer.h.

278{false};

◆ m_LGOverflowADC

int ZDCPulseAnalyzer::m_LGOverflowADC {}
private

Definition at line 135 of file ZDCPulseAnalyzer.h.

135{};

◆ m_LGT0CorrParams

std::vector<float> ZDCPulseAnalyzer::m_LGT0CorrParams {}
private

Definition at line 219 of file ZDCPulseAnalyzer.h.

219{}; // Parameters used to correct the fit LG times

◆ m_LGUnderflow

bool ZDCPulseAnalyzer::m_LGUnderflow {false}
private

Definition at line 279 of file ZDCPulseAnalyzer.h.

279{false};

◆ m_maxADCHG

float ZDCPulseAnalyzer::m_maxADCHG {}
private

Definition at line 308 of file ZDCPulseAnalyzer.h.

308{};

◆ m_maxADCLG

float ZDCPulseAnalyzer::m_maxADCLG {}
private

Definition at line 312 of file ZDCPulseAnalyzer.h.

312{};

◆ m_maxADCSampleHG

int ZDCPulseAnalyzer::m_maxADCSampleHG
private

Definition at line 310 of file ZDCPulseAnalyzer.h.

◆ m_maxADCSampleLG

int ZDCPulseAnalyzer::m_maxADCSampleLG
private

Definition at line 315 of file ZDCPulseAnalyzer.h.

◆ m_maxDelta

float ZDCPulseAnalyzer::m_maxDelta {}
private

Definition at line 320 of file ZDCPulseAnalyzer.h.

320{};

◆ m_maxSampleEvt

unsigned int ZDCPulseAnalyzer::m_maxSampleEvt {}
private

Definition at line 250 of file ZDCPulseAnalyzer.h.

250{};

◆ m_maxSamplesPostExcl

unsigned int ZDCPulseAnalyzer::m_maxSamplesPostExcl {0}
private

Definition at line 206 of file ZDCPulseAnalyzer.h.

206{0};

◆ m_maxSamplesPreExcl

unsigned int ZDCPulseAnalyzer::m_maxSamplesPreExcl {0}
private

Definition at line 199 of file ZDCPulseAnalyzer.h.

199{0};

◆ m_minADCHG

float ZDCPulseAnalyzer::m_minADCHG {}
private

Definition at line 307 of file ZDCPulseAnalyzer.h.

307{};

◆ m_minADCLG

float ZDCPulseAnalyzer::m_minADCLG {}
private

Definition at line 313 of file ZDCPulseAnalyzer.h.

313{};

◆ m_minADCSampleHG

int ZDCPulseAnalyzer::m_minADCSampleHG
private

Definition at line 309 of file ZDCPulseAnalyzer.h.

◆ m_minADCSampleLG

int ZDCPulseAnalyzer::m_minADCSampleLG
private

Definition at line 314 of file ZDCPulseAnalyzer.h.

◆ m_minDelta

float ZDCPulseAnalyzer::m_minDelta {}
private

Definition at line 321 of file ZDCPulseAnalyzer.h.

321{};

◆ m_minDeriv2nd

float ZDCPulseAnalyzer::m_minDeriv2nd {}
private

Definition at line 324 of file ZDCPulseAnalyzer.h.

324{};

◆ m_minDeriv2ndIndex

int ZDCPulseAnalyzer::m_minDeriv2ndIndex {}
private

Definition at line 325 of file ZDCPulseAnalyzer.h.

325{};

◆ m_minDeriv2ndSig

float ZDCPulseAnalyzer::m_minDeriv2ndSig
private

Definition at line 332 of file ZDCPulseAnalyzer.h.

◆ m_minSampleEvt

unsigned int ZDCPulseAnalyzer::m_minSampleEvt {}
private

Definition at line 249 of file ZDCPulseAnalyzer.h.

249{};

◆ m_msgFunc_p

ZDCMsg::MessageFunctionPtr ZDCPulseAnalyzer::m_msgFunc_p {}
private

Definition at line 88 of file ZDCPulseAnalyzer.h.

88{};

◆ m_noiseSigHG

float ZDCPulseAnalyzer::m_noiseSigHG {}
private

Definition at line 122 of file ZDCPulseAnalyzer.h.

122{};

◆ m_noiseSigLG

float ZDCPulseAnalyzer::m_noiseSigLG {}
private

Definition at line 123 of file ZDCPulseAnalyzer.h.

123{};

◆ m_nominalT0HG

float ZDCPulseAnalyzer::m_nominalT0HG {}
private

Definition at line 137 of file ZDCPulseAnalyzer.h.

137{};

◆ m_nominalT0LG

float ZDCPulseAnalyzer::m_nominalT0LG {}
private

Definition at line 138 of file ZDCPulseAnalyzer.h.

138{};

◆ m_nominalTau1

float ZDCPulseAnalyzer::m_nominalTau1 {}
private

Definition at line 140 of file ZDCPulseAnalyzer.h.

140{};

◆ m_nominalTau2

float ZDCPulseAnalyzer::m_nominalTau2 {}
private

Definition at line 141 of file ZDCPulseAnalyzer.h.

141{};

◆ m_nonLinCorrParamsHG

std::vector<float> ZDCPulseAnalyzer::m_nonLinCorrParamsHG {}
private

Definition at line 225 of file ZDCPulseAnalyzer.h.

225{};

◆ m_nonLinCorrParamsLG

std::vector<float> ZDCPulseAnalyzer::m_nonLinCorrParamsLG {}
private

Definition at line 226 of file ZDCPulseAnalyzer.h.

226{};

◆ m_nonLinCorrRefADC

float ZDCPulseAnalyzer::m_nonLinCorrRefADC {500}
private

Definition at line 223 of file ZDCPulseAnalyzer.h.

223{500};

◆ m_nonLinCorrRefScale

float ZDCPulseAnalyzer::m_nonLinCorrRefScale {100}
private

Definition at line 224 of file ZDCPulseAnalyzer.h.

224{100};

◆ m_Nsample

unsigned int ZDCPulseAnalyzer::m_Nsample {}
private

Definition at line 90 of file ZDCPulseAnalyzer.h.

90{};

◆ m_NSamplesAna

unsigned int ZDCPulseAnalyzer::m_NSamplesAna {0}
private

Definition at line 383 of file ZDCPulseAnalyzer.h.

383{0};

◆ m_peak2ndDerivMinRepassHG

float ZDCPulseAnalyzer::m_peak2ndDerivMinRepassHG {}
private

Definition at line 113 of file ZDCPulseAnalyzer.h.

113{};

◆ m_peak2ndDerivMinRepassLG

float ZDCPulseAnalyzer::m_peak2ndDerivMinRepassLG {}
private

Definition at line 112 of file ZDCPulseAnalyzer.h.

112{};

◆ m_peak2ndDerivMinSample

size_t ZDCPulseAnalyzer::m_peak2ndDerivMinSample {}
private

Definition at line 104 of file ZDCPulseAnalyzer.h.

104{};

◆ m_peak2ndDerivMinThreshHG

float ZDCPulseAnalyzer::m_peak2ndDerivMinThreshHG {}
private

Definition at line 107 of file ZDCPulseAnalyzer.h.

107{};

◆ m_peak2ndDerivMinThreshLG

float ZDCPulseAnalyzer::m_peak2ndDerivMinThreshLG {}
private

Definition at line 106 of file ZDCPulseAnalyzer.h.

106{};

◆ m_peak2ndDerivMinTolerance

size_t ZDCPulseAnalyzer::m_peak2ndDerivMinTolerance {1}
private

Definition at line 105 of file ZDCPulseAnalyzer.h.

105{1};

◆ m_pedestal

int ZDCPulseAnalyzer::m_pedestal {}
private

Definition at line 94 of file ZDCPulseAnalyzer.h.

94{};

◆ m_postAmplitude

float ZDCPulseAnalyzer::m_postAmplitude {}
private

Definition at line 363 of file ZDCPulseAnalyzer.h.

363{};

◆ m_postExclHGADCThresh

unsigned int ZDCPulseAnalyzer::m_postExclHGADCThresh {0}
private

Definition at line 204 of file ZDCPulseAnalyzer.h.

204{0};

◆ m_postExclLGADCThresh

unsigned int ZDCPulseAnalyzer::m_postExclLGADCThresh {0}
private

Definition at line 205 of file ZDCPulseAnalyzer.h.

205{0};

◆ m_postPulse

bool ZDCPulseAnalyzer::m_postPulse {false}
private

Definition at line 282 of file ZDCPulseAnalyzer.h.

282{false};

◆ m_postPulseAbsDer2ndMinSig

float ZDCPulseAnalyzer::m_postPulseAbsDer2ndMinSig {}
private

Definition at line 191 of file ZDCPulseAnalyzer.h.

191{};

◆ m_postPulseDelta

unsigned int ZDCPulseAnalyzer::m_postPulseDelta {0}
private

Definition at line 189 of file ZDCPulseAnalyzer.h.

189{0};

◆ m_postPulseDerivMinSig

float ZDCPulseAnalyzer::m_postPulseDerivMinSig {}
private

Definition at line 190 of file ZDCPulseAnalyzer.h.

190{};

◆ m_postPulseMainMinDer2ndRatio

float ZDCPulseAnalyzer::m_postPulseMainMinDer2ndRatio {}
private

Definition at line 192 of file ZDCPulseAnalyzer.h.

192{};

◆ m_preAmplitude

float ZDCPulseAnalyzer::m_preAmplitude {}
private

Definition at line 362 of file ZDCPulseAnalyzer.h.

362{};

◆ m_preExclHGADCThresh

unsigned int ZDCPulseAnalyzer::m_preExclHGADCThresh {0}
private

Definition at line 200 of file ZDCPulseAnalyzer.h.

200{0};

◆ m_preExclLGADCThresh

unsigned int ZDCPulseAnalyzer::m_preExclLGADCThresh {0}
private

Definition at line 201 of file ZDCPulseAnalyzer.h.

201{0};

◆ m_preExpFitWrapper

std::unique_ptr<ZDCPreExpFitWrapper> ZDCPulseAnalyzer::m_preExpFitWrapper {}
private

Definition at line 243 of file ZDCPulseAnalyzer.h.

243{};

◆ m_preExpSig

float ZDCPulseAnalyzer::m_preExpSig
private

Definition at line 333 of file ZDCPulseAnalyzer.h.

◆ m_preExpTail

bool ZDCPulseAnalyzer::m_preExpTail {false}
private

Definition at line 289 of file ZDCPulseAnalyzer.h.

289{false};

◆ m_prePulse

bool ZDCPulseAnalyzer::m_prePulse {false}
private

Definition at line 281 of file ZDCPulseAnalyzer.h.

281{false};

◆ m_prePulseCombinedFitter

std::unique_ptr<TFitter> ZDCPulseAnalyzer::m_prePulseCombinedFitter {}
private

Definition at line 260 of file ZDCPulseAnalyzer.h.

260{};

◆ m_prePulseDelta

unsigned int ZDCPulseAnalyzer::m_prePulseDelta {0}
private

Definition at line 194 of file ZDCPulseAnalyzer.h.

194{0};

◆ m_prePulseFitWrapper

std::unique_ptr<ZDCPrePulseFitWrapper> ZDCPulseAnalyzer::m_prePulseFitWrapper {}
private

Definition at line 242 of file ZDCPulseAnalyzer.h.

242{};

◆ m_prePulseSig

float ZDCPulseAnalyzer::m_prePulseSig
private

Definition at line 334 of file ZDCPulseAnalyzer.h.

◆ m_preSample

float ZDCPulseAnalyzer::m_preSample {}
private

Definition at line 305 of file ZDCPulseAnalyzer.h.

305{};

◆ m_preSampleAmp

float ZDCPulseAnalyzer::m_preSampleAmp {}
private

Definition at line 361 of file ZDCPulseAnalyzer.h.

361{};

◆ m_preSampleIdx

unsigned int ZDCPulseAnalyzer::m_preSampleIdx {}
private

Definition at line 91 of file ZDCPulseAnalyzer.h.

91{};

◆ m_PSHGOverUnderflow

bool ZDCPulseAnalyzer::m_PSHGOverUnderflow {false}
private

Definition at line 277 of file ZDCPulseAnalyzer.h.

277{false};

◆ m_quietFits

bool ZDCPulseAnalyzer::m_quietFits {true}
private

Definition at line 99 of file ZDCPulseAnalyzer.h.

99{true};

◆ m_refitLGAmpError

float ZDCPulseAnalyzer::m_refitLGAmpError {0}
private

Definition at line 374 of file ZDCPulseAnalyzer.h.

374{0};

◆ m_refitLGAmpl

float ZDCPulseAnalyzer::m_refitLGAmpl {0}
private

Definition at line 371 of file ZDCPulseAnalyzer.h.

371{0};

◆ m_refitLGAmplCorr

float ZDCPulseAnalyzer::m_refitLGAmplCorr {0}
private

Definition at line 373 of file ZDCPulseAnalyzer.h.

373{0};

◆ m_refitLGChisq

float ZDCPulseAnalyzer::m_refitLGChisq {0}
private

Definition at line 375 of file ZDCPulseAnalyzer.h.

375{0};

◆ m_refitLGChisqRatio

float ZDCPulseAnalyzer::m_refitLGChisqRatio {0}
private

Definition at line 376 of file ZDCPulseAnalyzer.h.

376{0};

◆ m_refitLGFitAmpl

float ZDCPulseAnalyzer::m_refitLGFitAmpl {0}
private

Definition at line 372 of file ZDCPulseAnalyzer.h.

372{0};

◆ m_refitLGTime

float ZDCPulseAnalyzer::m_refitLGTime {0}
private

Definition at line 377 of file ZDCPulseAnalyzer.h.

377{0};

◆ m_refitLGTimeSub

float ZDCPulseAnalyzer::m_refitLGTimeSub {0}
private

Definition at line 378 of file ZDCPulseAnalyzer.h.

378{0};

◆ m_repassPulse

bool ZDCPulseAnalyzer::m_repassPulse {false}
private

Definition at line 293 of file ZDCPulseAnalyzer.h.

293{false};

◆ m_sampleNoiseHG

std::vector<float> ZDCPulseAnalyzer::m_sampleNoiseHG
private

Definition at line 388 of file ZDCPulseAnalyzer.h.

◆ m_sampleNoiseLG

std::vector<float> ZDCPulseAnalyzer::m_sampleNoiseLG
private

Definition at line 389 of file ZDCPulseAnalyzer.h.

◆ m_samplesDeriv2nd

std::vector<float> ZDCPulseAnalyzer::m_samplesDeriv2nd
private

Definition at line 403 of file ZDCPulseAnalyzer.h.

◆ m_samplesDeriv2ndErr

std::vector<float> ZDCPulseAnalyzer::m_samplesDeriv2ndErr
private

Definition at line 404 of file ZDCPulseAnalyzer.h.

◆ m_samplesLGRefit

std::vector<float> ZDCPulseAnalyzer::m_samplesLGRefit
private

Definition at line 400 of file ZDCPulseAnalyzer.h.

◆ m_samplesNoise

std::vector<float> ZDCPulseAnalyzer::m_samplesNoise
private

Definition at line 398 of file ZDCPulseAnalyzer.h.

◆ m_samplesNoiseLGRefit

std::vector<float> ZDCPulseAnalyzer::m_samplesNoiseLGRefit
private

Definition at line 401 of file ZDCPulseAnalyzer.h.

◆ m_samplesSub

std::vector<float> ZDCPulseAnalyzer::m_samplesSub
private

Definition at line 397 of file ZDCPulseAnalyzer.h.

◆ m_saveFitFunc

bool ZDCPulseAnalyzer::m_saveFitFunc {false}
private

Definition at line 100 of file ZDCPulseAnalyzer.h.

100{false};

◆ m_setPerSampleNoiseHG

std::vector<float> ZDCPulseAnalyzer::m_setPerSampleNoiseHG
private

Definition at line 127 of file ZDCPulseAnalyzer.h.

◆ m_setPerSampleNoiseLG

std::vector<float> ZDCPulseAnalyzer::m_setPerSampleNoiseLG
private

Definition at line 128 of file ZDCPulseAnalyzer.h.

◆ m_shapeParameters

std::vector<float> ZDCPulseAnalyzer::m_shapeParameters
private

Definition at line 368 of file ZDCPulseAnalyzer.h.

◆ m_sigMinHG

float ZDCPulseAnalyzer::m_sigMinHG {}
private

Definition at line 179 of file ZDCPulseAnalyzer.h.

179{}; // Minimum amplitude significance to be considered valid pulse

◆ m_sigMinLG

float ZDCPulseAnalyzer::m_sigMinLG {}
private

Definition at line 180 of file ZDCPulseAnalyzer.h.

180{}; // Minimum amplitude significance to be considered valid pulse

◆ m_T0CutHighHG

float ZDCPulseAnalyzer::m_T0CutHighHG {}
private

Definition at line 162 of file ZDCPulseAnalyzer.h.

162{}; // maximum good corrected time for HG fits

◆ m_T0CutHighLG

float ZDCPulseAnalyzer::m_T0CutHighLG {}
private

Definition at line 159 of file ZDCPulseAnalyzer.h.

159{}; // maximum good corrected time for LG fits

◆ m_T0CutLowHG

float ZDCPulseAnalyzer::m_T0CutLowHG {}
private

Definition at line 161 of file ZDCPulseAnalyzer.h.

161{}; // minimum good corrected time for HG fits

◆ m_T0CutLowLG

float ZDCPulseAnalyzer::m_T0CutLowLG {}
private

Definition at line 158 of file ZDCPulseAnalyzer.h.

158{}; // minimum good corrected time for LG fits

◆ m_t0CutSig

float ZDCPulseAnalyzer::m_t0CutSig {}
private

Definition at line 166 of file ZDCPulseAnalyzer.h.

166{};

◆ m_tag

std::string ZDCPulseAnalyzer::m_tag {}
private

Definition at line 89 of file ZDCPulseAnalyzer.h.

89{};

◆ m_timeCutMode

unsigned int ZDCPulseAnalyzer::m_timeCutMode {0}
private

Definition at line 167 of file ZDCPulseAnalyzer.h.

167{0}; // 0 - no significance cut, 1 - cut ORed with fixed cut, 2 - cut ANDed with fixed cut

◆ m_timeResFuncHG_p

std::unique_ptr<const TF1> ZDCPulseAnalyzer::m_timeResFuncHG_p {}
private

Definition at line 164 of file ZDCPulseAnalyzer.h.

164{};

◆ m_timeResFuncLG_p

std::unique_ptr<const TF1> ZDCPulseAnalyzer::m_timeResFuncLG_p {}
private

Definition at line 165 of file ZDCPulseAnalyzer.h.

165{};

◆ m_timeSig

float ZDCPulseAnalyzer::m_timeSig {}
private

Definition at line 346 of file ZDCPulseAnalyzer.h.

346{};

◆ m_timingCorrMode

unsigned int ZDCPulseAnalyzer::m_timingCorrMode {NoTimingCorr}
private

Definition at line 216 of file ZDCPulseAnalyzer.h.

◆ m_timingCorrRefADC

float ZDCPulseAnalyzer::m_timingCorrRefADC {500}
private

Definition at line 217 of file ZDCPulseAnalyzer.h.

217{500};

◆ m_timingCorrScale

float ZDCPulseAnalyzer::m_timingCorrScale {100}
private

Definition at line 218 of file ZDCPulseAnalyzer.h.

218{100};

◆ m_tmax

float ZDCPulseAnalyzer::m_tmax {}
private

Definition at line 97 of file ZDCPulseAnalyzer.h.

97{};

◆ m_tmin

float ZDCPulseAnalyzer::m_tmin {}
private

Definition at line 96 of file ZDCPulseAnalyzer.h.

96{};

◆ m_underFlowExclSamplesPostHG

unsigned int ZDCPulseAnalyzer::m_underFlowExclSamplesPostHG {0}
private

Definition at line 211 of file ZDCPulseAnalyzer.h.

211{0};

◆ m_underFlowExclSamplesPostLG

unsigned int ZDCPulseAnalyzer::m_underFlowExclSamplesPostLG {0}
private

Definition at line 213 of file ZDCPulseAnalyzer.h.

213{0};

◆ m_underFlowExclSamplesPreHG

unsigned int ZDCPulseAnalyzer::m_underFlowExclSamplesPreHG {0}
private

Definition at line 210 of file ZDCPulseAnalyzer.h.

210{0};

◆ m_underFlowExclSamplesPreLG

unsigned int ZDCPulseAnalyzer::m_underFlowExclSamplesPreLG {0}
private

Definition at line 212 of file ZDCPulseAnalyzer.h.

212{0};

◆ m_underflowExclusion

bool ZDCPulseAnalyzer::m_underflowExclusion {false}
private

Definition at line 295 of file ZDCPulseAnalyzer.h.

295{false};

◆ m_useDelayed

bool ZDCPulseAnalyzer::m_useDelayed {false}
private

Definition at line 109 of file ZDCPulseAnalyzer.h.

109{false};

◆ m_usedPresampIdx

int ZDCPulseAnalyzer::m_usedPresampIdx {}
private

Definition at line 304 of file ZDCPulseAnalyzer.h.

304{};

◆ m_useFixedBaseline

bool ZDCPulseAnalyzer::m_useFixedBaseline {}
private

Definition at line 254 of file ZDCPulseAnalyzer.h.

254{};

◆ m_useLowGain

bool ZDCPulseAnalyzer::m_useLowGain {false}
private

Definition at line 272 of file ZDCPulseAnalyzer.h.

272{false};

◆ m_useSampleHG

std::vector<bool> ZDCPulseAnalyzer::m_useSampleHG
private

Definition at line 392 of file ZDCPulseAnalyzer.h.

◆ m_useSampleLG

std::vector<bool> ZDCPulseAnalyzer::m_useSampleLG
private

Definition at line 391 of file ZDCPulseAnalyzer.h.

◆ s_combinedFitFunc

TF1 * ZDCPulseAnalyzer::s_combinedFitFunc = nullptr
staticprivate

Definition at line 81 of file ZDCPulseAnalyzer.h.

◆ s_combinedFitTMax

float ZDCPulseAnalyzer::s_combinedFitTMax = 1000
staticprivate

Definition at line 82 of file ZDCPulseAnalyzer.h.

◆ s_combinedFitTMin

float ZDCPulseAnalyzer::s_combinedFitTMin = -0.5
staticprivate

Definition at line 83 of file ZDCPulseAnalyzer.h.

◆ s_delayedFitHist

TH1 * ZDCPulseAnalyzer::s_delayedFitHist = nullptr
staticprivate

Definition at line 80 of file ZDCPulseAnalyzer.h.

◆ s_pullValues

std::vector< float > ZDCPulseAnalyzer::s_pullValues
staticprivate

Definition at line 84 of file ZDCPulseAnalyzer.h.

◆ s_undelayedFitHist

TH1 * ZDCPulseAnalyzer::s_undelayedFitHist = nullptr
staticprivate

Definition at line 79 of file ZDCPulseAnalyzer.h.


The documentation for this class was generated from the following files: