5 #ifndef ZDCANALYSIS_ZDCPulseAnalyzer_h
6 #define ZDCANALYSIS_ZDCPulseAnalyzer_h
11 #include "TGraphErrors.h"
30 PSHGOverUnderflowBit = 5,
40 ExcludeEarlyLGBit = 13,
41 ExcludeLateLGBit = 14,
46 ArmSumIncludeBit = 18,
77 unsigned int m_Nsample{};
78 unsigned int m_preSampleIdx{};
79 float m_deltaTSample{};
82 unsigned int m_LGMode{LGModeNormal};
87 size_t m_2ndDerivStep{1};
88 size_t m_peak2ndDerivMinSample{};
89 size_t m_peak2ndDerivMinTolerance{1};
90 float m_peak2ndDerivMinThreshLG{};
91 float m_peak2ndDerivMinThreshHG{};
93 bool m_useDelayed{
false};
95 bool m_enableRepass{
false};
96 float m_peak2ndDerivMinRepassLG{};
97 float m_peak2ndDerivMinRepassHG{};
101 float m_gainFactorHG{};
102 float m_gainFactorLG{};
106 float m_noiseSigHG{};
107 float m_noiseSigLG{};
112 int m_HGOverflowADC{};
113 int m_HGUnderflowADC{};
114 int m_LGOverflowADC{};
116 float m_nominalT0HG{};
117 float m_nominalT0LG{};
119 float m_nominalTau1{};
120 float m_nominalTau2{};
125 float m_defaultFitTMax{};
126 float m_defaultFitTMin{};
128 float m_chisqDivAmpCutLG{};
129 float m_chisqDivAmpCutHG{};
131 float m_T0CutLowLG{};
132 float m_T0CutHighLG{};
134 float m_T0CutLowHG{};
135 float m_T0CutHighHG{};
137 std::unique_ptr<const TF1> m_timeResFuncHG_p{};
138 std::unique_ptr<const TF1> m_timeResFuncLG_p{};
140 unsigned int m_timeCutMode{0};
142 float m_defaultT0Max{};
143 float m_defaultT0Min{};
145 float m_fitAmpMinHG{};
146 float m_fitAmpMinLG{};
148 float m_fitAmpMaxHG{};
149 float m_fitAmpMaxLG{};
153 bool m_enablePreExcl{
false};
154 unsigned int m_maxSamplesPreExcl{0};
155 unsigned int m_preExclHGADCThresh{0};
156 unsigned int m_preExclLGADCThresh{0};
158 bool m_enablePostExcl{
false};
159 unsigned int m_postExclHGADCThresh{0};
160 unsigned int m_postExclLGADCThresh{0};
161 unsigned int m_maxSamplesPostExcl{0};
164 unsigned int m_timingCorrMode{NoTimingCorr};
165 float m_timingCorrRefADC{500};
166 float m_timingCorrScale{100};
170 bool m_haveNonlinCorr{
false};
171 float m_nonLinCorrRefADC{500};
172 float m_nonLinCorrRefScale{100};
176 bool m_haveFADCCorrections{
false};
177 bool m_FADCCorrPerSample{
false};
178 std::unique_ptr<const TH1> m_FADCCorrHG{};
179 std::unique_ptr<const TH1> m_FADCCorrLG{};
186 bool m_initializedFits{
false};
193 bool m_adjTimeRangeEvent{};
195 unsigned int m_minSampleEvt{};
196 unsigned int m_maxSampleEvt{};
200 bool m_useFixedBaseline{};
201 float m_delayedDeltaT{};
202 float m_delayedPedestalDiff{};
222 bool m_HGUnderflow{};
223 bool m_PSHGOverUnderflow{};
225 bool m_LGUnderflow{};
233 bool m_ExcludeEarly{};
234 bool m_ExcludeLate{};
237 bool m_fixPrePulse{};
239 bool m_repassPulse{};
243 bool m_backToHG_pre{};
244 float m_baselineCorr{};
248 int m_usedPresampIdx{};
267 float m_initialExpAmp{};
268 float m_minDeriv2nd{};
269 int m_minDeriv2ndIndex{};
274 float m_fitPostT0lo{};
280 float m_initialPrePulseT0{};
281 float m_initialPrePulseAmp{};
283 float m_initialPostPulseT0{};
285 float m_fitAmplitude{};
286 float m_fitAmpError{};
288 float m_fitTimeSub{};
289 float m_fitTimeCorr{};
291 float m_fitTCorr2nd{};
299 float m_fitPostAmp{};
302 float m_ampNoNonLin{};
304 float m_preSampleAmp{};
305 float m_preAmplitude{};
306 float m_postAmplitude{};
307 float m_expAmplitude{};
308 float m_bkgdMaxFraction{};
309 float m_delayedBaselineShift{};
311 bool m_evtLGRefit{
false};
312 float m_refitLGAmpl{0};
313 float m_refitLGFitAmpl{0};
314 float m_refitLGAmplCorr{0};
315 float m_refitLGAmpError{0};
316 float m_refitLGChisq{0};
317 float m_refitLGTime{0};
318 float m_refitLGTimeSub{0};
320 int m_lastHGOverFlowSample{-1};
321 int m_firstHGOverFlowSample{-1};
323 unsigned int m_NSamplesAna{0};
352 void Reset(
bool reanalyze =
false);
354 void SetupFitFunctions();
356 bool DoAnalysis(
bool repass);
358 bool ScanAndSubtractSamples();
360 bool AnalyzeData(
size_t nSamples,
size_t preSample,
361 const std::vector<float>& samples,
362 const std::vector<bool>& useSamples,
363 float peak2ndDerivMinThresh,
365 const std::vector<float>& toCorrParams,
366 float maxChisqDivAmp,
367 float minT0Corr,
float maxT0Corr
371 double getAmplitudeCorrection(
bool highGain);
373 static std::vector<float> Calculate2ndDerivative(
const std::vector <float>& inputData,
unsigned int step);
374 static std::vector<float> CalculateDerivative(
const std::vector <float>& inputData,
unsigned int step);
375 static float obtainDelayedBaselineCorr(
const std::vector<float>& samples);
377 void prepareLGRefit(
const std::vector<float>& samplesLG,
const std::vector<float>& samplesSig,
378 const std::vector<bool>& useSamples);
386 for (
size_t isample = 0; isample < m_NSamplesAna; isample++) {
387 m_fitHist->SetBinContent(isample + 1, m_samplesSub[isample]);
388 m_fitHist->SetBinError(isample + 1, m_samplesSig[isample]);
392 for (
size_t isample = 0; isample < m_NSamplesAna; isample++) {
393 m_fitHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample]);
394 m_fitHistLGRefit->SetBinError(isample + 1, m_samplesSigLGRefit[isample]);
402 for (
size_t isample = 0; isample < m_Nsample; isample++) {
403 m_fitHist->SetBinContent(isample + 1, m_samplesSub[isample * 2]);
404 m_delayedHist->SetBinContent(isample + 1, m_samplesSub[isample * 2 + 1]);
406 m_fitHist->SetBinError(isample + 1, m_samplesSig[isample]);
407 m_delayedHist->SetBinError(isample + 1, m_samplesSig[isample]);
413 for (
size_t isample = 0; isample < m_Nsample; isample++) {
414 m_fitHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample * 2]);
415 m_delayedHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample * 2 + 1]);
417 m_fitHistLGRefit->SetBinError(isample + 1, m_samplesSigLGRefit[isample]);
418 m_delayedHistLGRefit->SetBinError(isample + 1, m_samplesSigLGRefit[isample]);
424 void DoFit(
bool refitLG =
false);
425 void DoFitCombined(
bool refitLG =
false);
427 static std::unique_ptr<TFitter> MakeCombinedFitter(TF1* func);
431 static void CombinedPulsesFCN(
int& numParam,
double*,
double&
f,
double*
par,
int flag);
438 const std::string& fitFunction,
int peak2ndDerivMinSample,
float peak2DerivMinThreshHG,
float peak2DerivMinThreshLG);
442 void SetFitOPtions(
const std::string& fitOptions) { m_fitOptions = fitOptions;}
447 void enableDelayed(
float deltaT,
float pedestalShift,
bool fixedBaseline =
false);
449 void enableRepass(
float peak2ndDerivMinRepassHG,
float peak2ndDerivMinRepassLG);
451 void enableTimeSigCut(
bool AND,
float sigCut,
const std::string& TF1String,
452 const std::vector<double>& parsHG,
453 const std::vector<double>& parsLG);
455 void enablePreExclusion(
unsigned int maxSamplesExcl,
unsigned int HGADCThresh,
unsigned int LGADCThresh)
457 m_enablePreExcl =
true;
458 m_maxSamplesPreExcl = maxSamplesExcl;
459 m_preExclHGADCThresh = HGADCThresh;
460 m_preExclLGADCThresh = LGADCThresh;
465 m_enablePostExcl =
true;
466 m_maxSamplesPostExcl = maxSamplesExcl;
467 m_postExclHGADCThresh = HGADCThresh;
468 m_postExclLGADCThresh = LGADCThresh;
473 m_initializedFits =
false;
481 void SetCutValues(
float chisqDivAmpCutHG,
float chisqDivAmpCutLG,
482 float deltaT0MinHG,
float deltaT0MaxHG,
483 float deltaT0MinLG,
float deltaT0MaxLG) ;
487 m_noiseSigHG = noiseSigHG;
488 m_noiseSigLG = noiseSigLG;
491 void SetGainFactorsHGLG(
float gainFactorHG,
float gainFactorLG);
493 void SetFitMinMaxAmp(
float minAmpHG,
float minAmpLG,
float maxAmpHG,
float maxAmpLG);
495 void SetTauT0Values(
bool fixTau1,
bool fixTau2,
float tau1,
float tau2,
float t0HG,
float t0LG);
497 void SetADCOverUnderflowValues(
int HGOverflowADC,
int HGUnderflowADC,
int LGOverflowADC);
500 const std::vector<float>& HGT0CorrParams,
const std::vector<float>& LGT0CorrParams)
502 m_timingCorrMode =
mode;
503 if (
mode != NoTimingCorr) {
504 m_timingCorrRefADC = refADC;
505 m_timingCorrScale = refScale;
507 m_HGT0CorrParams = HGT0CorrParams;
508 m_LGT0CorrParams = LGT0CorrParams;
512 void SetFitTimeMax(
float tmax);
514 void SetNonlinCorrParams(
float refADC,
float refScale,
const std::vector<float>& paramsHG,
const std::vector<float>& paramsLG)
516 std::string HGParamsStr =
"HG coefficients = ", LGParamsStr =
"LG coefficients = ";
521 (*m_msgFunc_p)(
ZDCMsg::Info, (
"Setting non-linear parameters for module: " + m_tag +
", reference ADC = " +
527 m_nonLinCorrRefADC = refADC;
528 m_nonLinCorrRefScale = refScale;
529 m_nonLinCorrParamsHG = paramsHG;
530 m_nonLinCorrParamsLG = paramsLG;
531 m_haveNonlinCorr =
true;
537 void enableFADCCorrections(
bool correctPerSample, std::unique_ptr<const TH1>& correHistHG, std::unique_ptr<const TH1>& correHistLG);
540 bool LoadAndAnalyzeData(
const std::vector<float>& ADCSamplesHG,
const std::vector<float>& ADCSamplesLG);
542 bool LoadAndAnalyzeData(
const std::vector<float>& ADCSamplesHG,
const std::vector<float>& ADCSamplesLG,
543 const std::vector<float>& ADCSamplesHGDelayed,
const std::vector<float>& ADCSamplesLGDelayed);
545 bool ReanalyzeData();
567 bool BadT0()
const {
return m_badT0;}
573 bool ArmSumInclude()
const {
return HavePulse() && !(FitFailed() || BadChisq() || BadT0() || fitMinimumAmplitude() || LGOverflow());}
603 if (m_evtLGRefit)
return m_refitLGAmpl;
609 if (m_evtLGRefit)
return m_refitLGFitAmpl;
615 if (m_evtLGRefit)
return m_refitLGAmplCorr;
621 if (m_evtLGRefit)
return m_refitLGChisq;
627 if (m_evtLGRefit)
return m_refitLGTime;
633 if (m_evtLGRefit)
return m_refitLGTimeSub;
644 float maxADCNosub = m_useLowGain ? m_maxADCLG : m_maxADCHG;
645 return maxADCNosub - m_pedestal - m_preSample;
649 float minADCNosub = m_useLowGain ? m_minADCLG : m_minADCHG;
650 return minADCNosub - m_pedestal - m_preSample;
673 unsigned int GetStatusMask()
const;
687 FillHistogram(refitLG);
690 return refitLG ? m_fitHistLGRefit.get() : m_fitHist.get();
693 std::shared_ptr<TGraphErrors> GetCombinedGraph(
bool forceLG =
false);
694 std::shared_ptr<TGraphErrors> GetGraph(
bool forceLG =
false);
696 std::vector<float> GetFitPulls(
bool forceLG =
false)
const;
699 void dumpSetting()
const;
700 void dumpTF1(
const TF1*)
const;