Hey there,
When fitting TH1F
histograms, i seem to randomly get the error message:
ROOT::Math::ParameterSettings>: lower/upper bounds outside current parameter value. The value will be set to (low+up)/2
I found a related thread saying that I should make sure, that my default parameter values are between the set limits. However, this should be true for my TF1
objects.
Here is how I use them:
Generating a function to be cloned when fitting a new TH1F
:
TF1* HistogramFitter::ascendingSigmoidTemplate =
new TF1("ascendingSigmoidTemplate", "[0] / ((1 + exp([1] - x) / [2]))"); // Static member
Setting default parameter values and limits:
HistogramFitter::ascendingSigmoidTemplate -> SetParameter(0, 0.5 * (PAR_LIMITS[0].first + PAR_LIMITS[0].second));
HistogramFitter::ascendingSigmoidTemplate -> SetParameter(1, 0.5 * (PAR_LIMITS[1].first + PAR_LIMITS[1].second));
HistogramFitter::ascendingSigmoidTemplate -> SetParameter(2, 0.5 * (PAR_LIMITS[2].first + PAR_LIMITS[2].second));
HistogramFitter::ascendingSigmoidTemplate -> SetParLimits(0, PAR_LIMITS[0].first, PAR_LIMITS[0].second);
HistogramFitter::ascendingSigmoidTemplate -> SetParLimits(1, PAR_LIMITS[1].first, PAR_LIMITS[1].second);
HistogramFitter::ascendingSigmoidTemplate -> SetParLimits(2, PAR_LIMITS[2].first, PAR_LIMITS[2].second);
Generating a unique TF1
each time I fit a histogram:
static auto generateAscendingSigmoidName = [i = 0] () mutable { return "ascendingSigmoid_" + std::to_string(i++); };
TF1* ascendingSigmoid = static_cast<TF1*>(ascendingSigmoidTemplate -> Clone(generateAscendingSigmoidName().c_str()));
Trying to find initial parameter values that will converge:
// This is inside an infinite loop
// rndGen is a TRandom3 object
t_function -> SetParameter(0, PAR_LIMITS[0].first + rndGen.Rndm(PAR_LIMITS[0].second - PAR_LIMITS[0].first));
t_function -> SetParameter(1, PAR_LIMITS[1].first + rndGen.Rndm(PAR_LIMITS[1].second - PAR_LIMITS[1].first));
t_function -> SetParameter(2, PAR_LIMITS[2].first + rndGen.Rndm(PAR_LIMITS[2].second - PAR_LIMITS[2].first));
TFitResultPtr fitResults = t_histogram -> Fit(t_function -> GetName(), "QNRMS", "", t_lowerBound, t_upperBound);
(...) // check fitResults until it converges, or certain number of attempts are performed
Am I doing something wrong? (Will cloning not preserve paramter limits?)
Cheers,
Adam Hunyadi
Related thread: