Fitfunc report only for fit convergence

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.

Here is something that I use in a user function that reports an error if a fit fails. Maybe that helps.

 

 

function/WAVE PeakFitRatios(Mask, enA, widthA, enB, widthB)  
    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

 

In reply to by maru

maru wrote:

Thanks for the advice. I found V_FitNumIters and can get the iteration number to check if the fit is converged.

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_FitError = 0
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.