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   {
"gainFactorHG", {JSON::value_t::number_float, 1, 
true, 
true}},
 
   56   {
"gainFactorLG", {JSON::value_t::number_float, 1, 
true, 
true}},
 
   57   {
"noiseSigmaHG", {JSON::value_t::number_float, 1, 
true, 
true}},
 
   58   {
"noiseSigmaLG", {JSON::value_t::number_float, 1, 
true, 
true}},
 
   59   {
"enableRepass", {JSON::value_t::boolean, 1, 
false, 
false}},
 
   60   {
"Repass2ndDerivThreshHG", {JSON::value_t::number_integer, 1, 
true, 
true}},
 
   61   {
"Repass2ndDerivThreshLG", {JSON::value_t::number_integer, 1, 
true, 
true}},
 
   72   {
"useDelayed", {JSON::value_t::boolean, 1, 
false, 
false}},
 
   73   {
"delayDeltaT", {JSON::value_t::number_float, 1, 
true, 
false}}
 
   97   float delayBaselineAdjust = 
par[0];
 
  101   for (
int isample = 0; isample < 
nSamples; isample++) {
 
  111     double pull = (histValue - funcVal) / histError;
 
  119   for (
int isample = 0; isample < 
nSamples; isample++) {
 
  128     double pull = (histValue - funcVal) / histError;
 
  139                                    float gainHG, 
const std::string& fitFunction, 
int peak2ndDerivMinSample,
 
  140                                    float peak2ndDerivMinThreshHG, 
float peak2ndDerivMinThreshLG) :
 
  141   m_msgFunc_p(std::move(msgFunc_p)),
 
  142   m_tag(
tag), m_Nsample(Nsample),
 
  143   m_preSampleIdx(preSampleIdx),
 
  144   m_deltaTSample(deltaTSample),
 
  145   m_pedestal(pedestal), m_gainHG(gainHG), m_fitFunction(fitFunction),
 
  146   m_peak2ndDerivMinSample(peak2ndDerivMinSample),
 
  147   m_peak2ndDerivMinThreshLG(peak2ndDerivMinThreshLG),
 
  148   m_peak2ndDerivMinThreshHG(peak2ndDerivMinThreshHG),
 
  149   m_ADCSamplesHGSub(Nsample, 0), m_ADCSamplesLGSub(Nsample, 0),
 
  150   m_ADCSSampSigHG(Nsample, 0), m_ADCSSampSigLG(Nsample, 0), 
 
  151   m_samplesSub(Nsample, 0)
 
  155   m_tmin = -deltaTSample / 2;
 
  160   std::string histNameLGRefit = 
"ZDCFitHist" + 
tag + 
"_LGRefit";
 
  173   m_msgFunc_p(msgFunc_p)
 
  181   (*m_msgFunc_p)(
ZDCMsg::Debug, 
"ConfigFromJSON produced result: "+ resultString2);
 
  193   std::string histNameLGRefit = 
"ZDCFitHist" + 
m_tag + 
"_LGRefit";
 
  214   std::string delayedHGName = std::string(
m_fitHist->GetName()) + 
"delayed";
 
  215   std::string delayedLGName = std::string(
m_fitHistLGRefit->GetName()) + 
"delayed";
 
  470   std::ostringstream ostrm;
 
  498                                     float deltaT0MinHG, 
float deltaT0MaxHG,
 
  499                                     float deltaT0MinLG, 
float deltaT0MaxLG)
 
  512                     const std::vector<double>& parsHG, 
 
  513                     const std::vector<double>& parsLG)
 
  520   std::string timeResHGName = 
"TimeResFuncHG_" + 
m_tag;
 
  521   std::string timeResLGName = 
"TimeResFuncLG_" + 
m_tag;
 
  523   TF1* funcHG_p = 
new TF1(timeResHGName.c_str(), TF1String.c_str(), 0, 
m_HGOverflowADC);
 
  524   TF1* funcLG_p = 
new TF1(timeResLGName.c_str(), TF1String.c_str(), 0, 
m_LGOverflowADC);
 
  526   if (parsHG.size() != 
static_cast<unsigned int>(funcHG_p->GetNpar()) ||
 
  527       parsLG.size() != 
static_cast<unsigned int>(funcLG_p->GetNpar())) {
 
  532   funcHG_p->SetParameters(&parsHG[0]);
 
  533   funcLG_p->SetParameters(&parsLG[0]);
 
  547   auto getXmin=[](
const TH1 * pH){
 
  548     return pH->GetXaxis()->GetXmin();
 
  550   auto getXmax=[](
const TH1 * pH){
 
  551     return pH->GetXaxis()->GetXmax();
 
  553   auto xmin= getXmin(correHistHG.get());
 
  554   auto xmax= getXmax(correHistHG.get());
 
  555   if (std::abs(
xmin+0.5) > 1
e-3 || std::abs(
xmax - 4095.5) > 1
e-3) {
 
  556     (*m_msgFunc_p)(
ZDCMsg::Error, 
"ZDCPulseAnalyzer::enableFADCCorrections:: invalid high gain correction histogram range: xmin, xmax = " +
 
  562   xmin= getXmin(correHistLG.get());
 
  563   xmax= getXmax(correHistLG.get());
 
  564   if (std::abs(
xmin+0.5) > 1
e-3 ||
 
  565       std::abs(
xmax - 4095.5) > 1
e-3) {
 
  566     (*m_msgFunc_p)(
ZDCMsg::Error, 
"ZDCPulseAnalyzer::enableFADCCorrections:: invalid low gain correction histogram range: xmin, xmax = " +
 
  593     std::vector<float> pulls(
m_Nsample, -100);
 
  596     const TF1* fit_p = 
static_cast<const TF1*
>(dataHist_p->GetListOfFunctions()->Last());
 
  598     for (
size_t ibin = 0; ibin < 
m_Nsample ; ibin++) {
 
  599       float t = dataHist_p->GetBinCenter(ibin + 1);
 
  600       float fitVal = fit_p->Eval(
t);
 
  601       float histVal = dataHist_p->GetBinContent(ibin + 1);
 
  602       float histErr = dataHist_p->GetBinError(ibin + 1);
 
  603       float pull = (histVal - fitVal)/histErr;
 
  613   double amplCorrFactor  = 1;
 
  619     amplCorrFactor *= fadcCorr;
 
  631     float invNLCorr = 1.0;
 
  645     amplCorrFactor /= invNLCorr;  
 
  648   return amplCorrFactor;
 
  653   float prePulseTMin = 0;
 
  747     (*m_msgFunc_p)(
ZDCMsg::Fatal, 
"ZDCPulseAnalyzer::LoadAndAnalyzeData:: Wrong LoadAndAnalyzeData called -- expecting both delayed and undelayed samples");
 
  770                       const std::vector<float>& ADCSamplesHGDelayed, 
const std::vector<float>& ADCSamplesLGDelayed)
 
  773     (*m_msgFunc_p)(
ZDCMsg::Fatal, 
"ZDCPulseAnalyzer::LoadAndAnalyzeData:: Wrong LoadAndAnalyzeData called -- expecting only undelayed samples");
 
  795   for (
size_t isample = 0; isample < 
m_Nsample; isample++) {
 
  796     float ADCHG = ADCSamplesHG[isample];
 
  797     float ADCLG = ADCSamplesLG[isample];
 
  838   bool doDump = (*m_msgFunc_p)(
ZDCMsg::Verbose, 
"Dumping all samples before subtraction: ");
 
  856   for (
size_t isample = 0; isample < 
m_NSamplesAna; isample++) {
 
  879     std::ostringstream dumpString;
 
  880     dumpString << 
"After FADC correction, sample " << isample << 
", HG ADC = " << 
m_ADCSamplesHGSub[isample]
 
  997     if (m_lastHGOverFlowSample < 2 && m_lastHGOverFlowSample > -1) {
 
 1019   float deriv2ndThreshHG = 0;
 
 1020   float deriv2ndThreshLG = 0;
 
 1124                                    const std::vector<float>& samples,        
 
 1125                                    const std::vector<bool>& useSample,       
 
 1126                                    float peak2ndDerivMinThresh,
 
 1128                                    const std::vector<float>& t0CorrParams,   
 
 1129                                    float maxChisqDivAmp,                     
 
 1130                                    float minT0Corr, 
float maxT0Corr          
 
 1143   bool haveFirst = 
false;
 
 1144   unsigned int lastUsed = 0;
 
 1204       std::ostringstream baselineMsg;
 
 1205       baselineMsg << 
"Delayed samples baseline correction = " << 
m_baselineCorr << std::endl;
 
 1211     for (
size_t isample = 0; isample < 
nSamples; isample++) {
 
 1222   std::for_each(
m_samplesSub.begin(), 
m_samplesSub.end(), [ = ] (
float & adcUnsub) {return adcUnsub -= m_preSample;} );
 
 1295     if (derivPresampleSig < -5) {
 
 1301       if (!useSample[isample]) 
continue;
 
 1303       float sampleSig = -
m_samplesSub[isample]/(std::sqrt(2.0)*noiseSig);
 
 1319     float maxPrepulseSig = 0;
 
 1320     unsigned int maxPrepulseSample = 0;
 
 1322     for (
int isample = loopStart; isample <= loopLimit; isample++) {
 
 1323       if (!useSample[isample]) 
continue;
 
 1339     if (prePulseSig > maxPrepulseSig) {
 
 1340       maxPrepulseSig = prePulseSig;
 
 1341       maxPrepulseSample = isample;
 
 1376     for (
int isample = postStartIdx; isample < (
int) 
nSamples - 1; isample++) {
 
 1377       if (!useSample.at(isample)) 
continue;
 
 1408       float derivSig = deriv/(std::sqrt(2)*noiseSig);
 
 1417     if (std::abs(deriv2ndTest) > 0.15) {
 
 1430       if (deriv2ndSig > 5 && deriv2ndTest < -0.1) {
 
 1441     std::ostringstream ostrm;
 
 1442     ostrm << 
"Post pulse found, m_maxSampleEvt = " << 
m_maxSampleEvt;
 
 1460     std::ostringstream ostrm;
 
 1479       for (
unsigned int ipow = 0; ipow < t0CorrParams.size(); ipow++) {
 
 1488     bool failFixedCut = m_fitTimeCorr < minT0Corr || m_fitTimeCorr > maxT0Corr;
 
 1498       double timeResolution = 0;
 
 1510       if (failFixedCut) 
m_badT0 = 
true;
 
 1530                       const std::vector<bool>& useSamples)
 
 1539   for (
unsigned int idx = 0; 
idx < samplesLG.size(); 
idx++) {
 
 1542     if (useSamples[
idx]) {
 
 1556   TH1* hist_p = 
nullptr;
 
 1561   float ampInitial, fitAmpMin, fitAmpMax, t0Initial;
 
 1582   if (ampInitial < fitAmpMin) ampInitial = fitAmpMin * 1.5;
 
 1604     fitWrapper->
Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
 
 1623   int fitStatus = result_ptr;
 
 1629   if (fitStatus != 0 && result_ptr->Edm() > 0.001) 
 
 1639     if ((
int) constrFitResult_ptr != 0) {
 
 1649       if ((
int) unconstrFitResult_ptr != 0) {
 
 1656     if ((
int) constrFit2Result_ptr != 0) {
 
 1663     result_ptr = constrFit2Result_ptr;
 
 1667     result_ptr = unconstrFitResult_ptr;
 
 1673     hist_p->GetListOfFunctions()->Clear();
 
 1676     std::string 
name = func->GetName();
 
 1678     TF1* copyFunc = 
static_cast<TF1*
>(func->Clone((
name + 
"_copy").c_str()));
 
 1679     hist_p->GetListOfFunctions()->Add(copyFunc);
 
 1729   TH1* hist_p = 
nullptr, *delayedHist_p = 
nullptr;
 
 1741   float fitAmpMin, fitAmpMax, t0Initial, ampInitial;
 
 1757   if (ampInitial < fitAmpMin) ampInitial = fitAmpMin * 1.5;
 
 1783     fitWrapper->
Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
 
 1788   TFitter* theFitter = 
nullptr;
 
 1812   size_t numFitPar = theFitter->GetNumberTotalParameters();
 
 1814   theFitter->GetMinuit()->fISW[4] = -1;
 
 1819     theFitter->GetMinuit()->fISW[4] = -1;
 
 1822     theFitter->GetMinuit()->mnexcm(
"SET NOWarnings",
nullptr,0,ierr);
 
 1824   else theFitter->GetMinuit()->fISW[4] = 0;
 
 1829     theFitter->SetParameter(0, 
"delayBaselineAdjust", 0, 0.01, -100, 100);
 
 1830     theFitter->ReleaseParameter(0);
 
 1833     theFitter->SetParameter(0, 
"delayBaselineAdjust", 0, 0.01, -100, 100);
 
 1834     theFitter->FixParameter(0);
 
 1838   double arglist[100];
 
 1841   int status = theFitter->ExecuteCommand(
"MIGRAD", arglist, 2);
 
 1843   double fitAmp = theFitter->GetParameter(1);
 
 1847   double chi2, edm, errdef;
 
 1850   theFitter->GetStats(
chi2, edm, errdef, nvpar, nparx);
 
 1855   if (
status || fitAmp < fitAmpMin * 1.01 || edm > 0.01){
 
 1860     theFitter->SetParameter(0, 
"delayBaselineAdjust", 0, 0.01, -100, 100);
 
 1861     theFitter->FixParameter(0);
 
 1865     if (fitAmp < fitAmpMin * 1.01) {
 
 1871         fitWrapper->
Initialize(ampInitial, t0Initial, fitAmpMin, fitAmpMax);
 
 1875     status = theFitter->ExecuteCommand(
"MIGRAD", arglist, 2);
 
 1880       theFitter->ReleaseParameter(0);
 
 1888       theFitter->ReleaseParameter(0);
 
 1889       status = theFitter->ExecuteCommand(
"MIGRAD", arglist, 2);
 
 1894         theFitter->SetParameter(0, 
"delayBaselineAdjust", 0, 0.01, -100, 100);
 
 1895         theFitter->FixParameter(0);
 
 1896         status = theFitter->ExecuteCommand(
"MIGRAD", arglist, 2);
 
 1904   fitAmp = theFitter->GetParameter(1);
 
 1908   if (fitAmp < fitAmpMin * 1.01) {
 
 1919   if (!
m_quietFits) theFitter->GetMinuit()->fISW[4] = -1;
 
 1921   std::vector<double> funcParams(numFitPar - 1);
 
 1922   std::vector<double> funcParamErrs(numFitPar - 1);
 
 1930   for (
size_t ipar = 1; ipar < numFitPar; ipar++) {
 
 1931     funcParams[ipar - 1] = theFitter->GetParameter(ipar);
 
 1932     funcParamErrs[ipar - 1] = theFitter->GetParError(ipar);
 
 1940   theFitter->GetStats(
chi2, edm, errdef, nvpar, nparx);
 
 1960     theFitter->ExecuteCommand(
"Cal1fcn", arglist, 1);
 
 2002   for (
int ipar = 0; ipar < func->GetNpar(); ipar++) {
 
 2003     double parLimitLow, parLimitHigh;
 
 2005     func->GetParLimits(ipar, parLimitLow, parLimitHigh);
 
 2008                   "ZDCPulseAnalyzer name=" + std::string(func->GetName())
 
 2016     if (std::abs(parLimitHigh - parLimitLow) > (1
e-6)*std::abs(parLimitLow)) {
 
 2017       double value = func->GetParameter(ipar);
 
 2018       if (
value >= parLimitHigh) {
 
 2019     value = parLimitHigh * 0.9;
 
 2021       else if (
value <= parLimitLow) {
 
 2022     value = parLimitLow + 0.1*std::abs(parLimitLow);
 
 2024       func->SetParameter(ipar, 
value);
 
 2031   TVirtualFitter::SetDefaultFitter(
"Minuit");
 
 2033   size_t nFitParams = func->GetNpar() + 1;
 
 2034   std::unique_ptr<TFitter> 
fitter = std::make_unique<TFitter>(nFitParams);
 
 2036   fitter->GetMinuit()->fISW[4] = -1;
 
 2037   fitter->SetParameter(0, 
"delayBaselineAdjust", 0, 0.01, -100, 100);
 
 2039   for (
size_t ipar = 0; ipar < nFitParams - 1; ipar++) {
 
 2040     double parLimitLow, parLimitHigh;
 
 2042     func->GetParLimits(ipar, parLimitLow, parLimitHigh);
 
 2043     if (std::abs(parLimitHigh / parLimitLow - 1) < 1
e-6) {
 
 2044       double value   = func->GetParameter(ipar);
 
 2048       fitter->SetParameter(ipar + 1, func->GetParName(ipar), func->GetParameter(ipar), 0.01, lowLim, highLim);
 
 2049       fitter->FixParameter(ipar + 1);
 
 2052       double value = func->GetParameter(ipar);
 
 2053       if (
value >= parLimitHigh)     
value = parLimitHigh * 0.99;
 
 2054       else if (
value <= parLimitLow) 
value = parLimitLow * 1.01;
 
 2056       double step = 
std::min((parLimitHigh - parLimitLow)/100., (
value - parLimitLow)/100.);
 
 2058       fitter->SetParameter(ipar + 1, func->GetParName(ipar), 
value, 
step, parLimitLow, parLimitHigh);
 
 2069   double parLimitLow, parLimitHigh;
 
 2072   func_p->GetParLimits(1, parLimitLow, parLimitHigh);
 
 2074   fitter->SetParameter(2, func_p->GetParName(1), func_p->GetParameter(1), 0.01, parLimitLow, parLimitHigh);
 
 2079     func_p->GetParLimits(parIndex, parLimitLow, parLimitHigh);
 
 2080     fitter->SetParameter(parIndex + 1, func_p->GetParName(parIndex), func_p->GetParameter(parIndex), 0.01, parLimitLow, parLimitHigh);
 
 2095   std::ostringstream message1;
 
 2096   message1 << 
"samplesSub ";
 
 2102   std::ostringstream message3;
 
 2103   message3 << 
"samplesDeriv2nd ";
 
 2114   std::string 
message = 
"Dump of TF1: " + std::string(func->GetName());
 
 2116   if (!continueDump) 
return;
 
 2118   unsigned int npar = func->GetNpar();
 
 2119   for (
unsigned int ipar = 0; ipar < npar; ipar++) {
 
 2120     std::ostringstream msgstr;
 
 2122     double parMin = 0, parMax = 0;
 
 2123     func->GetParLimits(ipar, parMin, parMax);
 
 2125     msgstr << 
"Parameter " << ipar << 
", value = " << func->GetParameter(ipar) << 
", error = " 
 2126        << func->GetParError(ipar) << 
", min = " << parMin << 
", max = " << parMax;
 
 2133   std::ostringstream ostrStream;
 
 2135   (*m_msgFunc_p)(
ZDCMsg::Info, (
"ZDCPulserAnalyzer:: settings for instance: " + 
m_tag));
 
 2137   ostrStream << 
"Nsample = " << 
m_Nsample << 
" at frequency " << 
m_freqMHz << 
" MHz, preSample index = " 
 2140   (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2143   (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2148   (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2151     ostrStream << 
"using delayed samples with delta T = " << 
m_delayedDeltaT << 
", and default pedestalDiff == " 
 2153     (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2159   (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2163   (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2168   (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2172     (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2176     ostrStream << 
"Pre-exclusion enabled for up to " << 
m_maxSamplesPreExcl << 
", samples with ADC threshold HG = " 
 2178     (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2181     ostrStream << 
"Post-exclusion enabled for up to " << 
m_maxSamplesPostExcl << 
", samples with ADC threshold HG = " 
 2183     (*m_msgFunc_p)(
ZDCMsg::Info, ostrStream.str()); ostrStream.str(
""); ostrStream.clear();
 
 2190   unsigned int statusMask = 0;
 
 2226   TH1* hist_p = 
nullptr, *delayedHist_p = 
nullptr;
 
 2236   std::shared_ptr<TGraphErrors> theGraph = std::make_shared<TGraphErrors>(TGraphErrors(2 * 
m_Nsample));
 
 2239   for (
int ipt = 0; ipt < hist_p->GetNbinsX(); ipt++) {
 
 2240     theGraph->SetPoint(npts, hist_p->GetBinCenter(ipt + 1), hist_p->GetBinContent(ipt + 1));
 
 2241     theGraph->SetPointError(npts++, 0, hist_p->GetBinError(ipt + 1));
 
 2244   for (
int iDelayPt = 0; iDelayPt < delayedHist_p->GetNbinsX(); iDelayPt++) {
 
 2245     theGraph->SetPoint(npts, delayedHist_p->GetBinCenter(iDelayPt + 1), delayedHist_p->GetBinContent(iDelayPt + 1) - 
m_delayedBaselineShift);
 
 2246     theGraph->SetPointError(npts++, 0, delayedHist_p->GetBinError(iDelayPt + 1));
 
 2249     TF1* func_p = 
static_cast<TF1*
>(hist_p->GetListOfFunctions()->Last());
 
 2251       theGraph->GetListOfFunctions()->Add(
new TF1(*func_p));
 
 2252       hist_p->GetListOfFunctions()->SetOwner (
false);
 
 2255   theGraph->SetName(( std::string(hist_p->GetName()) + 
"combinaed").c_str());
 
 2257   theGraph->SetMarkerStyle(20);
 
 2258   theGraph->SetMarkerColor(1);
 
 2271   std::shared_ptr<TGraphErrors> theGraph = std::make_shared<TGraphErrors>(TGraphErrors(
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   TF1* func_p = 
static_cast<TF1*
>(hist_p->GetListOfFunctions()->Last());
 
 2280   theGraph->GetListOfFunctions()->Add(func_p);
 
 2281   theGraph->SetName(( std::string(hist_p->GetName()) + 
"not_combinaed").c_str());
 
 2283   theGraph->SetMarkerStyle(20);
 
 2284   theGraph->SetMarkerColor(1);
 
 2292   unsigned int nSamples = inputData.size();
 
 2297   std::vector<float> 
results(vecSize, 0);
 
 2301   unsigned int fillIdx = 
step - 1;
 
 2305     results.at(fillIdx++) = deriv;
 
 2313   unsigned int nSamples = inputData.size();
 
 2319   std::vector<float> 
results(vecSize, 0);
 
 2321   unsigned int fillIndex = 
step;
 
 2324     results.at(fillIndex++) = deriv2nd;
 
 2345   const unsigned int nsamples = samples.size();
 
 2353   float minScore = 1.0e9;
 
 2354   unsigned int minIndex = 0;
 
 2357     float deriv = derivVec[
idx];
 
 2358     float prevDeriv = derivVec[
idx - 1];
 
 2360     float derivDiff = deriv - prevDeriv;
 
 2362     float deriv2nd = deriv2ndVec[
idx];
 
 2368     float score = (deriv*deriv + 2*derivDiff*derivDiff +
 
 2369            0.5*deriv2nd*deriv2nd);
 
 2371     if (
score < minScore) {
 
 2382   if (minIndex<2 or (minIndex+1) >=
nsamples){
 
 2383     throw std::out_of_range(
"minIndex out of range in ZDCPulseAnalyzer::obtainDelayedBaselineCorr");
 
 2385   float sample0 = samples[minIndex - 2];
 
 2386   float sample1 = samples[minIndex - 1];
 
 2387   float sample2 = samples[minIndex];
 
 2388   float sample3 = samples[minIndex + 1];
 
 2392   float baselineCorr = (0.5 * (sample1 - sample0 + sample3 - sample2) -
 
 2393             0.25 * (sample3 - sample1 + sample2 - sample0));
 
 2395   if (minIndex % 2 != 0) baselineCorr =-baselineCorr;
 
 2397   return baselineCorr;
 
 2403   std::string resultString = 
"success";
 
 2411       auto jsonType = 
iter.value().type();
 
 2412       auto paramType = std::get<0>(
descr);
 
 2413       if (jsonType != paramType) {
 
 2415     resultString = 
"Bad type for parameter " + 
key + 
", type in JSON = " + 
std::to_string((
unsigned int) jsonType) ;
 
 2419       size_t paramSize = std::get<1>(
descr);
 
 2420       size_t jsonSize = 
iter.value().size();
 
 2421       if (jsonSize != paramSize) {
 
 2423     resultString = 
"Bad length for parameter " + 
key + 
", length in JSON = " + 
std::to_string(jsonSize) ;
 
 2431     resultString = 
"Missing required parameter " + 
key;
 
 2450     resultString = 
"Unknown parameter, key = " + 
key;
 
 2456   return {
result, resultString};
 
 2462   std::string resultString = 
"success";
 
 2491     else if (
key == 
"T0CutsHG") {
 
 2495     else if (
key == 
"T0CutsLG") {
 
 2508     else if (
key == 
"fitAmpMinMaxHG") {
 
 2512     else if (
key == 
"fitAmpMinMaxLG") {
 
 2516     else if (
key == 
"quietFits") {
 
 2519     else if (
key == 
"enablePreExclusion") {
 
 2525     else if (
key == 
"enablePostExclusion") {
 
 2531     else if (
key == 
"ampMinSignifHGLG") {
 
 2536     else if (
key == 
"enableFADCCorrections") {
 
 2537       auto fileNameJson = 
value[
"filename"];
 
 2538       auto doPerSampleCorrJson = 
value[
"doPerSampleCorr"];
 
 2540       if (fileNameJson.is_null() || doPerSampleCorrJson.is_null()) {
 
 2542     std::string resultString = 
"failure processing enableFADCCorrections object";
 
 2552       std::string resultString = 
"unprocessed parameter";
 
 2557   return {
result, resultString};