;------------------------------------------------------------- ;+ ; 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 ; ; 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