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_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< ZDCFitWrapperm_defaultFitWrapper {}
std::unique_ptr< ZDCPrePulseFitWrapperm_prePulseFitWrapper {}
std::unique_ptr< ZDCPreExpFitWrapperm_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 424 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 158 of file ZDCPulseAnalyzer.cxx.

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

◆ ZDCPulseAnalyzer() [2/2]

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

Definition at line 190 of file ZDCPulseAnalyzer.cxx.

190 :
191 m_msgFunc_p(std::move(msgFunc_p))
192{
193 setDefaults();
194
195 // auto [result, resultString] = ValidateJSONConfig(configJSON);
196 // (*m_msgFunc_p)(ZDCMsg::Debug, "ValidateJSON produced result: " + resultString);
197
198 auto [result2, resultString2] = ConfigFromJSON(configJSON);
199 (*m_msgFunc_p)(ZDCMsg::Debug, "ConfigFromJSON produced result: "+ resultString2);
200
202
203 // Create the histogram used for fitting
204 //
205 if (m_freqMHz >1.e-6) m_deltaTSample = 1000./m_freqMHz;
206 m_tmin = -m_deltaTSample / 2;
209
210 std::string histName = "ZDCFitHist" + m_tag;
211 std::string histNameLGRefit = "ZDCFitHist" + m_tag + "_LGRefit";
212
213 m_fitHist = std::make_unique<TH1F>(histName.c_str(), "", m_Nsample, m_tmin, m_tmax);
214 m_fitHistLGRefit = std::make_unique<TH1F>(histNameLGRefit.c_str(), "", m_Nsample, m_tmin, m_tmax);
215
216 m_fitHist->SetDirectory(0);
217 m_fitHistLGRefit->SetDirectory(0);
218
219 if(m_useDelayed) {
221 }
222
223 reset();
224}
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 515 of file ZDCPulseAnalyzer.h.

515{}

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 1294 of file ZDCPulseAnalyzer.cxx.

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

669{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 661 of file ZDCPulseAnalyzer.h.

661{return m_badChisq;}

◆ badT0()

bool ZDCPulseAnalyzer::badT0 ( ) const
inline

Definition at line 663 of file ZDCPulseAnalyzer.h.

663{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 2540 of file ZDCPulseAnalyzer.cxx.

2541{
2542 unsigned int nSamples = inputData.size();
2543
2544 // We start with two zero entries for which we can't calculate the double-step derivative
2545 // and would pad with two zero entries at the end. Start by initializing
2546 //
2547 unsigned int vecSize = 2*step + nSamples - step - 1;
2548 std::vector<float> results(vecSize, 0);
2549 std::vector<float> resultsErr(vecSize, 0);
2550
2551 unsigned int fillIndex = step;
2552 for (unsigned int sample = step; sample < nSamples - step; sample++) {
2553 float deriv2nd = inputData[sample + step] + inputData[sample - step] - 2*inputData[sample];
2554 float deriv2ndErr = std::sqrt(Sqr(inputNoise[sample + step]) + Sqr(inputNoise[sample - step]) + 2*Sqr(inputNoise[sample]));
2555
2556 results[fillIndex] = deriv2nd;
2557 resultsErr[fillIndex++] = deriv2ndErr;
2558 }
2559
2560 return {results, resultsErr};
2561}

◆ calculate2ndDerivative() [2/2]

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

Definition at line 2520 of file ZDCPulseAnalyzer.cxx.

2521{
2522 unsigned int nSamples = inputData.size();
2523
2524 // We start with two zero entries for which we can't calculate the double-step derivative
2525 // and would pad with two zero entries at the end. Start by initializing
2526 //
2527 unsigned int vecSize = 2*step + nSamples - step - 1;
2528 std::vector<float> results(vecSize, 0);
2529
2530 unsigned int fillIndex = step;
2531 for (unsigned int sample = step; sample < nSamples - step; sample++) {
2532 auto deriv2nd = inputData[sample + step] + inputData[sample - step] - 2*inputData[sample];
2533 results.at(fillIndex++) = deriv2nd;
2534 }
2535
2536 return results;
2537}

◆ calculateDerivative()

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

Definition at line 2499 of file ZDCPulseAnalyzer.cxx.

2500{
2501 unsigned int nSamples = inputData.size();
2502
2503 // 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
2504 //
2505 unsigned int vecSize = 2*(step - 1) + nSamples - step - 1;
2506 std::vector<float> results(vecSize, 0);
2507
2508 // Now fill out the values
2509 //
2510 unsigned int fillIdx = step - 1;
2511
2512 for (unsigned int sample = 0; sample < nSamples - step; sample++) {
2513 int deriv = inputData[sample + step] - inputData[sample];
2514 results.at(fillIdx++) = deriv;
2515 }
2516
2517 return results;
2518}

◆ checkTF1Limits()

void ZDCPulseAnalyzer::checkTF1Limits ( TF1 * func)
private

Definition at line 2178 of file ZDCPulseAnalyzer.cxx.

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

◆ CombinedPulsesFCN()

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

Definition at line 104 of file ZDCPulseAnalyzer.cxx.

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

2693{
2694 bool result = true;
2695 std::string resultString = "success";
2696
2697 for (auto [key, value] : config.items()) {
2698 //
2699 // Big if statement to process configuration parameters
2700 //
2701 if (key == "Nsample") m_Nsample = value;
2702 else if (key == "tag") m_tag = value;
2703 else if (key == "LGMode") m_LGMode = value;
2704 else if (key == "Nsample") m_Nsample = value;
2705 else if (key == "useDelayed") m_useDelayed = value;
2706 else if (key == "preSampleIdx") m_preSampleIdx = value;
2707 else if (key == "FADCFreqMHz") m_freqMHz = value;
2708 else if (key == "nominalPedestal") m_pedestal = value;
2709 else if (key == "fitFunction") m_fitFunction = value;
2710 else if (key == "peakSample") m_peak2ndDerivMinSample = value;
2711 else if (key == "peakTolerance") m_peak2ndDerivMinTolerance = value;
2712 else if (key == "2ndDerivThreshHG") m_peak2ndDerivMinThreshHG = value;
2713 else if (key == "2ndDerivThreshLG") m_peak2ndDerivMinThreshLG = value;
2714 else if (key == "2ndDerivStep") m_2ndDerivStep = value;
2715 else if (key == "HGOverflowADC") m_HGOverflowADC = value;
2716 else if (key == "HGUnderflowADC") m_HGUnderflowADC = value;
2717 else if (key == "LGOverflowADC") m_LGOverflowADC = value;
2718 else if (key == "nominalT0HG") m_nominalT0HG = value;
2719 else if (key == "nominalT0LG") m_nominalT0LG = value;
2720 else if (key == "nominalTau1") m_nominalTau1 = value;
2721 else if (key == "nominalTau2") m_nominalTau2 = value;
2722 else if (key == "fixTau1") m_fixTau1 = value;
2723 else if (key == "fixTau2") m_fixTau2 = value;
2724 else if (key == "T0CutsHG") {
2725 m_T0CutLowHG = value[0];
2726 m_T0CutHighHG = value[1];
2727 }
2728 else if (key == "T0CutsLG") {
2729 m_T0CutLowLG = value[0];
2730 m_T0CutHighLG = value[1];
2731 m_initializedFits = false;
2732 }
2733 else if (key == "chisqDivAmpCutHG") m_chisqDivAmpCutHG = value;
2734 else if (key == "chisqDivAmpCutLG") m_chisqDivAmpCutLG = value;
2735 else if (key == "chisqDivAmpOffsetHG") m_chisqDivAmpOffsetHG = value;
2736 else if (key == "chisqDivAmpScaleLG") m_chisqDivAmpScaleLG = value;
2737 else if (key == "chisqDivAmpScaleHG") m_chisqDivAmpScaleHG = value;
2738 else if (key == "chisqDivAmpOffsetLG") m_chisqDivAmpOffsetLG = value;
2739 else if (key == "chisqDivAmpPowerHG") m_chisqDivAmpPowerHG = value;
2740 else if (key == "chisqDivAmpPowerLG") m_chisqDivAmpPowerLG = value;
2741 else if (key == "gainFactorHG") m_gainFactorHG = value;
2742 else if (key == "gainFactorLG") m_gainFactorLG = value;
2743 else if (key == "noiseSigmaHG") m_noiseSigHG = value;
2744 else if (key == "noiseSigmaLG") m_noiseSigLG = value;
2745 else if (key == "perSampleNoiseSigmaHG") {
2748 }
2749 else if (key == "perSampleNoiseSigmaLG") {
2752 // m_setPerSampleNoiseLG.clear();
2753
2754 // for (auto elem : value) {
2755 // m_setPerSampleNoiseLG.push_back(elem);
2756 // }
2757 }
2758 else if (key == "fitTimeMax") {
2759 SetFitTimeMax(static_cast<float>(value));
2760 }
2761 else if (key == "enableRepass") m_enableRepass = value;
2762 else if (key == "Repass2ndDerivThreshHG") m_peak2ndDerivMinRepassHG = value;
2763 else if (key == "Repass2ndDerivThreshLG") m_peak2ndDerivMinRepassLG = value;
2764 else if (key == "fitAmpMinMaxHG") {
2765 m_fitAmpMinHG = value[0];
2766 m_fitAmpMaxHG = value[1];
2767 }
2768 else if (key == "fitAmpMinMaxLG") {
2769 m_fitAmpMinLG = value[0];
2770 m_fitAmpMaxLG = value[1];
2771 }
2772 else if (key == "quietFits") {
2774 }
2775 else if (key == "enablePreExclusion") {
2776 m_enablePreExcl = true;
2780 }
2781 else if (key == "enablePostExclusion") {
2782 m_enablePostExcl = true;
2786 }
2787 else if (key == "enableUnderflowExclusionHG") {
2791 }
2792 else if (key == "enableUnderflowExclusionLG") {
2796 }
2797 else if (key == "ampMinSignifHGLG") {
2798 m_haveSignifCuts = true;
2799 m_sigMinHG = value[0];
2800 m_sigMinLG = value[1];
2801 }
2802 else if (key == "enableFADCCorrections") {
2803 auto fileNameJson = value["filename"];
2804 auto doPerSampleCorrJson = value["doPerSampleCorr"];
2805
2806 if (fileNameJson.is_null() || doPerSampleCorrJson.is_null()) {
2807 result = false;
2808 resultString = "failure processing enableFADCCorrections object";
2809 break;
2810 }
2811
2812 m_haveFADCCorrections = true;
2813 m_FADCCorrPerSample = doPerSampleCorrJson;
2814 m_fadcCorrFileName = fileNameJson;
2815 }
2816 else if(key =="useDelayed"){
2817 if(value){
2818 m_useDelayed = true;
2819 }
2820 }
2821 else if (key == "delayDeltaT") m_delayedDeltaT = value;
2822 else if (key == "delayDefaultPedestalShift") m_delayedPedestalDiff = value;
2823 else if (key == "enableTimingCorrection") {
2827 }
2828 else if(key == "timeCorrCoeffHG"){
2829 for(int i = 0;auto coeff:value){
2830 m_HGT0CorrParams.at(i) = coeff;
2831 i++;
2832 }
2833 }
2834 else if(key == "timeCorrCoeffLG"){
2835 for(int i = 0;auto coeff:value){
2836 m_LGT0CorrParams.at(i) = coeff;
2837 i++;
2838 }
2839 }
2840 else if(key == "enableNLCorrection"){
2841 m_haveNonlinCorr = true;
2844 (*m_msgFunc_p)(
2845 ZDCMsg::Debug, ("Setting non-linear parameters"
2846 ", reference ADC = " + std::to_string(m_nonLinCorrRefADC) +
2847 ", reference scale = " + std::to_string(m_nonLinCorrRefScale)));
2848 }
2849 else if(key == "HGNLCorrCoeffs"){
2850 std::string HGParamsStr = "HG coefficients = ";
2851 for (auto coeff : value) {
2852 m_nonLinCorrParamsHG.push_back(coeff);
2853 HGParamsStr += std::to_string(m_nonLinCorrParamsHG.back()) + " ";
2854 }
2855 (*m_msgFunc_p)(ZDCMsg::Debug, std::move(HGParamsStr));
2856 }
2857 else if(key == "LGNLCorrCoeffs"){
2858 std::string LGParamsStr = "LG coefficients = ";
2859 for(auto coeff:value){
2860 m_nonLinCorrParamsLG.push_back(coeff);
2861 LGParamsStr += std::to_string(m_nonLinCorrParamsLG.back()) + " ";
2862 }
2863 (*m_msgFunc_p)(ZDCMsg::Debug, std::move(LGParamsStr));
2864 }
2865 else {
2866 result = false;
2867 resultString = "unprocessed parameter";
2868 break;
2869 }
2870 }
2871
2872 return {result, resultString};
2873}
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 634 of file ZDCPulseAnalyzer.h.

634{m_haveFADCCorrections = false;}

◆ disablePostPulseCheck()

void ZDCPulseAnalyzer::disablePostPulseCheck ( )
inline

Definition at line 591 of file ZDCPulseAnalyzer.h.

591{m_doPostPulseCheck = false;}

◆ DoAnalysis()

bool ZDCPulseAnalyzer::DoAnalysis ( bool repass)
private

Definition at line 1163 of file ZDCPulseAnalyzer.cxx.

1164{
1165 float deriv2ndThreshHG = 0;
1166 float deriv2ndThreshLG = 0;
1167
1168 if (!repass) {
1170
1171 deriv2ndThreshHG = m_peak2ndDerivMinThreshHG;
1172 deriv2ndThreshLG = m_peak2ndDerivMinThreshLG;
1173 }
1174 else {
1175 deriv2ndThreshHG = m_peak2ndDerivMinRepassHG;
1176 deriv2ndThreshLG = m_peak2ndDerivMinRepassLG;
1177 }
1178
1180 if (m_useLowGain) {
1181 // (*m_msgFunc_p)(ZDCMsg::Verbose, "ZDCPulseAnalyzer:: " + m_tag + " using low gain data ");
1182
1183 auto chisqCutLambda = [cut = m_chisqDivAmpCutLG,
1186 power = m_chisqDivAmpPowerLG]
1187 (float chisq, float amp, unsigned int fitNDoF, float& ratio)->bool
1188 {
1189 // Avoid a spurious FPE from clang.
1191 if (amp < 1e-6) return true;
1192 ratio = chisq /(scale* (std::pow(amp/1000 + offset, power)));
1193 if (chisq/fitNDoF > 2 && ratio > cut) return false;
1194 else return true;
1195 };
1196
1198 deriv2ndThreshLG, m_LGT0CorrParams, chisqCutLambda, m_T0CutLowLG, m_T0CutHighLG);
1199 if (result) {
1200 //
1201 // +++BAC
1202 //
1203 // I have removed some code that attempted a refit in case of failure of the chi-square cut
1204 // Instead, we should implement an analysis of the failure with possible re-fit afterwards
1205 // with possible change of the pre- or post-pulse condition
1206 //
1207 // --BAC
1208 //
1209
1210 double amplCorrFactor = getAmplitudeCorrection(false);
1211
1212 //
1213 // Multiply amplitude by gain factor
1214 //
1216 m_amplitude = m_fitAmplitude * amplCorrFactor * m_gainFactorLG;
1217 m_ampError = m_fitAmpError * amplCorrFactor * m_gainFactorLG;
1222
1223 // BAC: also scale up the 2nd derivative by the gain factor so low and high gain can be treated on the same footing
1224 //
1226 }
1227
1228 return result;
1229 }
1230 else {
1231 // (*m_msgFunc_p)(ZDCMsg::Verbose, "ZDCPulseAnalyzer:: " + m_tag + " using high gain data ");
1232 auto chisqCutLambda = [cut = m_chisqDivAmpCutHG,
1235 power = m_chisqDivAmpPowerHG, tag = m_tag]
1236 (float chisq, float amp, unsigned int fitNDoF, float& ratio)->bool
1237 {
1238 // Avoid a spurious FPE from clang.
1240 if (amp < 1e-6) return true;
1241 ratio = chisq /(scale*(std::pow(amp/1000 + offset, power)));
1242 if (chisq/float(fitNDoF) > 2 && ratio > cut) return false;
1243 else return true;
1244 };
1245
1247 deriv2ndThreshHG, m_HGT0CorrParams, chisqCutLambda, m_T0CutLowHG, m_T0CutHighHG);
1248 if (result) {
1249 // +++BAC
1250 //
1251 // I have removed some code that attempted a refit in case of failure of the chi-square cut
1252 // Instead, we should implement an analysis of the failure with possible re-fit afterwards
1253 // with possible change of the pre- or post-pulse condition
1254 //
1255 // --BAC
1256
1264
1266
1267 // If we have a non-linear correction, apply it here
1268 //
1269 // We apply it as an inverse correction - i.e. we divide by a correction
1270 // term tha is a sum of coefficients times the ADC minus a reference
1271 // to a power. The lowest power is 1, the highest is deteremined by
1272 // the number of provided coefficients
1273 //
1274 double amplCorrFactor = getAmplitudeCorrection(true);
1275
1276 m_amplitude *= amplCorrFactor;
1277 m_ampError *= amplCorrFactor;
1278 }
1279
1280 // If LG refit has been requested, do it now
1281 //
1284 DoFit(true);
1285
1286 double amplCorrFactor = getAmplitudeCorrection(false);
1287 m_refitLGAmplCorr = m_refitLGAmpl*amplCorrFactor;
1288 }
1289
1290 return result;
1291 }
1292}
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 1709 of file ZDCPulseAnalyzer.cxx.

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

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

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

◆ dumpConfiguration()

void ZDCPulseAnalyzer::dumpConfiguration ( ) const

Definition at line 2308 of file ZDCPulseAnalyzer.cxx.

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

◆ dumpTF1()

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

Definition at line 2289 of file ZDCPulseAnalyzer.cxx.

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

◆ enableDelayed()

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

Definition at line 226 of file ZDCPulseAnalyzer.cxx.

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

◆ enableFADCCorrections()

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

Definition at line 644 of file ZDCPulseAnalyzer.cxx.

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

541 {
542 m_enablePostExcl = true;
543 m_maxSamplesPostExcl = maxSamplesExcl;
544 m_postExclHGADCThresh = HGADCThresh;
545 m_postExclLGADCThresh = LGADCThresh;
546 }

◆ enablePostPulseCheck()

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

Definition at line 253 of file ZDCPulseAnalyzer.cxx.

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

◆ enablePreExclusion()

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

Definition at line 532 of file ZDCPulseAnalyzer.h.

533 {
534 m_enablePreExcl = true;
535 m_maxSamplesPreExcl = maxSamplesExcl;
536 m_preExclHGADCThresh = HGADCThresh;
537 m_preExclLGADCThresh = LGADCThresh;
538 }

◆ enableRepass()

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

Definition at line 246 of file ZDCPulseAnalyzer.cxx.

247{
248 m_enableRepass = true;
249 m_peak2ndDerivMinRepassHG = peak2ndDerivMinRepassHG;
250 m_peak2ndDerivMinRepassLG = peak2ndDerivMinRepassLG;
251}

◆ 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 615 of file ZDCPulseAnalyzer.cxx.

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

◆ excludeEarlyLG()

bool ZDCPulseAnalyzer::excludeEarlyLG ( ) const
inline

Definition at line 664 of file ZDCPulseAnalyzer.h.

664{return m_ExcludeEarly;}

◆ excludeLateLG()

bool ZDCPulseAnalyzer::excludeLateLG ( ) const
inline

Definition at line 665 of file ZDCPulseAnalyzer.h.

665{return m_ExcludeLate;}

◆ failed()

bool ZDCPulseAnalyzer::failed ( ) const
inline

Definition at line 650 of file ZDCPulseAnalyzer.h.

650{return m_fail;}

◆ failSigCut()

bool ZDCPulseAnalyzer::failSigCut ( ) const
inline

Definition at line 670 of file ZDCPulseAnalyzer.h.

670{return m_failSigCut;}

◆ FillHistogram()

void ZDCPulseAnalyzer::FillHistogram ( bool refitLG)
inlineprivate

Definition at line 450 of file ZDCPulseAnalyzer.h.

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

◆ fitFailed()

bool ZDCPulseAnalyzer::fitFailed ( ) const
inline

Definition at line 660 of file ZDCPulseAnalyzer.h.

660{return m_fitFailed;}

◆ fitMinimumAmplitude()

bool ZDCPulseAnalyzer::fitMinimumAmplitude ( ) const
inline

Definition at line 667 of file ZDCPulseAnalyzer.h.

667{return m_fitMinAmp;}

◆ getADCPeakHG()

float ZDCPulseAnalyzer::getADCPeakHG ( ) const
inline

Definition at line 766 of file ZDCPulseAnalyzer.h.

766{return m_ADCPeakHG;}

◆ getADCPeakLG()

float ZDCPulseAnalyzer::getADCPeakLG ( ) const
inline

Definition at line 767 of file ZDCPulseAnalyzer.h.

767{return m_ADCPeakLG;}

◆ GetAmpError()

float ZDCPulseAnalyzer::GetAmpError ( ) const
inline

Definition at line 697 of file ZDCPulseAnalyzer.h.

697{return m_ampError;}

◆ GetAmplitude()

float ZDCPulseAnalyzer::GetAmplitude ( ) const
inline

Definition at line 696 of file ZDCPulseAnalyzer.h.

696{return m_amplitude;}

◆ getAmplitudeCorrection()

double ZDCPulseAnalyzer::getAmplitudeCorrection ( bool highGain)
private

Definition at line 715 of file ZDCPulseAnalyzer.cxx.

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

◆ GetAmpNoNonLin()

float ZDCPulseAnalyzer::GetAmpNoNonLin ( ) const
inline

Definition at line 695 of file ZDCPulseAnalyzer.h.

695{return m_ampNoNonLin;}

◆ GetBkgdMaxFraction()

float ZDCPulseAnalyzer::GetBkgdMaxFraction ( ) const
inline

Definition at line 783 of file ZDCPulseAnalyzer.h.

783{return m_bkgdMaxFraction;}

◆ GetChisq()

float ZDCPulseAnalyzer::GetChisq ( ) const
inline

Definition at line 684 of file ZDCPulseAnalyzer.h.

684{return m_fitChisq;}

◆ GetChisqRatio()

float ZDCPulseAnalyzer::GetChisqRatio ( ) const
inline

Definition at line 685 of file ZDCPulseAnalyzer.h.

685{return m_chisqRatio;}

◆ GetCombinedGraph()

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

Definition at line 2428 of file ZDCPulseAnalyzer.cxx.

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

◆ GetdelayBS()

float ZDCPulseAnalyzer::GetdelayBS ( ) const
inline

Definition at line 775 of file ZDCPulseAnalyzer.h.

◆ GetDelayedBaselineCorr()

float ZDCPulseAnalyzer::GetDelayedBaselineCorr ( ) const
inline

Definition at line 786 of file ZDCPulseAnalyzer.h.

786{return m_baselineCorr;}

◆ GetDelayedBaselineShiftFit()

float ZDCPulseAnalyzer::GetDelayedBaselineShiftFit ( ) const
inline

Definition at line 785 of file ZDCPulseAnalyzer.h.

◆ GetFitAmplitude()

float ZDCPulseAnalyzer::GetFitAmplitude ( ) const
inline

Definition at line 679 of file ZDCPulseAnalyzer.h.

679{return m_fitAmplitude;}

◆ GetFitExpAmp()

float ZDCPulseAnalyzer::GetFitExpAmp ( ) const
inline

Definition at line 692 of file ZDCPulseAnalyzer.h.

692{return m_fitExpAmp;}

◆ GetFitPostAmp()

float ZDCPulseAnalyzer::GetFitPostAmp ( ) const
inline

Definition at line 691 of file ZDCPulseAnalyzer.h.

691{return m_postAmplitude;}

◆ GetFitPostT0()

float ZDCPulseAnalyzer::GetFitPostT0 ( ) const
inline

Definition at line 690 of file ZDCPulseAnalyzer.h.

690{return m_fitPostT0;}

◆ GetFitPreAmp()

float ZDCPulseAnalyzer::GetFitPreAmp ( ) const
inline

Definition at line 689 of file ZDCPulseAnalyzer.h.

689{return m_preAmplitude;}

◆ GetFitPreT0()

float ZDCPulseAnalyzer::GetFitPreT0 ( ) const
inline

Definition at line 688 of file ZDCPulseAnalyzer.h.

688{return m_fitPreT0;}

◆ GetFitPulls()

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

Definition at line 678 of file ZDCPulseAnalyzer.cxx.

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

◆ GetFitT0()

float ZDCPulseAnalyzer::GetFitT0 ( ) const
inline

Definition at line 680 of file ZDCPulseAnalyzer.h.

680{return m_fitTime;}

◆ GetFitTau1()

float ZDCPulseAnalyzer::GetFitTau1 ( ) const
inline

Definition at line 686 of file ZDCPulseAnalyzer.h.

686{return m_fitTau1;}

◆ GetFitTau2()

float ZDCPulseAnalyzer::GetFitTau2 ( ) const
inline

Definition at line 687 of file ZDCPulseAnalyzer.h.

687{return m_fitTau2;}

◆ GetFitTMax()

float ZDCPulseAnalyzer::GetFitTMax ( ) const
inline

Definition at line 772 of file ZDCPulseAnalyzer.h.

772{return m_fitTMax;}

◆ GetFitTMin()

float ZDCPulseAnalyzer::GetFitTMin ( ) const
inline

Definition at line 773 of file ZDCPulseAnalyzer.h.

773{return m_fitTMin;}

◆ GetGraph()

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

Definition at line 2473 of file ZDCPulseAnalyzer.cxx.

2474{
2475 //
2476 // We defer filling the histogram if we don't have a pulse until the histogram is requested
2477 //
2478 const TH1* hist_p = GetHistogramPtr(forceLG);
2479
2480 std::shared_ptr<TGraphErrors> theGraph = std::make_shared<TGraphErrors>(TGraphErrors(m_Nsample));
2481 size_t npts = 0;
2482
2483 for (int ipt = 0; ipt < hist_p->GetNbinsX(); ipt++) {
2484 theGraph->SetPoint(npts, hist_p->GetBinCenter(ipt + 1), hist_p->GetBinContent(ipt + 1));
2485 theGraph->SetPointError(npts++, 0, hist_p->GetBinError(ipt + 1));
2486 }
2487
2488 TF1* func_p = static_cast<TF1*>(hist_p->GetListOfFunctions()->Last());
2489 theGraph->GetListOfFunctions()->Add(func_p);
2490 theGraph->SetName(( std::string(hist_p->GetName()) + "not_combinaed").c_str());
2491
2492 theGraph->SetMarkerStyle(20);
2493 theGraph->SetMarkerColor(1);
2494
2495 return theGraph;
2496}

◆ GetHistogramPtr()

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

Definition at line 788 of file ZDCPulseAnalyzer.h.

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

◆ getLGMode()

unsigned int ZDCPulseAnalyzer::getLGMode ( ) const
inline

Definition at line 562 of file ZDCPulseAnalyzer.h.

562{return m_LGMode;}

◆ getMaxADCHG()

float ZDCPulseAnalyzer::getMaxADCHG ( ) const
inline

Definition at line 745 of file ZDCPulseAnalyzer.h.

745{return m_maxADCHG;}

◆ getMaxADCLG()

float ZDCPulseAnalyzer::getMaxADCLG ( ) const
inline

Definition at line 746 of file ZDCPulseAnalyzer.h.

746{return m_maxADCLG;}

◆ getMaxADCSampleHG()

int ZDCPulseAnalyzer::getMaxADCSampleHG ( ) const
inline

Definition at line 760 of file ZDCPulseAnalyzer.h.

◆ getMaxADCSampleLG()

int ZDCPulseAnalyzer::getMaxADCSampleLG ( ) const
inline

Definition at line 763 of file ZDCPulseAnalyzer.h.

◆ getMaxADCSub()

float ZDCPulseAnalyzer::getMaxADCSub ( ) const
inline

Definition at line 750 of file ZDCPulseAnalyzer.h.

750 {
751 float maxADCNosub = m_useLowGain ? m_maxADCLG : m_maxADCHG;
752 return maxADCNosub - m_pedestal - m_preSample;
753 }

◆ GetMaxDelta()

float ZDCPulseAnalyzer::GetMaxDelta ( ) const
inline

Definition at line 769 of file ZDCPulseAnalyzer.h.

769{return m_maxDelta;}

◆ getMinADCHG()

float ZDCPulseAnalyzer::getMinADCHG ( ) const
inline

Definition at line 747 of file ZDCPulseAnalyzer.h.

747{return m_minADCHG;}

◆ getMinADCLG()

float ZDCPulseAnalyzer::getMinADCLG ( ) const
inline

Definition at line 748 of file ZDCPulseAnalyzer.h.

748{return m_minADCLG;}

◆ getMinADCSampleHG()

int ZDCPulseAnalyzer::getMinADCSampleHG ( ) const
inline

Definition at line 761 of file ZDCPulseAnalyzer.h.

◆ getMinADCSampleLG()

int ZDCPulseAnalyzer::getMinADCSampleLG ( ) const
inline

Definition at line 764 of file ZDCPulseAnalyzer.h.

◆ getMinADCSub()

float ZDCPulseAnalyzer::getMinADCSub ( ) const
inline

Definition at line 755 of file ZDCPulseAnalyzer.h.

755 {
756 float minADCNosub = m_useLowGain ? m_minADCLG : m_minADCHG;
757 return minADCNosub - m_pedestal - m_preSample;
758 }

◆ GetMinDelta()

float ZDCPulseAnalyzer::GetMinDelta ( ) const
inline

Definition at line 770 of file ZDCPulseAnalyzer.h.

770{return m_minDelta;}

◆ GetMinDeriv2nd()

float ZDCPulseAnalyzer::GetMinDeriv2nd ( ) const
inline

Definition at line 777 of file ZDCPulseAnalyzer.h.

777{return m_minDeriv2nd;}

◆ GetMinDeriv2ndIndex()

float ZDCPulseAnalyzer::GetMinDeriv2ndIndex ( ) const
inline

Definition at line 778 of file ZDCPulseAnalyzer.h.

778{return m_minDeriv2ndIndex;}

◆ GetPreExpAmp()

float ZDCPulseAnalyzer::GetPreExpAmp ( ) const
inline

Definition at line 698 of file ZDCPulseAnalyzer.h.

698{return m_expAmplitude;}

◆ getPresample()

float ZDCPulseAnalyzer::getPresample ( ) const
inline

Definition at line 744 of file ZDCPulseAnalyzer.h.

744{return m_preSample;}

◆ GetPreSampleAmp()

float ZDCPulseAnalyzer::GetPreSampleAmp ( ) const
inline

Definition at line 782 of file ZDCPulseAnalyzer.h.

782{return m_preSampleAmp;}

◆ getRefitLGAmp()

float ZDCPulseAnalyzer::getRefitLGAmp ( ) const
inline

Definition at line 702 of file ZDCPulseAnalyzer.h.

703 {
704 if (m_evtLGRefit) return m_refitLGAmpl;
705 else return 0;
706 }

◆ getRefitLGAmpCorr()

float ZDCPulseAnalyzer::getRefitLGAmpCorr ( ) const
inline

Definition at line 714 of file ZDCPulseAnalyzer.h.

715 {
717 else return 0;
718 }

◆ getRefitLGChisq()

float ZDCPulseAnalyzer::getRefitLGChisq ( ) const
inline

Definition at line 720 of file ZDCPulseAnalyzer.h.

721 {
722 if (m_evtLGRefit) return m_refitLGChisq;
723 else return 0;
724 }

◆ getRefitLGChisqRatio()

float ZDCPulseAnalyzer::getRefitLGChisqRatio ( ) const
inline

Definition at line 726 of file ZDCPulseAnalyzer.h.

727 {
729 else return 0;
730 }

◆ getRefitLGFitAmp()

float ZDCPulseAnalyzer::getRefitLGFitAmp ( ) const
inline

Definition at line 708 of file ZDCPulseAnalyzer.h.

709 {
710 if (m_evtLGRefit) return m_refitLGFitAmpl;
711 else return 0;
712 }

◆ getRefitLGTime()

float ZDCPulseAnalyzer::getRefitLGTime ( ) const
inline

Definition at line 732 of file ZDCPulseAnalyzer.h.

733 {
734 if (m_evtLGRefit) return m_refitLGTime;
735 else return 0;
736 }

◆ getRefitLGTimeSub()

float ZDCPulseAnalyzer::getRefitLGTimeSub ( ) const
inline

Definition at line 738 of file ZDCPulseAnalyzer.h.

739 {
740 if (m_evtLGRefit) return m_refitLGTimeSub;
741 else return 0;
742 }

◆ GetSamplesDeriv2nd()

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

Definition at line 810 of file ZDCPulseAnalyzer.h.

810{return m_samplesDeriv2nd;}

◆ GetSamplesSub()

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

Definition at line 809 of file ZDCPulseAnalyzer.h.

809{return m_samplesSub;}

◆ GetShapeParameters()

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

Definition at line 700 of file ZDCPulseAnalyzer.h.

700{return m_shapeParameters;}

◆ GetStatusMask()

unsigned int ZDCPulseAnalyzer::GetStatusMask ( ) const

Definition at line 2396 of file ZDCPulseAnalyzer.cxx.

2397{
2398 unsigned int statusMask = 0;
2399
2400 if (havePulse()) statusMask |= 1 << PulseBit;
2401 if (useLowGain()) statusMask |= 1 << LowGainBit;
2402 if (failed()) statusMask |= 1 << FailBit;
2403 if (HGOverflow()) statusMask |= 1 << HGOverflowBit;
2404
2405 if (HGUnderflow()) statusMask |= 1 << HGUnderflowBit;
2406 if (PSHGOverUnderflow()) statusMask |= 1 << PSHGOverUnderflowBit;
2407 if (LGOverflow()) statusMask |= 1 << LGOverflowBit;
2408 if (LGUnderflow()) statusMask |= 1 << LGUnderflowBit;
2409
2410 if (prePulse()) statusMask |= 1 << PrePulseBit;
2411 if (postPulse()) statusMask |= 1 << PostPulseBit;
2412 if (fitFailed()) statusMask |= 1 << FitFailedBit;
2413 if (badChisq()) statusMask |= 1 << BadChisqBit;
2414
2415 if (badT0()) statusMask |= 1 << BadT0Bit;
2416 if (excludeEarlyLG()) statusMask |= 1 << ExcludeEarlyLGBit;
2417 if (excludeLateLG()) statusMask |= 1 << ExcludeLateLGBit;
2418 if (preExpTail()) statusMask |= 1 << preExpTailBit;
2419 if (fitMinimumAmplitude()) statusMask |= 1 << FitMinAmpBit;
2420 if (repassPulse()) statusMask |= 1 << RepassPulseBit;
2421 if (armSumInclude()) statusMask |= 1 << ArmSumIncludeBit;
2422 if (failSigCut()) statusMask |= 1 << FailSigCutBit;
2423 if (underflowExclusion()) statusMask |= 1<<UnderFlowExclusionBit;
2424
2425 return statusMask;
2426}
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 682 of file ZDCPulseAnalyzer.h.

682{return m_fitTimeCorr;}

◆ GetT0Sub()

float ZDCPulseAnalyzer::GetT0Sub ( ) const
inline

Definition at line 681 of file ZDCPulseAnalyzer.h.

681{return m_fitTimeSub;}

◆ getTimeSig()

float ZDCPulseAnalyzer::getTimeSig ( ) const
inline

Definition at line 683 of file ZDCPulseAnalyzer.h.

683{return m_timeSig;}

◆ HaveData()

bool ZDCPulseAnalyzer::HaveData ( ) const
inline

Definition at line 643 of file ZDCPulseAnalyzer.h.

643{return m_haveData;}

◆ havePulse()

bool ZDCPulseAnalyzer::havePulse ( ) const
inline

Definition at line 648 of file ZDCPulseAnalyzer.h.

648{return m_havePulse;}

◆ HGOverflow()

bool ZDCPulseAnalyzer::HGOverflow ( ) const
inline

Definition at line 651 of file ZDCPulseAnalyzer.h.

651{return m_HGOverflow;}

◆ HGUnderflow()

bool ZDCPulseAnalyzer::HGUnderflow ( ) const
inline

Definition at line 653 of file ZDCPulseAnalyzer.h.

653{return m_HGUnderflow;}

◆ initialize()

void ZDCPulseAnalyzer::initialize ( )
private

Definition at line 345 of file ZDCPulseAnalyzer.cxx.

346{
348
355
356 m_initialized = true;
357}
std::vector< float > m_ADCSSampNoiseLG
std::vector< float > m_ADCSSampNoiseHG

◆ LGOverflow()

bool ZDCPulseAnalyzer::LGOverflow ( ) const
inline

Definition at line 655 of file ZDCPulseAnalyzer.h.

655{return m_LGOverflow;}

◆ LGUnderflow()

bool ZDCPulseAnalyzer::LGUnderflow ( ) const
inline

Definition at line 656 of file ZDCPulseAnalyzer.h.

656{return m_LGUnderflow;}

◆ LoadAndAnalyzeData() [1/2]

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

Definition at line 860 of file ZDCPulseAnalyzer.cxx.

861{
862 if (m_useDelayed) {
863 (*m_msgFunc_p)(ZDCMsg::Fatal, "ZDCPulseAnalyzer::LoadAndAnalyzeData:: Wrong LoadAndAnalyzeData called -- expecting both delayed and undelayed samples");
864 }
865
868
869 // Clear any transient data
870 //
871 reset(false);
872
873 // Make sure we have the right number of samples. Should never fail. necessry?
874 //
875 if (ADCSamplesHG.size() != m_Nsample || ADCSamplesLG.size() != m_Nsample) {
876 m_fail = true;
877 return false;
878 }
879
880 m_ADCSamplesHG = ADCSamplesHG;
881 m_ADCSamplesLG = ADCSamplesLG;
882
883 return DoAnalysis(false);
884}
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 886 of file ZDCPulseAnalyzer.cxx.

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

◆ MakeCombinedFitter()

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

Definition at line 2206 of file ZDCPulseAnalyzer.cxx.

2207{
2208 TVirtualFitter::SetDefaultFitter("Minuit");
2209
2210 size_t nFitParams = func->GetNpar() + 1;
2211 std::unique_ptr<TFitter> fitter = std::make_unique<TFitter>(nFitParams);
2212
2213 fitter->GetMinuit()->fISW[4] = -1;
2214 fitter->SetParameter(0, "delayBaselineAdjust", 0, 0.01, -100, 100);
2215
2216 for (size_t ipar = 0; ipar < nFitParams - 1; ipar++) {
2217 double parLimitLow, parLimitHigh;
2218
2219 func->GetParLimits(ipar, parLimitLow, parLimitHigh);
2220 if (std::abs(parLimitHigh - parLimitLow) < (1e-6)*std::abs(parLimitLow)) {
2221 double value = func->GetParameter(ipar);
2222 double lowLim = std::min(value * 0.99, value * 1.01);
2223 double highLim = std::max(value * 0.99, value * 1.01);
2224
2225 fitter->SetParameter(ipar + 1, func->GetParName(ipar), func->GetParameter(ipar), 0.01, lowLim, highLim);
2226 fitter->FixParameter(ipar + 1);
2227 }
2228 else {
2229 double value = func->GetParameter(ipar);
2230 if (value >= parLimitHigh) value = parLimitHigh * 0.99;
2231 else if (value <= parLimitLow) value = parLimitLow * 1.01;
2232
2233 double step = std::min((parLimitHigh - parLimitLow)/100., (value - parLimitLow)/100.);
2234
2235 fitter->SetParameter(ipar + 1, func->GetParName(ipar), value, step, parLimitLow, parLimitHigh);
2236 }
2237 }
2238
2240
2241 return fitter;
2242}
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 2576 of file ZDCPulseAnalyzer.cxx.

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

◆ postPulse()

bool ZDCPulseAnalyzer::postPulse ( ) const
inline

Definition at line 659 of file ZDCPulseAnalyzer.h.

659{return m_postPulse;}

◆ preExpTail()

bool ZDCPulseAnalyzer::preExpTail ( ) const
inline

Definition at line 666 of file ZDCPulseAnalyzer.h.

666{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 1686 of file ZDCPulseAnalyzer.cxx.

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

◆ prePulse()

bool ZDCPulseAnalyzer::prePulse ( ) const
inline

Definition at line 658 of file ZDCPulseAnalyzer.h.

658{return m_prePulse;}

◆ PSHGOverUnderflow()

bool ZDCPulseAnalyzer::PSHGOverUnderflow ( ) const
inline

Definition at line 654 of file ZDCPulseAnalyzer.h.

◆ quietFits()

bool ZDCPulseAnalyzer::quietFits ( ) const
inline

Definition at line 520 of file ZDCPulseAnalyzer.h.

520{return m_quietFits;}

◆ ReanalyzeData()

bool ZDCPulseAnalyzer::ReanalyzeData ( )

Definition at line 943 of file ZDCPulseAnalyzer.cxx.

944{
945 reset(true);
946
947 bool result = DoAnalysis(true);
948 if (result && havePulse()) {
949 m_repassPulse = true;
950 }
951
952 return result;
953}

◆ repassPulse()

bool ZDCPulseAnalyzer::repassPulse ( ) const
inline

Definition at line 668 of file ZDCPulseAnalyzer.h.

668{return m_repassPulse;}

◆ reset()

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

Definition at line 359 of file ZDCPulseAnalyzer.cxx.

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

◆ saveFitFunc()

void ZDCPulseAnalyzer::saveFitFunc ( bool save)
inline

Definition at line 518 of file ZDCPulseAnalyzer.h.

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

◆ ScanAndSubtractSamples()

bool ZDCPulseAnalyzer::ScanAndSubtractSamples ( )
private

Definition at line 955 of file ZDCPulseAnalyzer.cxx.

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

◆ set2ndDerivStep()

void ZDCPulseAnalyzer::set2ndDerivStep ( size_t step)
inline

Definition at line 564 of file ZDCPulseAnalyzer.h.

◆ SetADCOverUnderflowValues()

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

Definition at line 561 of file ZDCPulseAnalyzer.cxx.

562{
563 m_HGOverflowADC = HGOverflowADC;
564 m_LGOverflowADC = LGOverflowADC;
565 m_HGUnderflowADC = HGUnderflowADC;
566}

◆ SetChisqCuts()

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

Definition at line 601 of file ZDCPulseAnalyzer.cxx.

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

◆ SetCutValues()

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

Definition at line 568 of file ZDCPulseAnalyzer.cxx.

571{
572 m_chisqDivAmpCutHG = chisqDivAmpCutHG;
573 m_chisqDivAmpCutLG = chisqDivAmpCutLG;
574
577
580
583
584 m_T0CutLowHG = deltaT0MinHG;
585 m_T0CutLowLG = deltaT0MinLG;
586
587 m_T0CutHighHG = deltaT0MaxHG;
588 m_T0CutHighLG = deltaT0MaxLG;
589}

◆ setDefaults()

void ZDCPulseAnalyzer::setDefaults ( )
private

Definition at line 262 of file ZDCPulseAnalyzer.cxx.

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

◆ SetFitMinMaxAmp()

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

Definition at line 522 of file ZDCPulseAnalyzer.cxx.

523{
524 m_fitAmpMinHG = minAmpHG;
525 m_fitAmpMinLG = minAmpLG;
526
527 m_fitAmpMaxHG = maxAmpHG;
528 m_fitAmpMaxLG = maxAmpLG;
529}

◆ setFitOPtions()

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

Definition at line 517 of file ZDCPulseAnalyzer.h.

517{ m_fitOptions = fitOptions;}

◆ SetFitTimeMax()

void ZDCPulseAnalyzer::SetFitTimeMax ( float tmax)

Definition at line 549 of file ZDCPulseAnalyzer.cxx.

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

◆ SetGainFactorsHGLG()

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

Definition at line 516 of file ZDCPulseAnalyzer.cxx.

517{
518 m_gainFactorHG = gainFactorHG;
519 m_gainFactorLG = gainFactorLG;
520}

◆ setLGMode()

void ZDCPulseAnalyzer::setLGMode ( unsigned int mode)
inline

Definition at line 561 of file ZDCPulseAnalyzer.h.

◆ setMinimumSignificance()

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

Definition at line 509 of file ZDCPulseAnalyzer.cxx.

510{
511 m_haveSignifCuts = true;
512 m_sigMinHG = sigMinHG;
513 m_sigMinLG = sigMinLG;
514}

◆ SetNoiseSigmas()

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

Definition at line 576 of file ZDCPulseAnalyzer.h.

577 {
578 m_noiseSigHG = noiseSigHG;
579 m_noiseSigLG = noiseSigLG;
580 }

◆ SetNonlinCorrParams()

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

Definition at line 610 of file ZDCPulseAnalyzer.h.

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

◆ SetPeak2ndDerivMinTolerance()

void ZDCPulseAnalyzer::SetPeak2ndDerivMinTolerance ( size_t tolerance)
inline

Definition at line 548 of file ZDCPulseAnalyzer.h.

548 {
550 m_initializedFits = false;
551 }
constexpr double tolerance

◆ setPerSampleNoiseSigmas()

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

Definition at line 553 of file ZDCPulseAnalyzer.h.

554 {
555 m_setPerSampleNoiseHG = sigmaHG;
556 m_setPerSampleNoiseLG = sigmaLG;
559 }

◆ setQuietFits()

void ZDCPulseAnalyzer::setQuietFits ( )
inline

Definition at line 521 of file ZDCPulseAnalyzer.h.

521{m_quietFits = true;}

◆ SetTauT0Values()

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

Definition at line 531 of file ZDCPulseAnalyzer.cxx.

532{
533 m_fixTau1 = fixTau1;
534 m_fixTau2 = fixTau2;
535 m_nominalTau1 = tau1;
536 m_nominalTau2 = tau2;
537
538 m_nominalT0HG = t0HG;
539 m_nominalT0LG = t0LG;
540
541 std::ostringstream ostrm;
542 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;
543
544 (*m_msgFunc_p)(ZDCMsg::Info, ostrm.str());
545
546 m_initializedFits = false;
547}

◆ SetTimeCuts()

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

Definition at line 591 of file ZDCPulseAnalyzer.cxx.

593{
594 m_T0CutLowHG = deltaT0MinHG;
595 m_T0CutLowLG = deltaT0MinLG;
596
597 m_T0CutHighHG = deltaT0MaxHG;
598 m_T0CutHighLG = deltaT0MaxLG;
599}

◆ SetTimingCorrParams()

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

Definition at line 595 of file ZDCPulseAnalyzer.h.

597 {
599 if (mode != NoTimingCorr) {
600 m_timingCorrRefADC = refADC;
601 m_timingCorrScale = refScale;
602
603 m_HGT0CorrParams = HGT0CorrParams;
604 m_LGT0CorrParams = LGT0CorrParams;
605 }
606 }

◆ setUnquietFits()

void ZDCPulseAnalyzer::setUnquietFits ( )
inline

Definition at line 522 of file ZDCPulseAnalyzer.h.

522{m_quietFits = false;}

◆ SetupFitFunctions()

void ZDCPulseAnalyzer::SetupFitFunctions ( )
private

Definition at line 755 of file ZDCPulseAnalyzer.cxx.

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

◆ underflowExclusion()

bool ZDCPulseAnalyzer::underflowExclusion ( ) const
inline

Definition at line 671 of file ZDCPulseAnalyzer.h.

671{return m_underflowExclusion;}

◆ UpdateFitterTimeLimits()

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

Definition at line 2244 of file ZDCPulseAnalyzer.cxx.

2245{
2246 double parLimitLow, parLimitHigh;
2247
2248 auto func_p = wrapper->GetWrapperTF1();
2249 func_p->GetParLimits(1, parLimitLow, parLimitHigh);
2250
2251 fitter->SetParameter(2, func_p->GetParName(1), func_p->GetParameter(1), 0.01, parLimitLow, parLimitHigh);
2252
2253 if (prePulse) {
2254 unsigned int parIndex = static_cast<ZDCPrePulseFitWrapper*>(wrapper)->GetPreT0ParIndex();
2255
2256 func_p->GetParLimits(parIndex, parLimitLow, parLimitHigh);
2257 fitter->SetParameter(parIndex + 1, func_p->GetParName(parIndex), func_p->GetParameter(parIndex), 0.01, parLimitLow, parLimitHigh);
2258 }
2259}
virtual std::shared_ptr< TF1 > GetWrapperTF1()

◆ useLowGain()

bool ZDCPulseAnalyzer::useLowGain ( ) const
inline

Definition at line 649 of file ZDCPulseAnalyzer.h.

649{return m_useLowGain;}

◆ ValidateJSONConfig()

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

Definition at line 2633 of file ZDCPulseAnalyzer.cxx.

2634{
2635 bool result = true;
2636 std::string resultString = "success";
2637
2638 for (auto [key, descr] : JSONConfigParams) {
2639 auto iter = config.find(key);
2640 if (iter != config.end()) {
2641 //
2642 // Check type consistency
2643 //
2644 auto jsonType = iter.value().type();
2645 auto paramType = std::get<0>(descr);
2646 if (jsonType != paramType) {
2647 result = false;
2648 resultString = "Bad type for parameter " + key + ", type in JSON = " + std::to_string((unsigned int) jsonType) ;
2649 break;
2650 }
2651
2652 size_t paramSize = std::get<1>(descr);
2653 size_t jsonSize = iter.value().size();
2654 if (jsonSize != paramSize) {
2655 result = false;
2656 resultString = "Bad length for parameter " + key + ", length in JSON = " + std::to_string(jsonSize) ;
2657 break;
2658 }
2659 }
2660 else {
2661 bool required = std::get<2>(descr);
2662 if (required) {
2663 result = false;
2664 resultString = "Missing required parameter " + key;
2665 break;
2666 }
2667 }
2668 }
2669
2670 if (result) {
2671 //
2672 // Now check that the parameters in the JSON object are in the master list of parameters
2673 //
2674 for (auto [key, value] : config.items()) {
2675 //
2676 // Look for this key in the list of allowed parameters. Yes, it's a slow
2677 // search but we only do it once at configuration time.
2678 //
2679 // bool found = false;
2680 auto iter = JSONConfigParams.find(key);
2681 if (iter == JSONConfigParams.end()) {
2682 result = false;
2683 resultString = "Unknown parameter, key = " + key;
2684 break;
2685 }
2686 }
2687 }
2688
2689 return {result, resultString};
2690}
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};
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 313 of file ZDCPulseAnalyzer.h.

313{};

◆ m_ADCPeakLG

float ZDCPulseAnalyzer::m_ADCPeakLG {}
private

Definition at line 314 of file ZDCPulseAnalyzer.h.

314{};

◆ m_ADCSamplesHG

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

Definition at line 380 of file ZDCPulseAnalyzer.h.

◆ m_ADCSamplesHGSub

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

Definition at line 382 of file ZDCPulseAnalyzer.h.

◆ m_ADCSamplesLG

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

Definition at line 381 of file ZDCPulseAnalyzer.h.

◆ m_ADCSamplesLGSub

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

Definition at line 383 of file ZDCPulseAnalyzer.h.

◆ m_ADCSSampNoiseHG

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

Definition at line 390 of file ZDCPulseAnalyzer.h.

◆ m_ADCSSampNoiseLG

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

Definition at line 391 of file ZDCPulseAnalyzer.h.

◆ m_adjTimeRangeEvent

bool ZDCPulseAnalyzer::m_adjTimeRangeEvent {false}
private

Definition at line 243 of file ZDCPulseAnalyzer.h.

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

◆ m_ampError

float ZDCPulseAnalyzer::m_ampError {}
private

Definition at line 356 of file ZDCPulseAnalyzer.h.

356{};

◆ m_amplitude

float ZDCPulseAnalyzer::m_amplitude {}
private

Definition at line 354 of file ZDCPulseAnalyzer.h.

354{};

◆ m_ampNoNonLin

float ZDCPulseAnalyzer::m_ampNoNonLin {}
private

Definition at line 355 of file ZDCPulseAnalyzer.h.

355{};

◆ m_backToHG_pre

bool ZDCPulseAnalyzer::m_backToHG_pre {false}
private

Definition at line 295 of file ZDCPulseAnalyzer.h.

295{false};

◆ m_badChisq

bool ZDCPulseAnalyzer::m_badChisq {false}
private

Definition at line 280 of file ZDCPulseAnalyzer.h.

280{false};

◆ m_badT0

bool ZDCPulseAnalyzer::m_badT0 {false}
private

Definition at line 282 of file ZDCPulseAnalyzer.h.

282{false};

◆ m_baselineCorr

float ZDCPulseAnalyzer::m_baselineCorr {}
private

Definition at line 296 of file ZDCPulseAnalyzer.h.

296{};

◆ m_bkgdMaxFraction

float ZDCPulseAnalyzer::m_bkgdMaxFraction {}
private

Definition at line 361 of file ZDCPulseAnalyzer.h.

361{};

◆ 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 347 of file ZDCPulseAnalyzer.h.

347{};

◆ m_defaultCombinedFitter

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

Definition at line 257 of file ZDCPulseAnalyzer.h.

257{};

◆ 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 237 of file ZDCPulseAnalyzer.h.

237{};

◆ 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 362 of file ZDCPulseAnalyzer.h.

362{};

◆ m_delayedDeltaT

float ZDCPulseAnalyzer::m_delayedDeltaT {}
private

Definition at line 251 of file ZDCPulseAnalyzer.h.

251{};

◆ m_delayedHist

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

Definition at line 253 of file ZDCPulseAnalyzer.h.

253{};

◆ m_delayedHistLGRefit

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

Definition at line 254 of file ZDCPulseAnalyzer.h.

254{};

◆ m_delayedPedestalDiff

float ZDCPulseAnalyzer::m_delayedPedestalDiff {}
private

Definition at line 252 of file ZDCPulseAnalyzer.h.

252{};

◆ 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 184 of file ZDCPulseAnalyzer.h.

184{false};

◆ m_enablePostExcl

bool ZDCPulseAnalyzer::m_enablePostExcl {false}
private

Definition at line 199 of file ZDCPulseAnalyzer.h.

199{false};

◆ m_enablePreExcl

bool ZDCPulseAnalyzer::m_enablePreExcl {false}
private

Definition at line 194 of file ZDCPulseAnalyzer.h.

194{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 204 of file ZDCPulseAnalyzer.h.

204{false};

◆ m_enableUnderflowExclLG

bool ZDCPulseAnalyzer::m_enableUnderflowExclLG {false}
private

Definition at line 205 of file ZDCPulseAnalyzer.h.

205{false};

◆ m_evtLGRefit

bool ZDCPulseAnalyzer::m_evtLGRefit {false}
private

Definition at line 366 of file ZDCPulseAnalyzer.h.

366{false};

◆ m_ExcludeEarly

bool ZDCPulseAnalyzer::m_ExcludeEarly {false}
private

Definition at line 283 of file ZDCPulseAnalyzer.h.

283{false};

◆ m_ExcludeLate

bool ZDCPulseAnalyzer::m_ExcludeLate {false}
private

Definition at line 284 of file ZDCPulseAnalyzer.h.

284{false};

◆ m_expAmplitude

float ZDCPulseAnalyzer::m_expAmplitude {}
private

Definition at line 360 of file ZDCPulseAnalyzer.h.

360{};

◆ m_fadcCorrFileName

std::string ZDCPulseAnalyzer::m_fadcCorrFileName
private

Definition at line 225 of file ZDCPulseAnalyzer.h.

◆ m_FADCCorrHG

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

Definition at line 227 of file ZDCPulseAnalyzer.h.

227{};

◆ m_FADCCorrLG

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

Definition at line 228 of file ZDCPulseAnalyzer.h.

228{};

◆ m_FADCCorrPerSample

bool ZDCPulseAnalyzer::m_FADCCorrPerSample {false}
private

Definition at line 226 of file ZDCPulseAnalyzer.h.

226{false};

◆ m_fail

bool ZDCPulseAnalyzer::m_fail {false}
private

Definition at line 269 of file ZDCPulseAnalyzer.h.

269{false};

◆ m_failSigCut

bool ZDCPulseAnalyzer::m_failSigCut {false}
private

Definition at line 290 of file ZDCPulseAnalyzer.h.

290{false};

◆ m_firstHGOverFlowSample

int ZDCPulseAnalyzer::m_firstHGOverFlowSample {-1}
private

Definition at line 377 of file ZDCPulseAnalyzer.h.

377{-1};

◆ m_fitAmpError

float ZDCPulseAnalyzer::m_fitAmpError {}
private

Definition at line 338 of file ZDCPulseAnalyzer.h.

338{};

◆ m_fitAmplitude

float ZDCPulseAnalyzer::m_fitAmplitude {}
private

Definition at line 337 of file ZDCPulseAnalyzer.h.

337{};

◆ 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 346 of file ZDCPulseAnalyzer.h.

346{};

◆ m_fitExpAmp

float ZDCPulseAnalyzer::m_fitExpAmp {}
private

Definition at line 353 of file ZDCPulseAnalyzer.h.

353{};

◆ m_fitFailed

bool ZDCPulseAnalyzer::m_fitFailed {false}
private

Definition at line 279 of file ZDCPulseAnalyzer.h.

279{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 232 of file ZDCPulseAnalyzer.h.

232{};

◆ m_fitHistLGRefit

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

Definition at line 233 of file ZDCPulseAnalyzer.h.

233{};

◆ m_fitMinAmp

bool ZDCPulseAnalyzer::m_fitMinAmp {false}
private

Definition at line 288 of file ZDCPulseAnalyzer.h.

288{false};

◆ m_fitNDoF

float ZDCPulseAnalyzer::m_fitNDoF {}
private

Definition at line 348 of file ZDCPulseAnalyzer.h.

348{};

◆ 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 352 of file ZDCPulseAnalyzer.h.

352{};

◆ m_fitPostT0

float ZDCPulseAnalyzer::m_fitPostT0 {}
private

Definition at line 351 of file ZDCPulseAnalyzer.h.

351{};

◆ m_fitPostT0lo

float ZDCPulseAnalyzer::m_fitPostT0lo {}
private

Definition at line 326 of file ZDCPulseAnalyzer.h.

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

◆ m_fitPreAmp

float ZDCPulseAnalyzer::m_fitPreAmp {}
private

Definition at line 350 of file ZDCPulseAnalyzer.h.

350{};

◆ m_fitPreT0

float ZDCPulseAnalyzer::m_fitPreT0 {}
private

Definition at line 349 of file ZDCPulseAnalyzer.h.

349{};

◆ m_fitPulls

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

Definition at line 407 of file ZDCPulseAnalyzer.h.

◆ m_fitTau1

float ZDCPulseAnalyzer::m_fitTau1 {}
private

Definition at line 344 of file ZDCPulseAnalyzer.h.

344{};

◆ m_fitTau2

float ZDCPulseAnalyzer::m_fitTau2 {}
private

Definition at line 345 of file ZDCPulseAnalyzer.h.

345{};

◆ m_fitTCorr2nd

float ZDCPulseAnalyzer::m_fitTCorr2nd {}
private

Definition at line 343 of file ZDCPulseAnalyzer.h.

343{};

◆ m_fitTime

float ZDCPulseAnalyzer::m_fitTime {}
private

Definition at line 339 of file ZDCPulseAnalyzer.h.

339{};

◆ m_fitTimeCorr

float ZDCPulseAnalyzer::m_fitTimeCorr {}
private

Definition at line 341 of file ZDCPulseAnalyzer.h.

341{};

◆ m_fitTimeSub

float ZDCPulseAnalyzer::m_fitTimeSub {}
private

Definition at line 340 of file ZDCPulseAnalyzer.h.

340{};

◆ m_fitTMax

float ZDCPulseAnalyzer::m_fitTMax {}
private

Definition at line 323 of file ZDCPulseAnalyzer.h.

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

◆ m_fitTMin

float ZDCPulseAnalyzer::m_fitTMin {}
private

Definition at line 324 of file ZDCPulseAnalyzer.h.

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

◆ m_fixPrePulse

bool ZDCPulseAnalyzer::m_fixPrePulse {false}
private

Definition at line 287 of file ZDCPulseAnalyzer.h.

287{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 265 of file ZDCPulseAnalyzer.h.

265{false};

◆ m_haveFADCCorrections

bool ZDCPulseAnalyzer::m_haveFADCCorrections {false}
private

Definition at line 224 of file ZDCPulseAnalyzer.h.

224{false};

◆ m_haveNonlinCorr

bool ZDCPulseAnalyzer::m_haveNonlinCorr {false}
private

Definition at line 218 of file ZDCPulseAnalyzer.h.

218{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 267 of file ZDCPulseAnalyzer.h.

267{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 270 of file ZDCPulseAnalyzer.h.

270{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 216 of file ZDCPulseAnalyzer.h.

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

◆ m_HGUnderflow

bool ZDCPulseAnalyzer::m_HGUnderflow {false}
private

Definition at line 272 of file ZDCPulseAnalyzer.h.

272{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 319 of file ZDCPulseAnalyzer.h.

319{};

◆ m_initialized

bool ZDCPulseAnalyzer::m_initialized {false}
private

Definition at line 235 of file ZDCPulseAnalyzer.h.

235{false};

◆ m_initializedFits

bool ZDCPulseAnalyzer::m_initializedFits {false}
private

Definition at line 236 of file ZDCPulseAnalyzer.h.

236{false};

◆ m_initialPostPulseT0

float ZDCPulseAnalyzer::m_initialPostPulseT0 {}
private

Definition at line 335 of file ZDCPulseAnalyzer.h.

335{};

◆ m_initialPrePulseAmp

float ZDCPulseAnalyzer::m_initialPrePulseAmp {}
private

Definition at line 333 of file ZDCPulseAnalyzer.h.

333{};

◆ m_initialPrePulseT0

float ZDCPulseAnalyzer::m_initialPrePulseT0 {}
private

Definition at line 332 of file ZDCPulseAnalyzer.h.

332{};

◆ m_lastHGOverFlowSample

int ZDCPulseAnalyzer::m_lastHGOverFlowSample {-1}
private

Definition at line 376 of file ZDCPulseAnalyzer.h.

376{-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 274 of file ZDCPulseAnalyzer.h.

274{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 215 of file ZDCPulseAnalyzer.h.

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

◆ m_LGUnderflow

bool ZDCPulseAnalyzer::m_LGUnderflow {false}
private

Definition at line 275 of file ZDCPulseAnalyzer.h.

275{false};

◆ m_maxADCHG

float ZDCPulseAnalyzer::m_maxADCHG {}
private

Definition at line 304 of file ZDCPulseAnalyzer.h.

304{};

◆ m_maxADCLG

float ZDCPulseAnalyzer::m_maxADCLG {}
private

Definition at line 308 of file ZDCPulseAnalyzer.h.

308{};

◆ m_maxADCSampleHG

int ZDCPulseAnalyzer::m_maxADCSampleHG
private

Definition at line 306 of file ZDCPulseAnalyzer.h.

◆ m_maxADCSampleLG

int ZDCPulseAnalyzer::m_maxADCSampleLG
private

Definition at line 311 of file ZDCPulseAnalyzer.h.

◆ m_maxDelta

float ZDCPulseAnalyzer::m_maxDelta {}
private

Definition at line 316 of file ZDCPulseAnalyzer.h.

316{};

◆ m_maxSampleEvt

unsigned int ZDCPulseAnalyzer::m_maxSampleEvt {}
private

Definition at line 246 of file ZDCPulseAnalyzer.h.

246{};

◆ m_maxSamplesPostExcl

unsigned int ZDCPulseAnalyzer::m_maxSamplesPostExcl {0}
private

Definition at line 202 of file ZDCPulseAnalyzer.h.

202{0};

◆ m_maxSamplesPreExcl

unsigned int ZDCPulseAnalyzer::m_maxSamplesPreExcl {0}
private

Definition at line 195 of file ZDCPulseAnalyzer.h.

195{0};

◆ m_minADCHG

float ZDCPulseAnalyzer::m_minADCHG {}
private

Definition at line 303 of file ZDCPulseAnalyzer.h.

303{};

◆ m_minADCLG

float ZDCPulseAnalyzer::m_minADCLG {}
private

Definition at line 309 of file ZDCPulseAnalyzer.h.

309{};

◆ m_minADCSampleHG

int ZDCPulseAnalyzer::m_minADCSampleHG
private

Definition at line 305 of file ZDCPulseAnalyzer.h.

◆ m_minADCSampleLG

int ZDCPulseAnalyzer::m_minADCSampleLG
private

Definition at line 310 of file ZDCPulseAnalyzer.h.

◆ m_minDelta

float ZDCPulseAnalyzer::m_minDelta {}
private

Definition at line 317 of file ZDCPulseAnalyzer.h.

317{};

◆ m_minDeriv2nd

float ZDCPulseAnalyzer::m_minDeriv2nd {}
private

Definition at line 320 of file ZDCPulseAnalyzer.h.

320{};

◆ m_minDeriv2ndIndex

int ZDCPulseAnalyzer::m_minDeriv2ndIndex {}
private

Definition at line 321 of file ZDCPulseAnalyzer.h.

321{};

◆ m_minDeriv2ndSig

float ZDCPulseAnalyzer::m_minDeriv2ndSig
private

Definition at line 328 of file ZDCPulseAnalyzer.h.

◆ m_minSampleEvt

unsigned int ZDCPulseAnalyzer::m_minSampleEvt {}
private

Definition at line 245 of file ZDCPulseAnalyzer.h.

245{};

◆ 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 221 of file ZDCPulseAnalyzer.h.

221{};

◆ m_nonLinCorrParamsLG

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

Definition at line 222 of file ZDCPulseAnalyzer.h.

222{};

◆ m_nonLinCorrRefADC

float ZDCPulseAnalyzer::m_nonLinCorrRefADC {500}
private

Definition at line 219 of file ZDCPulseAnalyzer.h.

219{500};

◆ m_nonLinCorrRefScale

float ZDCPulseAnalyzer::m_nonLinCorrRefScale {100}
private

Definition at line 220 of file ZDCPulseAnalyzer.h.

220{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 379 of file ZDCPulseAnalyzer.h.

379{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 359 of file ZDCPulseAnalyzer.h.

359{};

◆ m_postExclHGADCThresh

unsigned int ZDCPulseAnalyzer::m_postExclHGADCThresh {0}
private

Definition at line 200 of file ZDCPulseAnalyzer.h.

200{0};

◆ m_postExclLGADCThresh

unsigned int ZDCPulseAnalyzer::m_postExclLGADCThresh {0}
private

Definition at line 201 of file ZDCPulseAnalyzer.h.

201{0};

◆ m_postPulse

bool ZDCPulseAnalyzer::m_postPulse {false}
private

Definition at line 278 of file ZDCPulseAnalyzer.h.

278{false};

◆ m_postPulseAbsDer2ndMinSig

float ZDCPulseAnalyzer::m_postPulseAbsDer2ndMinSig {}
private

Definition at line 187 of file ZDCPulseAnalyzer.h.

187{};

◆ m_postPulseDelta

unsigned int ZDCPulseAnalyzer::m_postPulseDelta {0}
private

Definition at line 185 of file ZDCPulseAnalyzer.h.

185{0};

◆ m_postPulseDerivMinSig

float ZDCPulseAnalyzer::m_postPulseDerivMinSig {}
private

Definition at line 186 of file ZDCPulseAnalyzer.h.

186{};

◆ m_postPulseMainMinDer2ndRatio

float ZDCPulseAnalyzer::m_postPulseMainMinDer2ndRatio {}
private

Definition at line 188 of file ZDCPulseAnalyzer.h.

188{};

◆ m_preAmplitude

float ZDCPulseAnalyzer::m_preAmplitude {}
private

Definition at line 358 of file ZDCPulseAnalyzer.h.

358{};

◆ m_preExclHGADCThresh

unsigned int ZDCPulseAnalyzer::m_preExclHGADCThresh {0}
private

Definition at line 196 of file ZDCPulseAnalyzer.h.

196{0};

◆ m_preExclLGADCThresh

unsigned int ZDCPulseAnalyzer::m_preExclLGADCThresh {0}
private

Definition at line 197 of file ZDCPulseAnalyzer.h.

197{0};

◆ m_preExpFitWrapper

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

Definition at line 239 of file ZDCPulseAnalyzer.h.

239{};

◆ m_preExpSig

float ZDCPulseAnalyzer::m_preExpSig
private

Definition at line 329 of file ZDCPulseAnalyzer.h.

◆ m_preExpTail

bool ZDCPulseAnalyzer::m_preExpTail {false}
private

Definition at line 285 of file ZDCPulseAnalyzer.h.

285{false};

◆ m_prePulse

bool ZDCPulseAnalyzer::m_prePulse {false}
private

Definition at line 277 of file ZDCPulseAnalyzer.h.

277{false};

◆ m_prePulseCombinedFitter

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

Definition at line 256 of file ZDCPulseAnalyzer.h.

256{};

◆ m_prePulseDelta

unsigned int ZDCPulseAnalyzer::m_prePulseDelta {0}
private

Definition at line 190 of file ZDCPulseAnalyzer.h.

190{0};

◆ m_prePulseFitWrapper

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

Definition at line 238 of file ZDCPulseAnalyzer.h.

238{};

◆ m_prePulseSig

float ZDCPulseAnalyzer::m_prePulseSig
private

Definition at line 330 of file ZDCPulseAnalyzer.h.

◆ m_preSample

float ZDCPulseAnalyzer::m_preSample {}
private

Definition at line 301 of file ZDCPulseAnalyzer.h.

301{};

◆ m_preSampleAmp

float ZDCPulseAnalyzer::m_preSampleAmp {}
private

Definition at line 357 of file ZDCPulseAnalyzer.h.

357{};

◆ 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 273 of file ZDCPulseAnalyzer.h.

273{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 370 of file ZDCPulseAnalyzer.h.

370{0};

◆ m_refitLGAmpl

float ZDCPulseAnalyzer::m_refitLGAmpl {0}
private

Definition at line 367 of file ZDCPulseAnalyzer.h.

367{0};

◆ m_refitLGAmplCorr

float ZDCPulseAnalyzer::m_refitLGAmplCorr {0}
private

Definition at line 369 of file ZDCPulseAnalyzer.h.

369{0};

◆ m_refitLGChisq

float ZDCPulseAnalyzer::m_refitLGChisq {0}
private

Definition at line 371 of file ZDCPulseAnalyzer.h.

371{0};

◆ m_refitLGChisqRatio

float ZDCPulseAnalyzer::m_refitLGChisqRatio {0}
private

Definition at line 372 of file ZDCPulseAnalyzer.h.

372{0};

◆ m_refitLGFitAmpl

float ZDCPulseAnalyzer::m_refitLGFitAmpl {0}
private

Definition at line 368 of file ZDCPulseAnalyzer.h.

368{0};

◆ m_refitLGTime

float ZDCPulseAnalyzer::m_refitLGTime {0}
private

Definition at line 373 of file ZDCPulseAnalyzer.h.

373{0};

◆ m_refitLGTimeSub

float ZDCPulseAnalyzer::m_refitLGTimeSub {0}
private

Definition at line 374 of file ZDCPulseAnalyzer.h.

374{0};

◆ m_repassPulse

bool ZDCPulseAnalyzer::m_repassPulse {false}
private

Definition at line 289 of file ZDCPulseAnalyzer.h.

289{false};

◆ m_sampleNoiseHG

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

Definition at line 384 of file ZDCPulseAnalyzer.h.

◆ m_sampleNoiseLG

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

Definition at line 385 of file ZDCPulseAnalyzer.h.

◆ m_samplesDeriv2nd

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

Definition at line 399 of file ZDCPulseAnalyzer.h.

◆ m_samplesDeriv2ndErr

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

Definition at line 400 of file ZDCPulseAnalyzer.h.

◆ m_samplesLGRefit

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

Definition at line 396 of file ZDCPulseAnalyzer.h.

◆ m_samplesNoise

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

Definition at line 394 of file ZDCPulseAnalyzer.h.

◆ m_samplesNoiseLGRefit

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

Definition at line 397 of file ZDCPulseAnalyzer.h.

◆ m_samplesSub

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

Definition at line 393 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 364 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 342 of file ZDCPulseAnalyzer.h.

342{};

◆ m_timingCorrMode

unsigned int ZDCPulseAnalyzer::m_timingCorrMode {NoTimingCorr}
private

Definition at line 212 of file ZDCPulseAnalyzer.h.

◆ m_timingCorrRefADC

float ZDCPulseAnalyzer::m_timingCorrRefADC {500}
private

Definition at line 213 of file ZDCPulseAnalyzer.h.

213{500};

◆ m_timingCorrScale

float ZDCPulseAnalyzer::m_timingCorrScale {100}
private

Definition at line 214 of file ZDCPulseAnalyzer.h.

214{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 207 of file ZDCPulseAnalyzer.h.

207{0};

◆ m_underFlowExclSamplesPostLG

unsigned int ZDCPulseAnalyzer::m_underFlowExclSamplesPostLG {0}
private

Definition at line 209 of file ZDCPulseAnalyzer.h.

209{0};

◆ m_underFlowExclSamplesPreHG

unsigned int ZDCPulseAnalyzer::m_underFlowExclSamplesPreHG {0}
private

Definition at line 206 of file ZDCPulseAnalyzer.h.

206{0};

◆ m_underFlowExclSamplesPreLG

unsigned int ZDCPulseAnalyzer::m_underFlowExclSamplesPreLG {0}
private

Definition at line 208 of file ZDCPulseAnalyzer.h.

208{0};

◆ m_underflowExclusion

bool ZDCPulseAnalyzer::m_underflowExclusion {false}
private

Definition at line 291 of file ZDCPulseAnalyzer.h.

291{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 300 of file ZDCPulseAnalyzer.h.

300{};

◆ m_useFixedBaseline

bool ZDCPulseAnalyzer::m_useFixedBaseline {}
private

Definition at line 250 of file ZDCPulseAnalyzer.h.

250{};

◆ m_useLowGain

bool ZDCPulseAnalyzer::m_useLowGain {false}
private

Definition at line 268 of file ZDCPulseAnalyzer.h.

268{false};

◆ m_useSampleHG

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

Definition at line 388 of file ZDCPulseAnalyzer.h.

◆ m_useSampleLG

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

Definition at line 387 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: