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