Fitfunc report only for fit convergence
maru
Hi,
I am using Fitfunc command to fit 1000 data sets with a user defined fit function. I want to know which fit was NOT converged properly.
However, general report in command line contains too many information.
Can I simply get the wave name of non-converged fits? I have tried to use V_flag but it does not report properly.
Look at DisplayHelpTopic "Special Variables for Curve Fitting"
August 30, 2019 at 02:43 am - Permalink
Here is something that I use in a user function that reports an error if a fit fails. Maybe that helps.
Wave Mask
variable enA, widthA, enB, widthB
wave/Z cube
wave/Z M_Groups
if(!WaveExists(cube) || !WaveExists(M_Groups))
return $""
endif
variable timer = StartMStimer
variable rows = DimSize(M_Groups, 0)
variable cols = DimSize(M_Groups, 1)
Make/D/O/N=(rows, cols) M_Ratio = NaN
//SET CURVE FIT OPTIONS
variable/G V_FitOptions = 4
variable/G V_FitError = 0
variable ErrorCount = 0
// set the energy/channel ranges over which the gaussian peaks are fitted
variable lowA = enA - widthA
variable highA = enA + widthA
variable lowB = enB - widthB
variable highB = enB + widthB
variable i,j, PeakA, PeakB
for (i=0; i<cols; i+=1)
for (j=0; j<rows; j+=1)
if (mask[j][i]) // fit pixel if M_Mask is 1
// Extract spectrum from cube and scale energy
MatrixOP/O spec = beam(cube, j, i)
wave spec
SetScale/P x 0, 0.01, spec
try
// fit first peak
K0 = 0; K2 = enA
CurveFit/Q/H="1010"/NTHR=0 gauss spec(lowA,highA) /D; AbortOnRTE
wave peak = $"fit_Spec"
PeakA = area(peak)
// fit second peak
K0 = 0; K2 = enB
CurveFit/Q/H="1010"/NTHR=0 gauss spec(lowB,highB) /D; AbortOnRTE
PeakB = area(peak)
M_Ratio[j][i] = PeakA/PeakB
catch
if (V_AbortCode == -4)
ErrorCount +=1
variable CFerror = GetRTError(1)
printf "Curve fit error at coordinate %g, %g: %s\r", j, i, GetErrMessage(CFError)
M_Ratio[j][i] =NaN
endif
endtry
endif
endfor
endfor
// clean up
KillWaves/Z W_coef, W_sigma, Spec, fit_Spec
printf "%g pixels not fitted due to CurveFit errors.\r", errorcount
Printf "Time: %g seconds \r", stopMStimer(timer)/1e6
return M_Ratio
end
August 30, 2019 at 03:07 am - Permalink
In reply to Look at DisplayHelpTopic … by olelytken
Thanks for the advice. I found V_FitNumIters and can get the iteration number to check if the fit is converged.
August 30, 2019 at 05:18 am - Permalink
In reply to olelytken wrote: Look at… by maru
I'm not sure this is a good way to do it. I would use a combination of V_fitError and V_fitQuitReason:
Variable V_FitQuitReason = 0
FuncFit ...
if (V_FitError)
... handle error such as singular matrix ...
endif
if (V_FitQuitReason == 1) // max iterations without convergence
... do something about it ...
endif
Note that you need to create these variables yourself. Also, you should zero them right before calling CurveFit or FuncFit.
August 30, 2019 at 09:36 am - Permalink
In reply to maru wrote: Thanks for… by johnweeks
Thanks! This solution is much better.
September 1, 2019 at 05:31 am - Permalink