5 #ifndef ZDCANALYSIS_ZDCPulseAnalyzer_h
6 #define ZDCANALYSIS_ZDCPulseAnalyzer_h
12 #include "TGraphErrors.h"
34 PSHGOverUnderflowBit = 5,
44 ExcludeEarlyLGBit = 13,
45 ExcludeLateLGBit = 14,
50 ArmSumIncludeBit = 18,
52 UnderFlowExclusionBit = 20,
90 unsigned int m_Nsample{};
91 unsigned int m_preSampleIdx{};
93 float m_deltaTSample{};
95 unsigned int m_LGMode{LGModeNormal};
99 bool m_quietFits{
true};
100 bool m_saveFitFunc{
false};
103 size_t m_2ndDerivStep{1};
104 size_t m_peak2ndDerivMinSample{};
105 size_t m_peak2ndDerivMinTolerance{1};
106 float m_peak2ndDerivMinThreshLG{};
107 float m_peak2ndDerivMinThreshHG{};
109 bool m_useDelayed{
false};
111 bool m_enableRepass{
false};
112 float m_peak2ndDerivMinRepassLG{};
113 float m_peak2ndDerivMinRepassHG{};
117 float m_gainFactorHG{};
118 float m_gainFactorLG{};
122 float m_noiseSigHG{};
123 float m_noiseSigLG{};
127 std::string m_fitOptions{};
128 int m_HGOverflowADC{};
129 int m_HGUnderflowADC{};
130 int m_LGOverflowADC{};
132 float m_nominalT0HG{};
133 float m_nominalT0LG{};
135 float m_nominalTau1{};
136 float m_nominalTau2{};
141 float m_defaultFitTMax{};
142 float m_defaultFitTMin{};
144 float m_chisqDivAmpCutLG{};
145 float m_chisqDivAmpCutHG{};
146 float m_chisqDivAmpOffsetLG{};
147 float m_chisqDivAmpOffsetHG{};
148 float m_chisqDivAmpPowerLG{};
149 float m_chisqDivAmpPowerHG{};
151 float m_T0CutLowLG{};
152 float m_T0CutHighLG{};
154 float m_T0CutLowHG{};
155 float m_T0CutHighHG{};
157 std::unique_ptr<const TF1> m_timeResFuncHG_p{};
158 std::unique_ptr<const TF1> m_timeResFuncLG_p{};
160 unsigned int m_timeCutMode{0};
162 float m_defaultT0Max{};
163 float m_defaultT0Min{};
165 float m_fitAmpMinHG{};
166 float m_fitAmpMinLG{};
168 float m_fitAmpMaxHG{};
169 float m_fitAmpMaxLG{};
171 bool m_haveSignifCuts{
false};
177 bool m_enablePreExcl{
false};
178 unsigned int m_maxSamplesPreExcl{0};
179 unsigned int m_preExclHGADCThresh{0};
180 unsigned int m_preExclLGADCThresh{0};
182 bool m_enablePostExcl{
false};
183 unsigned int m_postExclHGADCThresh{0};
184 unsigned int m_postExclLGADCThresh{0};
185 unsigned int m_maxSamplesPostExcl{0};
187 bool m_enableUnderflowExclHG{
false};
188 bool m_enableUnderflowExclLG{
false};
189 unsigned int m_underFlowExclSamplesPreHG{0};
190 unsigned int m_underFlowExclSamplesPostHG{0};
191 unsigned int m_underFlowExclSamplesPreLG{0};
192 unsigned int m_underFlowExclSamplesPostLG{0};
196 bool m_haveUserFilter{
false};
197 void (*m_userFilterHG)(std::vector<float>& FADCSamples, std::vector<bool> useSamples){};
198 void (*m_userFilterLG)(std::vector<float>& FADCSamples, std::vector<bool> useSamples){};
201 unsigned int m_timingCorrMode{NoTimingCorr};
202 float m_timingCorrRefADC{500};
203 float m_timingCorrScale{100};
204 std::vector<float> m_LGT0CorrParams{};
205 std::vector<float> m_HGT0CorrParams{};
207 bool m_haveNonlinCorr{
false};
208 float m_nonLinCorrRefADC{500};
209 float m_nonLinCorrRefScale{100};
210 std::vector<float> m_nonLinCorrParamsHG{};
211 std::vector<float> m_nonLinCorrParamsLG{};
213 bool m_haveFADCCorrections{
false};
215 bool m_FADCCorrPerSample{
false};
216 std::unique_ptr<const TH1> m_FADCCorrHG{};
217 std::unique_ptr<const TH1> m_FADCCorrLG{};
221 std::unique_ptr<TH1> m_fitHist{};
222 std::unique_ptr<TH1> m_fitHistLGRefit{};
224 bool m_initializedFits{
false};
225 std::unique_ptr<ZDCFitWrapper> m_defaultFitWrapper{};
226 std::unique_ptr<ZDCPrePulseFitWrapper> m_prePulseFitWrapper{};
227 std::unique_ptr<ZDCPreExpFitWrapper> m_preExpFitWrapper{};
231 bool m_adjTimeRangeEvent{
false};
233 unsigned int m_minSampleEvt{};
234 unsigned int m_maxSampleEvt{};
238 bool m_useFixedBaseline{};
239 float m_delayedDeltaT{};
240 float m_delayedPedestalDiff{};
241 std::unique_ptr<TH1> m_delayedHist{};
242 std::unique_ptr<TH1> m_delayedHistLGRefit{};
244 std::unique_ptr<TFitter> m_prePulseCombinedFitter{};
245 std::unique_ptr<TFitter> m_defaultCombinedFitter{};
253 bool m_haveData{
false};
255 bool m_havePulse{
false};
256 bool m_useLowGain{
false};
258 bool m_HGOverflow{
false};
260 bool m_HGUnderflow{
false};
261 bool m_PSHGOverUnderflow{
false};
262 bool m_LGOverflow{
false};
263 bool m_LGUnderflow{
false};
265 bool m_prePulse{
false};
266 bool m_postPulse{
false};
267 bool m_fitFailed{
false};
268 bool m_badChisq{
false};
271 bool m_ExcludeEarly{
false};
272 bool m_ExcludeLate{
false};
273 bool m_preExpTail{
false};
275 bool m_fixPrePulse{
false};
276 bool m_fitMinAmp{
false};
277 bool m_repassPulse{
false};
278 bool m_failSigCut{
false};
279 bool m_underflowExclusion{
false};
283 bool m_backToHG_pre{
false};
284 float m_baselineCorr{};
288 int m_usedPresampIdx{};
307 float m_initialExpAmp{};
308 float m_minDeriv2nd{};
309 int m_minDeriv2ndIndex{};
314 float m_fitPostT0lo{};
320 float m_initialPrePulseT0{};
321 float m_initialPrePulseAmp{};
323 float m_initialPostPulseT0{};
325 float m_fitAmplitude{};
326 float m_fitAmpError{};
328 float m_fitTimeSub{};
329 float m_fitTimeCorr{};
331 float m_fitTCorr2nd{};
339 float m_fitPostAmp{};
342 float m_ampNoNonLin{};
344 float m_preSampleAmp{};
345 float m_preAmplitude{};
346 float m_postAmplitude{};
347 float m_expAmplitude{};
348 float m_bkgdMaxFraction{};
349 float m_delayedBaselineShift{};
351 bool m_evtLGRefit{
false};
352 float m_refitLGAmpl{0};
353 float m_refitLGFitAmpl{0};
354 float m_refitLGAmplCorr{0};
355 float m_refitLGAmpError{0};
356 float m_refitLGChisq{0};
357 float m_refitLGTime{0};
358 float m_refitLGTimeSub{0};
360 int m_lastHGOverFlowSample{-1};
361 int m_firstHGOverFlowSample{-1};
363 unsigned int m_NSamplesAna{0};
392 void Reset(
bool reanalyze =
false);
395 std::pair<bool, std::string> ValidateJSONConfig(
const JSON&
config);
396 std::pair<bool, std::string> ConfigFromJSON(
const JSON&
config);
398 void SetupFitFunctions();
400 bool DoAnalysis(
bool repass);
402 bool ScanAndSubtractSamples();
405 bool AnalyzeData(
size_t nSamples,
size_t preSample,
406 const std::vector<float>& samples,
407 const std::vector<bool>& useSamples,
408 float peak2ndDerivMinThresh,
410 const std::vector<float>& toCorrParams,
412 float minT0Corr,
float maxT0Corr
416 double getAmplitudeCorrection(
bool highGain);
418 static std::vector<float> Calculate2ndDerivative(
const std::vector <float>& inputData,
unsigned int step);
419 static std::vector<float> CalculateDerivative(
const std::vector <float>& inputData,
unsigned int step);
420 static float obtainDelayedBaselineCorr(
const std::vector<float>& samples);
422 void prepareLGRefit(
const std::vector<float>& samplesLG,
const std::vector<float>& samplesSig,
423 const std::vector<bool>& useSamples);
431 for (
size_t isample = 0; isample < m_NSamplesAna; isample++) {
432 m_fitHist->SetBinContent(isample + 1, m_samplesSub[isample]);
433 m_fitHist->SetBinError(isample + 1, m_samplesSig[isample]);
437 for (
size_t isample = 0; isample < m_NSamplesAna; isample++) {
438 m_fitHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample]);
439 m_fitHistLGRefit->SetBinError(isample + 1, m_samplesSigLGRefit[isample]);
447 for (
size_t isample = 0; isample < m_Nsample; isample++) {
448 m_fitHist->SetBinContent(isample + 1, m_samplesSub[isample * 2]);
449 m_delayedHist->SetBinContent(isample + 1, m_samplesSub[isample * 2 + 1]);
451 m_fitHist->SetBinError(isample + 1, m_samplesSig[isample]);
452 m_delayedHist->SetBinError(isample + 1, m_samplesSig[isample]);
458 for (
size_t isample = 0; isample < m_Nsample; isample++) {
459 m_fitHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample * 2]);
460 m_delayedHistLGRefit->SetBinContent(isample + 1, m_samplesLGRefit[isample * 2 + 1]);
462 m_fitHistLGRefit->SetBinError(isample + 1, m_samplesSigLGRefit[isample]);
463 m_delayedHistLGRefit->SetBinError(isample + 1, m_samplesSigLGRefit[isample]);
469 void checkTF1Limits(TF1* func);
471 void DoFit(
bool refitLG =
false);
472 void DoFitCombined(
bool refitLG =
false);
474 static std::unique_ptr<TFitter> MakeCombinedFitter(TF1* func);
478 static void CombinedPulsesFCN(
int& numParam,
double*,
double&
f,
double*
par,
int flag);
485 int pedestal,
const std::string& fitFunction,
int peak2ndDerivMinSample,
float peak2DerivMinThreshHG,
486 float peak2DerivMinThreshLG);
492 void setFitOPtions(
const std::string& fitOptions) { m_fitOptions = fitOptions;}
499 void enableDelayed(
float deltaT,
float pedestalShift,
bool fixedBaseline =
false);
501 void enableRepass(
float peak2ndDerivMinRepassHG,
float peak2ndDerivMinRepassLG);
503 void enableTimeSigCut(
bool AND,
float sigCut,
const std::string& TF1String,
504 const std::vector<double>& parsHG,
505 const std::vector<double>& parsLG);
507 void enablePreExclusion(
unsigned int maxSamplesExcl,
unsigned int HGADCThresh,
unsigned int LGADCThresh)
509 m_enablePreExcl =
true;
510 m_maxSamplesPreExcl = maxSamplesExcl;
511 m_preExclHGADCThresh = HGADCThresh;
512 m_preExclLGADCThresh = LGADCThresh;
517 m_enablePostExcl =
true;
518 m_maxSamplesPostExcl = maxSamplesExcl;
519 m_postExclHGADCThresh = HGADCThresh;
520 m_postExclLGADCThresh = LGADCThresh;
525 m_initializedFits =
false;
533 void SetCutValues(
float chisqDivAmpCutHG,
float chisqDivAmpCutLG,
534 float deltaT0MinHG,
float deltaT0MaxHG,
535 float deltaT0MinLG,
float deltaT0MaxLG) ;
539 m_noiseSigHG = noiseSigHG;
540 m_noiseSigLG = noiseSigLG;
543 void SetGainFactorsHGLG(
float gainFactorHG,
float gainFactorLG);
545 void SetFitMinMaxAmp(
float minAmpHG,
float minAmpLG,
float maxAmpHG,
float maxAmpLG);
547 void setMinimumSignificance(
float sigMinHG,
float sigMinLG);
549 void SetTauT0Values(
bool fixTau1,
bool fixTau2,
float tau1,
float tau2,
float t0HG,
float t0LG);
551 void SetADCOverUnderflowValues(
int HGOverflowADC,
int HGUnderflowADC,
int LGOverflowADC);
554 const std::vector<float>& HGT0CorrParams,
const std::vector<float>& LGT0CorrParams)
556 m_timingCorrMode =
mode;
557 if (
mode != NoTimingCorr) {
558 m_timingCorrRefADC = refADC;
559 m_timingCorrScale = refScale;
561 m_HGT0CorrParams = HGT0CorrParams;
562 m_LGT0CorrParams = LGT0CorrParams;
566 void SetFitTimeMax(
float tmax);
568 void SetNonlinCorrParams(
float refADC,
float refScale,
const std::vector<float>& paramsHG,
const std::vector<float>& paramsLG)
570 std::string HGParamsStr =
"HG coefficients = ", LGParamsStr =
"LG coefficients = ";
575 (*m_msgFunc_p)(
ZDCMsg::Info, (
"Setting non-linear parameters for module: " + m_tag +
", reference ADC = " +
581 m_nonLinCorrRefADC = refADC;
582 m_nonLinCorrRefScale = refScale;
583 m_nonLinCorrParamsHG = paramsHG;
584 m_nonLinCorrParamsLG = paramsLG;
585 m_haveNonlinCorr =
true;
591 void enableFADCCorrections(
bool correctPerSample, std::unique_ptr<const TH1>& correHistHG, std::unique_ptr<const TH1>& correHistLG);
594 bool LoadAndAnalyzeData(
const std::vector<float>& ADCSamplesHG,
const std::vector<float>& ADCSamplesLG);
596 bool LoadAndAnalyzeData(
const std::vector<float>& ADCSamplesHG,
const std::vector<float>& ADCSamplesLG,
597 const std::vector<float>& ADCSamplesHGDelayed,
const std::vector<float>& ADCSamplesLGDelayed);
599 bool ReanalyzeData();
621 bool badT0()
const {
return m_badT0;}
627 bool armSumInclude()
const {
return havePulse() && !(failed() ||
fitFailed() || badChisq() || badT0() || fitMinimumAmplitude() || LGOverflow() || LGUnderflow() || failSigCut());}
659 if (m_evtLGRefit)
return m_refitLGAmpl;
665 if (m_evtLGRefit)
return m_refitLGFitAmpl;
671 if (m_evtLGRefit)
return m_refitLGAmplCorr;
677 if (m_evtLGRefit)
return m_refitLGChisq;
683 if (m_evtLGRefit)
return m_refitLGTime;
689 if (m_evtLGRefit)
return m_refitLGTimeSub;
700 float maxADCNosub = m_useLowGain ? m_maxADCLG : m_maxADCHG;
701 return maxADCNosub - m_pedestal - m_preSample;
705 float minADCNosub = m_useLowGain ? m_minADCLG : m_minADCHG;
706 return minADCNosub - m_pedestal - m_preSample;
729 unsigned int GetStatusMask()
const;
743 FillHistogram(refitLG);
746 return refitLG ? m_fitHistLGRefit.get() : m_fitHist.get();
749 std::shared_ptr<TGraphErrors> GetCombinedGraph(
bool forceLG =
false);
750 std::shared_ptr<TGraphErrors> GetGraph(
bool forceLG =
false);
752 std::vector<float> GetFitPulls(
bool forceLG =
false)
const;
755 void dumpConfiguration()
const;
756 void dumpTF1(
const TF1*)
const;