7 #include "TFitResult.h"
8 #include "TFitResultPtr.h"
9 #include "TVirtualFitter.h"
29 {
"tag", {JSON::value_t::string, 1,
true,
true}},
30 {
"enabled", {JSON::value_t::boolean, 1,
true,
true}},
31 {
"LGMode", {JSON::value_t::number_unsigned, 1,
false,
true}},
32 {
"Nsample", {JSON::value_t::number_integer, 1,
false,
true}},
33 {
"FADCFreqMHz", {JSON::value_t::number_integer, 1,
false,
true}},
34 {
"preSampleIdx", {JSON::value_t::number_integer, 1,
true,
true}},
35 {
"nominalPedestal", {JSON::value_t::number_integer, 1,
false,
true}},
36 {
"fitFunction", {JSON::value_t::string, 1,
true,
true}},
37 {
"peakSample", {JSON::value_t::number_integer, 1,
true,
true}},
38 {
"peakTolerance", {JSON::value_t::number_integer, 1,
true,
false}},
39 {
"2ndDerivThreshHG", {JSON::value_t::number_integer, 1,
true,
true}},
40 {
"2ndDerivThreshLG", {JSON::value_t::number_integer, 1,
true,
true}},
41 {
"2ndDerivStep", {JSON::value_t::number_integer, 1,
false,
false}},
42 {
"HGOverflowADC", {JSON::value_t::number_integer, 1,
true,
true}},
43 {
"HGUnderflowADC", {JSON::value_t::number_integer, 1,
true,
true}},
44 {
"LGOverflowADC", {JSON::value_t::number_integer, 1,
true,
true}},
45 {
"nominalT0HG", {JSON::value_t::number_float, 1,
true,
true}},
46 {
"nominalT0LG", {JSON::value_t::number_float, 1,
true,
true}},
47 {
"nominalTau1", {JSON::value_t::number_float, 1,
true,
false}},
48 {
"nominalTau2", {JSON::value_t::number_float, 1,
true,
false}},
49 {
"fixTau1", {JSON::value_t::boolean, 1,
true,
false}},
50 {
"fixTau2", {JSON::value_t::boolean, 1,
true,
false}},
53 {
"chisqDivAmpCutHG", {JSON::value_t::number_float, 1,
true,
true}},
54 {
"chisqDivAmpCutLG", {JSON::value_t::number_float, 1,
true,
true}},
55 {
"chisqDivAmpOffsetHG", {JSON::value_t::number_float, 1,
true,
true}},
56 {
"chisqDivAmpOffsetLG", {JSON::value_t::number_float, 1,
true,
true}},
57 {
"chisqDivAmpPowerHG", {JSON::value_t::number_float, 1,
true,
true}},
58 {
"chisqDivAmpPowerLG", {JSON::value_t::number_float, 1,
true,
true}},
59 {
"gainFactorHG", {JSON::value_t::number_float, 1,
true,
true}},
60 {
"gainFactorLG", {JSON::value_t::number_float, 1,
true,
true}},
61 {
"noiseSigmaHG", {JSON::value_t::number_float, 1,
true,
true}},
62 {
"noiseSigmaLG", {JSON::value_t::number_float, 1,
true,
true}},
63 {
"enableRepass", {JSON::value_t::boolean, 1,
false,
false}},
64 {
"Repass2ndDerivThreshHG", {JSON::value_t::number_integer, 1,
true,
true}},
65 {
"Repass2ndDerivThreshLG", {JSON::value_t::number_integer, 1,
true,
true}},
76 {
"useDelayed", {JSON::value_t::boolean, 1,
false,
false}},
77 {
"delayDeltaT", {JSON::value_t::number_float, 1,
true,
false}}
101 float delayBaselineAdjust =
par[0];
105 for (
int isample = 0; isample <
nSamples; isample++) {
115 double pull = (histValue - funcVal) / histError;
123 for (
int isample = 0; isample <
nSamples; isample++) {
132 double pull = (histValue - funcVal) / histError;
143 const std::string& fitFunction,
int peak2ndDerivMinSample,
144 float peak2ndDerivMinThreshHG,
float peak2ndDerivMinThreshLG) :
145 m_msgFunc_p(std::move(msgFunc_p)),
146 m_tag(
tag), m_Nsample(Nsample),
147 m_preSampleIdx(preSampleIdx),
148 m_deltaTSample(deltaTSample),
149 m_pedestal(pedestal), m_fitFunction(fitFunction),
150 m_peak2ndDerivMinSample(peak2ndDerivMinSample),
151 m_peak2ndDerivMinThreshLG(peak2ndDerivMinThreshLG),
152 m_peak2ndDerivMinThreshHG(peak2ndDerivMinThreshHG),
153 m_ADCSamplesHGSub(Nsample, 0), m_ADCSamplesLGSub(Nsample, 0),
154 m_ADCSSampSigHG(Nsample, 0), m_ADCSSampSigLG(Nsample, 0),
155 m_samplesSub(Nsample, 0)
159 m_tmin = -deltaTSample / 2;
164 std::string histNameLGRefit =
"ZDCFitHist" +
tag +
"_LGRefit";
177 m_msgFunc_p(std::move(msgFunc_p))
185 (*m_msgFunc_p)(
ZDCMsg::Debug,
"ConfigFromJSON produced result: "+ resultString2);
197 std::string histNameLGRefit =
"ZDCFitHist" +
m_tag +
"_LGRefit";
218 std::string delayedHGName = std::string(
m_fitHist->GetName()) +
"delayed";
219 std::string delayedLGName = std::string(
m_fitHistLGRefit->GetName()) +
"delayed";
481 std::ostringstream ostrm;
509 float deltaT0MinHG,
float deltaT0MaxHG,
510 float deltaT0MinLG,
float deltaT0MaxLG)
523 const std::vector<double>& parsHG,
524 const std::vector<double>& parsLG)
531 std::string timeResHGName =
"TimeResFuncHG_" +
m_tag;
532 std::string timeResLGName =
"TimeResFuncLG_" +
m_tag;
534 TF1* funcHG_p =
new TF1(timeResHGName.c_str(), TF1String.c_str(), 0,
m_HGOverflowADC);
535 TF1* funcLG_p =
new TF1(timeResLGName.c_str(), TF1String.c_str(), 0,
m_LGOverflowADC);
537 if (parsHG.size() !=
static_cast<unsigned int>(funcHG_p->GetNpar()) ||
538 parsLG.size() !=
static_cast<unsigned int>(funcLG_p->GetNpar())) {
543 funcHG_p->SetParameters(&parsHG[0]);
544 funcLG_p->SetParameters(&parsLG[0]);
558 auto getXmin=[](
const TH1 * pH){
559 return pH->GetXaxis()->GetXmin();
561 auto getXmax=[](
const TH1 * pH){
562 return pH->GetXaxis()->GetXmax();
564 auto xmin= getXmin(correHistHG.get());
565 auto xmax= getXmax(correHistHG.get());
566 if (std::abs(
xmin+0.5) > 1
e-3 || std::abs(
xmax - 4095.5) > 1
e-3) {
567 (*m_msgFunc_p)(
ZDCMsg::Error,
"ZDCPulseAnalyzer::enableFADCCorrections:: invalid high gain correction histogram range: xmin, xmax = " +
573 xmin= getXmin(correHistLG.get());
574 xmax= getXmax(correHistLG.get());
575 if (std::abs(
xmin+0.5) > 1
e-3 ||
576 std::abs(
xmax - 4095.5) > 1
e-3) {
577 (*m_msgFunc_p)(
ZDCMsg::Error,
"ZDCPulseAnalyzer::enableFADCCorrections:: invalid low gain correction histogram range: xmin, xmax = " +
604 std::vector<float> pulls(
m_Nsample, -100);
607 const TF1* fit_p =
static_cast<const TF1*
>(dataHist_p->GetListOfFunctions()->Last());
609 for (
size_t ibin = 0; ibin <
m_Nsample ; ibin++) {
610 float t = dataHist_p->GetBinCenter(ibin + 1);
611 float fitVal = fit_p->Eval(
t);
612 float histVal = dataHist_p->GetBinContent(ibin + 1);
613 float histErr = dataHist_p->GetBinError(ibin + 1);
614 float pull = (histVal - fitVal)/histErr;
624 double amplCorrFactor = 1;
630 amplCorrFactor *= fadcCorr;
642 float invNLCorr = 1.0;
656 amplCorrFactor /= invNLCorr;
659 return amplCorrFactor;
664 float prePulseTMin = 0;
758 (*m_msgFunc_p)(
ZDCMsg::Fatal,
"ZDCPulseAnalyzer::LoadAndAnalyzeData:: Wrong LoadAndAnalyzeData called -- expecting both delayed and undelayed samples");
781 const std::vector<float>& ADCSamplesHGDelayed,
const std::vector<float>& ADCSamplesLGDelayed)
784 (*m_msgFunc_p)(
ZDCMsg::Fatal,
"ZDCPulseAnalyzer::LoadAndAnalyzeData:: Wrong LoadAndAnalyzeData called -- expecting only undelayed samples");
806 for (
size_t isample = 0; isample <
m_Nsample; isample++) {
807 float ADCHG = ADCSamplesHG[isample];
808 float ADCLG = ADCSamplesLG[isample];
849 bool doDump = (*m_msgFunc_p)(
ZDCMsg::Verbose,
"Dumping all samples before subtraction: ");
867 for (
size_t isample = 0; isample <
m_NSamplesAna; isample++) {
890 std::ostringstream dumpString;
891 dumpString <<
"After FADC correction, sample " << isample <<
", HG ADC = " <<
m_ADCSamplesHGSub[isample]
1008 if (m_lastHGOverFlowSample < 2 && m_lastHGOverFlowSample > -1) {
1030 float deriv2ndThreshHG = 0;
1031 float deriv2ndThreshLG = 0;
1051 (
float chisq,
float amp,
unsigned int fitNDoF)->
bool
1054 if (chisq/fitNDoF > 2 &&
ratio >
cut)
return false;
1097 (
float chisq,
float amp,
unsigned int fitNDoF)->
bool
1101 if (chisq/
float(fitNDoF) > 2 &&
ratio >
cut)
return false;
1155 const std::vector<float>& samples,
1156 const std::vector<bool>& useSample,
1157 float peak2ndDerivMinThresh,
1159 const std::vector<float>& t0CorrParams,
1161 float minT0Corr,
float maxT0Corr
1174 bool haveFirst =
false;
1175 unsigned int lastUsed = 0;
1235 std::ostringstream baselineMsg;
1236 baselineMsg <<
"Delayed samples baseline correction = " <<
m_baselineCorr << std::endl;
1242 for (
size_t isample = 0; isample <
nSamples; isample++) {
1253 std::for_each(
m_samplesSub.begin(),
m_samplesSub.end(), [ = ] (
float & adcUnsub) {return adcUnsub -= m_preSample;} );
1326 if (derivPresampleSig < -5) {
1332 if (!useSample[isample])
continue;
1334 float sampleSig = -
m_samplesSub[isample]/(std::sqrt(2.0)*noiseSig);
1350 float maxPrepulseSig = 0;
1351 unsigned int maxPrepulseSample = 0;
1353 for (
int isample = loopStart; isample <= loopLimit; isample++) {
1354 if (!useSample[isample])
continue;
1366 if (prePulseSig > maxPrepulseSig) {
1367 maxPrepulseSig = prePulseSig;
1368 maxPrepulseSample = isample;
1402 for (
int isample = postStartIdx; isample < (
int)
nSamples - 1; isample++) {
1403 if (!useSample.at(isample))
continue;
1434 float derivSig = deriv/(std::sqrt(2)*noiseSig);
1443 if (std::abs(deriv2ndTest) > 0.15) {
1456 if (deriv2ndSig > 5 && deriv2ndTest < -0.1) {
1467 std::ostringstream ostrm;
1468 ostrm <<
"Post pulse found, m_maxSampleEvt = " <<
m_maxSampleEvt;
1486 std::ostringstream ostrm;
1505 for (
unsigned int ipow = 0; ipow < t0CorrParams.size(); ipow++) {
1514 bool failFixedCut = m_fitTimeCorr < minT0Corr || m_fitTimeCorr > maxT0Corr;
1524 double timeResolution = 0;
1536 if (failFixedCut)
m_badT0 =
true;
1556 const std::vector<bool>& useSamples)
1565 for (
unsigned int idx = 0;
idx < samplesLG.size();
idx++) {
1568 if (useSamples[
idx]) {
1582 TH1* hist_p =
nullptr;
1587 float ampInitial, fitAmpMin, fitAmpMax, t0Initial;
1608 if (ampInitial < fitAmpMin) ampInitial = fitAmpMin * 1.5;
1630 fitWrapper->
Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
1649 int fitStatus = result_ptr;
1655 if (fitStatus != 0 && result_ptr->Edm() > 0.001)
1665 if ((
int) constrFitResult_ptr != 0) {
1675 if ((
int) unconstrFitResult_ptr != 0) {
1682 if ((
int) constrFit2Result_ptr != 0) {
1689 result_ptr = constrFit2Result_ptr;
1693 result_ptr = unconstrFitResult_ptr;
1699 hist_p->GetListOfFunctions()->Clear();
1702 std::string
name = func->GetName();
1704 TF1* copyFunc =
static_cast<TF1*
>(func->Clone((
name +
"_copy").c_str()));
1705 hist_p->GetListOfFunctions()->Add(copyFunc);
1758 TH1* hist_p =
nullptr, *delayedHist_p =
nullptr;
1770 float fitAmpMin, fitAmpMax, t0Initial, ampInitial;
1786 if (ampInitial < fitAmpMin) ampInitial = fitAmpMin * 1.5;
1812 fitWrapper->
Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
1817 TFitter* theFitter =
nullptr;
1841 size_t numFitPar = theFitter->GetNumberTotalParameters();
1843 theFitter->GetMinuit()->fISW[4] = -1;
1848 theFitter->GetMinuit()->fISW[4] = -1;
1851 theFitter->GetMinuit()->mnexcm(
"SET NOWarnings",
nullptr,0,ierr);
1853 else theFitter->GetMinuit()->fISW[4] = 0;
1858 theFitter->SetParameter(0,
"delayBaselineAdjust", 0, 0.01, -100, 100);
1859 theFitter->ReleaseParameter(0);
1862 theFitter->SetParameter(0,
"delayBaselineAdjust", 0, 0.01, -100, 100);
1863 theFitter->FixParameter(0);
1867 double arglist[100];
1870 int status = theFitter->ExecuteCommand(
"MIGRAD", arglist, 2);
1872 double fitAmp = theFitter->GetParameter(1);
1876 double chi2, edm, errdef;
1879 theFitter->GetStats(
chi2, edm, errdef, nvpar, nparx);
1884 if (
status || fitAmp < fitAmpMin * 1.01 || edm > 0.01){
1889 theFitter->SetParameter(0,
"delayBaselineAdjust", 0, 0.01, -100, 100);
1890 theFitter->FixParameter(0);
1894 if (fitAmp < fitAmpMin * 1.01) {
1900 fitWrapper->
Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
1904 status = theFitter->ExecuteCommand(
"MIGRAD", arglist, 2);
1909 theFitter->ReleaseParameter(0);
1917 theFitter->ReleaseParameter(0);
1918 status = theFitter->ExecuteCommand(
"MIGRAD", arglist, 2);
1923 theFitter->SetParameter(0,
"delayBaselineAdjust", 0, 0.01, -100, 100);
1924 theFitter->FixParameter(0);
1925 status = theFitter->ExecuteCommand(
"MIGRAD", arglist, 2);
1933 fitAmp = theFitter->GetParameter(1);
1937 if (fitAmp < fitAmpMin * 1.01) {
1948 if (!
m_quietFits) theFitter->GetMinuit()->fISW[4] = -1;
1950 std::vector<double> funcParams(numFitPar - 1);
1951 std::vector<double> funcParamErrs(numFitPar - 1);
1959 for (
size_t ipar = 1; ipar < numFitPar; ipar++) {
1960 funcParams[ipar - 1] = theFitter->GetParameter(ipar);
1961 funcParamErrs[ipar - 1] = theFitter->GetParError(ipar);
1969 theFitter->GetStats(
chi2, edm, errdef, nvpar, nparx);
1989 theFitter->ExecuteCommand(
"Cal1fcn", arglist, 1);
2031 for (
int ipar = 0; ipar < func->GetNpar(); ipar++) {
2032 double parLimitLow, parLimitHigh;
2034 func->GetParLimits(ipar, parLimitLow, parLimitHigh);
2037 "ZDCPulseAnalyzer name=" + std::string(func->GetName())
2045 if (std::abs(parLimitHigh - parLimitLow) > (1
e-6)*std::abs(parLimitLow)) {
2046 double value = func->GetParameter(ipar);
2047 if (
value >= parLimitHigh) {
2048 value = parLimitHigh * 0.9;
2050 else if (
value <= parLimitLow) {
2051 value = parLimitLow + 0.1*std::abs(parLimitLow);
2053 func->SetParameter(ipar,
value);
2060 TVirtualFitter::SetDefaultFitter(
"Minuit");
2062 size_t nFitParams = func->GetNpar() + 1;
2063 std::unique_ptr<TFitter>
fitter = std::make_unique<TFitter>(nFitParams);
2065 fitter->GetMinuit()->fISW[4] = -1;
2066 fitter->SetParameter(0,
"delayBaselineAdjust", 0, 0.01, -100, 100);
2068 for (
size_t ipar = 0; ipar < nFitParams - 1; ipar++) {
2069 double parLimitLow, parLimitHigh;
2071 func->GetParLimits(ipar, parLimitLow, parLimitHigh);
2072 if (std::abs(parLimitHigh / parLimitLow - 1) < 1
e-6) {
2073 double value = func->GetParameter(ipar);
2077 fitter->SetParameter(ipar + 1, func->GetParName(ipar), func->GetParameter(ipar), 0.01, lowLim, highLim);
2078 fitter->FixParameter(ipar + 1);
2081 double value = func->GetParameter(ipar);
2082 if (
value >= parLimitHigh)
value = parLimitHigh * 0.99;
2083 else if (
value <= parLimitLow)
value = parLimitLow * 1.01;
2085 double step =
std::min((parLimitHigh - parLimitLow)/100., (
value - parLimitLow)/100.);
2087 fitter->SetParameter(ipar + 1, func->GetParName(ipar),
value,
step, parLimitLow, parLimitHigh);
2098 double parLimitLow, parLimitHigh;
2101 func_p->GetParLimits(1, parLimitLow, parLimitHigh);
2103 fitter->SetParameter(2, func_p->GetParName(1), func_p->GetParameter(1), 0.01, parLimitLow, parLimitHigh);
2108 func_p->GetParLimits(parIndex, parLimitLow, parLimitHigh);
2109 fitter->SetParameter(parIndex + 1, func_p->GetParName(parIndex), func_p->GetParameter(parIndex), 0.01, parLimitLow, parLimitHigh);
2124 std::ostringstream message1;
2125 message1 <<
"samplesSub ";
2131 std::ostringstream message3;
2132 message3 <<
"samplesDeriv2nd ";
2143 std::string
message =
"Dump of TF1: " + std::string(func->GetName());
2145 if (!continueDump)
return;
2147 unsigned int npar = func->GetNpar();
2148 for (
unsigned int ipar = 0; ipar < npar; ipar++) {
2149 std::ostringstream msgstr;
2151 double parMin = 0, parMax = 0;
2152 func->GetParLimits(ipar, parMin, parMax);
2154 msgstr <<
"Parameter " << ipar <<
", value = " << func->GetParameter(ipar) <<
", error = "
2155 << func->GetParError(ipar) <<
", min = " << parMin <<
", max = " << parMax;
2162 std::ostringstream ostrStream;
2164 (*m_msgFunc_p)(
ZDCMsg::Info, (
"ZDCPulserAnalyzer:: settings for instance: " +
m_tag));
2166 ostrStream <<
"Nsample = " <<
m_Nsample <<
" at frequency " <<
m_freqMHz <<
" MHz, preSample index = "
2169 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2172 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2177 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2180 ostrStream <<
"using delayed samples with delta T = " <<
m_delayedDeltaT <<
", and default pedestalDiff == "
2182 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2190 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2194 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2199 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2203 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2207 ostrStream <<
"Pre-exclusion enabled for up to " <<
m_maxSamplesPreExcl <<
", samples with ADC threshold HG = "
2209 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2212 ostrStream <<
"Post-exclusion enabled for up to " <<
m_maxSamplesPostExcl <<
", samples with ADC threshold HG = "
2214 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2217 ostrStream <<
"Minimum significance cuts applied: HG min. sig. = " <<
m_sigMinHG <<
", LG min. sig. " <<
m_sigMinLG;
2218 (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
2225 unsigned int statusMask = 0;
2261 TH1* hist_p =
nullptr, *delayedHist_p =
nullptr;
2271 std::shared_ptr<TGraphErrors> theGraph = std::make_shared<TGraphErrors>(TGraphErrors(2 *
m_Nsample));
2274 for (
int ipt = 0; ipt < hist_p->GetNbinsX(); ipt++) {
2275 theGraph->SetPoint(npts, hist_p->GetBinCenter(ipt + 1), hist_p->GetBinContent(ipt + 1));
2276 theGraph->SetPointError(npts++, 0, hist_p->GetBinError(ipt + 1));
2279 for (
int iDelayPt = 0; iDelayPt < delayedHist_p->GetNbinsX(); iDelayPt++) {
2280 theGraph->SetPoint(npts, delayedHist_p->GetBinCenter(iDelayPt + 1), delayedHist_p->GetBinContent(iDelayPt + 1) -
m_delayedBaselineShift);
2281 theGraph->SetPointError(npts++, 0, delayedHist_p->GetBinError(iDelayPt + 1));
2284 TF1* func_p =
static_cast<TF1*
>(hist_p->GetListOfFunctions()->Last());
2286 theGraph->GetListOfFunctions()->Add(
new TF1(*func_p));
2287 hist_p->GetListOfFunctions()->SetOwner (
false);
2290 theGraph->SetName(( std::string(hist_p->GetName()) +
"combinaed").c_str());
2292 theGraph->SetMarkerStyle(20);
2293 theGraph->SetMarkerColor(1);
2306 std::shared_ptr<TGraphErrors> theGraph = std::make_shared<TGraphErrors>(TGraphErrors(
m_Nsample));
2309 for (
int ipt = 0; ipt < hist_p->GetNbinsX(); ipt++) {
2310 theGraph->SetPoint(npts, hist_p->GetBinCenter(ipt + 1), hist_p->GetBinContent(ipt + 1));
2311 theGraph->SetPointError(npts++, 0, hist_p->GetBinError(ipt + 1));
2314 TF1* func_p =
static_cast<TF1*
>(hist_p->GetListOfFunctions()->Last());
2315 theGraph->GetListOfFunctions()->Add(func_p);
2316 theGraph->SetName(( std::string(hist_p->GetName()) +
"not_combinaed").c_str());
2318 theGraph->SetMarkerStyle(20);
2319 theGraph->SetMarkerColor(1);
2327 unsigned int nSamples = inputData.size();
2332 std::vector<float>
results(vecSize, 0);
2336 unsigned int fillIdx =
step - 1;
2340 results.at(fillIdx++) = deriv;
2348 unsigned int nSamples = inputData.size();
2354 std::vector<float>
results(vecSize, 0);
2356 unsigned int fillIndex =
step;
2359 results.at(fillIndex++) = deriv2nd;
2380 const unsigned int nsamples = samples.size();
2388 float minScore = 1.0e9;
2389 unsigned int minIndex = 0;
2392 float deriv = derivVec[
idx];
2393 float prevDeriv = derivVec[
idx - 1];
2395 float derivDiff = deriv - prevDeriv;
2397 float deriv2nd = deriv2ndVec[
idx];
2403 float score = (deriv*deriv + 2*derivDiff*derivDiff +
2404 0.5*deriv2nd*deriv2nd);
2406 if (
score < minScore) {
2417 if (minIndex<2 or (minIndex+1) >=
nsamples){
2418 throw std::out_of_range(
"minIndex out of range in ZDCPulseAnalyzer::obtainDelayedBaselineCorr");
2420 float sample0 = samples[minIndex - 2];
2421 float sample1 = samples[minIndex - 1];
2422 float sample2 = samples[minIndex];
2423 float sample3 = samples[minIndex + 1];
2427 float baselineCorr = (0.5 * (sample1 - sample0 + sample3 - sample2) -
2428 0.25 * (sample3 - sample1 + sample2 - sample0));
2430 if (minIndex % 2 != 0) baselineCorr =-baselineCorr;
2432 return baselineCorr;
2438 std::string resultString =
"success";
2446 auto jsonType =
iter.value().type();
2447 auto paramType = std::get<0>(
descr);
2448 if (jsonType != paramType) {
2450 resultString =
"Bad type for parameter " +
key +
", type in JSON = " +
std::to_string((
unsigned int) jsonType) ;
2454 size_t paramSize = std::get<1>(
descr);
2455 size_t jsonSize =
iter.value().size();
2456 if (jsonSize != paramSize) {
2458 resultString =
"Bad length for parameter " +
key +
", length in JSON = " +
std::to_string(jsonSize) ;
2466 resultString =
"Missing required parameter " +
key;
2485 resultString =
"Unknown parameter, key = " +
key;
2491 return {
result, resultString};
2497 std::string resultString =
"success";
2526 else if (
key ==
"T0CutsHG") {
2530 else if (
key ==
"T0CutsLG") {
2547 else if (
key ==
"fitAmpMinMaxHG") {
2551 else if (
key ==
"fitAmpMinMaxLG") {
2555 else if (
key ==
"quietFits") {
2558 else if (
key ==
"enablePreExclusion") {
2564 else if (
key ==
"enablePostExclusion") {
2570 else if (
key ==
"ampMinSignifHGLG") {
2575 else if (
key ==
"enableFADCCorrections") {
2576 auto fileNameJson =
value[
"filename"];
2577 auto doPerSampleCorrJson =
value[
"doPerSampleCorr"];
2579 if (fileNameJson.is_null() || doPerSampleCorrJson.is_null()) {
2581 std::string resultString =
"failure processing enableFADCCorrections object";
2591 std::string resultString =
"unprocessed parameter";
2596 return {
result, resultString};