Viewing contents of file '../idllib/jhuapls1r/usr/eqv.pro'
;-------------------------------------------------------------
;+
; NAME:
; EQV
; PURPOSE:
; Interactive equation viewer and curve fitter.
; CATEGORY:
; CALLING SEQUENCE:
; eqv
; INPUTS:
; KEYWORD PARAMETERS:
; Keywords:
; FILE=filename Name of equation file to view.
; LIST=list List of equation file names. If LIST is
; given then FILE is ignored.
; XS=x, YS=y Optional arrays of scatterplot points.
; Useful for interactive curve fitting.
; PSYM=p Scatter plot symbol (def=2 (*)).
; SNAPSHOT=file name of snapshot file (def=snapshot.eqv).
; TITLE=tt plot title (over-rides value from eqv file).
; XTITLE=tx X axis title (over-rides value from eqv file).
; YTITLE=ty Y axis title (over-rides value from eqv file).
; OUTPUTS:
; COMMON BLOCKS:
; NOTES:
; MODIFICATION HISTORY:
; R. Sterner, 26 Oct, 1993
; R. Sterner, 1998 Jan 15 --- Dropped use of !d.n_colors.
;
; Copyright (C) 1993, Johns Hopkins University/Applied Physics Laboratory
; This software may be used, copied, or redistributed as long as it is not
; sold and this copyright notice is reproduced on each copy made. This
; routine is provided as is without any express or implied warranties
; whatsoever. Other limitations apply as described in the file disclaimer.txt.
;-
;-------------------------------------------------------------
pro eqv_plot, _d, hard=_hard
;------- Predefine a number of variables ---------
; These variables may be used as parameters in the equation
; with no cost in code space.
a=(b=(c=(d=(e=(f=(g=(h=(i=(j=(k=(l=(m=0B))))))))))))
n=(o=(p=(q=(r=(s=(t=(u=(v=(w=(x=(y=(z=0B))))))))))))
ax=(bx=(cx=(dx=(ex=(fx=(gx=(hx=(ix=(jx=(kx=(lx=(mx=0B))))))))))))
nx=(ox=(px=(qx=(rx=(sx=(tx=(ux=(vx=(wx=(xx=(yx=(zx=0B))))))))))))
ay=(by=(cy=(dy=(ey=(fy=(gy=(hy=(iy=(jy=(ky=(ly=(my=0B))))))))))))
ny=(oy=(py=(qy=(ry=(sy=(ty=(uy=(vy=(wy=(yy=(yy=(zy=0B))))))))))))
;------- Get X and Y ranges ----------
widget_control, _d.x1, get_val=_x1 & _x1 = _x1(0)
_err = execute('_x1='+_x1)
widget_control, _d.x2, get_val=_x2 & _x2 = _x2(0)
_err = execute('_x2='+_x2)
widget_control, _d.y1, get_val=_y1 & _y1 = _y1(0)
_err = execute('_y1='+_y1)
widget_control, _d.y2, get_val=_y2 & _y2 = _y2(0)
_err = execute('_y2='+_y2)
;------- Get parameter, T, range ----------
widget_control, _d.t1, get_val=_t1 & _t1 = _t1(0)
if _t1 eq '' then begin
_t1 = '-10'
widget_control, _d.t1, set_val=_t1
endif
widget_control, _d.t2, get_val=_t2 & _t2 = _t2(0)
if _t2 eq '' then begin
_t2 = '10'
widget_control, _d.t2, set_val=_t2
endif
;------- Get number of points ------
widget_control, _d.n, get_val=_n & _n = _n(0)
if _n eq '' then begin
_n = '100'
widget_control, _d.n, set_val=_n
endif
;------ Get axis types and styles -------------
_xtype = _d.xtype
_ytype = _d.ytype
_xstyle = _d.xstyle
_ystyle = _d.ystyle
;------ Get plot type --------------
_ptype = _d.ptype
;------- Read equation -------------
widget_control, _d.equat, get_val=_equat
_equat = _equat(0)
;----- Set parameters to their values ------
for _i = 0, n_elements(_d.pname)-1 do begin
_t = _d.pname(_i)+'='+string(_d.pval(_i))
_err = execute(_t)
endfor
;------ Generate independent array ----------------
widget_control, _d.iv, get_val=_t & _t = _t(0)
;-------- Compute both y(x) and y(xs) ---------
if (_d.fitflag eq 0) or (_d.psym eq -99) then begin
_tmp = _t+'=maken('+_t1+','+_t2+','+_n+')'
_err = execute(_tmp)
if _err ne 1 then begin
xhelp,exit='OK',['Error generating independent variable:',$
_tmp,!err_string,$
' ','Do the following to recover:',$
'1. Correct any errors in the name of the',$
' independent variable, its limits, or number of points.',$
'2. Do retall.','3. Do xmanager.','4. Press the OK button below.']
return
endif
;------ Compute just y(xs): Y at scatter X. ---------
endif else begin
_tmp = _t+'=_d.x' ; _t is Ind. Var. Set to scatt X.
_err = execute(_tmp)
if _err ne 1 then stop,' Error in setting Ind. Var = scatter X.'
endelse
;------ Define some special case values --------
;------ May use in equation ----------
_t1 = _t1 + 0. ; Min Ind. Var.
_t2 = _t2 + 0. ; Max Ind. Var.
_dt = _t2 - _t1 ; Range of Ind. Var.
;------ Compute Y(X): actually Y(Ind Var) --------------------
_err = execute(_equat)
if _err ne 1 then begin
xhelp,exit='OK',['Error executing:',_equat,!err_string,$
' ','Do the following to recover:',$
'1. Correct any errors in the equation text',$
' the name of the independent variable.',$
'2. Do retall.','3. Do xmanager.','4. Press the OK button below.']
return
endif
;-----------------------------------------------------------
; At this point the equation has been executed. So variables
; X and Y are now both defined. Y is either the equation
; value at the independent variable values, or the equation
; value at the scatter plot values. Either way Y is fitted.
; _d.x and _d.y are the scatter plot points, if any.
; The plot limits are _x1 to _x2, and _y1 to _y2.
;------------------------------------------------------------
;------ Plot ----------------------------
wset, _d.win
_pos = [.15,.1,.95,.9]
scat_color = !p.color-1
if keyword_set(_hard) then begin
psinit, comment=' Program: eqv.pro. '+$
'Equation file: '+_d.file
scat_color = !p.color
endif
if _ptype eq 1 then begin
subnormal, [.1,.1,0,.9], _pos
_dx = (1-(_pos(2)-_pos(1)))/2.
_pos = _pos + (_dx-_pos(0))*[1,0,1,0]
endif
;--------- Plot equation -------------
if _ptype eq 0 then begin
plot, x, y, xran=[_x1,_x2], yran=[_y1,_y2], xtype=_xtype, $
ytype=_ytype, xtitle=_d.xtitle, ytitle=_d.ytitle, $
title=_d.title, pos=_pos, xstyle=_xstyle, ystyle=_ystyle
endif else begin
plot, y, x, xran=[_x1,_x2], yran=[_y1,_y2], xtype=_xtype, $
ytype=_ytype, /polar, xtitle=_d.xtitle, ytitle=_d.ytitle, $
title=_d.title, pos=_pos, xstyle=_xstyle, ystyle=_ystyle
endelse
;------- Scatter plot -------------------
if _d.psym ne -99 then begin
if _d.ptype eq 0 then begin
oplot, _d.x, _d.y, psym=_d.psym, color=scat_color
oplot, x, y
endif else begin
oplot, _d.y, _d.x, psym=_d.psym, /polar, color=scat_color
oplot, y, x, /polar
endelse
endif
;-------- Compute and display fit ------------
if _d.fittype gt 0 then begin
if _d.fitflag eq 0 then begin
_tmp = _t+'=_d.x' ; Command to set ind. var. to xs.
_err = execute(_tmp) ; Actually set independent var.
_err = execute(_equat) ; Compute y(xs).
if _err ne 1 then stop
endif
case _d.fittype of
1: begin
w = where((_d.x ge _x1) and (_d.x le _x2), cnt)
if cnt gt 0 then begin
fit = strtrim(total((_d.y(w) - y(w))^2/y(w)))
fit_txt = 'Chi Sq: Total(((y-yfit)^2/yfit) over plot range only'
endif
end
else:
endcase
widget_control, _d.fitgood, set_val=fit
endif
if keyword_set(_hard) then begin
eqv_stat, _d, text=txt
xprint,/init,/norm,.1,-.1,chars=1.5, dy=1.5
xprint,txt
xprint,' '
xprint,_equat
xprint,' '
xprint,'where '+_t+' has '+strtrim(_n,2)+' points from '+$
strtrim(_t1,2)+' to '+strtrim(_t2,2)+' and'
for i=0, n_elements(_d.pname)-1 do begin
xprint,_d.pname(i)+' = '+strtrim(_d.pval(i),2)
endfor
if _d.fittype gt 0 then begin
xprint,' '
xprint,'Fit: '+fit_txt+' = '+fit
endif
psterm
endif
return
end
;===============================================================
; eqv_stat = Update status display.
; R. Sterner, 28 Oct, 1993
;===============================================================
pro eqv_stat, d, text=txt
if d.ptype eq 0 then txt = 'XY Plot. ' else $
txt = 'Polar Plot. Angle=x Radius=y. '
if d.xtype eq 0 then txt = txt + 'Linear X ' else $
txt = txt + 'Log X '
if d.ytype eq 0 then txt = txt + 'Linear Y' else $
txt = txt + 'Log Y'
widget_control, d.stat, set_val=txt
return
end
;===============================================================
; sp2v = Convert slider position to value.
; R. Sterner, 26 Oct, 1993
;===============================================================
function sp2v, p, smax, pmin, pmax
return, (p/float(smax))*(pmax-pmin) + pmin
end
;===============================================================
; sv2p = Convert slider value to position.
; R. Sterner, 26 Oct, 1993
;===============================================================
function sv2p, v, smax, pmin, pmax
p = fix(.5+float(smax)*(v-pmin)/(pmax-pmin))
return, p>0<smax
end
;===============================================================
; eqv_compile = Equation file compiler.
; R. Sterner, 25 Oct, 1993
;===============================================================
pro eqv_compile, file, title=title, xrange=xran, yrange=yran, $
par=par, number=num, equation=equat, xtype=xtype, ytype=ytype, $
ptype=ptype, psym=psym, xs=xs, ys=ys, trange=tran, $
out=out, xtitle=xtitle, ytitle=ytitle, indv=indv, $
discuss=discuss, error=err
;------- Add default extension -------
filebreak, file, dir=dir, name=name, ext=ext
if ext eq '' then ext='eqv'
f = dir+name+'.'+ext
;------- Get equation title ----------
txt = getfile(f)
if (size(txt))(0) eq 0 then begin
xmess,['Equation file not opened:',f]
err = 1
return
endif
title = txtgetkey(init=txt, 'title', del=':',/start)
;------- X axis title ---------------
xtitle = txtgetkey('xtitle', /start)
;------- Y axis title ---------------
ytitle = txtgetkey('ytitle', /start)
;------- Snapshot file name ---------
out = txtgetkey('snapshot', /start)
if out eq '' then out = 'snapshot.eqv'
;------- Discussion file name ---------
discuss = txtgetkey('discussion', /start)
;------- Get X Range ----------
tmp = txtgetkey('xrange', /start)
if tmp eq '' then begin
xmess,['Error in equation file:',file,' No X Range found.']
err = 1
return
endif
tmp = repchr(tmp,',')
xran = [getwrd(tmp,0),getwrd(tmp,1)]
;------- Get Y Range ----------
tmp = txtgetkey('yrange', /start)
if tmp eq '' then begin
xmess,['Error in equation file:',file,' No Y Range found.']
err = 1
return
endif
tmp = repchr(tmp,',')
yran = [getwrd(tmp,0),getwrd(tmp,1)]
;------- Get T Range ----------
tmp = txtgetkey('trange', /start)
if tmp eq '' then begin
tran = xran ; Default to xrange.
endif else begin
tmp = repchr(tmp,',')
tran = [getwrd(tmp,0),getwrd(tmp,1)]
endelse
;--------- Get number of points -------
tmp = txtgetkey('n_points', /start)
if tmp eq '' then tmp = '100'
num = tmp + 0
;--------- Get X axis type ---------
tmp = txtgetkey('xtype', /start)
if tmp eq '' then tmp = '0'
xtype = tmp + 0
;--------- Get Y axis type ---------
tmp = txtgetkey('ytype', /start)
if tmp eq '' then tmp = '0'
ytype = tmp + 0
;--------- Get Plot type ---------
tmp = txtgetkey('ptype', /start)
if tmp eq '' then tmp = '0'
ptype = tmp + 0
;--------- Get independent variable ---------
tmp = txtgetkey('independent', /start)
if tmp eq '' then tmp = 'x'
indv = tmp
;--------- Handle scatter plot points ------------
psym = -99
xs = [0]
ys = [0]
tmp = txtgetkey('psym', /start)
if tmp eq '' then tmp = '-99'
psym0 = tmp + 0
tmp = txtgetkey('scatter', /start)
err = 0
if tmp ne '' then begin
err = 1
on_ioerror, scerr
openr, lun, tmp, /get_lun ; Get scatter plot data from text file.
ns = 0 ; Number of x,y pairs.
readf, lun, ns
data = fltarr(2,ns) ; Array to read xy pairs into.
readf,lun,data
close, lun
free_lun, lun
err = 0
xs = data(0,*)
ys = data(1,*)
psym = psym0
if psym eq -99 then psym = 2
endif
scerr: if err eq 1 then begin
xmess,['Error reading scatter plot data from equation file',$
file,' ',' Scatter plot ignored.']
endif
;--------- Get equation ---------------
w = where(strupcase(strmid(txt,0,3)) eq 'EQ:', cnt)
if cnt eq 0 then begin
xmess,['Error in equation file:',file,' No equation found.']
err = 1
return
endif
equat = ''
i = w(0)
tmp = txt(i) ; First line of equation.
p = strpos(tmp,':') ; Skip over eq:.
tmp = strmid(tmp,p+1,999)
loop: p = strpos(tmp,'$') ; $? = continued?
if p gt 0 then begin ; Yes:
tmp = strmid(tmp,0,p) ; 1. Drop $.
equat = equat + tmp ; 2. Concat line.
i = i + 1 ; 3. Read next.
tmp = txt(i)
goto, loop ; 4. Process.
endif else begin ; No.
equat = equat + tmp ; Last line, concat.
endelse
;-------- Get adjustable parameters ----------
w = where(strupcase(strmid(txt,0,4)) eq 'PAR:', cnt) ; Any par lines?
if cnt eq 0 then begin ; No.
par = {n:0} ; Set par count to 0 and return.
err = 0
return
endif
txt = txt(w) ; Extract parameter lines.
pname = strarr(cnt)
pmin = fltarr(cnt)
pmax = fltarr(cnt)
pdef = fltarr(cnt)
for i = 0, cnt-1 do begin
tmp = getwrd(txt(i),delim=':',/last) ; i'th parameter line.
tmp = repchr(tmp,',') ; Drop any commas.
pname(i)= getwrd(tmp,0) ; Get name.
pmin(i) = getwrd(tmp,1) + 0. ; Get parameter range min.
pmax(i) = getwrd(tmp,2) + 0. ; Get parameter range max.
pdef(i) = getwrd(tmp,3) + 0. ; Get parameter range def.
endfor
par = {n:cnt, name:pname, min:pmin, max:pmax, def:pdef}
err = 0
return
end
;===============================================================
; eqvlist_event = Equation file list selection event handler.
; R. Sterner, 25 Oct, 1993
;===============================================================
pro eqvlist_event, ev
widget_control, ev.id, get_uval=name ; Get name of action.
widget_control, ev.top, get_uval=base ; Get address of base.
if name eq 'QUIT' then begin
widget_control, /dest, ev.top
return
endif
if name eq 'HELP' then begin
print,'HELP'
return
endif
widget_control, base, get_uval=uval ; Get uval stored in base.
list = uval.list ; Extract list and status.
status = uval.status
if status(ev.index) ne 0 then begin ; Check status.
xmess,['File could not be opened','or file format error in',$
list(ev.index)]
return
endif
eqv, file=list(ev.index) ; Execute equation file.
return
end
;===============================================================
; eqvlist = Equation file list selection.
; R. Sterner, 25 Oct, 1993
;===============================================================
pro eqvlist, list
;--------- Set up equation list text ---------
n = n_elements(list) ; Number of files in list.
titles = strarr(n) ; Space for list entries.
status = intarr(n) ; File status flags: 0=ok.
for i = 0, n-1 do begin ; Loop through given files.
file = list(i) ; i'th file name.
filebreak,file,dir=dir,name=name,ext=ext ; Pick apart name.
if ext eq '' then ext='eqv' ; Handle default extension.
file = dir+name+'.'+ext ; Reassemble.
txt = getfile(file,err=err,/quiet) ; Read file.
if err ne 0 then begin ; Could not read.
tt = 'File not opened: '+name ; List text message.
status(i) = 1 ; Set status.
endif else begin ; Could read file.
tt = txtgetkey(init=txt,'title',del=':',/start) ; Get title text.
if tt eq '' then tt = 'Title text not found in '+name ; Error.
endelse
titles(i) = tt
endfor
;--------- Set up equation selection widget -----------
top = widget_base(title='Select Equation to view',/column)
base = widget_base(top, /row)
id = widget_button(base,val='QUIT',uval='QUIT')
id = widget_button(base,val='HELP',uval='HELP')
id_list = widget_list(top, val=titles, uval='LIST',ysize=10<n)
widget_control, base, set_uval={list:list, status:status}
widget_control, top, set_uval=base ; Store base wid in top uval.
widget_control, top, /real
xmanager, 'eqvlist', top
return
end
;===============================================================
; eqv_event = eqv event handler.
; R. Sterner, 25 Oct, 1993
;===============================================================
pro eqv_event, ev
widget_control, ev.id, get_uval=name0 ; Get name of action.
widget_control, ev.top, get_uval=d ; Get data structure.
name = strmid(name0,0,3) ; First 3 chars.
if name eq 'QUI' then begin
widget_control, /dest, ev.top
return
endif
;------- Handle plot related items ---------------
if name eq 'PLT' then begin
eqv_plot, d
return
endif
;------- Handle axis type -------------
if name eq 'AXS' then begin
act = strmid(name0,3,1)
i = strmid(name0,4,1) + 0
if i lt 2 then begin
case act of
'X': d.xtype = i
'Y': d.ytype = i
endcase
endif else begin
s = 3-i
case act of
'X': d.xstyle = s
'Y': d.ystyle = s
endcase
endelse
widget_control, ev.top, set_uval=d
eqv_stat, d
eqv_plot, d
return
endif
;------- Handle plot type --------------
if name eq 'TYP' then begin
act = strmid(name0,3,1) + 0
d.ptype = act
widget_control, ev.top, set_uval=d
eqv_stat, d
eqv_plot, d
return
endif
;------- Handle plot symbol --------------
if name eq 'PSY' then begin
act = strmid(name0,3,2) + 0
if act gt 10 then act = -act
if n_elements(d.x) le 1 then act = -99 ; No scatterplot.
d.psym = act
widget_control, ev.top, set_uval=d
eqv_plot, d
return
endif
;------- Handle parameter realted items ----------
if name eq 'PAR' then begin
act = strmid(name0,3,3) ; Parameter action code.
i = strmid(name0,6,2) + 0 ; Parameter index.
;------- Process action code --------
case act of
'SLD': begin ;*** Moved slider. ***
widget_control, d.id_slid(i), get_val=p ; New pos.
end
'MIN': begin ;*** Entered new range min. ***
widget_control, d.id_pmin(i), get_val=t ; Get ran min.
d.pmin(i) = t+0. ; Store.
p = sv2p(d.pval(i), d.smax, d.pmin(i), d.pmax(i)) ; New pos.
widget_control, d.id_slid(i), set_val=p ; Update slider.
end
'MAX': begin ;*** Entered new range max. ***
widget_control, d.id_pmax(i), get_val=t ; Get ran min.
d.pmax(i) = t+0. ; Store.
p = sv2p(d.pval(i), d.smax, d.pmin(i), d.pmax(i)) ; New pos.
widget_control, d.id_slid(i), set_val=p ; Update slider.
end
'STN': begin ;*** Set current value as new range min. ***
d.pmin(i) = d.pval(i) ; Update and display new range min.
widget_control, d.id_pmin(i), set_val=strtrim(d.pmin(i),2)
p = 0
widget_control, d.id_slid(i), set_val=p ; Update slider.
end
'STX': begin ;*** Set current value as new range max. ***
d.pmax(i) = d.pval(i) ; Update and display new range max.
widget_control, d.id_pmax(i), set_val=strtrim(d.pmax(i),2)
p = d.smax
widget_control, d.id_slid(i), set_val=p ; Update slider.
end
'VAL': begin
widget_control, d.id_pval(i), get_val=t ; Get ran min.
d.pval(i) = t+0. ; Store.
p = sv2p(d.pval(i), d.smax, d.pmin(i), d.pmax(i)) ; New pos.
widget_control, d.id_slid(i), set_val=p ; Update slider.
widget_control, ev.top, set_uval=d ; Update parameter values.
eqv_plot, d ; Update plot.
return
end
'NAM': begin
widget_control, d.id_pnam(i), get_val=t ; Get par name.
d.pname(i) = t ; Replace old.
widget_control, ev.top, set_uval=d ; Update parameter values.
eqv_plot, d ; Update plot.
return
end
endcase
;------- Always: compute new val, display it, store it.
v = sp2v(p, d.smax, d.pmin(i), d.pmax(i)) ; New val.
widget_control,d.id_pval(i),set_val=strtrim(v,2) ; Display..
d.pval(i) = v ; Store.
widget_control, ev.top, set_uval=d ; Update parameter values.
eqv_plot, d ; Update plot.
return
endif
;------------ Handle snapshot ------------
if name eq 'SNA' then begin
;---------- Write eqv file --------------------
openw, lun, d.out, /get_lun
user=getenv('USER')
user = strupcase(strmid(user,0,1))+strmid(user,1,99)
printf, lun, $
'*-------- '+d.out+' = snapshot of current status -------'
printf, lun, '* '+user+', '+systime()
printf, lun, ' '
printf, lun, 'title: '+d.title
widget_control, d.equat, get_val=txt
printf, lun, 'eq: '+txt
widget_control, d.x1, get_val=txt1
widget_control, d.x2, get_val=txt2
printf, lun, 'xrange: '+txt1+' '+txt2
widget_control, d.y1, get_val=txt1
widget_control, d.y2, get_val=txt2
printf, lun, 'yrange: '+txt1+' '+txt2
widget_control, d.t1, get_val=txt1
widget_control, d.t2, get_val=txt2
printf, lun, 'trange: '+txt1+' '+txt2
widget_control, d.iv, get_val=txt
printf, lun, 'independent: '+txt
widget_control, d.n, get_val=txt
printf, lun, 'n_points: '+txt
printf, lun, 'xtype: ',d.xtype
printf, lun, 'ytype: ',d.ytype
printf, lun, 'ptype: ',d.ptype
if d.psym ne -99 then begin ; Scatter plot info.
filebreak, d.out, dir=dir, name=fname, ext=ext
out2 = dir+fname+'.eqdat'
printf, lun, 'psym: ',d.psym
printf, lun, 'scatter: '+out2
endif
for i = 0, n_elements(d.pname)-1 do begin
printf, lun, 'par: ',d.pname(i),' ',d.pmin(i),d.pmax(i), d.pval(i)
endfor
close, lun
free_lun, lun
txt = 'Snapshot saved in '+d.out
;----------- Write scatter plot data ----------------
if d.psym ne -99 then begin ; Save Scatter plot data.
openw, lun, out2, /get_lun
printf, lun, n_elements(d.x)
data = [d.x,d.y]
printf, lun, data
close, lun
free_lun, lun
txt = [txt,'and scatter plot data in '+out2]
endif
xmess,txt
return
endif
;-------- Zoom ---------------
if name eq 'ZOO' then begin
txt = ['Select plot region to zoom using box.',$
' ','Mouse buttons:','Left: toggles between move and resize mode',$
'Middle: Cancel zoom (use alternate exit)',$
'Right: exit and zoom selected area.',' ',$
'This help text will not be displayed again.']
if d.zhelp eq 1 then xhelp,txt, wid=id ; Show help only once.
pk, xran=xr, yran=yr, /nomark, code=code
if d.zhelp eq 1 then widget_control, /dest, id ; Kill help.
d.zhelp = 0 ; No more help.
widget_control, ev.top, set_uval=d ; Store no help status.
if code eq 2 then return ; Zoom canceled.
widget_control, d.x1, set_val=strtrim(xr(0),2)
widget_control, d.x2, set_val=strtrim(xr(1),2)
widget_control, d.y1, set_val=strtrim(yr(0),2)
widget_control, d.y2, set_val=strtrim(yr(1),2)
eqv_plot, d
return
endif
;-------- Cursor ---------------
if name eq 'CUR' then begin
xcursor
return
endif
;-------- Hardcopy ---------------
if name eq 'HAR' then begin
eqv_plot, d, /hard
return
endif
;------- Discussion file -----------
if name eq 'DIS' then begin
txt = getfile(d.discuss, err=err, /quiet)
if err ne 0 then begin
xmess,['Could not open discussion file:',d.discuss]
endif else begin
xhelp, txt,group=ev.top,exit='Quit discussion'
endelse
return
endif
;-------- color edit -------------
if name eq 'BKH' then begin
xced1,!p.background,title='Modify background color',/hsv,group=ev.top
return
endif
if name eq 'BKR' then begin
xced1,!p.background,title='Modify background color',group=ev.top
return
endif
if name eq 'PCH' then begin
xced1,!p.color,title='Modify plot color',/hsv,group=ev.top
return
endif
if name eq 'PCR' then begin
xced1,!p.color,title='Modify plot color',group=ev.top
return
endif
if name eq 'SCH' then begin
xced1,!p.color-1,title='Modify plot color',/hsv,group=ev.top
return
endif
if name eq 'SCR' then begin
xced1,!p.color-1,title='Modify plot color',group=ev.top
return
endif
;--------- Handle fit related items -----------
if name eq 'FIT' then begin
act = strmid(name0,3,1)+0
case act of
0: begin ; No fit.
d.fittype = 0
if d.fitwid gt 0 then begin ; Kill any fit status display.
widget_control, d.fitwid, /dest
d.fitwid = -1
endif
end
1: begin ; Chi Sq.
if n_elements(d.x) le 1 then return ; Must have scatterplot data.
d.fittype = 1
xbb, lines=['--- Chi Sq ---',' '],res=1,nid=nid,wid=wid,gr=ev.top
d.fitwid=wid
d.fitgood=nid(0)
end
2: begin ; Compute both y(x) and y(xs).
d.fitflag = 0
end
3: begin ; Compute just y(xs).
d.fitflag = 1
end
endcase
widget_control, ev.top, set_uval=d
eqv_plot, d
return
endif
;--------- Help -----------------
if name eq 'HEL' then begin
act = strmid(name0,4,1) ; Help code.
case act of
'0': xhelp,group=ev.top,['Overview and Index',' ',$
'The Equation Viewing tool, EQV, makes it easy to study',$
'an equation and see what each parameter in it does.',$
'Equation parameters may be varied by moving a slider',$
'bar allowing the effects of hundreds of values to be',$
'examined in seconds. The equation itself may be modified',$
'with the result being instantly displayed. Plots may be',$
'displayed with linear or log axes and in polar',$
'coordinates. The default equation is a gaussian but',$
'another equation may be entered as a replacement and',$
'equations may be read in from equation files. Changes',$
'may be saved in a new equation file and the current plot',$
'may be sent to the printer. A set of data points may',$
'optionally be given. They will be displayed as a',$
'scatterplot. They equation and parameter values may',$
'be adjusted to do a curve fit to these points.',' ',$
'The Equation Viewing tool has 4 main sections: the',$
'display panel, the plot control panel, the equation',$
'display and entry area, and the adjustable parameter',$
'panel. More help is available for each of these sections',$
'and also for the equation file format.',$
'In the HELP menu see the following:',' ',$
' Plot display panel',' Plot control panel',$
' Equation display and entry area',$
' Adjustable parameters', ' Equation file format',' ',$
'Calling syntax:',' ',$
'eqv',$
' All arguments are keywords.',$
'Keywords:',$
' FILE=filename Name of equation file to view.',$
' LIST=list List of equation file names. If LIST is',$
' given then FILE is ignored.',$
' X=x, Y=y Optional arrays of scatterplot points.',$
' Useful for interactive curve fitting.',$
' PSYM=p Scatter plot symbol (def=2 (*)).',$
' SNAPSHOT=file name of snapshot file (def=snapshot.eqv).']
'1': xhelp,group=ev.top,['Plot display panel',' ',$
'This is the area of EQV that displays the equation',$
'being examined. Several items are of interest.',' ',$
'The plot and axis titles are optional entries in the',$
'equation file (see Equation file format in the HELP menu).',$
' ','The character size used for the plot is controlled',$
'by setting !p.charsize to a new value. 1.5 works well.',' ',$
'The default plot colors are Mint and Chocolate.',$
'The plot colors may be adjusted using the Colors button.']
'2': xhelp,group=ev.top,['Plot control panel',' ',$
'This panel consists of buttons and text entry fields',$
'at the upper right region of the equation viewer widget.',$
'These items are related to the overall plot. This panel',$
'has 5 main areas, from the top down they are:',$
' Action buttons',$
' Plot and axis type status line',$
' Pull-down menus',$
' Plot limits',$
' Independent variable setup',' ',$
' Action buttons',$
' Quit: exit EQV.',$
' Zoom: gives an interactive box which is used to select',$
' an area of the plot to zoom.',$
' Cursor: displays position of a cursor in the plot area.',$
' Snapshot: save the current eqv status in an equation',$
' file. The name of this file may be set when starting',$
' eqv using the keyword snapshot=filename. The default',$
' is snapshot.eqv and snapshot.edat for any scatter',$
' plot data.',$
' Hardcopy: send the current plot to a PostScript printer',$
' and list the equation and parameter values.',$
' Discussion: appears only if the discussion entry is',$
' specified in the equation file (see Equation file',$
' format). When pressed this button displays the',$
' contents of the discussion text file specified.',' ',$
' Pull-down menus',$
' Help: allows selection from a number of help topics.',$
' X Axis: select Linear or Log X axis, exact or extended.',$
' Y Axis: select Linear or Log Y axis, exact or extended.',$
' Plot Type: select XY or Polar plot type.',$
' Colors: allows plot, background, and scatter plot colors',$
' to be modified using the HSV or RGB color systems.',$
' Plot Symbol: allows plot symbol change.',$
' Fit: if scatter plot data has been specified this button',$
' activates the display of goodness of fit values.',$
' May compute both Y(X), the full curve, or just Y(XS),',$
' Y of the scatter plot X values (faster). If you pick',$
' the latter option the scatter plot data should have',$
' been sorted in X.',$
' Currently the fit only works for Y=f(X), not',$
' parametric equations.',' ',$
' Plot and axis type status line',$
' This line gives the plot type (XY or Polar) and',$
' axis types (Linear or Log).',' ',$
' Plot limits',$
' May enter values for the four plot limits: min x, max x,',$
' min y, max y. Press RETURN (ENTER) for the new value',$
' to take effect. May use expressions.',' ',$
' Independent variable setup',$
' There are four values related to the independent',$
' variable: Variable name, Min value, Max value, and',$
' Number of points spaced between the min and max values.',$
' All these values may be changed by entering new values',$
' and pressing RETURN (ENTER). May use expressions.']
'3': xhelp,group=ev.top,['Equation display and entry area',' ',$
'The current equation is shown below the plot display and',$
'plot control panels. The equation may be modified just by',$
'deleting or typing text in this area. Press RETURN (ENTER)',$
'to see the results of the change. Several items to note:',$
' ','The independent variable in the equation must be the',$
'same as named in the plot control panel or an error will',$
'occur. The default independent variable is x.',' ',$
'For polar plots, x is the angle in radians, and y is the',$
'radius. This is stated in the plot status line.',' ',$
'Parametric equations may be plotted as follows:',$
'Define the independent variable in the plot control',$
'panel to be something like t. Then in the equation area',$
'enter the two parametric equations for x and y separated',$
'by &. For example: x=a*sin(b*t) & y=c*cos(d*t)',$
'The range and resolution of parameter t is set in the',$
'independent variable area of the plot control panel.',' ',$
'The variable names used in the equation may be changed.',$
'To do so, change one parameter in the equation, but DO',$
'NOT press RETURN after. Then make the same name change',$
'in the parameter control panel and press RETURN. Repeat',$
'for each parameter.',' ',$
'Note: there are 3 special values made available:',$
' _t1 = minimum of independent variable.',$
' _t2 = maximum of independent variable.',$
' _dt = range of independent variable.',$
'These may be used in the equation if desired.']
'4': xhelp,group=ev.top,['Adjustable parameters',' ',$
'Below the equation display area is the adjustable',$
'parameter control panel. Each adjustable parameter in',$
'the equation has a set of labeled text entry fields,',$
'two buttons, and a slider bar. These are discussed below.',$
' ','Parameter name: The left-most text entry field for each',$
' parameter. See note on name changing unde the equation',$
' display help.',$
' ','Parameter value field: The text entry field to the right',$
' of the parameter name. It displays the current value of',$
' the parameter. It will be updated as the slider bar',$
' is moved. If a new value is entered, press RETURN.',' ',$
'Parameter range fields: these give the min and max values',$
' for the slider bar. These values may be changed by',$
' typing new values and pressing RETURN (ENTER).',' ',$
'Range Min and Max buttons: these set the range min or',$
' max to the current parameter value. They make it easy',$
' decrease the range for finer control. To increase the',$
' range new values must be typed in the fields.',' ',$
'Slider bar: the mouse is used to move the slider bar',$
' pointer to change the value of the corresponding',$
' adjustable parameter.',' ',$
'Note: there may be extra parameters unused in the equation.',$
'These may be used to add new adjustable parameters.']
'5': xhelp,group=ev.top,['Equation file format',' ',$
'The equation viewer, eqv, may be given an initialization',$
'file called an equation file. The calling syntax is:',$
' eqv, file=name','where the default extension is .eqv,',$
'like gaussian.eqv. So eqv,file="gaussian" is ok.',' ',$
'Equation files set up an equation, parameter values,',$
'plot limits, and so on.',' ',$
'Equation files contain 3 types of lines: command lines,',$
'null lines, and keyword/value lines. Comment lines have',$
'* in line 1. Null lines have no text. Keyword/value',$
'lines have a keyword starting in column 1. The keyword',$
'is followed by a colon (:). The value is on the rest of',$
'line. Only equation lines may be continued.',' ',$
'Example equation file:',' ',$
'*--------- gaussian.equ = Gaussian curve -----------',$
'* R. Sterner, 25 Oct, 1993',$
' ',$
'title: Gaussian Curve',$
'eq: y = amp*exp(-(x-mu)^2/sigma)',$
'xrange: -10, 10',$
'yrange: 0, 10',$
'n_points: 100',$
'par: amp -10 10 8',$
'par: mu -10 10 0',$
'par: sigma 0 100 6',' ',$
'All the recognized keywords are listed below in example',$
'lines with a discussion on the next line(s).',' ',$
'title: Polar Curve # 2.',$
' The plot title. It is also used for the list text',$
' if eqv is called with the LIST keyword.',$
'eq: y = a*sin(x/b)',$
' The initial equation. It may be continued by',$
' ending lines with a $.',$
'xtitle: Position (km)',$
' X axis title. Optional.',$
'ytitle: Temperature (deg C)',$
' Y axis title. Optional.',$
'xrange: 0 0',$
' The plot X range min and max. If both 0, as here, then',$
' autoscaling is done. Keyword required.',$
'yrange: 0 0',$
' The plot Y range min and max. If both 0, as here, then',$
' autoscaling is done. Keyword required.',$
'trange: 0 150',$
' The independent variable range. Defaults to xrange.',$
'n_points: 1000',$
' Number of points in the independent variable range.',$
' Defaults to 100.',$
'xtype: 0',$
' X axis type: 0=linear (default), 1=log.',$
'ytype: 1',$
' Y axis type: 0=linear (default), 1=log.',$
'ptype: 1',$
' Plot type: 0=XY (default), 1=Polar.',$
'independent: t',$
' Name of independent variable. Defaults to x.',$
'par: ax 1.00000 10.0000 3.12625',$
'par: ay 1.00000 10.0000 3.68875',$
' Adjustable parameter definition line. Must have 4',$
' items: parameter name, slider bar min, slider bar max,',$
' starting value. There is one par line for each',$
' adjustable parameter in the equation. Extra par',$
' lines may be used to define potiential new parameters.',$
'scatter: g_scatter.txt',$
' Name of file containing scatter plot data. This must',$
' be a text with number of points in line 1 and XY pairs',$
' on following lines. Example (first 3 lines):',$
' 20',$
' 7.53239 0.807365',$
' -3.05645 0.00850357',$
'psym: 4',$
' Plot symbol for scatter plot. Default is 2.',$
'discussion: lissajous.dsc',$
' Name of a text file to display that discusses the',$
' current equation. It is displayed in a scrolling',$
' window and could be used to suggest experiments with',$
' the equation.',$
'snapshot: tmp.tmp',$
' Name of an equation file to create when the snapshot',$
' button is pressed. The default is snapshot.eqv. Any',$
' scatterplot data is saved in a file with the same name',$
' but extension .eqdat.']
endcase
return
endif
end
;===============================================================
; eqv.pro = Equation viewer
; R. Sterner, 25 Oct, 1993
;===============================================================
pro eqv, file=file, list=list, xs=xs, ys=ys, psym=psym, $
snapshot=out, help=hlp, title=title0, xtitle=xtitle0, $
ytitle=ytitle0
if keyword_set(hlp) then begin
print,' Interactive equation viewer and curve fitter.'
print,' eqv'
print,' All arguments are keywords.'
print,' Keywords:'
print,' FILE=filename Name of equation file to view.'
print,' LIST=list List of equation file names. If LIST is'
print,' given then FILE is ignored.'
print,' XS=x, YS=y Optional arrays of scatterplot points.'
print,' Useful for interactive curve fitting.'
print,' PSYM=p Scatter plot symbol (def=2 (*)).'
print,' SNAPSHOT=file name of snapshot file (def=snapshot.eqv).'
print,' TITLE=tt plot title (over-rides value from eqv file).'
print,' XTITLE=tx X axis title (over-rides value from eqv file).'
print,' YTITLE=ty Y axis title (over-rides value from eqv file).'
return
endif
;------- Handle equation file list -------------
if n_elements(list) ne 0 then begin
eqvlist, list
return
endif
;-------- Handle equation file or set defaults -------
if n_elements(out) eq 0 then out = 'snapshot.eqv'
xstyle = 1 ; Start with exact axes.
ystyle = 1
fittype = 0 ; No goodness of fit display.
fitflag = 0 ; Do both y(x) and y(xs) for fit.
;------- No equation file ------------
if n_elements(file) eq 0 then begin
file = 'Default equation'
title = 'Gaussian Curve'
xran = [-10,10]
yran = [0,10]
tran = xran
num = 100
xtype = 0
ytype = 0
ptype = 0
xtitle = ''
ytitle = ''
indv = 'x'
discuss = ''
eqt = 'y = amp*exp(-(x-mu)^2/sigma)'
par = {n:3, name:['amp','mu','sigma'], min:[0.,-10,0], $
max:[10.,10,10], def:[8.,0,6]}
;------- Equation file given -----------
endif else begin
eqv_compile, file, title=title, xrange=xran, yrange=yran, $
par=par, equat=eqt, number=num, xtype=xtype, ytype=ytype, $
ptype=ptype, xs=xsf, ys=ysf, psym=psymf, trange=tran, $
out=outf, xtitle=xtitle, ytitle=ytitle, indv=indv, $
discuss=discuss, err=err
if err ne 0 then return
if n_elements(out) eq 0 then out=outf
if n_elements(xs) eq 0 then xs=xsf
if n_elements(ys) eq 0 then ys=ysf
if n_elements(psym) eq 0 then psym=psymf
endelse
if n_elements(title0) ne 0 then title=title0 ; Use given titles.
if n_elements(xtitle0) ne 0 then xtitle=xtitle0
if n_elements(ytitle0) ne 0 then ytitle=ytitle0
;------- Handle scatter plot parameters ----------
if n_elements(xs) le 1 then begin ; No scatter plot.
xs = [0]
ys = [0]
psym = -99
endif else begin ; Have scatter plot.
if n_elements(psym) eq 0 then psym = -99
if psym eq -99 then psym = 2
endelse
;-------- Set up equation viewer widget ----------
smax = 800
top = widget_base(/column, title=title)
base = widget_base(top,/row)
id_draw = widget_draw(base, xsize=450, ysize=450)
right = widget_base(base,/column)
but = widget_base(right, /row)
b = widget_button(but, val='Quit',uval='QUIT')
b = widget_button(but, val='Zoom',uval='ZOOM')
b = widget_button(but, val='Cursor',uval='CURS')
b = widget_button(but, val='Snapshot',uval='SNAP')
b = widget_button(but, val='Hardcopy',uval='HARD')
if discuss ne '' then $
b = widget_button(but, val='Discussion',uval='DISC')
b = widget_button(but, val='Help',menu=2)
b2 = widget_button(b,val='Overview and Index',uval='HELP0')
b2 = widget_button(b,val='Plot display panel',uval='HELP1')
b2 = widget_button(b,val='Plot control panel',uval='HELP2')
b2 = widget_button(b,val='Equation display and entry area',$
uval='HELP3')
but = widget_base(right, /row)
b2 = widget_button(b,val='Adjustable parameters',uval='HELP4')
b2 = widget_button(b,val='Equation file format',uval='HELP5')
b = widget_button(but, val='X Axis',menu=2)
b2 = widget_button(b, val='Linear',uval='AXSX0')
b2 = widget_button(b, val='Log',uval='AXSX1')
b2 = widget_button(b, val='Exact',uval='AXSX2')
b2 = widget_button(b, val='Extend',uval='AXSX3')
b = widget_button(but, val='Y Axis',menu=2)
b2 = widget_button(b, val='Linear',uval='AXSY0')
b2 = widget_button(b, val='Log',uval='AXSY1')
b2 = widget_button(b, val='Exact',uval='AXSY2')
b2 = widget_button(b, val='Extend',uval='AXSY3')
b = widget_button(but, val='Plot Type',menu=2)
b2 = widget_button(b, val='XY',uval='TYP0')
b2 = widget_button(b, val='Polar',uval='TYP1')
b = widget_button(but, val='Colors',menu=2)
b2 = widget_button(b, Val='Modify Background',menu=2)
b3=widget_button(b2,Val='Hue, Saturation, Value',uval='BKH')
b3 = widget_button(b2, Val='Red, Green, Blue', uval='BKR')
b2 = widget_button(b, Val='Modify Plot Color', menu=2)
b3=widget_button(b2,Val='Hue, Saturation, Value',uval='PCH')
b3 = widget_button(b2, Val='Red, Green, Blue', uval='PCR')
b2 = widget_button(b, Val='Modify Scatter Plot Color', menu=2)
b3=widget_button(b2,Val='Hue, Saturation, Value',uval='SCH')
b3 = widget_button(b2, Val='Red, Green, Blue', uval='SCR')
b = widget_button(but, val='Plot Symbol',menu=2)
b2 = widget_button(b, Val=' No scatter plot', uval='PSY99')
b2 = widget_button(b, Val='0 Connect points', uval='PSY0')
b2 = widget_button(b, Val='1 Plus sign (+)', uval='PSY1')
b2 = widget_button(b, Val='2 Asterisk (*)', uval='PSY2')
b2 = widget_button(b, Val='3 Period (.)', uval='PSY3')
b2 = widget_button(b, Val='4 Diamond', uval='PSY4')
b2 = widget_button(b, Val='5 Triangle', uval='PSY5')
b2 = widget_button(b, Val='6 Square', uval='PSY6')
b2 = widget_button(b, Val='7 X', uval='PSY7')
b2 = widget_button(b, Val='8 User-defined', uval='PSY8')
b = widget_button(but, val='Fit',menu=2)
b2 = widget_button(b,val='No Fit',uval='FIT0')
b2 = widget_button(b,val='Chi Sq',uval='FIT1')
b2 = widget_button(b,val='Compute both Y(X) and Y(XS)',$
uval='FIT2')
b2 = widget_button(b,val='Compute just Y(XS)',uval='FIT3')
id_stat = widget_label(right,value=' ',/dynamic)
rn = widget_base(right, column=2)
id = widget_label(rn,val='Plot X Min: ')
id = widget_label(rn,val='Plot X Max: ')
id_x1 = widget_text(rn,val=strtrim(xran(0),2),/edit,$
xsize=15, uval='PLT')
id_x2 = widget_text(rn,val=strtrim(xran(1),2),/edit,$
xsize=15, uval='PLT')
rn = widget_base(right, column=2)
id = widget_label(rn,val='Plot Y Min: ')
id = widget_label(rn,val='Plot Y Max: ')
id_y1 = widget_text(rn,val=strtrim(yran(0),2),/edit,$
xsize=15, uval='PLT')
id_y2 = widget_text(rn,val=strtrim(yran(1),2),/edit,$
xsize=15, uval='PLT')
rn = widget_base(right, column=2)
id = widget_label(rn,val='Independent Variable: ')
id = widget_label(rn,val='Independent Variable Min: ')
id = widget_label(rn,val='Independent Variable Max: ')
id_iv = widget_text(rn,val=indv, /edit,uval='PLT')
id_t1 = widget_text(rn,val=strtrim(tran(0),2),/edit,$
xsize=15, uval='PLT')
id_t2 = widget_text(rn,val=strtrim(tran(1),2),/edit,$
xsize=15, uval='PLT')
rn = widget_base(right, /row)
id = widget_label(rn,val='Number of points: ')
id_n = widget_text(rn,val=strtrim(num,2),/edit,$
xsize=15, uval='PLT')
id_eq = widget_text(top,val=eqt,xsize=60,ysize=1,/edit,uval='PLT')
;-------- Set up parameter related items ---------------
id_slid = lonarr(par.n) ; Parameter slider related wids.
id_parnam = strarr(par.n)
id_parval = lonarr(par.n)
id_parmin = lonarr(par.n)
id_parmax = lonarr(par.n)
if par.n lt 6 then begin
bot = widget_base(top,/column)
endif else begin
bot = widget_base(top,/column,y_scroll=450)
endelse
for i = 0, par.n-1 do begin ; Loop through parameters.
b = widget_base(bot,/column)
b2 = widget_base(b,/row)
id = widget_text(b2,val=par.name(i),xsize=10, /edit, $
uval='PARNAM'+strtrim(i,2))
id_parnam(i) = id
id = widget_text(b2,val=strtrim(par.def(i),2),xsize=15,/edit,$
uval='PARVAL'+strtrim(i,2))
id_parval(i) = id
id = widget_label(b2,val='Range: ')
id = widget_text(b2,val=strtrim(par.min(i),2),/edit,$
uval='PARMIN'+strtrim(i,2),xsize=15)
id_parmin(i) = id
id = widget_label(b2,val=' to ')
id = widget_text(b2,val=strtrim(par.max(i),2),/edit,$
uval='PARMAX'+strtrim(i,2),xsize=15)
id_parmax(i) = id
id = widget_button(b2,val='Set Min',uval='PARSTN'+strtrim(i,2))
id = widget_button(b2,val='Set Max',uval='PARSTX'+strtrim(i,2))
s = widget_slider(b,uval='PARSLD'+strtrim(i,2),xsize=smax+1,$
max=smax, /suppress,/drag)
id_slid(i) = s
endfor
;------- Display widget and update plot -------
for i=0, par.n-1 do begin ; Set parameter slider starting points.
widget_control, id_slid(i),set_val=$
sv2p(par.def(i),smax,par.min(i),par.max(i))
endfor
widget_control, top, /real
widget_control, id_draw, get_val=draw_win
tvlct,rr,gg,bb,/get
rr(0)=66 & gg(0)=0 & bb(0)=0
rr(!d.table_size-1)=0 & gg(!d.table_size-1)=255&bb(!d.table_size-1)=165
rr(!d.table_size-2)=0 & gg(!d.table_size-2)=88 & bb(!d.table_size-2)=183
tvlct, rr, gg, bb
erase
;----- Package and store needed global values --------
data = {x1:id_x1, x2:id_x2, y1:id_y1, y2:id_y2, n:id_n, $
equat:id_eq, win:draw_win, id_slid:[id_slid], id_pval:[id_parval], $
id_pmin:[id_parmin], id_pmax:[id_parmax], x:xs, y:ys, psym:psym, $
id_pnam:[id_parnam], $
pname:[par.name], pval:[par.def], pmin:[par.min], pmax:[par.max], $
smax:smax, xtype:xtype, ytype:ytype, ptype:ptype, title:title, $
xstyle:xstyle, ystyle:ystyle, $
t1:id_t1, t2:id_t2, out:out, xtitle:xtitle, ytitle:ytitle, $
fittype:fittype, fitflag:fitflag, fitwid:-1, fitgood:-1, $
stat:id_stat, iv:id_iv, zhelp:1, file:file, discuss:discuss}
widget_control, top, set_uval=data
eqv_stat, data
;------ Start plot ----------
tmp = check_math(1,1)
eqv_plot, data
;------- xmanager -------
xmanager, 'eqv', top
tmp = check_math(0,0)
return
end