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:
-
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.
-
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.
-
The fit excludes some points, because the fitting area is not rectangular (so cannot be properly adjusted with SetRange()).
-
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
The required files (5 MB, too large for a forum attachment) can be downloaded from fuw.edu.pl/~lewhoo/transfer/test_fit.zip