File indexing completed on 2026-10-30 08:34:03
0001 #ifndef LFHCAL_FIT_CURVE_DRAWING_H
0002 #define LFHCAL_FIT_CURVE_DRAWING_H
0003
0004 #include <algorithm>
0005 #include <cmath>
0006 #include <stdexcept>
0007 #include <string>
0008 #include <TF1.h>
0009 #include <TGraph.h>
0010 #include <TError.h>
0011
0012 namespace lfhcal {
0013
0014
0015
0016
0017 inline TGraph SampleMipFit(const TF1& fit, double visibleLow, double visibleHigh) {
0018 const double lo = visibleLow;
0019 const double hi = visibleHigh;
0020 TGraph graph;
0021 graph.SetName((std::string(fit.GetName()) + "_evaluated_curve").c_str());
0022 graph.SetLineColor(fit.GetLineColor());
0023 graph.SetLineStyle(fit.GetLineStyle());
0024 graph.SetLineWidth(fit.GetLineWidth());
0025 if (!(hi > lo)) return graph;
0026 if (fit.GetNpar() < 4 || !std::isfinite(fit.GetParameter(0)) ||
0027 !std::isfinite(fit.GetParameter(3)) || fit.GetParameter(0) <= 0. ||
0028 fit.GetParameter(3) <= 0.)
0029 throw std::runtime_error("invalid Langau widths in fit drawing");
0030
0031
0032
0033 double step = std::min((hi-lo)/1000., fit.GetParameter(0)/16.);
0034
0035 if (fit.GetNpar() == 7 && std::isfinite(fit.GetParameter(6)) &&
0036 fit.GetParameter(6) > 0.)
0037 step = std::min(step, fit.GetParameter(6)/16.);
0038 if (fit.GetParameter(0) < .2*fit.GetParameter(3))
0039 step = std::min(step, fit.GetParameter(3)/320.);
0040 const double intervals = std::ceil((hi-lo)/step);
0041
0042
0043 if (!std::isfinite(intervals) || intervals > 200000.)
0044 throw std::runtime_error("fit drawing exceeds 200000-interval rendering budget");
0045 const int n = static_cast<int>(intervals);
0046 graph.Set(n+1);
0047 for (int i=0; i<=n; ++i) {
0048 const double x = lo + (hi-lo)*i/n;
0049 const double y = fit.Eval(x);
0050 if (!std::isfinite(y)) throw std::runtime_error("nonfinite fit drawing value");
0051 graph.SetPoint(i,x,y);
0052 }
0053 return graph;
0054 }
0055
0056
0057
0058
0059 inline TGraph* DrawMipFit(const TF1& fit, double lo, double hi) {
0060 try {
0061 auto* drawn = new TGraph(SampleMipFit(fit,lo,hi));
0062 if (drawn->GetN() == 0) { delete drawn; return nullptr; }
0063 drawn->SetBit(TObject::kCanDelete);
0064 drawn->Draw("L SAME");
0065 return drawn;
0066 } catch (const std::exception& e) {
0067 Warning("DrawMipFit", "%s: %s", fit.GetName(), e.what());
0068 return nullptr;
0069 }
0070 }
0071
0072 }
0073 #endif