; Copyright (c) 1998-2009 A.P. Hitchcock  All rights reserved
;+
;NAME:
;	STACK_PROCESS_TOF.PRO
;
;LAST CHANGED: -----------------------------  30-Jul-09 [from 13-Apr-08  (aph FROM 26-Feb-04)]
;   CAUTION - lots of updates of regular stack_analayze missed !!
;
; PURPOSE:
;	This set of procedures and functions is a widget to display
; and extract spectra from stacks.
; This version (derived from from late January 98 version of CJJ) has been
; modifed to handle file names and paths better.
; Read in Io signals from ascii (*.txt) spectral format files (x,y)
; Correct E-scales; normalize yield data; subtract spectra, stacks
; extract images (*.nc format) from stacks.
;
; CATEGORY:
;	Stack analysis.
; Called from aXis2000 by stacks~stack~analyse~AXIS (or AXIS binary)
;
; CALLING SEQUENCE:
;	STACK_PROCESS, [ list_filename, shift_filename, fpath=fpath, binary=binary, $
;                   zoom=zoom, text_height=text_height, realign=realign, $
;                   help=help, no_align = no_align ]
;
; INPUTS:
; list_filename		name of file with list of *.nc image files
; shift_filename	name of file with list of x,y pixel shifts for alignment
;
; KEYWORDS:
; fpath			path for files
; binary		read in as *.ncb binary (all images in one file)
; zoom			zoom factor
; text_height	size of text
; realign		launch stack_align after applying shifs in shift_filename
; help			print help information
; no_align		do not launch stack_align
;
; COMMON BLOCKS:
;	AXIS_COM	standard set of common blocks
;	BSIF_COM	common for NetCDF files
;	STACK_PROCESS_CCM		common for stack process_tof
;	VOLUME_DATA image_stack - 3d array of stack data
;	PIX_SHIFT	set of pixel shifts ( xpix_shift, ypix_shift  )
;
; ROUTINES
; STACK_PROCESS_readroi
; STACK_PROCESS_writeroi
; STACK_PROCESS_gifmovie
; STACK_PROCESS_roi_event,event
; STACK_PROCESS_roi
; STACK_PROCESS_desensitive
; STACK_PROCESS_sensitive
; STACK_PROCESS_graphics
; STACK_PROCESS_bar
; STACK_PROCESS_makespectrum
; STACK_PROCESS_plotspectrum, i_file
; STACK_PROCESS_imgdisp,i_file
; STACK_PROCESS_event,event

; MODIFICATION HISTORY:
; ( 2-may-98 aph) improve filenames and Io read-in
; (20-may-99 aph) - BINARY keyword added to call
; (13-jun-98 aph) correct printed flag on writes
; (14-jun-98 aph) bsif_com
; (30-jun-98 aph) OD determination;
; (6-jul-98 aph) movie buttons, eV_shift, cursor select frame
; (8-Jan-99 aph) hourglass, close,/all to get round no lun problems (movie); path
; (11-Jan-99 aph) symbols - default to none; noYzero; aloadct for IDL 4
; (14-May-99 aph) add TEY-ON/TEY-OFF button for PEEM stacks
; (15-May-99 aph) drop first line
; (19-may-99 aph) REINTRODUCE option to save only image as the movie
; (22-may-99 aph) read-in from binary files enabled (optiona); write to binary
; (08-jun-99 aph) use new version of get_num: group = STACK_PROCESS_par.main_base
; (25-jun-99 aph) add axis_com to put in top_color_index, white_color_index
; (28-jun-99 aph) remove conflict with 'label' and axis_com use of this
; (10-jul-99 aph) add clipping to common area; reverse -ve slope axes; fixe error
; (16-jul-99 aph) remove infinite loop on check for location of files
; (18-jul-99 aph) adapt stack_wb procedure to work with TEY (I/I-t (no log) data (PEEM; TEY-stxm)
; (26-sep-99 aph) remove aloadct (no longer supporting IDL 4.0 operation)
; (27-oct-99 aph) reset (x,y) scales in stack binary writes
; (28-oct-99 aph) no_align keyword added to call
; (28-oct-99 aph) no_align keyword added to call
; (26-jan-00 aph) let sub-flag work independent of OD flag
; (30-mar-00 aph) added group id to get_text
; (09-apr-00 aph) add save image; subtract image; subtract background stack
; (16-apr-00 aph) initial path is DefPath
; (24-apr-00 aph) path picked up at all writes; images (*.nc) allows all to write
; (30-apr-00 aph) image write - allow start number to sync with original file numbers
; (08-may-00 aph) image write - make file numbers be 3 digits; default start with 1; write *.sl
; (10-may-00 aph) stack_binary (*.ncb) default cols/rows eliminate grey;
; (14-may-00 aph) correct filter for image subtraction
; (19-Jul-00 aph) option to update spectrum in movie
; (30-may-01 aph) force energy values to be sorted and increasing
; (11-may-01 aph) if have subtracted spectrum, image or stack,
;                 ensure the difference is what is saved as *.ncb, or images etc
; (23-dec-01 aph) start *.nc numbering at 0; remove desensitize of stack "*.ncb" & others
; (28-dec-01 aph) sesnsitize stack (*.ncb); fix first file blank on image (*.nc)
; (06-jan-01 aph) add slicer3; query removal energy sorting !
; (12-may-02 aph) AXIS standard header added
; (25-may-03 aph) fix co-ordinate error if Io read-in;
;					add all-pixels button; add ratio image button
;					improve sensitize / desensitize
; (15-jun-03 aph) add exchange E-scale; delete image
; (10-jul-03 aph) fix problem of wrong DAT file with multiple 'remove images'
; (26-feb-04 aph) add x,y axis control
;;
; -------- MANY UPDATES TO MAINLINE CODE SHOULD BE ADDED !!!!
;
; (13-apr-08 aph) turn on pre-set window size (X_Scroll_size, Y_Scroll_size) only for non-Windows OS
;                 over-write warning when writing spectra or images
;
;
; -------- MANY UPDATES TO MAINLINE CODE SHOULD BE ADDED !!!!
;
; (30-jul-09 aph) changed analcom to stack_process_com (update to stack_process)
; (29-jul-11 aph) changed stack_analyze_par.spec_savefile_label to replace wt_spec (old spectrum writer) to use spc_save
;-

PRO STACK_PROCESS_readroi
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

old_i_roi = i_roi
old_i0_roi = i0_roi
on_ioerror,STACK_PROCESS_readroi_bailout
t = findfile(roi_filename, count=tcount)
if tcount EQ 0 then roi_filename = pickfile2(/read,FILTER='*.roi', /LPATH, DEFPATH=defpath)
t = ax_name(roi_filename)
widget_control, STACK_PROCESS_par.roi_filename_label, $
          set_value = t(1)
get_lun,lun
openr,lun,roi_filename,/xdr
n_i_roi = long(0)
n_i0_roi = long(0)
readu,lun,n_i_roi,n_i0_roi
IF (n_i_roi NE 0) THEN BEGIN
    i_roi = lonarr(n_i_roi)
    readu,lun,long(i_roi)
ENDIF ELSE BEGIN
    i_roi = 0
ENDELSE
IF (n_i0_roi NE 0) THEN BEGIN
    i0_roi = lonarr(n_i0_roi)
    readu,lun,long(i0_roi)
ENDIF ELSE BEGIN
    i0_roi = 0
ENDELSE
close,lun
free_lun,lun

print,'Read ROI file "'+roi_filename+'"'

return

STACK_PROCESS_readroi_bailout:
print,'Error on reading ROI file "'+roi_filename+'"'
close,lun
free_lun,lun

i_roi = old_i_roi
i0_roi = old_i0_roi

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_writeroi
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

on_ioerror,STACK_PROCESS_writeroi_bailout
i_svec = size(i_roi)
i0_svec = size(i0_roi)
IF (i_svec(0) EQ 0) THEN BEGIN
    n_i_roi = long(0)
ENDIF ELSE BEGIN
    n_i_roi = long(n_elements(i_roi))
ENDELSE
IF (i0_svec(0) EQ 0) THEN BEGIN
    n_i0_roi = long(0)
ENDIF ELSE BEGIN
    n_i0_roi = long(n_elements(i0_roi))
ENDELSE
get_lun,lun
openw,lun,filename_header+'.roi',/xdr
writeu,lun,n_i_roi,n_i0_roi
IF (n_i_roi NE 0) THEN BEGIN
    writeu,lun,long(i_roi)
ENDIF
IF (n_i0_roi NE 0) THEN BEGIN
    writeu,lun,long(i0_roi)
ENDIF

print,'Wrote ROI file "'+filename_header+'.roi"'

STACK_PROCESS_writeroi_bailout:
close,lun
free_lun,lun

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_gifmovie
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

print,'Starting to generate movie'
WIDGET_CONTROL, /Hourglass
close, /all
get_lun,lun
openw,lun,'tempgif.tmp'
image_only = get_text(Prompt='image only?', Val='N', group = axis_ID)

gifmx=[plot_cols,n_cols*img_zoom]
gifmy=[plot_rows,textregion_ypix+n_rows*img_zoom]
if image_only NE 'N' then begin
     gifmy=[plot_rows, n_rows*img_zoom]     ; find out bottom 80 lines are the bar etc
     n_xmin = get_num(prompt='xmin',val = 0, group=STACK_PROCESS_par.main_base)			; allow user to get subset
	 n_xmax = img_zoom*get_num(prompt='xmax',val = n_cols, group=STACK_PROCESS_par.main_base)
	 n_ymin = get_num(prompt='ymin',val = 0, group=STACK_PROCESS_par.main_base)
	 n_ymax = img_zoom*get_num(prompt='ymax',val = n_rows, group=STACK_PROCESS_par.main_base)
endif
; print, 'x,y, limits ' , gifmx, gifmy
FOR i_file=0,(n_elements(filename_list)-1) DO BEGIN
    STACK_PROCESS_imgdisp, i_file
    STACK_PROCESS_plotspectrum, i_file
    wset,STACK_PROCESS_par.image_win
    if image_only EQ 'N' then begin
    	bytimg1 = tvrd(0,0,gifmx(1),gifmy(1))  ; the image, size bar and filename
    endif else bytimg1 = tvrd(0,80,gifmx(1),gifmy(1))	; offset start by 80 to remove bars etc
    wset,STACK_PROCESS_par.plot_win
    bytimg2 = tvrd(0,0,gifmx(0),gifmy(0))	; spectrum
    bytimg = bytarr(max(gifmx),total(gifmy))
    bytimg(0:(plot_cols-1),0:(plot_rows-1)) = $
      bytimg2(0:(plot_cols-1),0:(plot_rows-1))
    bytimg(0:(gifmx(1)-1),gifmy(0):(gifmy(0)+gifmy(1)-1)) = $
      bytimg1(0:(gifmx(1)-1),0:(gifmy(1)-1))

    IF (i_file LT 10) THEN BEGIN
        gifframe_filename = 'temp000'+strtrim(string(i_file),2)+'.gif'
    ENDIF ELSE IF (i_file LT 100) THEN BEGIN
        gifframe_filename = 'temp00'+strtrim(string(i_file),2)+'.gif'
    ENDIF ELSE IF (i_file LT 1000) THEN BEGIN
        gifframe_filename = 'temp0'+strtrim(string(i_file),2)+'.gif'
    ENDIF ELSE BEGIN
        gifframe_filename = 'temp'+strtrim(string(i_file),2)+'.gif'
    ENDELSE
    if image_only EQ 'N' then begin
    	write_gif,gifframe_filename,bytimg,r,g,b
    endif else begin
    	write_gif,gifframe_filename,bytimg1(n_xmin:n_xmax-1,n_ymin:n_ymax-1),r,g,b
    endelse
    printf,lun,gifframe_filename
ENDFOR

close,lun
free_lun,lun

IF (strlen(filename_header) GT 7) THEN BEGIN
    print,'Warning: GIF movie filename may be truncated to "'+$
      strmid(filename_header,0,7)+'m.gif"'
ENDIF
gifmovie_filename = filename_header+'m.gif'
command='multigif -n 0 -o '+gifmovie_filename+' @tempgif.tmp'
result=''
print,'Command: "'+command+'"'
spawn,command,result
print,'  Result: "'+result+'"'
del_files = 'Y'
del_files = get_text(Prompt='Delete *.gif?',Val = del_files, group = axis_ID)
if del_files EQ 'Y' then begin
	osname=strupcase(strmid(!version.os,0,3))
	IF (osname EQ 'VMS') THEN BEGIN
	    command1='del temp*.gif;*'
	    command2='del tempgif.tmp;*'
	ENDIF ELSE IF (osname EQ 'WIN') THEN BEGIN
	    command1 = 'del temp*.gif'
	    command2 = 'del tempgif.tmp'
	ENDIF ELSE BEGIN
	    command1 = 'rm temp*.gif'
	    command2 = 'rm tempgif.tmp'
	ENDELSE
	print,'Command: "'+command1+'"'
	spawn,command1,result
	print,'  Result: "'+result+'"'
	print,'Command: "'+command2+'"'
	spawn,command2,result
	print,'  Result: "'+result+'"'
endif else print, 'temp*.gif files are likely in c:\axis !'
print,'Created GIF movie "'+gifmovie_filename+'"'

STACK_PROCESS_imgdisp, displayed_file_index
STACK_PROCESS_plotspectrum, displayed_file_index
widget_control,STACK_PROCESS_par.main_base,show=1,map=1

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_roi_event,event
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

CASE event.id OF
    STACK_PROCESS_par.roi_accept_label: BEGIN
; add i0-values to roi pixel list
; in (x,y) zoom mode, need to rescale the cursor co-ordinates to the data co-ordinates
; (22-feb-04 aph)
        IF (STACK_PROCESS_par.is_i0_roi NE 0L) THEN BEGIN
            svec = size(i0_roi)
            IF (svec(0) EQ 0) THEN BEGIN
                i0_roi = roi
            ENDIF ELSE BEGIN
                i0_roi = [i0_roi,roi]
                i0_roi = i0_roi(uniq(i0_roi,sort(i0_roi)))
            ENDELSE
; add i-values to roi pixel list
        ENDIF ELSE BEGIN
            svec = size(i_roi)
            IF (svec(0) EQ 0) THEN BEGIN
                i_roi = roi
            ENDIF ELSE BEGIN
                i_roi = [i_roi,roi]
                i_roi = i_roi(uniq(i_roi,sort(i_roi)))
            ENDELSE
        ENDELSE
        widget_control, STACK_PROCESS_par.roi_base,/destroy
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
        widget_control, STACK_PROCESS_par.main_base,show=1
        STACK_PROCESS_sensitive
    END

    STACK_PROCESS_par.roi_reject_label: BEGIN
        widget_control, STACK_PROCESS_par.roi_base,/destroy
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
        widget_control, STACK_PROCESS_par.main_base,show=1
        STACK_PROCESS_sensitive
    END
ENDCASE
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_roi, all=all
; ------ add all keyword (aph 25-may-03)
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

; *img_zoom,n_rows*img_zoom

IF keyword_set(all) then begin
	t = make_array(n_cols,n_rows,/integer,value = 1)
	roi = where(t GT 0)
    svec = size(i_roi)
    IF (svec(0) EQ 0) THEN BEGIN
        i_roi = roi
    ENDIF ELSE BEGIN
        i_roi = [i_roi,roi]
        i_roi = i_roi(uniq(i_roi,sort(i_roi)))
    ENDELSE
    STACK_PROCESS_makespectrum
    STACK_PROCESS_plotspectrum,displayed_file_index
    STACK_PROCESS_imgdisp,displayed_file_index
    widget_control, STACK_PROCESS_par.main_base,show=1
    STACK_PROCESS_sensitive
	return
ENDIF

IF (STACK_PROCESS_par.is_i0_roi NE 0L) THEN BEGIN
    title_string = 'Add I0 region'
ENDIF ELSE BEGIN
    title_string = 'Add I region'
ENDELSE

STACK_PROCESS_par.roi_base = widget_base(title=title_string,/column)
tlabel = $
  widget_text( STACK_PROCESS_par.roi_base, $
               xsize=30, ysize=4,/scroll,/wrap, $
               value='Left button adds points, middle button '+$
               'erases last point, right button closes '+$
               'region.  You must then either ACCEPT or '+$
               'REJECT the region.')
STACK_PROCESS_par.roi_accept_label = $
  widget_button( STACK_PROCESS_par.roi_base, value='ACCEPT region')
STACK_PROCESS_par.roi_reject_label = $
  widget_button( STACK_PROCESS_par.roi_base, value='REJECT region')

widget_control, STACK_PROCESS_par.roi_base, /realize
widget_control, STACK_PROCESS_par.roi_accept_label, sensitive=0
widget_control, STACK_PROCESS_par.roi_reject_label, sensitive=0
widget_control, STACK_PROCESS_par.main_base,show=1

wset,STACK_PROCESS_par.image_win
; get pixels from user-selected cursor region
;roi = cw_defroi(n_cols,n_rows,zoom=img_zoom,offset=[0,textregion_ypix]) ; new (aph 22-feb-04)
 roi = defroi(n_cols,n_rows,zoom=img_zoom,y0=textregion_ypix)  ; old (CJJ)

; print, ' roi ', roi
; convert from displayed pixels to pixels in data in range ([ixl:ixh],[iyl:iyh])
; first set up a 0/1 array in ncol, nrow format  - this is the information returned from defroi
t = make_array(n_cols,n_rows,/integer,value = 0)
t(roi) = 1

; image what is going on !!
i_file = displayed_file_index
delx = (x_stop - x_start)/float(n_cols)
ixl = floor((disp_xmin - x_start)/delx)
if ixl lt 0 then ixl = 0
ixh = floor((disp_xmax - x_start)/delx)
if ixh gt n_cols-1 then ixh = n_cols-1

dely = (y_stop - y_start)/float(n_rows)
iyl = floor((disp_ymin - y_start)/dely)
if iyl lt 0 then iyl = 0
iyh = floor((disp_ymax - y_start)/dely)
if iyh gt n_rows-1 then iyh = n_rows-1
tmp_dat =  image_stack(ixl:ixh,iyl:iyh,i_file)
tmp_min = disp_min
tmp_max = disp_max
test = where(i0_signal GT 0,count)
if OD_flag EQ 1 AND count GT 0 then begin
	tmp_i0 = i0_signal(i_file)
    if tmp_i0 LE 0 then i0_signal(i_file) = 1.
 	tmp_dat = -alog(image_stack(*,*,i_file)/i0_signal(i_file))
endif
byte_image = byte(0.5+float(top_color_index)* $
                  (( (((tmp_dat-tmp_min) / $
                       float(tmp_max-tmp_min))^disp_gamma) $
                     >0.)<1.))<byte(top_color_index)
tmp_dat = intarr(n_cols*img_zoom, n_rows*img_zoom)
tmp_dat = congrid(byte_image,n_cols*img_zoom,n_rows*img_zoom)
tmp_dat(roi) = i_color_index
window, 21, xsize = n_cols, ysize = n_rows, ypos = 1.5*n_rows,  xpos = !D.X_SIZE - n_cols
tv, tmp_dat
wshow, 21

; convert pixels selected on (possibly) zoomed image to pixels in data file
roi_img = make_array(n_cols,n_rows,/integer,value = 0)
ixslope = (ixh - ixl)/n_cols
iyslope = (iyh - iyl)/n_rows
for i = 0, n_cols-1 do begin
	for j = 0, n_rows-1 do begin
		if t(i,j) EQ 1 then begin
			ix = fix(ixl+ i*ixslope)
			iy = fix(iyl +j*iyslope)
			roi_img(ix, iy) = 1
		endif
	endfor
endfor

roi = where(roi_img EQ 1)

tmp_dat = image_stack(*,*,displayed_file_index)
byte_image = byte(0.5+float(top_color_index)* $
                  (( (((tmp_dat-tmp_min) / $
                       float(tmp_max-tmp_min))^disp_gamma) $
                     >0.)<1.))<byte(top_color_index)
byte_image(roi) = i_color_index
window, 22, xsize = n_cols, ysize = n_rows, ypos = 3*n_rows, xpos = !D.X_SIZE - n_cols
tv, byte_image
wshow, 22

widget_control, STACK_PROCESS_par.roi_accept_label, sensitive=1
widget_control, STACK_PROCESS_par.roi_reject_label, sensitive=1
widget_control, STACK_PROCESS_par.roi_base,show=1,map=1
xmanager, 'STACK_PROCESS_roi', STACK_PROCESS_par.roi_base, $
  group_leader = STACK_PROCESS_par.main_base

;wdelete, 21
;wdelete, 22
return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_desensitive
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

widget_control,STACK_PROCESS_par.disp_min_label, sensitive=0
widget_control,STACK_PROCESS_par.disp_max_label, sensitive=0
widget_control,STACK_PROCESS_par.disp_gamma_label, sensitive=0
widget_control,STACK_PROCESS_par.filename_ev_msec_list_label, sensitive=0
widget_control,STACK_PROCESS_par.add_i0_roi_label, sensitive=0
widget_control,STACK_PROCESS_par.add_i0_pix_label, sensitive=0
widget_control,STACK_PROCESS_par.reset_i0_label, sensitive=0
widget_control,STACK_PROCESS_par.Movie_buts, sensitive=1
widget_control,STACK_PROCESS_par.i0_readin, sensitive=0
widget_control,STACK_PROCESS_par.i0_norm, sensitive=0
WIDGET_CONTROL, STACK_PROCESS_par.OD_tran, sensitive=0
WIDGET_CONTROL, STACK_PROCESS_par.sub_spectrum, sensitive=0
widget_control, STACK_PROCESS_par.save_image_label, sensitive=0
widget_control, STACK_PROCESS_par.ratio_image, sensitive=0
widget_control, STACK_PROCESS_par.sub_image, sensitive=0
widget_control, STACK_PROCESS_par.sub_stack, sensitive=0
widget_control,STACK_PROCESS_par.eV_shift, sensitive=0
widget_control,STACK_PROCESS_par.add_all_label, sensitive=0
widget_control,STACK_PROCESS_par.add_i_roi_label, sensitive=0
widget_control,STACK_PROCESS_par.add_i_pix_label, sensitive=0
widget_control,STACK_PROCESS_par.reset_i_label, sensitive=0
; widget_control,STACK_PROCESS_par.roi_filename_label, sensitive=0
; widget_control,STACK_PROCESS_par.roi_readfile_label, sensitive=0
widget_control,STACK_PROCESS_par.filename_path, sensitive=0
widget_control,STACK_PROCESS_par.filename_label, sensitive=0
widget_control,STACK_PROCESS_par.spec_savefile_label, sensitive = 0
widget_control,STACK_PROCESS_par.gifimg_savefile_label, sensitive = 0
widget_control,STACK_PROCESS_par.gifmov_savefile_label, sensitive = 0
widget_control,STACK_PROCESS_par.stack_savefile_label, sensitive = 0
widget_control,STACK_PROCESS_par.roi_savefile_label, sensitive = 0
widget_control,STACK_PROCESS_par.slicer_label, sensitive=0
widget_control,STACK_PROCESS_par.slicer3_label, sensitive=0
widget_control,STACK_PROCESS_par.tey_label, sensitive=0
widget_control,STACK_PROCESS_par.exit_label, sensitive=0

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_sensitive
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

widget_control,STACK_PROCESS_par.disp_min_label, sensitive=1
widget_control,STACK_PROCESS_par.disp_max_label, sensitive=1
widget_control,STACK_PROCESS_par.disp_gamma_label, sensitive=1
widget_control,STACK_PROCESS_par.filename_ev_msec_list_label, sensitive=1
widget_control,STACK_PROCESS_par.add_i0_roi_label, sensitive=1
widget_control,STACK_PROCESS_par.Movie_buts, sensitive=1
widget_control,STACK_PROCESS_par.i0_readin, sensitive=1
widget_control,STACK_PROCESS_par.i0_norm, sensitive=1
WIDGET_CONTROL, STACK_PROCESS_par.OD_tran, sensitive=1
WIDGET_CONTROL, STACK_PROCESS_par.sub_spectrum, sensitive=1
widget_control, STACK_PROCESS_par.save_image_label, sensitive=1
widget_control, STACK_PROCESS_par.ratio_image, sensitive=1
widget_control, STACK_PROCESS_par.sub_image, sensitive=1
widget_control, STACK_PROCESS_par.sub_stack, sensitive=1
widget_control,STACK_PROCESS_par.add_i0_pix_label, sensitive=1
widget_control,STACK_PROCESS_par.reset_i0_label, sensitive=1
widget_control,STACK_PROCESS_par.eV_shift, sensitive=1
widget_control,STACK_PROCESS_par.add_all_label, sensitive=1
widget_control,STACK_PROCESS_par.add_i_roi_label, sensitive=1
widget_control,STACK_PROCESS_par.add_i_pix_label, sensitive=1
widget_control,STACK_PROCESS_par.reset_i_label, sensitive=1
widget_control,STACK_PROCESS_par.roi_filename_label, sensitive=1
;IF (strlen(roi_filename) NE 0) THEN BEGIN
    widget_control,STACK_PROCESS_par.roi_readfile_label, sensitive=1
;ENDIF ELSE BEGIN
;    widget_control,STACK_PROCESS_par.roi_readfile_label, sensitive=0
;ENDELSE
widget_control,STACK_PROCESS_par.filename_path, sensitive=1
widget_control,STACK_PROCESS_par.filename_label, sensitive=1
IF (strlen(filename_header) NE 0) THEN BEGIN
    widget_control, STACK_PROCESS_par.spec_savefile_label, sensitive = 1
    widget_control,STACK_PROCESS_par.stack_savefile_label, sensitive = 1
     widget_control, STACK_PROCESS_par.save_image_label, sensitive = 1
    widget_control, STACK_PROCESS_par.gifimg_savefile_label, sensitive = 1
    widget_control, STACK_PROCESS_par.gifmov_savefile_label, sensitive = 1
    widget_control, STACK_PROCESS_par.roi_savefile_label, sensitive = 1
ENDIF ELSE BEGIN
    widget_control, STACK_PROCESS_par.spec_savefile_label, sensitive = 0
     widget_control, STACK_PROCESS_par.save_image_label, sensitive = 0
    widget_control, STACK_PROCESS_par.gifimg_savefile_label, sensitive = 0
    widget_control, STACK_PROCESS_par.gifmov_savefile_label, sensitive = 0
    widget_control, STACK_PROCESS_par.stack_savefile_label, sensitive = 0
    widget_control, STACK_PROCESS_par.roi_savefile_label, sensitive = 0
ENDELSE
widget_control,STACK_PROCESS_par.exit_label, sensitive=1
widget_control,STACK_PROCESS_par.slicer_label, sensitive=1
widget_control,STACK_PROCESS_par.slicer3_label, sensitive=1
widget_control,STACK_PROCESS_par.tey_label, sensitive=1
return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; This routine sets up color maps and graphics parameters

PRO STACK_PROCESS_graphics
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

plot_cols = (n_cols*img_zoom)>300
plot_rows = 200
textregion_nlines=5

window,0,xsize=50,ysize=50
wset,0
xyouts,5,30,/device,'Please!Cwait...',font=0

i0_color_index = !d.table_size-1
i_color_index = !d.table_size-2
white_color_index = !d.table_size-3
top_color_index = !d.table_size-4

r = byte(0.5+255.*findgen(!d.table_size)/float(top_color_index))
g = r
b = r
r(i0_color_index) = 255
g(i0_color_index) = 0
b(i0_color_index) = 0
r(i_color_index) = 0
g(i_color_index) = 255
b(i_color_index) = 0
r(white_color_index) = 255
g(white_color_index) = 255
b(white_color_index) = 255
tvlct,r,g,b

charsize=char_ypix/float(!d.y_ch_size)
textregion_ypix=fix(textregion_nlines*char_ypix)

STACK_PROCESS_bar

wdelete,0

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_makespectrum
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

pixarea = abs(x_stop-x_start)*abs(y_stop-y_start) / $
  (float(n_cols-1)*float(n_rows-1))

i_svec = size(i_roi)
IF (i_svec(0) NE 0) THEN BEGIN
    print,'Area of I ROI: '+$
      strtrim(string(n_elements(i_roi)),2)+' pixels, '+$
      strtrim(string(n_elements(i_roi)*pixarea,format='(f10.3)'),2)+$
      ' square microns'
ENDIF

i0_svec = size(i0_roi)
IF (i0_svec(0) NE 0) THEN BEGIN
    print,'Area of I0 ROI: '+$
      strtrim(string(n_elements(i0_roi)),2)+' pixels, '+$
      strtrim(string(n_elements(i0_roi)*pixarea,format='(f10.3)'),2)+$
      ' square microns'
ENDIF

IF (i_svec(0) EQ 0) THEN BEGIN
    i_signal = 0
    IF (i0_svec(0) EQ 0) THEN BEGIN
        ;; we can't do anything at all
        i0_signal = 0
        spectrum = 0
        spectrum_title = ''
    ENDIF ELSE BEGIN
        ;; we can at least plot I0
    	if i0_read EQ 1 then begin		; add in ability to handle read-in Io
    	  i0_signal = i0_data
    	endif else begin
          i0_signal = fltarr(n_elements(ev))
          FOR i_ev=0,(n_elements(ev)-1) DO BEGIN
            khz = image_stack(*,*,i_ev)
            i0_signal(i_ev) = total(khz(i0_roi))/float(n_elements(i0_roi))
          ENDFOR
        endelse
        spectrum = i0_signal
        spectrum_title = 'I0'
    ENDELSE
ENDIF ELSE BEGIN
    i_signal = fltarr(n_elements(ev))
    FOR i_ev=0,(n_elements(ev)-1) DO BEGIN
        khz = image_stack(*,*,i_ev)
        i_signal(i_ev) = total(khz(i_roi))/float(n_elements(i_roi))
    ENDFOR

    IF (i0_svec(0) EQ 0 AND i0_read  EQ 0) THEN BEGIN
        ;; we can at least plot I
        i0_signal = 0

        spectrum = i_signal
        spectrum_title = 'I'
    ENDIF ELSE BEGIN
       ;; we can really do it
      if i0_read EQ 1 then begin		; add in ability to handle read-in Io
        i0_signal = i0_data
      endif else begin
        i0_signal = fltarr(n_elements(ev))
        FOR i_ev=0,(n_elements(ev)-1) DO BEGIN
            khz = image_stack(*,*,i_ev)
            i0_signal(i_ev) = total(khz(i0_roi))/float(n_elements(i0_roi))
        ENDFOR
      endelse
        spectrum_title = 'Yield (I/Io)'
      	spectrum = i_signal/i0_signal
        if tey_flag NE 1 then begin
        	spectrum = -alog(i_signal/i0_signal)
	        spectrum_title = 'Optical Density'
	    endif
    ENDELSE

; (aph 7-jul-98) ------ subtract reference (OD)  spectrum
; (aph 26-jan-00) - remove OD_flag requirement
;	IF sub_flag EQ 1 then spectrum = spectrum - ref_spectrum
; superceded by complete subtraction from image_stack to allow saves. aph 11-may-01
ENDELSE

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_plotspectrum, i_file
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

wset,STACK_PROCESS_par.plot_win
erase

svec = size(spectrum)
IF (svec(0) EQ 0) THEN return                               ; **********
!y.range=0       ; force auto rescaling                     ; APH CHANGES
!x.range=0
plot,ev,spectrum,xtitle='eV',ytitle=spectrum_title,$        ; ************
     color=white_color_index, psym = 0, ynozero = 1
IF (n_params() NE 0) THEN BEGIN
    plots,ev(i_file)+[0.,0.],!y.crange,color=white_color_index
;    plots,ev(i_file)+[0.,0.],!y.crange,color=i_color_index
ENDIF

spectrum_x_scale = !x.s
spectrum_y_scale = !y.s

return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FUNCTION disp_zoom_roi, indices
; converts data roi indices to zoomed roi indices using
; presently defined ixl, ixh, iyl, iyh corresponding to
; disp_xmin, disp_xmax, disp_ymin, disp_ymax

@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

t = make_array(n_cols,n_rows,/integer,value = 0)		; data pixels
t(indices) = 1
roi_img = make_array(n_cols,n_rows,/integer,value = 0)  ; expanded image pixels
ixslope = (ixh - ixl) / float(n_cols)
iyslope = (iyh - iyl) / float(n_rows)
help, ixslope,iyslope
for i = 0, n_cols-1 do begin
	for j = 0, n_rows-1 do begin
			ix = fix(i*ixslope + ixl )
			iy = fix(j*iyslope + iyl )
		if t(ix,iy) EQ 1 then roi_img(i, j) = 1
	endfor
endfor
data_roi = where(roi_img EQ 1)
return, data_roi
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_imgdisp,i_file

; --------------------- last changed: 24-feb-04
; ONLY plot image if flag set

@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

wset,STACK_PROCESS_par.image_win
; This produces less flicker than an "erase" instruction
tv,bytarr(n_cols*img_zoom,textregion_ypix),0,0,/device

; (aph 30-jun-98) - allow convert to OD

; (aph 21-feb-04) - identify indices corresponding to current x, y limits
delx = (x_stop - x_start)/float(n_cols)
ixl = floor((disp_xmin - x_start)/delx)
if ixl lt 0 then ixl = 0
ixh = floor((disp_xmax - x_start)/delx)
if ixh gt n_cols-1 then ixh = n_cols-1

dely = (y_stop - y_start)/float(n_rows)
iyl = floor((disp_ymin - y_start)/dely)
if iyl lt 0 then iyl = 0
iyh = floor((disp_ymax - y_start)/dely)
if iyh gt n_rows-1 then iyh = n_rows-1
;print,  'delx, dely ', delx, dely
;print, ' size of images: x: ', fix(n_cols), ' y: ', fix(n_rows)
;print, ' expand to: X: ', disp_xmin, ' - ', disp_xmax, '  Y: ', disp_ymin, ' - ', disp_ymax
;print, '   indices: X: ', ixl, ' - ', ixh, '  Y: ', iyl, ' - ', iyh
; extract portion of image within these indices
tmp_dat =  image_stack(ixl:ixh,iyl:iyh,i_file)
tmp_min = disp_min
tmp_max = disp_max
test = where(i0_signal GT 0,count)
if OD_flag EQ 1 AND count GT 0 then begin
	tmp_i0 = i0_signal(i_file)
    if tmp_i0 LE 0 then i0_signal(i_file) = 1.
 	tmp_dat = -alog(image_stack(*,*,i_file)/i0_signal(i_file))
endif

; ---- subtract ref. signal at this energy -------
; if sub_flag EQ 1 then tmp_dat = tmp_dat - ref_spectrum(i_file)
; superceded by complete subtraction from image_stack to allow saves. aph 11-may-01

if rescale_flag EQ 1 then begin
	tmp_min=0
	tmp_max = 255
;    medo=median(tmp_dat)
	tmp_dat = bytscl(tmp_dat)
; 	print,'rescale: old median = ',medo,' OD median = ',median(tmp_dat)
endif

byte_image = byte(0.5+float(top_color_index)* $
                  (( (((tmp_dat-tmp_min) / $
                       float(tmp_max-tmp_min))^disp_gamma) $
                     >0.)<1.))<byte(top_color_index)

i_svec = size(i_roi)
i0_svec = size(i0_roi)

IF (i_svec(0) NE 0) THEN BEGIN
; convert i_roi to the zoomed image scale
    i_roi_zoom = disp_zoom_roi(i_roi)
    byte_image(i_roi_zoom) = i_color_index
ENDIF
IF (i0_svec(0) NE 0) THEN BEGIN
    i0_roi_zoom = disp_zoom_roi(i0_roi)
    byte_image(i0_roi_zoom) = i0_color_index
ENDIF


tv,congrid(byte_image,n_cols*img_zoom,n_rows*img_zoom), $      ; replace rebin for non-integer
  0,textregion_ypix,/device							; removed ,/sample keyword

; add scale bar and energy
; ********
; CJJ - replaced to display ONLY name (not path) - APH 16-apr-98
;xyouts,5,fix(0.5*char_ypix),/device,charsize=charsize,font=0, $
;  filename_list(i_file),color=white_color_index
; strip filename
if !VERSION.OS_FAMILY EQ 'unix' then sep = '/' else sep = '\'
file =  string(filename_list(i_file))
file=strmid(file,rstrpos(file,sep)+1,strlen(file))
file = strmid(file,0,strpos(file,'.'))
xyouts,5,fix(0.5*char_ypix),/device,charsize=charsize,font=0, $
  file,color=white_color_index
; APH - end of changes
xyouts,5,fix(2.*char_ypix),/device,charsize=charsize,font=0, $
  strtrim(string(ev(i_file),format='(f10.2)'),2)+' eV',$
  color=white_color_index
tv,bar,5,fix(3.5*char_ypix),/device
xyouts,(5+bar_pixels+char_ypix),fix(3.5*char_ypix),/device,font=0,$
  charsize=charsize,bar_string,color=white_color_index

return
END

PRO STACK_PROCESS_bar
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack
COMMON pix_shift, xpix_shift, ypix_shift

bar_microns = 0.2*abs(disp_xmax-disp_xmin)
IF (bar_microns GE 10.) THEN BEGIN
    bar_microns = 10.*fix(0.5+0.1*fix(0.5+bar_microns))
    bar_string = strtrim(string(fix(0.01+bar_microns)),2)  +' micro'
ENDIF ELSE IF (bar_microns GE 1.) THEN BEGIN
    bar_microns = float(fix(0.5+bar_microns))
    IF (bar_microns EQ 1.) THEN BEGIN
        bar_string = '1 ' + ' micro'
    ENDIF ELSE BEGIN
        bar_string = strtrim(string(fix(0.01+bar_microns)),2)  +' micro'
    ENDELSE
ENDIF ELSE BEGIN
    bar_microns = (0.1*fix(0.5+10*bar_microns))>0.1
    bar_string = strtrim(string(bar_microns,format='(f10.1)'),2) +' micro'
ENDELSE
bar_pixels = fix(0.5+float(n_cols*img_zoom)*float(bar_microns) / $
                 float(abs(x_stop-x_start)))
bar = bytarr(bar_pixels,fix(0.4*char_ypix))+white_color_index
return
END

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PRO STACK_PROCESS_event,event
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack
COMMON pix_shift, xpix_shift, ypix_shift

on_error,2

CASE event.id OF
    STACK_PROCESS_par.disp_min_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_min_label,$
          get_value = temp_string
        on_ioerror, disp_min_label_oops
        reads,temp_string(0),disp_min
        disp_min_label_oops:
        widget_control, STACK_PROCESS_par.disp_min_label, $
          set_value = strtrim(string(disp_min,format='(f10.2)'),2)
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.disp_max_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_max_label,$
          get_value = temp_string
        on_ioerror, disp_max_label_oops
        reads,temp_string(0),disp_max
        disp_max_label_oops:
        widget_control, STACK_PROCESS_par.disp_max_label, $
          set_value = strtrim(string(disp_max,format='(f10.2)'),2)
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.disp_gamma_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_gamma_label,$
          get_value = temp_string
        on_ioerror, disp_gamma_label_oops
        reads,temp_string(0),disp_gamma
        disp_gamma_label_oops:
        widget_control, STACK_PROCESS_par.disp_gamma_label, $
          set_value = strtrim(string(disp_gamma,format='(f10.2)'),2)
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.disp_xmin_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_xmin_label,$
          get_value = temp_string
        on_ioerror, disp_xmin_label_oops
        reads,temp_string(0),disp_xmin
        disp_xmin_label_oops:
        widget_control, STACK_PROCESS_par.disp_xmin_label, $
          set_value = strtrim(string(disp_xmin,format='(f10.2)'),2)
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.disp_xmax_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_xmax_label,$
          get_value = temp_string
        on_ioerror, disp_xmax_label_oops
        reads,temp_string(0),disp_xmax
        disp_xmax_label_oops:
        widget_control, STACK_PROCESS_par.disp_xmax_label, $
          set_value = strtrim(string(disp_xmax,format='(f10.2)'),2)
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.disp_ymin_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_ymin_label,$
          get_value = temp_string
        on_ioerror, disp_ymin_label_oops
        reads,temp_string(0),disp_ymin
        disp_ymin_label_oops:
        widget_control, STACK_PROCESS_par.disp_ymin_label, $
          set_value = strtrim(string(disp_ymin,format='(f10.2)'),2)
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.disp_ymax_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_ymax_label,$
          get_value = temp_string
        on_ioerror, disp_ymax_label_oops
        reads,temp_string(0),disp_ymax
        disp_ymax_label_oops:
        widget_control, STACK_PROCESS_par.disp_ymax_label, $
          set_value = strtrim(string(disp_ymax,format='(f10.2)'),2)
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.disp_zoom: BEGIN
        BX_CURSOR, xl, yl, w, h
        yl = yl - textregion_ypix
;        print, xl, yl, w, h
		delx = (x_stop - x_start)/float(n_cols)
		disp_xmin = x_start + xl*delx
		disp_xmax = disp_xmin + w*delx
		dely = (y_stop - y_start)/float(n_rows)
		disp_ymin = y_start + yl*dely
		disp_ymax = disp_ymin + h*dely
		widget_control, STACK_PROCESS_par.disp_xmin_label, $
		    set_value = strtrim(string(disp_xmin,format='(f10.2)'),2)
		widget_control, STACK_PROCESS_par.disp_xmax_label, $
		    set_value = strtrim(string(disp_xmax,format='(f10.2)'),2)
		widget_control, STACK_PROCESS_par.disp_ymin_label, $
		    set_value = strtrim(string(disp_ymin,format='(f10.2)'),2)
		widget_control, STACK_PROCESS_par.disp_ymax_label, $
		    set_value = strtrim(string(disp_ymax,format='(f10.2)'),2)
		STACK_PROCESS_bar
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.disp_reset: BEGIN
		disp_xmin = x_start
		disp_xmax = x_stop
		disp_ymin = y_start
		disp_ymax = y_stop
		widget_control, STACK_PROCESS_par.disp_xmin_label, $
		    set_value = strtrim(string(disp_xmin,format='(f10.2)'),2)
		widget_control, STACK_PROCESS_par.disp_xmax_label, $
		    set_value = strtrim(string(disp_xmax,format='(f10.2)'),2)
		widget_control, STACK_PROCESS_par.disp_ymin_label, $
		    set_value = strtrim(string(disp_ymin,format='(f10.2)'),2)
		widget_control, STACK_PROCESS_par.disp_ymax_label, $
		    set_value = strtrim(string(disp_ymax,format='(f10.2)'),2)
		STACK_PROCESS_bar
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.xloadct_label: BEGIN
        tvlct,r,g,b
		xloadct, group = axis_ID, ncolors=top_color_index+1
    END

    STACK_PROCESS_par.filename_ev_msec_list_label: BEGIN
        displayed_file_index = event.index
        STACK_PROCESS_imgdisp, displayed_file_index
        STACK_PROCESS_plotspectrum, displayed_file_index
    END

    STACK_PROCESS_par.eV_shift: BEGIN          ; added 6-jul-98
	    E_shift = get_num(Prompt='E shift',val=0, group=STACK_PROCESS_par.main_base)
	    eV = eV + E_shift(0)
	    FOR i=0,(n_elements(filename_list)-1) DO BEGIN ; update list
	    	str = filename_ev_msec_list(i)
	    	strput, str,strtrim(string(ev(i),format='(f10.2)'),2),11
		    filename_ev_msec_list(i) = str
		ENDFOR
        WIDGET_CONTROL,STACK_PROCESS_par.filename_ev_msec_list_label, $
 			Set_Value = filename_ev_msec_list
	    STACK_PROCESS_makespectrum
	    STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.add_i0_roi_label: BEGIN
        STACK_PROCESS_desensitive
        STACK_PROCESS_par.is_i0_roi = 1L
        STACK_PROCESS_roi
    END

    STACK_PROCESS_par.add_i0_pix_label: BEGIN
        STACK_PROCESS_desensitive
        STACK_PROCESS_par.add_pix = 1
    END

    STACK_PROCESS_par.reset_i0_label: BEGIN
        i0_roi = 0
        i0_read=0                       ; zero out read-in data
        i0_data=0
        OD_flag = 0                     ; remove OD determination
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

    STACK_PROCESS_par.add_all_label: BEGIN
        STACK_PROCESS_par.is_i0_roi = 0L
        STACK_PROCESS_roi,/all
    END
    STACK_PROCESS_par.add_i_roi_label: BEGIN
        STACK_PROCESS_desensitive
        STACK_PROCESS_par.is_i0_roi = 0L
        STACK_PROCESS_roi
    END

    STACK_PROCESS_par.add_i_pix_label: BEGIN
        STACK_PROCESS_desensitive
        STACK_PROCESS_par.add_pix = 2
    END

    STACK_PROCESS_par.reset_i_label: BEGIN
        i_roi = 0
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (APH 16-apr-98) -------- allow read-in of Io from file (assumed AXIS) ----
	STACK_PROCESS_par.i0_readin: BEGIN
        STACK_PROCESS_desensitive
        tmp = spc_load(DEFPATH=DefPath, filter='*.txt')
        if n_tags(tmp) NE 0 then begin
        	i0_data = interpol(tmp.d, tmp.x, ev)
        	i0_read=1
        	i0_roi=1
        endif
		STACK_PROCESS_makespectrum
		STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
        STACK_PROCESS_sensitive
    END

; (APH 30-jun-98) ------set/reset FLAG to convert to OD (divide all pixels by Io)  ----
	STACK_PROCESS_par.i0_norm: BEGIN
	if i0_signal(0) EQ 0 then begin
		print, 'You must define the Io signal before converting to optical density'
	endif else BEGIN
    	if OD_flag EQ 0 then OD_flag = 1 else OD_flag = 0     ;flip state of switch
    	if OD_flag EQ 0 then begin
	    	WIDGET_CONTROL, STACK_PROCESS_par.OD_tran, set_value=' I(t)'
	    	sub_flag = 0
	    	disp_min = min(image_stack)
			disp_max = max(image_stack)
		 	WIDGET_CONTROL, STACK_PROCESS_par.disp_min_label, set_value=strcompress(string(disp_min))
		 	WIDGET_CONTROL, STACK_PROCESS_par.disp_max_label, set_value=strcompress(string(disp_max))
    	endif
    	if OD_flag EQ 1 then begin
	    	widget_control,/hourglass
	    	WIDGET_CONTROL, STACK_PROCESS_par.OD_tran, set_value=' O.D.'
	    	for i = 0, n_elements(eV)-1 do tmp = -alog(image_stack(*,*,i)/i0_signal(i))
	    	disp_min = min(tmp)
		 	disp_max = max(tmp)
		 	WIDGET_CONTROL, STACK_PROCESS_par.disp_min_label, set_value=strcompress(string(disp_min))
		 	WIDGET_CONTROL, STACK_PROCESS_par.disp_max_label, set_value=strcompress(string(disp_max))
		endif
    STACK_PROCESS_imgdisp,displayed_file_index
    endelse
    END

; (APH 7-jul-98) ------ subtract a user selected spectrum from all pixels   ----
    STACK_PROCESS_par.sub_spectrum: BEGIN
    	sub_flag = 0
        tmp = spc_load(DEFPATH=DefPath, filter='*.txt')
        if n_tags(tmp) NE 0 then begin
 ;       	if n_elements(tmp.d) EQ n_elements(ref_spectrum) then begin
        		weight=get_num(prompt='weight by',val=1.0, group=STACK_PROCESS_par.main_base)
        		ref_spectrum = weight* interpolate(tmp.d, ev, cubic=-0.5)
        		t = size(image_Stack)
        		t_img = make_array(t(1), t(2),value=1.0)
        		for i = 0, n_elements(ev)-1 do $
        		    image_stack(*,*,i) = image_stack(*,*,i) - t_img(*,*)*ref_spectrum(i)
;        		ref_spectrum = tmp.d*weight
        		sub_flag = 1
;        	endif else print, 'Mismatched energy scales', n_elements(tmp.d),n_elements(ref_spectrum)
        endif else  sub_flag = 0
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (APH 25-May-03) ------ ratio each image to a user selected image  ----
    STACK_PROCESS_par.ratio_image: BEGIN
    	last_image_ext = '*.nc'
	    tmp = axis_read_image(/axis)
        if n_tags(tmp) NE 0 then begin
        	if n_elements(tmp.d) EQ n_elements(image_stack(*,*,0)) then begin
        		weight=get_num(prompt='weight by',val=1.0, group=STACK_PROCESS_par.main_base)
        		for i = 0, n_elements(ev)-1 do $
        		    image_stack(*,*,i) = image_stack(*,*,i) / tmp.d*weight
        		    disp_max = max(image_stack, min = disp_min)
 		      		widget_control, STACK_PROCESS_par.disp_max_label, $
                        set_value = strtrim(string(disp_max,format='(f10.2)'),2)
         	        widget_control, STACK_PROCESS_par.disp_min_label, $
                        set_value = strtrim(string(disp_min,format='(f10.2)'),2)
        	endif else print, 'Reference image not same size'
        endif
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (APH 9-Apr-00) ------ subtract user selected image from each image  ----
    STACK_PROCESS_par.sub_image: BEGIN
    	last_image_ext = '*.nc'
	    tmp = axis_read_image(/axis)
        if n_tags(tmp) NE 0 then begin
        	if n_elements(tmp.d) EQ n_elements(image_stack(*,*,0)) then begin
        		weight=get_num(prompt='weight by',val=1.0, group=STACK_PROCESS_par.main_base)
        		for i = 0, n_elements(ev)-1 do $
        		    image_stack(*,*,i) = image_stack(*,*,i) - tmp.d*weight
        		    disp_max = max(image_stack, min = disp_min)
 		      		widget_control, STACK_PROCESS_par.disp_max_label, $
                        set_value = strtrim(string(disp_max,format='(f10.2)'),2)
         	        widget_control, STACK_PROCESS_par.disp_min_label, $
                        set_value = strtrim(string(disp_min,format='(f10.2)'),2)
        	endif else print, 'Reference image not same size'
        endif
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (APH 9-Apr-00) ------ subtract stored stack from this stack (to remove background)  ----
    STACK_PROCESS_par.sub_stack: BEGIN
	    tmp = image_stack
	    stack_rb
        image_stack = tmp - image_stack
	    disp_max = max(image_stack, min = disp_min)
		widget_control, STACK_PROCESS_par.disp_max_label, $
        	set_value = strtrim(string(disp_max,format='(f10.2)'),2)
    	widget_control, STACK_PROCESS_par.disp_min_label, $
        	set_value = strtrim(string(disp_min,format='(f10.2)'),2)
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (APH 30-jun-98) ------set/reset  FLAG to force byte-rescale  ----
	STACK_PROCESS_par.disp_rescale: BEGIN
    if Rescale_flag EQ 1 then Rescale_flag = 0 else Rescale_flag = 1
    IF (Rescale_flag EQ 0) THEN BEGIN
            widget_control, STACK_PROCESS_par.disp_max_label, $
                sensitive = 1
            widget_control, STACK_PROCESS_par.disp_min_label, $
                sensitive = 1
        ENDIF ELSE BEGIN
            widget_control, STACK_PROCESS_par.disp_max_label, $
                sensitive = 0
            widget_control, STACK_PROCESS_par.disp_min_label, $
                sensitive = 0
        ENDELSE
     STACK_PROCESS_imgdisp,displayed_file_index
    END

STACK_PROCESS_par.Movie_buts: BEGIN
; This sneaky move was figured out by Peter Hitchcock
; between developing 3d games (aph 6-jul-98)
	IF TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_TIMER' THEN begin
		STACK_PROCESS_imgdisp, framenum
		STACK_PROCESS_plotspectrum, framenum
		framenum = framenum + 1

		if framenum EQ n_elements(ev) or moviestate EQ 1 then begin
			moviestate = 1
			WIDGET_CONTROL, STACK_PROCESS_par.Movie_Buts, Set_Value=moviestate
			framenum = 0
			STACK_PROCESS_imgdisp, displayed_file_index
			STACK_PROCESS_plotspectrum, displayed_file_index
		endif

		if moviestate EQ 0 then begin
			WIDGET_CONTROL, STACK_PROCESS_par.Movie_buts, TIMER = framerate
		endif

		if moviestate EQ 2 then begin
			moviestate = 1                    ; show in stopped mode (?)
			WIDGET_CONTROL, STACK_PROCESS_par.Movie_Buts, Set_Value=moviestate
		endif

	endif	else begin
	   WIDGET_CONTROL, STACK_PROCESS_par.Movie_Buts, Get_Value=moviestate
		if moviestate EQ 0 then begin
	   		WIDGET_CONTROL, STACK_PROCESS_par.Movie_buts, TIMER = framerate
	   endif

	   if moviestate EQ 2 then begin
			if framenum EQ 0 then framenum = displayed_file_index  ; if stepping from STOP
	   	WIDGET_CONTROL, STACK_PROCESS_par.Movie_buts, TIMER = framerate
	   endif
   endelse

END

    STACK_PROCESS_par.roi_filename_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.roi_filename_label,$
          get_value = temp_string
        on_ioerror, roi_filename_label_oops
        roi_filename = strtrim(temp_string(0),2)
        dotpos = strpos(roi_filename,'.')
        IF (dotpos NE (-1)) THEN BEGIN
            roi_filename = strmid(roi_filename,0,dotpos)
        ENDIF
        roi_filename = roi_filename+'.roi'
        IF (strlen(roi_filename) NE 0) THEN BEGIN
            widget_control, STACK_PROCESS_par.roi_readfile_label, $
                sensitive = 1
        ENDIF ELSE BEGIN
            widget_control, STACK_PROCESS_par.roi_readfile_label, $
                sensitive = 0
        ENDELSE
        roi_filename_label_oops:
        widget_control, STACK_PROCESS_par.roi_filename_label, $
          set_value = roi_filename
    END

    STACK_PROCESS_par.roi_readfile_label: BEGIN
        widget_control,hourglass=1
        STACK_PROCESS_readroi
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
        widget_control,hourglass=0
    END

    STACK_PROCESS_par.image_label: BEGIN
        CASE STACK_PROCESS_par.add_pix OF
            0: BEGIN
            END

            ;; This is the case for adding a pixel to I0
            1: BEGIN
                x_index = fix(0.5+float(event.x)/float(img_zoom))
                y_index = fix(0.5+float(event.y-textregion_ypix) / $
                              float(img_zoom))
                roi = [x_index+y_index*n_cols]
                svec = size(i0_roi)
                IF (svec(0) EQ 0) THEN BEGIN
                    i0_roi = roi
                ENDIF ELSE BEGIN
                    i0_roi = [i0_roi,roi]
                    i0_roi = i0_roi(uniq(i0_roi,sort(i0_roi)))
                ENDELSE
                STACK_PROCESS_par.add_pix = 0
                STACK_PROCESS_makespectrum
                STACK_PROCESS_plotspectrum,displayed_file_index
                STACK_PROCESS_imgdisp,displayed_file_index
                STACK_PROCESS_sensitive
            END

            ;; This is the case for adding a pixel to I
            2: BEGIN
                x_index = fix(0.5+float(event.x)/float(img_zoom))
                y_index = fix(0.5+float(event.y-textregion_ypix) / $
                              float(img_zoom))
                roi = [x_index+y_index*n_cols]
                svec = size(i_roi)
                IF (svec(0) EQ 0) THEN BEGIN
                    i_roi = roi
                ENDIF ELSE BEGIN
                    i_roi = [i_roi,roi]
                    i_roi = i_roi(uniq(i_roi,sort(i_roi)))
                ENDELSE
                STACK_PROCESS_par.add_pix = 0
                STACK_PROCESS_makespectrum
                STACK_PROCESS_plotspectrum,displayed_file_index
                STACK_PROCESS_imgdisp,displayed_file_index
                STACK_PROCESS_sensitive
            END
        ENDCASE
    END

    STACK_PROCESS_par.spectrum_label: BEGIN

		if Event.Type EQ 1 AND Event.Release EQ 1b then begin
		    ; APH 1-jul-98 : cursor selection of display image
		    wset,STACK_PROCESS_par.plot_win
			if spectrum_x_scale(0) NE spectrum_x_scale(1) then begin; kluge (aph 30-may-03)
			    !X.s=spectrum_x_scale
			    !Y.s=spectrum_y_scale
			    curval = CONVERT_COORD(Event.X, Event.Y, /DEVICE, /TO_DATA)
			endif
		    new_E = curval(0)
		    i_file = displayed_file_index
		    i_file_old = i_file
		    ind = where(eV GE new_E,count)
		    if count GT 0 then i_file = ind(0)
		    displayed_file_index = i_file
;		    STACK_PROCESS_makespectrum				; removed as crashes plot on read in
		    STACK_PROCESS_plotspectrum,displayed_file_index
		    STACK_PROCESS_imgdisp,displayed_file_index
		    STACK_PROCESS_sensitive
	    endif
    END

; APH - added to allow path definition while using STACK_PROCESS
 STACK_PROCESS_par.filename_path: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.filename_path,$
          get_value = temp_string
        on_ioerror, filename_path_oops
        filepath = strtrim(temp_string(0),2)      ; remove blanks
;		print,'pre-filter filepath = ', filepath
        dotpos = strpos(filepath,'.')              ; abort if have dot
        IF (dotpos NE (-1)) THEN begin
        	print,'Path name can not contain a dot'
        	filepath='illegal path name'
        	GOTO, filename_path_oops
        endif
        if !VERSION.OS_FAMILY EQ 'unix' then sep = '/' else sep = '\'
		if strmid(filepath,strlen(filepath)-1,1) NE sep then $
	    filepath = filepath + sep    ; force path to end in separator
		filename_header=filepath + strcompress(string(filesave))

;		print, 'Path  set to: ', filepath, '.   Next file called: ', filename_header
        filename_path_oops:
        widget_control, STACK_PROCESS_par.filename_path, $
          set_value = filepath
	END

; ----------------- swap all energies with those in external file: aph 15-jun-03 -------
    STACK_PROCESS_par.change_e: BEGIN
		tmp = spc_load(title='file with new E-scale')
		if n_elements(tmp.x) EQ n_elements(ev) then begin
			ev = tmp.x
		    FOR i=0,(n_elements(filename_list)-1) DO BEGIN ; update list
		    	str = filename_ev_msec_list(i)
		    	strput, str,strtrim(string(ev(i),format='(f10.2)'),2),11
			    filename_ev_msec_list(i) = str
			ENDFOR
        	WIDGET_CONTROL,STACK_PROCESS_par.filename_ev_msec_list_label, $
 			Set_Value = filename_ev_msec_list
	        STACK_PROCESS_makespectrum
	        STACK_PROCESS_plotspectrum,displayed_file_index
    	    STACK_PROCESS_imgdisp,displayed_file_index
			print, 'E scale of stack changed to that of ', tmp.dl
		endif else begin
			    print,'Not the same number of E-values: no change made."
		   endelse
    END

; ----------------- remove current image from stack: aph 15-jun-03 -------
    STACK_PROCESS_par.remove_image: BEGIN
		t = size(image_stack)
		nx = t(1)
		ny = t(2)
		n_ev = t(3)
		tmp = ev
		del_img = displayed_file_index
		ev = fltarr(n_ev-1)
;		del_E = ev(displayed_file_index)
		ev(0:del_img-1) = tmp(0:del_img-1)
		if del_img LT n_ev-1 then ev(del_img:n_ev-2) = tmp(del_img+1:n_ev-1)
		tmp = image_stack
		image_stack = fltarr(nx,ny,n_ev-1)
		image_stack(*,*,0:del_img-1) = tmp(*,*,0:del_img-1)
		if del_img LT n_ev-1 then image_stack(*,*,del_img:n_ev-2) = tmp(*,*,del_img+1:n_ev-1)
	    tmp = filename_ev_msec_list
	    filename_ev_msec_list = strarr(n_ev-1)
	    filename_ev_msec_list(0:del_img-1) = tmp(0:del_img-1)
	    if del_img LT n_ev-1 then filename_ev_msec_list(del_img:n_ev-2) =  tmp(del_img+1:n_ev-1)
    	WIDGET_CONTROL,STACK_PROCESS_par.filename_ev_msec_list_label, $
		Set_Value = filename_ev_msec_list
		if displayed_file_index GE n_elements(eV) then displayed_file_index = displayed_file_index -1
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
	    STACK_PROCESS_imgdisp,displayed_file_index
;		print, 'removed image at E = ', del_E		; (10-jul-03 aph - just writes 0.00 eV fix later)
    END

    STACK_PROCESS_par.filename_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.filename_label,$
          get_value = temp_string
        on_ioerror, filename_label_oops
        filesave = strtrim(temp_string(0),2)
        dotpos = strpos(filesave,'.')
        IF (dotpos NE (-1)) THEN BEGIN
            filesave = strmid(filesave,0,dotpos)
        ENDIF
        IF (strlen(filesave) NE 0) THEN BEGIN
            widget_control, STACK_PROCESS_par.spec_savefile_label, sensitive = 1
            widget_control, STACK_PROCESS_par.stack_savefile_label, sensitive = 1
            widget_control, STACK_PROCESS_par.save_image_label, sensitive = 1
            widget_control, STACK_PROCESS_par.gifimg_savefile_label, sensitive = 1
            widget_control, STACK_PROCESS_par.gifmov_savefile_label, sensitive = 1
            widget_control, STACK_PROCESS_par.roi_savefile_label, sensitive = 1
        ENDIF ELSE BEGIN
            widget_control, STACK_PROCESS_par.spec_savefile_label, sensitive = 0
            widget_control, STACK_PROCESS_par.stack_savefile_label, sensitive = 0
            widget_control, STACK_PROCESS_par.save_image_label, sensitive = 0
            widget_control, STACK_PROCESS_par.gifimg_savefile_label, sensitive = 0
            widget_control, STACK_PROCESS_par.gifmov_savefile_label, sensitive = 0
            widget_control, STACK_PROCESS_par.roi_savefile_label, sensitive = 0
        ENDELSE
;  force filename_header used elsewhere to include filepath
;        if !VERSION.OS_FAMILY EQ 'unix' then sep = '/' else sep = '\'
;		GET path information to be sure
       temp_string = ''
        widget_control, STACK_PROCESS_par.filename_path,$
          get_value = temp_string
        filepath = strtrim(temp_string(0),2)      ; remove blanks
        dotpos = strpos(filepath,'.')              ; abort if have dot
        if !VERSION.OS_FAMILY EQ 'unix' then sep = '/' else sep = '\'
		if strmid(filepath,strlen(filepath)-1,1) NE sep then $
	    filepath = filepath + sep    ; force path to end in separator
		filename_header=filepath + strcompress(string(filesave))
;		print, 'Next file called: ', filename_header
        filename_label_oops:
        widget_control, STACK_PROCESS_par.filename_label, $
          set_value = filesave
    END

    STACK_PROCESS_par.spec_savefile_label: BEGIN
      if n_elements(spectrum) GT 1 then begin     ; ensure data there
        filename = strcompress((filename_header+'.txt'),/remove_all)
        t= ax_name(filename)
  ;   generate standard 1-d structure & write using spc_save
		s = {t:'1d', x:float(ev), d:float(spectrum), dn:float(spectrum), xl:'from stack ' + t1, dl:  t1 }
        t = spc_save(s, file=filename, /noLbl)
      endif
    END

; (APH 22-Apr-00) ------ save current image or ALL images  ----
    STACK_PROCESS_par.save_image_label: BEGIN
    t = dialog_message('Save all images ?', /question)
	if t(0) EQ 'Yes' then all_img = 1 else all_img = 0
	print, 'all_img ', all_img
    widget_control,hourglass=1
	x = findgen(n_cols)  & y = findgen(n_rows)
	xstep = (x_stop - x_start)/n_cols
	x = x_start + xstep*x
	ystep = (y_stop - y_start)/n_rows
	y = y_start + ystep*y
;	print, 'X: ', xstep, n_cols
;	print, 'Y: ', ystep, n_rows
	if all_img EQ 0 then begin
		i_start = displayed_file_index
		i_stop = i_start
	endif else begin
		i_start = 0
		i_stop = n_elements(ev)-1
		first_num = get_num(prompt = 'First number',val = 0, group = axis_ID)
	endelse
	for i_wr = i_start, i_stop do begin
    	str = filename_ev_msec_list(i_wr)
    	t= strpos(str,' msec')
		sd.dwell_time = float(strmid(str,t-5,5))
	    sd.wavelength = 12398./ev(i_wr)
		xl = string(FORMAT='("x (um)     E = ",f8.3," eV     dwell = ",f7.2," ms")', $
             ev(i_wr), sd.dwell_time)
	    tmp = {t:'2d', x:X, y:y, d:image_stack(*,*,i_wr), xl: xl, yl: ' ', dl:'stack image '+strcompress(i_wr,/remove_all)}
;		print, i_wr, '  min, max data ', min(tmp.d), max(tmp.d)
		if all_img EQ 0 then begin
			filename = strcompress((filename_header+'.nc'),/remove_all)
		endif else begin
;  force 3 character number
			zero = '000'
			t_num = strtrim(strcompress(string(fix(first_num)+i_wr)),2)
			strput, zero, t_num, 3-strlen(t_num)
			filename = strcompress((filename_header+'_'+zero+'.nc'),/remove_all)
		endelse
;		t =ax_name(filename) & fileaxb = t(0)+t(1)+'.axb'
;		file = axb_save(tmp, file=fileaxb)
		file=sav_nsls(tmp, file=filename)
	endfor
; --- write filename_header.sl file if more than one image written
	if abs(i_stop - i_start) GT 1 then begin
		filename_sl = strcompress((filename_header+'.sl'),/remove_all)
		t = ax_name(filename_sl)
		openw, iunit, filename_sl, /get_lun
		printf, iunit, t(0)
		for i_wr = i_start, i_stop do begin
			zero = '000'
			t_num = strtrim(strcompress(string(fix(first_num)+i_wr)),2)
			strput, zero, t_num, 3-strlen(t_num)
			filename = strcompress((t(1)+'_'+zero+'.nc'),/remove_all)
			printf, iunit, filename
		endfor
		close, iunit & free_lun, iunit
		print, 'wrote stack list in Zimba format to ', filename_sl
	endif
    widget_control,hourglass=0
    END

    STACK_PROCESS_par.gifimg_savefile_label: BEGIN
        widget_control,hourglass=1
        wset,STACK_PROCESS_par.image_win
        bytimg = tvrd(0,0,n_cols*img_zoom,n_rows*img_zoom+textregion_ypix)
        filename = filename_header+'.gif'
        write_gif,filename,bytimg,r,g,b
        print,'Wrote GIF image file "'+filename+'"'
        widget_control,hourglass=0
    END

    STACK_PROCESS_par.gifmov_savefile_label: BEGIN
        widget_control,hourglass=1
        STACK_PROCESS_gifmovie
        widget_control,hourglass=0
    END

    STACK_PROCESS_par.stack_savefile_label: BEGIN	; APH 22-may-99
        widget_control,hourglass=1
        svec = size(image_stack)
;        print, xpix_shift, ypix_shift
        nx_min = fix(-1*xpix_shift(0))			; (aph 8-may-00 - adjust common block to pass these from stack_align)
        nx_max = n_cols - fix(xpix_shift(1))
        ny_min = fix(-1*ypix_shift(0))
        ny_max = n_rows - fix(ypix_shift(1))
        nx_min = get_num(val=nx_min, Prompt='keep columns > ', group = STACK_PROCESS_par.main_base)
        nx_max = get_num(val=nx_max-1, Prompt='keep columns < ', group = STACK_PROCESS_par.main_base)
        ny_min = get_num(val=ny_min, Prompt='keep rows > ', group = STACK_PROCESS_par.main_base)
        ny_max = get_num(val=ny_max-1, Prompt='keep rows < ', group = STACK_PROCESS_par.main_base)
        widget_control,hourglass=1
; -------- reset (x,y) scales to truncated region -------------
		xstep = (x_stop - x_start)/n_cols
		x_start = x_start + xstep*(nx_min)
		x_stop  = x_stop - xstep*(n_cols - nx_max)
		ystep = (y_stop - y_start)/n_rows
		y_start = y_start + ystep*(ny_min)
		y_stop  = y_stop - ystep*(n_rows - ny_max)
        n_cols = nx_max - nx_min + 1
        n_rows = ny_max - ny_min + 1
		image_stack = image_stack(nx_min:nx_max,ny_min:ny_max,*)
		if OD_flag EQ 1 then begin
	    	for i = 0, n_elements(eV)-1 do image_stack(*,*,i) = -alog(image_stack(*,*,i)/i0_signal(i))
		endif
		if tey_flag EQ 1 then begin
			for i = 0, n_elements(eV)-1 do image_stack(*,*,i) = image_stack(*,*,i)/i0_signal(i)
		endif
        filename = filename_header
        if strlen(filename_header) GT 0 then  filename = filename_header +'.ncb'
		stack_wb, filename
        widget_control,hourglass=0
    END

    STACK_PROCESS_par.roi_savefile_label: BEGIN
        widget_control,hourglass=1
		STACK_PROCESS_writeroi
        widget_control,hourglass=0
    END

    STACK_PROCESS_par.tey_label: BEGIN		; APH 14-may-99
        if tey_flag EQ 0 then begin
        	tey_flag = 1
        	widget_control, STACK_PROCESS_par.tey_label, $
          		set_value = 'TEY-on'
        endif else begin
        	tey_flag = 0
        	widget_control, STACK_PROCESS_par.tey_label, $
          		set_value = 'TEY-off'
        endelse
    END

    STACK_PROCESS_par.slicer_label: BEGIN
       slicer
    END

    STACK_PROCESS_par.slicer3_label: BEGIN
    	tmp_img = image_Stack
		hData = PTR_NEW(image_stack, /NO_COPY)
		slicer3, hdata, DATA_NAMES='Stack', /modal
		if PTR_VALID(hdata) then PTR_FREE, hdata		; clean up pointers !
		image_stack = tmp_img
    END

    STACK_PROCESS_par.exit_label: BEGIN
        widget_control,STACK_PROCESS_par.main_base,/destroy
    END

ENDCASE
END


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

pro STACK_PROCESS_TOF, list_filename, shift_filename, fpath=fpath, binary=binary, $
                   zoom=zoom, text_height=text_height, realign=realign, $
                   help=help, no_align = no_align
; (20-may-99 aph) - BINARY keyword added to call
; (28-oct-99 aph) - no_align keyword added to call
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack
COMMON pix_shift, xpix_shift, ypix_shift

xpix_shift = fltarr(2) & ypix_shift = xpix_shift     ; ensure these are defined


IF keyword_set(help) THEN BEGIN
    print,'STACK_PROCESS,[list_filename,shift_filename]'
    print,'  [zoom=integer,text_height=pixels]'
    print,'  where [list_filename] is an optional list of files'
    print,'        [shift_filename] is a MAPPER-type file for pixel shifts'
    return
ENDIF

IF (n_elements(shift_filename) EQ 0) THEN BEGIN
    shift_filename = ''
ENDIF

IF (n_elements(realign) EQ 0) THEN realign = 0

i_roi = 0
i0_roi = 0
IF (n_elements(roi_filename) NE 0) THEN BEGIN
    dotpos = strpos(roi_filename,'.')
    IF (dotpos NE (-1)) THEN BEGIN
        roi_filename = strmid(roi_filename,0,dotpos)
    ENDIF
    roi_filename = roi_filename + '.roi'
    print,'ROI filename is now "'+roi_filename+'"'

    test = findfile(roi_filename)
    svec = size(test)
    IF (svec(0) NE 0) THEN BEGIN
        get_lun,lun
        openr,lun,test(0),/xdr
        n_i_roi = long(0)
        n_i0_roi = long(0)
        readu,lun,n_i_roi,n_i0_roi
        IF (n_i_roi NE 0) THEN BEGIN
            i_roi = lonarr(n_i_roi)
            readu,lun,long(i_roi)
        ENDIF
        IF (n_i0_roi NE 0) THEN BEGIN
            i0_roi = lonarr(n_i0_roi)
            readu,lun,long(i0_roi)
        ENDIF
        close,lun
        free_lun,lun
    ENDIF
ENDIF

spectrum = 0
i_signal = 0
i0_signal = 0
i0_read = 0			; aph - flag to indicate io read-in from file
OD_flag = 0			; aph - flag to plot as OD
rescale_flag = 0

filepath=''                  ; aph - added to allow specification of path
if keyword_set(fpath) then begin
	filepath=strcompress(string(fpath))
	if !VERSION.OS_FAMILY EQ 'unix' then sep = '/' else sep = '\'
	spos = rstrpos(filepath,sep)
	if strmid(filepath,strlen(filepath)-1,1) NE sep then $
	    filepath = filepath + sep    ; force path to end in separator
;	print, 'Incoming = ', fpath, ' filepath= ',filepath
endif

filesave=''
filename_header = ''
roi_filename = ''

if NOT keyword_set(binary) then begin					; switch out file-list stuff
	stack_readlist, list_filename, filename_list
	n_files = n_elements(filename_list)
	IF (n_files LT 2) THEN BEGIN
	    print,'No files in list for analyzing!'
	    return
	ENDIF
;
; FILE READ IN now done in stack_list to handle multiple formats
; list_Filename provided to STACK_PROCESS SHOULD be OK !
;
ENDIF

; READ IN DATA - use first file to advise user of possible ZOOM

if keyword_set(binary) then begin
;	help, list_filename
	stack_rb, list_filename
	cpos = strpos(filename_ev_msec_list(0),':')
	filename_list = strarr(n_elements(filename_ev_msec_list))
	for i = 0, n_elements(filename_list)-1 do begin
		filename_list(i) = strmid(filename_ev_msec_list(i),0,cpos-1)
	endfor
endif else read_stxm, filename_list(0),sd,/header

device,get_screen_size=screen_size
osname = strupcase(strmid(!version.os,0,3))
IF (osname EQ 'WIN') THEN BEGIN
    estimated_leftcol_pixels = 300
ENDIF ELSE BEGIN
    estimated_leftcol_pixels = 300
ENDELSE
estimated_max_zoom = $
    fix(0.05+float(screen_size(0)-estimated_leftcol_pixels)/float(n_cols))
print,'Estimated maximum zoom: '+strtrim(string(estimated_max_zoom),2)

IF keyword_set(zoom) THEN img_zoom = zoom ELSE img_zoom = 1

IF keyword_set(text_height) THEN char_ypix = text_height ELSE  char_ypix = 16

if NOT keyword_set(binary) then begin
	print,'Reading in the images'
	WIDGET_CONTROL, /Hourglass
	image_stack = fltarr(n_cols,n_rows,n_elements(filename_list))
	ev = fltarr(n_elements(filename_list))
	filename_ev_msec_list = strarr(n_elements(filename_list))
	FOR i=0,(n_elements(filename_list)-1) DO BEGIN
	    read_stxm,filename_list(i),sd,khz
	    ev(i) = 12398.52/sd.wavelength

	; APH (16-apr-98) - modified to dump PATH info
	; ********        filename_list(i)changed to filenm *********
		if !VERSION.OS_FAMILY EQ 'unix' then sep = '/' else sep = '\'
		filenm =  string(filename_list(i))
		filenm=strmid(filenm,rstrpos(filenm,sep)+1,strlen(filenm))
		filenm = strmid(filenm,0,strpos(filenm,'.'))
	    filename_ev_msec_list(i) = filenm  + ' : '+$
	        strtrim(string(ev(i),format='(f10.2)'),2)+' eV '+$
	        strtrim(string(sd.dwell_time,format='(f7.2)'),2)+' msec'
	; APH - end of changes
	;	print, 'CHECK: n_cols= ',n_cols,' n_rows= ', n_rows
	    image_stack(0:(n_cols-1),0:(n_rows-1),i) = khz
	ENDFOR
; check if x or y dimension has negative slope; if so, reverse
    if (x_start GT x_stop) then begin
    	image_stack = reverse(image_stack)
    	t = x_start & x_start = x_stop & x_stop = t
    	print, 'x data reversed'
    endif
    if (y_start GT y_stop) then begin
    	image_stack = reverse(image_stack,2)
    	t = y_start  & y_start = y_stop & y_stop = t
		print, 'y data reversed'
	endif

; force energy values to be sorted and increasing ------ aph 30-may-01
; ---- query because the nsls format energy gets reset which disorders files -- aph 6-jan-02
	for i = 1,n_elements(ev)-1 do begin
		if ev(i) LE ev(i-1) then goto, ev_sort
	endfor
	goto, end_ev_sort
	ev_sort:
	test = dialog_message(/question, 'Energies out of order. Sort ?')
	if test EQ 'No' then goto, end_ev_sort
	sort_ev = sort(ev)
	timg = image_stack
	tlbl = filename_ev_msec_list
	for i = 0,n_elements(ev)-1 do begin
		image_stack(*,*,i) = timg(*,*,sort_ev(i))
		filename_ev_msec_list(i) = tlbl(sort_ev(i))
	endfor
	ev = ev(sort(ev))
	print, filename_ev_msec_list
	end_ev_sort:
ENDIF

print,'Aligning the images'
; For compatibility with the SLICER, this gets its
; data from COMMON volume_data, image_stack
if not keyword_set(no_align) then $
     stack_align,filename_ev_msec_list,shift_filename,zoom=img_zoom,realign=realign

; ensure the display limits are defined
;catch, error_status
;if error_Status NE 0 then begin
	disp_xmin = x_start
	disp_xmax = x_stop
	disp_ymin = y_start
	disp_ymax = y_stop
;endif
;print, ' initial dsplay limits '
;print, disp_xmin, disp_xmax, disp_ymin, disp_ymax

STACK_PROCESS_graphics


IF (n_tags(STACK_PROCESS_par) EQ 0) THEN BEGIN
    STACK_PROCESS_par = $
      { STACK_PROCESS_par, $
        main_base: 0L, $
        disp_min_label: 0L, $
        disp_max_label: 0L, $
        disp_gamma_label: 0L, $
        disp_xmin_label: 0L, $
        disp_xmax_label: 0L, $
        disp_ymin_label: 0L, $
   		disp_ymax_label: 0L, $
        disp_zoom: 0L, $
        disp_reset: 0L, $
        xloadct_label: 0L, $
        filename_ev_msec_list_label: 0L, $
        play_movie_label: 0L, $
        add_i0_roi_label: 0L, $
        add_i0_pix_label: 0L, $
        i0_readin: 0L, $                ; added by aph   (apr98)
        i0_norm: 0L, $                  ; added by aph   (jun98)
        disp_rescale: 0L, $				; added by aph   (jun98)
        Movie_Buts: 0L, $               ; added by aph   (jun98)
        eV_shift: 0L, $                 ; added by aph   (jul98)
        sub_spectrum: 0L, $				; added by aph   (jul98)
        ratio_image: 0L, $				; added by aph   (may03)
        sub_image: 0L, $				; added by aph   (apr00)
        sub_stack: 0L, $				; added by aph   (apr00)
        OD_tran: 0L, $
        add_all_label: 0L, $			; added by aph   (may03)
        reset_i0_label: 0L, $
        add_i_roi_label: 0L, $
        add_i_pix_label: 0L, $
        reset_i_label: 0L, $
        roi_filename_label: 0L, $
        roi_readfile_label: 0L, $
        add_pix: 0L, $
        filename_path: 0L, $               ; added by aph
        filename_label: 0L, $
        spec_savefile_label: 0L, $
        gifimg_savefile_label: 0L, $
        gifmov_savefile_label: 0L, $
        stack_savefile_label: 0L, $ ; added by aph   (may99)
        save_image_label: 0L, $			; added by aph   (apr00)
        roi_savefile_label: 0L, $
        slicer_label: 0L, $
        slicer3_label: 0L, $			; added aby aph (jan02)
        tey_label:  0L, $				; added by aph   (may99)
        change_e:   0L, $
        remove_image:   0L, $
        exit_label: 0L, $
        image_win: 0L, $
        image_label: 0L, $
        plot_win: 0L, $
        spectrum_label: 0L, $
        roi_base: 0L, $
        is_i0_roi: 0L, $
        roi_accept_label: 0L, $
        roi_reject_label: 0L $
      }
ENDIF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

STACK_PROCESS_par.main_base = widget_base(title='Stack Analyze', /column )
row1 = widget_base(STACK_PROCESS_par.main_base,/row)
col1 = widget_base(row1,/column)
col2 = widget_base(row1,/column)
; Z-scale
base = widget_base(col1,/column,/frame)
row = widget_base(base,/row)
tlabel = widget_label(row,value='Display min, max: ')
STACK_PROCESS_par.disp_min_label = $
  widget_text(row,/frame,/editable,xsize=10)
STACK_PROCESS_par.disp_max_label = $
  widget_text(row,/frame,/editable,xsize=10)
row = widget_base(base,/row)
tlabel = widget_label(row,value='Gamma: ')
STACK_PROCESS_par.disp_gamma_label = $
  widget_text(row,/frame,/editable,xsize=10)
STACK_PROCESS_par.xloadct_label = $
  widget_button(row,value='Colors')
col = widget_base(base,/column)
STACK_PROCESS_par.disp_rescale = $
	widget_button(row,value='Rescale')

; X-scale
row = widget_base(base,/row)
tlabel = widget_label(row,value='X:  min, max:        ')
STACK_PROCESS_par.disp_xmin_label = $
  widget_text(row,/frame,/editable,xsize=10)
STACK_PROCESS_par.disp_xmax_label = $
  widget_text(row,/frame,/editable,xsize=10)
; Y-scale
row = widget_base(base,/row)
tlabel = widget_label(row,value='Y:  min, max:        ')
STACK_PROCESS_par.disp_ymin_label = $
  widget_text(row,/frame,/editable,xsize=10)
STACK_PROCESS_par.disp_ymax_label = $
  widget_text(row,/frame,/editable,xsize=10)
; controls to modify X,Y scale
row = widget_base(base,/row)
tlabel = widget_label(row,value='   ')
STACK_PROCESS_par.disp_zoom = $
	widget_button(row,value='Zoom x,y-scale')
tlabel = widget_label(row,value='   ')
STACK_PROCESS_par.disp_reset = $
	widget_button(row,value='Reset x,y-scale')

tlabel = widget_label(base,value='Image to display: ')
STACK_PROCESS_par.filename_ev_msec_list_label = $
  widget_list(base, value = filename_ev_msec_list, xsize=40, ysize=6 )

  movieBtns = ['Play  ', 'Stop  ', 'Pause/Step' ]
  STACK_PROCESS_par.Movie_Buts = CW_BGROUP(base, $
  	movieBtns, ROW=1, set_value = 1, EXCLUSIVE=1,  LABEL_LEFT='Movie',UVALUE=1 )
base = widget_base(col1,/column,/frame)
row = widget_base(base,/row)
STACK_PROCESS_par.add_all_label = $
  widget_button(row,value='all')			; aph (25-may-03)
STACK_PROCESS_par.add_i_roi_label = $
  widget_button(row,value='Add I region')
STACK_PROCESS_par.add_i_pix_label = $
  widget_button(row,value='Add I pixel')
STACK_PROCESS_par.reset_i_label = $
  widget_button(row,value='Reset I')

row = widget_base(base,/row)
STACK_PROCESS_par.roi_readfile_label = $
  widget_button(row,value='ROI file')
col = widget_base(base,/column)
STACK_PROCESS_par.roi_filename_label = $
  widget_text(row,/frame,/editable,xsize=20)

row = widget_base(base,/row)
STACK_PROCESS_par.add_i0_roi_label = $
  widget_button(row,value='Add I0 region')
STACK_PROCESS_par.add_i0_pix_label = $
  widget_button(row,value='Add I0 pixel')
STACK_PROCESS_par.reset_i0_label = $
  widget_button(row,value='Reset I0')

; add button to read in Io file  (APH 16-apr-98)
row = widget_base(base,/row)
col = widget_base(base,/column)
STACK_PROCESS_par.i0_readin = $
  widget_button(row,value='Read Io from file')
STACK_PROCESS_par.eV_shift = $
  widget_button(row,value='E_cal')
STACK_PROCESS_par.change_e = $
  widget_button(row,value='change energies')


; add button to generate OD from current Io (APH 30-jun-98)
row = widget_base(base,/row)
col = widget_base(base,/column)
STACK_PROCESS_par.i0_norm = $
  widget_button(row,value='  ->OD  ')
STACK_PROCESS_par.OD_tran = $
  widget_text(row,/frame,xsize=6, value=' I(t)')
STACK_PROCESS_par.tey_label = $
  widget_button(row,value='TEY-off')

row = widget_base(base,/row)					; (aph 09-apr-00)
col = widget_base(base,/column)
STACK_PROCESS_par.ratio_image = $
  widget_button(row,value='ratio image')		; (aph may-03)
STACK_PROCESS_par.sub_image = $
  widget_button(row,value='subtract image')
STACK_PROCESS_par.remove_image = $
  widget_button(row,value='remove image')

row = widget_base(base,/row)
col = widget_base(base,/column)
STACK_PROCESS_par.sub_spectrum = $
  widget_button(row,value='subtract spectrum')
STACK_PROCESS_par.sub_stack = $
  widget_button(row,value='subtract stack')

row = widget_base(col2,/row)
STACK_PROCESS_par.exit_label = $
  widget_button(row,value='Exit')	; moved up
STACK_PROCESS_par.slicer_label = $
  widget_button(row,value='IDL Slicer')
STACK_PROCESS_par.slicer3_label = $
  widget_button(row,value='IDL Slicer3')

base = widget_base(col1,/column,/frame)
tlabel = widget_label( base, value = 'Save files' )
; Aph - add path setting indicator
row = widget_base(base,/row)
tlabel = widget_label( row, value = 'Path  : ')
STACK_PROCESS_par.filename_path = $
  widget_text(row,/frame,/editable,xsize=30)

row = widget_base(base,/row)
tlabel = widget_label( row, value = 'Name: ')
STACK_PROCESS_par.filename_label = $
  widget_text(row,/frame,/editable,xsize=30)

row = widget_base(base,/row)
STACK_PROCESS_par.spec_savefile_label = $
  widget_button(row,value='Spectrum ".txt"')
STACK_PROCESS_par.roi_savefile_label = $
  widget_button(row,value='Region ".roi"')
STACK_PROCESS_par.save_image_label = $
  widget_button(row,value='Image ".nc"')

row = widget_base(base,/row)
STACK_PROCESS_par.gifimg_savefile_label = $
  widget_button(row,value='Image ".gif"')
STACK_PROCESS_par.gifmov_savefile_label = $
  widget_button(row,value='Movie "m.gif"')
STACK_PROCESS_par.stack_savefile_label = $
  widget_button(row,value='Stack ".ncb"')
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

STACK_PROCESS_par.image_label = $
  widget_draw(col2,$
              xsize=n_cols*img_zoom,$
              ysize=n_rows*img_zoom+textregion_ypix,$
              retain=2,/button_events)

STACK_PROCESS_par.spectrum_label = $
  widget_draw(col2,$                                 ; aph make it process mouse
      MOTION_EVENTS = 0, $             ;need click to update image
      BUTTON_EVENTS = 1, $
            xsize=plot_cols,ysize=plot_rows,retain=2)

widget_control, STACK_PROCESS_par.main_base, /realize

widget_control, STACK_PROCESS_par.filename_path, set_value = DefPath
widget_control, STACK_PROCESS_par.filename_path, sensitive = 0            ; *** aph
widget_control, STACK_PROCESS_par.filename_label, sensitive = 0
widget_control, STACK_PROCESS_par.spec_savefile_label, sensitive = 0
widget_control, STACK_PROCESS_par.gifimg_savefile_label, sensitive = 0
widget_control, STACK_PROCESS_par.gifmov_savefile_label, sensitive = 0
widget_control, STACK_PROCESS_par.stack_savefile_label, sensitive = 0
widget_control, STACK_PROCESS_par.save_image_label, sensitive = 0
widget_control, STACK_PROCESS_par.roi_savefile_label, sensitive = 0
widget_control, STACK_PROCESS_par.roi_readfile_label, sensitive = 1

widget_control,STACK_PROCESS_par.image_label,get_value=window
STACK_PROCESS_par.image_win = window
wset,window
tvlct,r,g,b

widget_control,STACK_PROCESS_par.spectrum_label,get_value=window
STACK_PROCESS_par.plot_win = window
wset,window
tvlct,r,g,b

displayed_file_index = 0
disp_min = min(image_stack)
disp_max = max(image_stack)
disp_gamma = 0.5
widget_control, STACK_PROCESS_par.disp_min_label, $
    set_value = strtrim(string(disp_min,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_max_label, $
    set_value = strtrim(string(disp_max,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_gamma_label, $
    set_value = strtrim(string(disp_gamma,format='(f10.2)'),2)

disp_xmin = x_start
disp_xmax = x_stop
disp_ymin = y_start
disp_ymax = y_stop
widget_control, STACK_PROCESS_par.disp_xmin_label, $
    set_value = strtrim(string(disp_xmin,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_xmax_label, $
    set_value = strtrim(string(disp_xmax,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_ymin_label, $
    set_value = strtrim(string(disp_ymin,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_ymax_label, $
    set_value = strtrim(string(disp_ymax,format='(f10.2)'),2)

; ------------- SET DEFAULTS ----------------------
framenum = 0
moviestate = 1
framerate = 0.001
spectrum_X_scale = fltarr(2)
spectrum_Y_scale = fltarr(2)
ref_spectrum = fltarr(n_elements(eV))
sub_flag = 0
tey_flag = 0

print,'Displaying the first image'
STACK_PROCESS_makespectrum
STACK_PROCESS_plotspectrum,displayed_file_index
STACK_PROCESS_imgdisp,displayed_file_index



xmanager, 'STACK_PROCESS', STACK_PROCESS_par.main_base, $
  group_leader = STACK_PROCESS_par.main_base

vec = bindgen(!d.table_size)
tvlct,vec,vec,vec

return
end
