Problems with fit with a complicated function

I try to perform a fit with a complicated function. The problem is that it sometimes works, sometimes does not. I attach here a simplified example with only one data set. The fitted parameters (function position in respect to the histogram) nearly do not change and fit fails. From a simplified fit I know that these parameters should change and fit with a simpler function converges (for example gaussian 2d). Perhaps, dear ROOTers, someone could tell me, why I cannot get a successfull fit, while, after visual inspection, it seems that the function describes the data?

I attach the source code, unfortunately it is fairly complicated:

  1. The function fitted is mpsf. It is a set of modyfied zernike polynomials, convoluted during the calculation with a pixel response function (prf). The polynomial weights and the pixel response function are read from histograms in par_histos.root. The weights do not change during the fit, but the parts of prf used for calculation change with the position parameters of the mpsf.

  2. Background for the function is calculated as the median of the data histogram. Scaling parameter is calculated manually for each new position for which mpsf is calculated (calc_scale_offset()).

So we have numerical fit of position parameters and analytical fit of the scaling parameter, performed during the fit.

  1. The fit excludes some points, because the fitting area is not rectangular (so cannot be properly adjusted with SetRange()).

  2. The fit involves caching of the function. The main function mpsf (calculated in multifun()) is cached, as well as parts of zernike polynomials (Rmnro_mat[n][m] in zernike_polynomials()).

I have checked the code and results many times and cannot find any errors. The function converges if made a little bit simpler, for example if calculated only one polynomial (uncomment line 178 in zernike_fit_area_speedup.h). However, in given example, the function with only this one polynomials and with all polynomials is very similar, for it is just an approximation of a 2D symmetrical gaussian. So in theory it should converge very similarily in both cases.

As you can see in the code, I’ve tried multiple fitting methods. Setting tolerance to a very large values makes the fit converge, but to a wrong parameters. I’d really apprieciate any help :slight_smile:

The required files (5 MB, too large for a forum attachment) can be downloaded from

OK, I found out that the caching was not dense enough and caused a lot of local minima in the chi2. Each fitting method converged to a slightly different local minimum.