Warning when setting TF1 parameter lower and upper bounds

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:

@moneta can you perhaps give a hand with this one? Thanks!

Hi,

It looks to me that you are setting the parameter values outside its limits. I don’t understand these lines

t_function -> SetParameter(0, PAR_LIMITS[0].first + rndGen.Rndm(PAR_LIMITS[0].second - PAR_LIMITS[0].first));

what is rndGen.Rndm( x) ?
are you sure with these lines you don’t set a value outside the limits ?

Concerning your other question, the Clone will preserve the parameter limits

Cheers

Lorenzo

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.