Viewing contents of file '../idllib/contrib/tappin/graffer/gr_fit_dset.pro'
;+
; GR_FIT_DSET
;	Select a data set to do a least-squares fit.
;
; Usage:
;	ichange = graff_ch_dset(pdefs)
;
; Return value:
;	ichange	int	1 if the DO button was used, 0 if cancel
;
; Argument:
;	pdefs	struct	input	The plot definition structure.
;
; History:
;	Original (from GRAFF_CH_DSET): 28/8/96; SJT
;	Modify to support median fits and simplify internal
;	representations: 23/9/96; SJT
;	Change to make this the outer routine & allow higher degree
;	fits: 22/11/96; SJT
;	Shorten name: 25/11/96; SJT
;	Made to function returning "cancel" state: 18/12/96; SJT
;	Add options to do "piecewise linear" fits: 4/2/97; SJT
;	Reorganize to give neater layout: 5/2/97; SJT
;	Add capture key to input boxes: 6/2/97; SJT
;-

function Grf_fit_event, event

base = widget_info(event.top, /child)
widget_control, base, get_uvalue = uv, /no_copy
widget_control, event.id, get_uvalue = but

iexit = 0;	Change to make this the outer routine & allow higher degree
;	fits: 22/11/96; SJT

case (but) of
    'POP': begin
        widget_control, event.top, /show
        widget_control, event.id, timer = 2.0
    end
    
    'CHOOSE': begin
        uv.chosen = event.index
        widget_control, uv.chid, set_value = uv.list(event.index)
        widget_control, uv.dobid, /sensitive
        widget_control, uv.upid, /sensitive
    end
    
    'FITT': uv.type(0) = event.index
    'FITD': if (event.index ne uv.type(1)) then begin
        if (uv.type(0) eq 1 or uv.type(0) eq 2) then begin
            uv.type(0) = uv.type(0) xor 3
            widget_control, uv.ftype, set_value = uv.type(0)
        endif
        uv.type(1) = event.index
    endif
    'FITN': begin
        uv.type(2) = event.index
        widget_control, uv.degid, sensitive = (event.index eq 0)
    end
        
    'DONT': iexit = -1
    'DO': begin
        iexit = 1
        widget_control, uv.nid, get_value = np
        uv.np = np
        widget_control, uv.part, get_value = sl
        uv.slice = sl
        widget_control, uv.degid, get_value = dg
        uv.type(3) = dg
    end
    'UPDATE': begin
        iexit = 2
        widget_control, uv.nid, get_value = np
        uv.np = np
        widget_control, uv.part, get_value = sl
        uv.slice = sl
        widget_control, uv.degid, get_value = dg
        uv.type(3) = dg
    end
    
end

widget_control, base, set_uvalue = uv, /no_copy

return, {id:event.handler, top:event.top, handler:event.handler, $
         Exit:iexit}
end






function Gr_fit_dset, pdefs

handle_value, pdefs.data, data, /no_copy

fflag = (data(pdefs.cset).type eq -1 or  $
         data(pdefs.cset).type eq -2 or $
         data(pdefs.cset).ndata eq 0)

tc = ['PF', 'F(Y)', 'F(X)', 'XY', 'XYE', 'XYEE', 'XYF', 'XYFF', $
      'XYFE', 'XYFEE', 'XYFFE', 'XYFFEE']
fitts = ['Polynomial', '"Exponential"', '"Logarithmic"', '"Power-law"', $
         'Piecewise linear']
fittd = pdefs.ytype + 2*pdefs.xtype

fitn = ['Least Square', '"Median"']

fitd = ['y = f(x)', 'x = f(y)']

dlist = data.descript

nlist = string(indgen(n_elements(dlist)), $
               format = "(I3,')')")

llist = string(data.ndata, format = "(' <',I0,'> ')")
lll = max(strlen(llist))
fmt = "(A"+string(lll, format = "(I0)")+")"
llist = string(llist, format = fmt)
nlist = nlist+llist
nlist = nlist+string([tc(data.type+3)], format = "(A6, ' - ')")

dlist = nlist+dlist
arexyd = where(data.type ge 0 and data.type le 8 $
               and data.ndata ge 2, nxy) ; Only X/Y datasets

widget_control, pdefs.ids.graffer, sensitive = 0

if (nxy eq 0) then begin
    message = ['No suitable datasets', $
               'Cannot perform fitting']
    tlb = widget_base(title = 'Graffer: No XY Data', group = $
                      pdefs.ids.graffer, resource = 'Graffer')
    
    base = widget_base(tlb, /column, uvalue = 1)
    
    junk = widget_text(base, value = message, xsize = $
                       max(strlen(message)), ysize = n_elements(message))
    
    junk = widget_button(base, value = 'Dismiss', uvalue = 'DONT')
    
endif else begin
    dlist = dlist(arexyd)
    

    tlb = widget_base(title = 'Graffer data set select', group = $
                      pdefs.ids.graffer, resource = 'Graffer')
    base = widget_base(tlb, /column)
    if (not fflag) then $
      junk = widget_text(base, xsize = 60, ysize = 3, value = $
                         ['CURRENT DATA SET IS XY DATA OR A PARAMETRIC', $
                          'FUNCTION ENTERING A FUNCTION WILL OVERWRITE', $
                          'IT. USE "CANCEL" NOW TO KEEP IT' $
                         ] $
                        )

    b1 = widget_base(base, /row)

    jb = widget_base(b1, /column)
    curr = widget_label(jb, value = 'Data Sets', uvalue = 'POP')
    junk = widget_list(jb, value = dlist, uvalue = 'CHOOSE', $
                       ysize = (8 < n_elements(dlist)))

    choice = graff_enter(jb, value = '', /text, /no_event, /display, $
                         xsize = max(strlen(dlist)), label = 'Current ' + $
                         'Selection', /column)


    jb = widget_base(b1, /column, /base_align_right, xpad = 1, ypad = $
                     1, space = 1)
    ftp = cw_bbselector(jb, fitts, label_left = 'Fit type', $
                        /return_index, set_value = fittd, uvalue = $
                        'FITT')
    junk = cw_bbselector(jb, fitn, label_left = 'Fit norm', /return_index, $
                         set_value = 0, uvalue = 'FITN')
    junk = cw_bbselector(jb, fitd, label_left = 'Fit sense', /return_index, $
                         set_value = 0, uvalue = 'FITD')

    degid = graff_enter(jb, /int, value = 1, /no_event, xsize = 3, label = $
                        'Degree:', /capture) 

    npts = graff_enter(jb, /int, value = 25, /no_event, xsize = 3, label = $
                       '# evaluations:', /capture)
    part = graff_enter(jb, /text, value = '', /no_event, xsize = 15, label $
                       = 'Slice:', /capture)

    jb = widget_base(base, /column, /align_center, /base_align_center)
    resid = graff_enter(jb, /text, value = '', /no_event, /display, $
                        xsize = 40, label = 'Fit', /column)
    csqid = graff_enter(jb, /float, value = 0., /no_event, /display, $
                        xsize = 14, label = 'Prob chance:')

    jb = widget_base(base, /row, /align_center)
    junk = widget_button(jb, value = '   Cancel   ', uvalue = 'DONT')
    upid = widget_button(jb, value = '   Update   ', uvalue = 'UPDATE')
    dobid = widget_button(jb, value = '    Do it    ', uvalue = 'DO')
    widget_control, dobid, sensitive = 0
    widget_control, upid, sensitive = 0

    widget_control, base, set_uvalue = {chosen: 0, $
                                        List:   dlist, $
                                        Chid:   choice, $
                                        Degid:  degid, $
                                        Nid:    npts, $
                                        Dobid:  dobid, $
                                        Upid:   upid, $
                                        Part:   part, $
                                        Ftype:  ftp, $
                                        Np:     25, $
                                        Slice:  '', $
                                        Type:   [fittd, 0, 0, 1]}

endelse

widget_control, base, event_func = 'grf_fit_event'

widget_control, tlb, /real
if (pdefs.popflag) then widget_control, curr, timer = 2.

old_data = data(pdefs.cset)     ; Save the old settings
handle_value, old_data.xydata, old_xy

handle_value, pdefs.data, data, /no_copy, /set

;			DIY widget management here

fitflag = 0
repeat begin
    ev = widget_event(base) 
    if (ev.exit gt 0) then begin
        widget_control, base, get_uvalue = uv
        fitstr = gr_fit_funct(pdefs, uv.type, uv.np, uv.slice, $
                              arexyd(uv.chosen), pr, resid)
        if (fitstr eq '') then begin
            ev.exit = 0
        endif else begin
            if (ev.exit eq 2) then begin
                widget_control, resid, set_value = fitstr
                widget_control, csqid, set_value = pr
            endif
            gr_plot_object, pdefs
            fitflag = 1
        endelse
    endif
endrep  until (ev.exit and 1) ne 0

widget_control, base, get_uvalue = uv, /no_copy
widget_control, tlb, /destroy
widget_control, pdefs.ids.graffer, sensitive = 1

if (ev.exit eq -1) then begin
    if (fitflag) then begin
        handle_value, pdefs.data, data, /no_copy
        handle_value, old_data.xydata, old_xy, /set, /no_copy
        data(pdefs.cset) = old_data
        handle_value, pdefs.data, data, /no_copy, /set
    endif
    return, 0
endif

return, 1

end