Viewing contents of file '../idllib/astron/contrib/varosi/code/allpro/approx_xsecs.pro'
; NAME:
; Approx_Xsecs_Ev
;
; PURPOSE:
; Approximate a cross-section by interactively
; selecting points for piece-wise Linear interpolation.
; This is the event handler routine that the XManager calls when
; a widget event occurs for the Approx_Xsecs widget.
; Process button events which are user requests for I/O, display, select,
; or unmap/destroy the widget if the user has pressed the DONE button.
;
; CALLING:
; Approx_Xsecs_Ev, event
;
; INPUT:
; event = structure variable defining the widget event.
;
; EXTERNAL CALLS:
; pros: Approx_Xsec_Cur, force_events,
; funcs: PickFile, get_text_input
; PROCEDURE:
; Big CASE breakdown.
; HISTORY:
; written: Frank Varosi HSTX @ NASA/GSFC 1995.
pro Approx_Xsecs_Ev, event
Widget_Control, event.handler, GET_UVAL=state,/NO_COPY
if (event.id EQ state.draw_wid) then begin
;process cursor events:
Approx_Xsec_Cur, event, state
Widget_Control, event.handler, SET_UVAL=state,/NO_COPY
return
endif
Widget_Control, event.id, GET_UVAL=uval
CASE uval(0) OF
"SELECT": BEGIN
state.Lsel = event.index
Handle_value, state.ELevs, ELevs,/NO_COPY
ELevel = ELevs(state.Lsel)
Handle_value, state.ELevs, ELevs,/NO_COPY,/SET
; must make copy of freq & xsec by creating new handles and keeping old ones:
if Handle_info( ELevel.freq_approx ) then begin
Handle_value, ELevel.freq_approx, freq
Handle_value, ELevel.xsec_approx, xsec
ELevel.npx = N_elements( freq ) < N_elements( xsec )
endif else ELevel.npx = 0
if (ELevel.npx GT 0) then begin
ELevel.freq_approx = Handle_create( VAL=freq,/NO_COPY )
ELevel.xsec_approx = Handle_create( VAL=xsec,/NO_COPY )
endif else begin
ELevel.freq_approx = 0
ELevel.xsec_approx = 0
endelse
wset, state.window
Levid = Level_info( ELevel )
Plot_Xsec, ELevel, TITLE=Levid
state.Lplot = state.Lsel
state.ELevel = Handle_create( VAL=ELevel,/NO_COPY )
Widget_Control, state.info_wid, SET_VAL=Levid
Widget_Control, state.instr_wid, $
SET_VAL="Left button = Insert a point, " + $
"Middle = Delete point nearest cursor"
Widget_Control, state.axes_wid,/SENSITIVE
Widget_Control, state.draw_wid,/DRAW_BUTTON_EV,/DRAW_MOTION_EV
for i=0,1 do begin
Widget_Control, state.x_wids(i),/SENSITIVE
Widget_Control, state.y_wids(i),/SENSITIVE
endfor
END
"HARDCOPY": BEGIN
if (state.Lsel GE 0) AND Handle_info( state.ELevel ) then begin
Handle_value, state.ELevel, ELevel,/NO_COPY
ApXsec_hardcopy, ELevel, get_words( event.value )
Handle_value, state.ELevel, ELevel,/NO_COPY,/SET
endif else if (state.Lplot GE 0) then begin
Handle_value, state.ELevs, ELevs,/NO_COPY
ELevel = ELevs(state.Lplot)
Handle_value, state.ELevs, ELevs,/NO_COPY,/SET
ApXsec_hardcopy, ELevel, get_words( event.value )
endif
END
"CANCEL": Cancel_Xsec, state
"KEEP": Commit_Xsec, state
"DONE": BEGIN
if state.modified AND $
(state.Lsel GE 0) AND Handle_info( state.ELevel ) then begin
if yes_no_menu( "Keep new approx. X-sec",/BIN ) $
then Commit_Xsec,state else Cancel_Xsec,state
endif else Cancel_Xsec, state
!X.range = 0
!Y.range = 0
!X.style = 0
!Y.style = 0
if (state.modal) then begin
Widget_Control, event.top,/DESTROY
return
endif else Widget_Control, event.top, MAP=0
END
"AXES": BEGIN
state.xyfix = event.value
replot = 1
CASE state.xyfix OF
0: BEGIN
!X.range = 0
!Y.range = 0
!X.style = 0
!Y.style = 0
END
1: BEGIN
!X.range = state.xrange
!Y.range = state.yrange
!X.style = 1
!Y.style = 1
END
2: BEGIN
Widget_Control, state.instr_wid, GET_VAL=instr
Widget_Control, state.instr_wid, SET_VAL = $
"define Zoom Box: Left -> Middle buttons, Right=abort"
wset, state.window
tvcrs,0.5,0.5,/NORM
zoomxy
state.xrange = !X.range
state.yrange = !Y.range
!X.style = 1
!Y.style = 1
for i=0,1 do begin
Widget_Control, state.x_wids(i),SET_VAL = $
string( state.xrange(i), F="(F6.2)" )
Widget_Control, state.y_wids(i),SET_VAL = $
string( state.yrange(i), F="(F6.2)" )
endfor
Widget_Control, state.instr_wid, SET_VAL=instr
END
else:
ENDCASE
state.xyfix = (state.xyfix > 0) < 1
Widget_Control, event.id, SET_VAL=state.xyfix
END
"XRANGE": BEGIN
Widget_Control, event.id, GET_VAL=value
ix = fix( uval(1) )
state.xrange(ix) = float( value )
Widget_Control, event.id, $
SET_VAL=string( state.xrange(ix), F="(F6.2)" )
if (state.xyfix) then begin
replot = 1
!X.range = state.xrange
endif
END
"YRANGE": BEGIN
Widget_Control, event.id, GET_VAL=value
ix = fix( uval(1) )
state.yrange(ix) = float( value )
Widget_Control, event.id, $
SET_VAL=string( state.yrange(ix), F="(F6.2)" )
if (state.xyfix) then begin
replot = 1
!Y.range = state.yrange
endif
END
else: BEGIN
help,/st,event
message,uval(0)+" not yet implemented",/INFO
END
ENDCASE
if keyword_set( replot ) then begin
if Handle_info( state.ELevel ) then begin
Handle_value, state.ELevel, ELevel,/NO_COPY
wset, state.window
Plot_Xsec, ELevel, TITLE=Level_info( ELevel )
Handle_value, state.ELevel, ELevel,/NO_COPY,/SET
endif
endif
Widget_Control, event.handler, SET_UVAL=state,/NO_COPY
END
;+
; NAME:
; Approx_Xsecs
;
; PURPOSE:
; Create a widget to approximate a cross-section by interactively
; selecting points for piece-wise Linear interpolation.
; Events are handled by pro Approx_Xsecs_Ev.
; State of widget is stored in user value so multiple instances
; can be running simultaneously.
; Called by Build_BFree_Tr which is called by Modion_Event (pro modion).
; CALLING:
; Approx_Xsecs
;
; INPUT:
; ELevs = array of structures with tags for energy of level,
; quantum numbers, and handles pointing to
; full and approximate photo-ionization cross-sections.
; This array is stored via handle of the widget base state.
; OUTPUT:
; ELevs = returned with updated x-secs if /MODAL when widget is DONE,
; otherwise, if not /MODAL then widget is never destroyed
; and the user must retrieve it from the state structure
; in the user-value of the base widget.
; KEYWORDS:
; /MODAL : causes Xmanager to wait until this widget is destroyed,
; so that events from all other widgets are suspended.
;
; GROUP = optional, the ID of the widget that calls this procedure,
; if specified, death of caller results in death of this widget.
;
; XPOS, YPOS = optional, desired position on screen of the widget.
;
; PLOT_SIZE = [xsize,ysize] of draw widget for plotting of X-secs.,
; default = [640,640].
;
; EXTERNAL CALLS:
; pros: Xmanager, widget_Location
; funcs: CW_Bgroup, CW_pdmenu, widget_Tree_Map
; PROCEDURE:
; Create the state structure variable.
; Create and register the widgets with the Xmanager.
; Events are then processed by pro Approx_Xsecs_Ev (above in same file).
; HISTORY:
; written: Frank Varosi HSTX @ NASA/GSFC 1995.
;-
function Approx_Xsecs, ELevs, ion_info, GROUP=group, MODAL=modal, $
PLOT_SIZE=xysize, XPOS=xpos, YPOS=ypos
state = { base:0L ,$
group:0L ,$
draw_wid:0L ,$
window:0 ,$
xyfix:0 ,$
xrange:fltarr(2),$
yrange:fltarr(2),$
x_wids:Lonarr(2),$
y_wids:Lonarr(2),$
info_wid:0L ,$
cursor_wid:0L ,$
instr_wid:0L ,$
List_wid:0L ,$
axes_wid:0L ,$
modal:0 ,$
ELevs:0L ,$ ;handle to Energy Levels.
Lsel:-1 ,$
Lplot:-1 ,$
ELevel:0L ,$ ;handle to selected Energy Level
modified:0 ,$
release:"version 1.5" ,$
wmap:replicate( widget_Tree_Map(), 70 ) }
if N_struct( ELevs ) LE 0 then begin
message,"Energy Level structure is missing",/INFO
return,0
endif
base = Widget_Base( TIT="Cross-Section Approximator : " + $
state.release,/ROW )
state.base = base
message, state.release,/INFO
if N_elements( group ) EQ 1 then state.group = group $
else state.group = 0
baseL = Widget_Base( base, /COLUMN )
baseR = Widget_Base( base, /COLUMN, SPACE=10 )
;first the Left side of widget:
state.instr_wid = Widget_Lab_Info( baseL,VALUE="Select from List",/DYN )
state.info_wid = Widget_Lab_Info( baseL, TIT="Selection:",/DYN )
state.cursor_wid = Widget_Lab_Info( baseL, TIT="Cursor:",/DYN )
if N_elements( xysize ) NE 2 then xysize = [640,640]
state.draw_wid = Widget_Draw( baseL, XSIZE=xysize(0), YSIZE=xysize(1) )
;Now the Right side of widget:
b = Widget_Button( baseR, VALUE="DONE", UVALUE="DONE" )
pdmenu = replicate( { CW_PDMENU_S, flags:0, name:"" }, 5 )
pdmenu.flags = [ 1, 0, 0, 0, 2 ]
pdmenu.name = ["HARDCOPY of Graph", $
"Black on white", $
"Black on white encapsulated PS",$
"Color on White Background", $
"Color on Black Background" ]
b = CW_pdmenu( baseR, pdmenu, /RETURN_NAME, UVAL="HARDCOPY" )
name = "( Z=" + strtrim( ELevs(0).nz,2 ) + $
" , ne=" + strtrim( ELevs(0).nel,2 ) + " )"
if N_struct( ion_info ) EQ 1 then name = ion_info.name + " " + name
b = Widget_Label( baseR, VAL=name )
Levids = Level_info( ELevs, title )
b = Widget_Label( baseR, VAL=title )
state.List_wid = Widget_List( baseR, UVAL="SELECT", VAL=Levids, $
YSIZE = N_elements( Levids ) < 13 )
b = Widget_Label( baseR, VAL="Status of Selected X-sec:" )
b = Widget_Button( baseR, VAL="KEEP new approx X-sec", UVAL="KEEP" )
b = Widget_Button( baseR, VALUE="CANCEL (keep old)", UVALUE="CANCEL" )
state.axes_wid = CW_Bgroup( UVAL="AXES", baseR, $
["Floating X-Y Axes","Fixed X-Y Axes","ZOOM"], $
/FRAME,/COLUMN,/EXCLUSIVE, SET_VAL=state.xyfix )
state.y_wids = Widget_Lab_Text( baseR, L="Y:", F=["min="," max="], $
VAL=string( state.yrange, F="(F6.2)" ), $
UVAL=[ ["YRANGE",'0'], ["YRANGE",'1'] ] )
state.x_wids = Widget_Lab_Text( baseR, L="X:", F=["min="," max="], $
VAL=string( state.xrange, F="(F6.2)" ), $
UVAL=[ ["XRANGE",'0'], ["XRANGE",'1'] ] )
Widget_Control, base, /REALIZE
Widget_Control, state.axes_wid,SENS=0
for i=0,1 do begin
Widget_Control, state.x_wids(i),SENS=0
Widget_Control, state.y_wids(i),SENS=0
endfor
state.wmap = widget_Tree_Map( base )
widget_Location, base, XPOS=xpos, YPOS=ypos
Widget_Control, state.draw_wid, GET_VAL=window
state.window = window
state.ELevs = Handle_create( VALUE=ELevs,/NO_COPY )
if keyword_set( modal ) then begin
state.modal = 1
ELevs_Handle = state.ELevs
endif
Widget_Control, base, SET_UVAL=state,/NO_COPY
Xmanager, "Approx_Xsecs", base, EVENT="Approx_Xsecs_Ev", $
GROUP=group, MODAL=modal
if keyword_set( modal ) then begin
Handle_value, ELevs_Handle, ELevs,/NO_COPY
Handle_free, ELevs_Handle
endif
return, base
END