; Copyright (c) 1998-2009 A.P. Hitchcock  All rights reserved
;+
;NAME:
;	STACK_PROCESS.PRO
;
;LAST CHANGED: ----------------------------------- 29-Jul-11 [ FROM 24-Apr-06 - INCOMPLETE ]
;
; 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_COM		common for stack_process
;	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 zoom, x,y axis control
; (01-mar-04 aph) fix display of roi (region, pixels) in zoom mode
; (27-mar-04 aph) add (E,I)-range control; avg stack; median added
; (07-apr-04 aph) remove first image;
; (10-apr-04 aph) add remove_zeros; troubleshoot spectral select
; (02-may-04 aph) continue trouble-shooting spectral select problem
; (15-may-04 aph) sensitize path & filename boxes if ROI selected
; (11-jul-04 aph) try to add scroll bars - failed so far !
;               shrink vertical size of commands to fit on 768 vertical screen
; (31-jul-04 aph) replace gif image with png image (gif not supported by IDL6, XP)
; (21-jan-05 aph) exit STACK_PROCESS after writing stack
; (19-feb-05 aph) add 'constant' and 'gain' controls
; (03-jul-05 aph) add 'ratio to spectrum'
; (07-jul-05 aph) change color reset properties when close to avoid problem of B/W inversion in aXis2000
; (15-nov-05 aph)  average images over E-range displayed
; (15-Dec-05 aph) add clip_images
; (18-feb-06 aph) add map
; (21-feb-06 aph) correct extensions when write out *.sl list file
; (08-apr-06 gaj) add write out of all images in tif format
; (19-apr-06 aph) correct row, column minimums for clipping after alignment; auto-zoom
; (21-apr-06 aph) add *.roi as default name for roi region
; (25-apr-06 aph) multiple region display
;
; -------- 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, _EXTRA = e
@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, _EXTRA = e
@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, _extra = e
@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, _extra = e
@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)
;  (24-apr-06 aph) extend to multiple roi
        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  ;, _extra = e
; ------ 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)
    i_roi = roi
    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)

if sa_debug EQ 1 then print, ' roi from defroi ', roi

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

	step_y = (y_stop - y_start)/float(n_rows)
	iyl = floor((disp_ymin - y_start)/step_y)
	if iyl lt 0 then iyl = 0
	iyh = floor((disp_ymax - y_start)/step_y)
	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 = n_rows,  xpos = !D.X_SIZE - n_cols
	tv, tmp_dat
	wshow, 21
endif

; convert pixels selected on (possibly) zoomed image to pixels in data file
; 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

roi_img = make_array(n_cols,n_rows,/integer,value = 0)

ixslope = (ixh - ixl)/(n_cols-1)           ; mod 2-may-04 untested
iyslope = (iyh - iyl)/(n_rows-1)
if sa_debug EQ 1 then begin
	print, 'n_cols, n_rows, ixh, ixl, iyh, iyl'
 	print, n_cols, n_rows, ixh, ixl, iyh, iyl
	print, 'conversion slopes (data / display) ', ixslope, iyslope
	print, 'tracking conversion in roi-generation ...'
	tt = min([9,n_elements(roi)-1])
	print, 'roi (DISPLAY) indices ', roi(0:tt)
	print, 'nx, ny ', n_cols, n_rows
	print,  ' DISPLAY:  i   j        DATA:   ix   iy'
endif
; ------------- scan through displayed signal to identify equivalent pixels in the DATA
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)

if sa_debug EQ 1 then print, ' roi after mapping to original data', roi


; check the correct pixels in the DATA were actually identified
if keyword_set(debug) then begin
	tt = min([9,n_elements(roi)-1])
	print, 'roi (DATA) indices ', roi(0:tt)
	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 = 2.2*n_rows, xpos = !D.X_SIZE - n_cols
	tv, byte_image
	wshow, 22
endif

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

return
END

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

PRO STACK_PROCESS_desensitive, _extra = e
@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.pngimg_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, _extra = e
@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.pngimg_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.pngimg_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, _extra = e
@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

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

; loadct,0,ncolors=top_color_index+1		; does this give correct colors ?

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

STACK_PROCESS_bar

return
END

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

PRO STACK_PROCESS_makespectrum, _extra = e
@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 -  neither I nor Io is defined
        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 is defined
    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	; ONLY I is defined
        i0_signal = 0
        spectrum = i_signal
        spectrum_title = 'I'
    ENDIF ELSE BEGIN				;  BOTH I and Io are defined
      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

; determine and set spectral display limits
disp_zmin = min(spectrum, max=disp_zmax)
widget_control, STACK_PROCESS_par.disp_zmin_label, $
set_value = strtrim(string(disp_zmin,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_zmax_label, $
set_value = strtrim(string(disp_zmax,format='(f10.2)'),2)

return
END

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

PRO STACK_PROCESS_plotspectrum, i_file, _extra = e
@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
!x.range=0
; set limits to user-specified energy range
plot,ev,spectrum,xtitle='eV',ytitle=spectrum_title,xrange=[disp_emin,disp_emax], $
     yrange=[disp_zmin,disp_zmax], 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


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

PRO STACK_PROCESS_imgdisp, i_file, _extra = e

; --------------------- last changed: 24-feb-04  ; 25-Apr-06 aph - multi-spectrum
; 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 21-feb-04) - identify indices corresponding to current x, y limits
step_x = (x_stop - x_start)/float(n_cols)
ixl = floor(0.5 + (disp_xmin - x_start)/step_x)
if ixl lt 0 then ixl = 0
ixh = floor(0.5 + (disp_xmax - x_start)/step_x)
if ixh gt n_cols-1 then ixh = fix(n_cols-1)
step_y = (y_stop - y_start)/float(n_rows)
iyl = floor(0.5 + (disp_ymin - y_start)/step_y)
if iyl lt 0 then iyl = 0
iyh = floor(.5 + (disp_ymax - y_start)/step_y)
if iyh gt n_rows-1 then iyh = fix(n_rows-1)
; 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)

; (aph 30-jun-98) - allow convert to OD
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
	tmp_dat = bytscl(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
	t = make_array(n_cols,n_rows,/integer,value = 0)		; set up array with i_roi
	for j = 0, n_roi-1 do begin
		t(i_roi(j)) = 1
		tt =  t(ixl:ixh,iyl:iyh)		; select out part that is in displayed region
		i_roi_zoom = where(tt EQ 1)
		all_img_indices = where(byte_image)
		all_img_min = min(all_img_indices, max = all_img_max)
		ttt = where(i_roi_zoom GE all_img_min AND i_roi_zoom LE all_img_max, count)
		if count GT 0 then begin
			i_roi_zoom_indices = i_roi_zoom(ttt)
	     	byte_image(i_roi_zoom_indices) = i_color_index(j)
       endif
    endfor
ENDIF
IF (i0_svec(0) NE 0) THEN BEGIN
; convert i0_roi to the zoomed image scale
	t = make_array(n_cols,n_rows,/integer,value = 0)		; set up array with i0_roi
	t(i0_roi) = 1
	tt =  t(ixl:ixh,iyl:iyh)		; select out part that is in displayed region
	i0_roi_zoom = where(tt EQ 1)
	all_img_indices = where(byte_image)
	all_img_min = min(all_img_indices, max = all_img_max)
	ttt = where(i0_roi_zoom GE all_img_min AND i0_roi_zoom LE all_img_max, count)
	if count GT 0 then begin
		i0_roi_zoom_indices = i0_roi_zoom(ttt)
        byte_image(i0_roi_zoom_indices) = i0_color_index
    endif
ENDIF

wset,STACK_PROCESS_par.image_win   ; force back to image display

tv,congrid(byte_image,n_cols*img_zoom,n_rows*img_zoom), $      ; replace rebin for non-integer
  0,textregion_ypix,xsize=n_cols*img_zoom, ysize=n_rows*img_zoom,/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, _extra = e
@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, _extra = e
@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


; ----------------------------------------------------------------------------------
; ****************************  Display processing ********************************
; ----------------------------------------------------------------------------------

    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
        STACK_PROCESS_plotspectrum,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
        STACK_PROCESS_plotspectrum,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_emin_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_emin_label,$
          get_value = temp_string
        on_ioerror, disp_emin_label_oops
        reads,temp_string(0),disp_emin
        disp_emin_label_oops:
        widget_control, STACK_PROCESS_par.disp_emin_label, $
          set_value = strtrim(string(disp_emin,format='(f10.2)'),2)
        STACK_PROCESS_plotspectrum,displayed_file_index
    END

    STACK_PROCESS_par.disp_emax_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_emax_label,$
          get_value = temp_string
        on_ioerror, disp_emax_label_oops
        reads,temp_string(0),disp_emax
        disp_emax_label_oops:
        widget_control, STACK_PROCESS_par.disp_emax_label, $
          set_value = strtrim(string(disp_emax,format='(f10.2)'),2)
        STACK_PROCESS_plotspectrum,displayed_file_index
    END


  STACK_PROCESS_par.disp_zmin_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_zmin_label,$
          get_value = temp_string
        on_ioerror, disp_zmin_label_oops
        reads,temp_string(0),disp_zmin
        disp_zmin_label_oops:
        widget_control, STACK_PROCESS_par.disp_zmin_label, $
          set_value = strtrim(string(disp_zmin,format='(f10.2)'),2)
        STACK_PROCESS_plotspectrum,displayed_file_index
    END

    STACK_PROCESS_par.disp_zmax_label: BEGIN
        temp_string = ''
        widget_control, STACK_PROCESS_par.disp_zmax_label,$
          get_value = temp_string
        on_ioerror, disp_zmax_label_oops
        reads,temp_string(0),disp_zmax
        disp_zmax_label_oops:
        widget_control, STACK_PROCESS_par.disp_zmax_label, $
          set_value = strtrim(string(disp_zmax,format='(f10.2)'),2)
        STACK_PROCESS_plotspectrum,displayed_file_index
    END

    STACK_PROCESS_par.disp_zoom: BEGIN
		wset,STACK_PROCESS_par.image_win
        BX_CURSOR, xl, yl, w, h
        yl = yl - textregion_ypix
;        print, 'xl, yl, w, h ', xl, yl, w, h
;  adjust values to reflect possibly integer zoom
		xl = floor(0.5 + xl/img_zoom)
		yl = floor(0.5 + yl/img_zoom)
		w = floor(0.5 + w/img_zoom)
		h = floor(0.5 + h/img_zoom)
	; adapt for fact that the displayed area can already be zoomed !!!
		step_x = (disp_xmax - disp_xmin)/float(n_cols)
		disp_xmin = disp_xmin + xl*step_x
		disp_xmax = disp_xmin + w*step_x
		step_y = (disp_ymax - disp_ymin)/float(n_rows)
		disp_ymin = disp_ymin + yl*step_y
		disp_ymax = disp_ymin + h*step_y
		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.disp_Ereset: BEGIN		; reset E and I scales
		disp_emin = ev(0)
		disp_emax = ev(n_elements(eV)-1)
		disp_zmin = min(spectrum, max = disp_zmax)
		widget_control, STACK_PROCESS_par.disp_emin_label, $
		    set_value = strtrim(string(disp_emin,format='(f10.2)'),2)
		widget_control, STACK_PROCESS_par.disp_emax_label, $
		    set_value = strtrim(string(disp_emax,format='(f10.2)'),2)
        STACK_PROCESS_plotspectrum,displayed_file_index
   	    widget_control, STACK_PROCESS_par.disp_zmin_label, $
	    	set_value = strtrim(string(disp_zmin,format='(f10.2)'),2)
		widget_control, STACK_PROCESS_par.disp_zmax_label, $
    		set_value = strtrim(string(disp_zmax,format='(f10.2)'),2)

    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.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 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
        STACK_PROCESS_sensitive
        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 = floor(0.5 +float(event.x)/float(img_zoom))
                y_index = floor(0.5 +float(event.y-textregion_ypix) / $
                              float(img_zoom))
;  adapt for image zoom conditions
 				ixslope = (ixh - ixl)/(n_cols-1)
				iyslope = (iyh - iyl)/(n_rows-1)
                x_index = fix(x_index*ixslope + ixl)
                y_index = fix(y_index*iyslope + iyl)
                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 = floor(0.5 + float(event.x)/float(img_zoom))
                y_index = floor(0.5 + float(event.y-textregion_ypix) / $
                              float(img_zoom))
;  adapt for image zoom conditions
				ixslope = (ixh - ixl)/(n_cols-1)
				iyslope = (iyh - iyl)/(n_rows-1)
                x_index = fix(x_index*ixslope + ixl)
                y_index = fix(y_index*iyslope + iyl)
                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

; ----------------------------------------------------------------------------------
; ****************************  stack modification processing **********************
; ----------------------------------------------------------------------------------


; APH 6-jul-98 ------- Energy calibration ----------------------------
    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

; (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 19-feb-05) ------ multipy  all pixels  by a user defined value   ----
    STACK_PROCESS_par.gain: BEGIN
    	gain = 1.0
		gain=get_num(prompt='gain',val=gain, group=STACK_PROCESS_par.main_base)
		image_stack = image_stack * gain
	; ------ re-adjust disp_min and disp_max values
		disp_min = min(Image_stack, max=disp_max)
        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)
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (APH 16-feb-06) ------ generate maps = background subtracted images = (I - a*A-b*B)
    STACK_PROCESS_par.map: BEGIN
;  ---- get  info on image umbers (using first image index = 1 ---------------
		if n_elements(peak_img) EQ 0 then peak_img = 2
    	peak_img = get_num(prompt='Image # of peak image',val=peak_img, group=STACK_PROCESS_par.main_base)
		if n_elements(bgnd_1) EQ 0 then bgnd_1 = 1
    	bgnd_1 = get_num(prompt='Image # of background 1',val=bgnd_1, group=STACK_PROCESS_par.main_base)
    	if n_elements(B1_wt) EQ 0 then B1_wt = 1.0
		B1_wt = get_num(prompt='weight for background 1',val=B1_wt, group=STACK_PROCESS_par.main_base)
    	if n_elements(bgnd_2) EQ 0 then bgnd_2 = 3
    	bgnd_2 = get_num(prompt='Image # of background 2 (-1 = none)',val=bgnd_2, group=STACK_PROCESS_par.main_base)
		if bgnd_2 GT 0 then begin
	    	if n_elements(B2_wt) EQ 0 then B2_wt = 0.5
			B2_wt = get_num(prompt='weight for background 2',val=B2_wt, group=STACK_PROCESS_par.main_base)
		endif
; ------ compute difference image
    	peak = image_stack(*,*,peak_img-1)
    	B1 = image_stack(*,*,bgnd_1-1)
    	if bgnd_2 GT 0 then begin
    		B2 = image_stack(*,*,bgnd_2-1)
    		peak = peak - B1_wt*B1 -  B2_wt*B2
    	endif else 	peak = peak - B1_wt*B1

; ------- store difference image
		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
		dl = 'map'
		tmp = {t:'2d', x:x, y:y, d:peak, e: 1., xl: 'x', yl: 'y', dl: dl}
		file = axb_save(tmp)
		tn = ax_name(file)
		axis_log, 'Map wrote to " tn(1)
; allow user to store in selected buffer
		bt = buffer(prompt = 'Store background subtracted image in ', group = AXIS_ID)
   	   	IF bt EQ -1 THEN RETURN
		CurBuf = fix(bt(0))
		HANDLE_VALUE, Data(CurBuf), tmp, /set
  		Label(CurBuf) = tmp.dl
		PlotBuf,CurBuf
    END


; (APH 19-feb-05) ------ subtract a user selected constant from all pixels   ----
    STACK_PROCESS_par.sub_constant: BEGIN
    	const = 0.0
		const=get_num(prompt='constant',val=const, group=STACK_PROCESS_par.main_base)
		image_stack = image_stack - const
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    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 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
        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 03-jul-05) ------ ratio a user selected spectrum to each image  ----
    STACK_PROCESS_par.ratio_spectrum: BEGIN
        tmp = spc_load(DEFPATH=DefPath, filter='*.txt')
        if n_tags(tmp) NE 0 then begin
        		ref_spectrum = tmp.d   ; 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)
        endif
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (APH 15-Dec-05) ------ clip all images to user defined limits  ----
    STACK_PROCESS_par.clip_img: BEGIN
    	img_min = min(image_stack,max=img_max)
		low_limit=get_num(prompt='low_limit',val=img_min, group=STACK_PROCESS_par.main_base)
		hi_limit= get_num(prompt= 'hi_limit',val=img_max, group=STACK_PROCESS_par.main_base)
		cnt = long(0) & index = lonarr(1) & nval = long(0) ; declare long for big images
		index = where(image_stack LT img_min,cnt)
		if cnt GT 0 THEN image_stack(index) = img_min
		index = where(image_stack GT img_max,cnt)
		if cnt GT 0 THEN image_stack(index) = img_max
        STACK_PROCESS_makespectrum
        STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (10-apr-04 APH) REMOVE ZEROS
	STACK_PROCESS_par.remove_zeros_label: BEGIN
    	image_stack = remove_zeros(image_stack,/silent)
		STACK_PROCESS_makespectrum
		STACK_PROCESS_plotspectrum,displayed_file_index
        STACK_PROCESS_imgdisp,displayed_file_index
    END

; (APH 27-mar-04) ------ add all images in stack, and save ------------
; (aph 14-Nov-05) ----- restrict to the energies displayed

    STACK_PROCESS_par.avg_stack: BEGIN
    	tmp = fltarr(n_cols,n_rows,1)
; get current energy limits and associated image indices
	    widget_control, STACK_PROCESS_par.disp_emin_label,$
          get_value = temp_string
        reads,temp_string(0),disp_emin
		widget_control, STACK_PROCESS_par.disp_emax_label,$
          get_value = temp_string1
        reads,temp_string1(0),disp_emax
        num_img = 0
;        print, 'averaging images: ', temp_string ,' - ', temp_string1
    	for i = 0, n_elements(eV)-1 do begin
	    	if eV(i) GE disp_emin AND ev(i) LE disp_emax then begin
	    		tmp = tmp +image_stack(*,*,i)
	    		num_img = num_img + 1
;	    		print, num_img, ev(i)
	    	endif
	    endfor
	    t = tmp/num_img
;	    print, 'data-range ', min(tmp), max(tmp)
		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
		dl = 'avg: ' + temp_string + ' - ' + temp_string1
		tmp = {t:'2d', x:x, y:y, d:t, e: 1., xl: 'x', yl: 'y', dl: dl}
		file = axb_save(tmp)
		tn = ax_name(file)

		axis_log, tn(1) + ': Averaged stack from ' + temp_string + ' to ' + temp_string1
; allow user to store in selected buffer
		bt = buffer(prompt = 'Store average image in ', group = AXIS_ID)
   	   	IF bt EQ -1 THEN RETURN
		CurBuf = fix(bt(0))
		HANDLE_VALUE, Data(CurBuf), tmp, /set
  		Label(CurBuf) = tmp.dl
		PlotBuf,CurBuf
    END

; ------- median smooth all images to remove extrema ('salt & pepper' noise)
    STACK_PROCESS_par.median_smooth: BEGIN
    	tmp = fltarr(n_cols,n_rows)
    	for i = 0, n_elements(ev) -1 do begin
	    	tmp = image_stack(*,*,i)
	    	image_stack(*,*,i) = median(tmp,3)
    	endfor
	    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 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

; ----------------- 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
		deleted_E = eV(displayed_file_index)
		del_img = displayed_file_index
; ------------ remove the energy value from the energy array --------------
		ev = fltarr(n_ev-1)
;		del_E = ev(displayed_file_index)
		if del_img EQ 0 then begin
			ev = tmp(1:n_ev-1)
		endif else begin
			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)
		endelse
; ------------ remove the image --------------- --------------
		tmp = image_stack
		image_stack = fltarr(nx,ny,n_ev-1)
		if del_img EQ 0 then begin
			image_stack = tmp(*,*,1:n_ev-1)
		endif else begin
			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)
		endelse
; ------------ remove the label from the label array --------------
	    tmp = filename_ev_msec_list
	    filename_ev_msec_list = strarr(n_ev-1)
   		if del_img EQ 0 then begin
			filename_ev_msec_list = tmp(1:n_ev-1)
		endif else begin
		    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)
		endelse
 ; ----------  update display ------------------
    	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 = ', deleted_E
    END

; ----------------------------------------------------------------------------------
; ****************************  Read-out processing ********************************
; ----------------------------------------------------------------------------------


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

    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.pngimg_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.pngimg_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_analyze_par.spec_savefile_label: BEGIN
      if n_elements(spectrum) GT 1 then begin     ; ensure data there
        filename = strcompress((filename_header+'.txt'),/remove_all)
        test = findfile(filename)
      if test(0) EQ filename then begin
        axis_log, 'File exists - overwrite ?'
        filename = pickfile2(/write, filter='*.txt', title = 'Alternate file name')  ;  LFILE = filename
      endif
        tn= ax_name(filename)
  ;   generate standard 1-d structure & write using spc_save
    tmps = {t:'1d', x:float(ev), d:float(spectrum), dn:float(spectrum), xl:('from stack ' + tn(1)), dl:tn(1) }
        t = spc_save(tmps, 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
	img_type = get_num(prompt = 'Format (0=*.nc, 1 = *.axb, 2 = *.bmp, 3 = *.tif(long), 4 = *.tif(float)) ',val = 0, group = axis_ID)
	img_case='nc'	; default
	if img_type EQ 1 then img_case = 'axb'
	if img_type EQ 2 then img_case = 'bmp'
	if img_type EQ 3 then img_case = 'tif-long'		; updated for tif formats  8-Apr-06 (gaj, aph)
	if img_type EQ 4 then img_case = 'tif-float'

	if img_type EQ 3 then begin
;	---------- rescale if too big
		tmp_min = min(image_stack, max=tmp_max)
  		scale = 1.0
   		while tmp_min LT -32768. OR tmp_max GT 32767. do begin
			scale = 0.1*scale
			tmp_min = scale*tmp_min
			tmp_max = scale*tmp_max
  		endwhile
;	---------- rescale if too small
		tmp_size = max(abs(image_stack))
  		while tmp_size LT 100. do begin
			scale = 10.*scale
			tmp_size = scale*tmp_size
		endwhile
		axis_log, 'Tif files: scaled by ' +string(scale)
	endif

    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
	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)}
		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)
		CASE img_case OF
		  'nc': BEGIN
				t=ax_name(filename)
				fileshort = t(1) + '.nc'
		        file=sav_nsls(tmp, file=filename)
		      END
		  'axb': BEGIN
		  		t=ax_name(filename)
		  		filename = t(0) + t(1) + '.axb'
		  		fileshort = t(1) + '.axb'
				file = axb_save(tmp, file=filename)
		      END
		  'bmp': BEGIN
		  		t=ax_name(filename)
		  		filename = t(0) + t(1) + '.bmp'
		  		fileshort = t(1) + '.bmp'
		  		Write_BMP, filename, bytscl(tmp.d)
		      END
		  'tif-long': BEGIN
		  		t=ax_name(filename)
		  		filename = t(0) + t(1) + '.tif'
		  		fileshort = t(1) + '.tif'
		  		Write_TIFF, /long, filename, scale*tmp.d
		      END
		  'tif-float': BEGIN
		  		t=ax_name(filename)
		  		filename = t(0) + t(1) + '.tif'
		  		fileshort = t(1) + '.tif'
		  		Write_TIFF, /float, filename, tmp.d
		      END
		ENDCASE
		axis_log, strtrim(string(i_wr),2) + ' ' + fileshort
	endfor
	if scale NE 1.0 AND img_type EQ 3 then 	axis_log, 'Tif files: scaled by ' + string(scale)

; --- 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+'.' + img_case),/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.pngimg_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+'.png'
        write_png,filename,bytimg,r,g,b
        print,'Wrote PNG 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; 21-jan-05 - shut down once write
        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 analcom to pass these from stack_align)
        if xpix_shift(0) NE 0 then nx_min = nx_min + 1
        nx_max = n_cols - fix(xpix_shift(1))
        ny_min = fix(-1*ypix_shift(0))
        if ypix_shift(0) NE 0 then ny_min = ny_min + 1
        ny_max = n_rows - fix(ypix_shift(1))
        nx_min = get_num(val=nx_min, $
        	Prompt='keep columns(x) > (' + strtrim(string(nx_min),2) + ')',$
            group = STACK_PROCESS_par.main_base)
        nx_max = get_num(val=nx_max-1, $
        	Prompt='keep columns(x) < (' + strtrim(string(nx_max),2) + ')',$
         	group = STACK_PROCESS_par.main_base)
        ny_min = get_num(val=ny_min, $
        	Prompt='keep rows(y) > (' + strtrim(string(ny_min),2) + ')',$
        	group = STACK_PROCESS_par.main_base)
        ny_max = get_num(val=ny_max-1, $
        	Prompt='keep rows(y) < (' + strtrim(string(ny_max),2) + ')',$
        	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
; --------------------- EXIT since the buffers are modified -----------------
;    	loadct,0,/silent
    	ax_color
        widget_control,STACK_PROCESS_par.main_base,/destroy
    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
;    	loadct,0,/silent
		ax_color
        widget_control,STACK_PROCESS_par.main_base,/destroy
    END

ENDCASE
END


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

pro STACK_PROCESS, list_filename, shift_filename, fpath=fpath, binary=binary, $
                   zoom=zoom, text_height=text_height, realign=realign, $
                   help=help, no_align = no_align, debug = debug, _extra = e
; (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

if keyword_set(debug) then sa_debug = 1 else sa_debug = 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
	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 = 450
ENDIF ELSE BEGIN
    estimated_leftcol_pixels = 450
ENDELSE

estimated_max_zoom = $
    fix(0.05+float(screen_size(0)-estimated_leftcol_pixels)/float(n_cols))
axis_log,'Estimated maximum zoom: '+ strtrim(string(estimated_max_zoom),2)

img_zoom = 1
IF keyword_set(zoom) THEN img_zoom = zoom ELSE BEGIN
; check for limits horizontally		; (aph  15-apr-06)
	if estimated_max_zoom GT 2 then img_zoom = estimated_max_zoom - 2
	if estimated_max_zoom GT 10 then img_zoom = 10.
; check for limits vertically
	Vspace = float(screen_size(1) - 380)
	if img_zoom*n_rows GT Vspace then img_zoom = fix(0.05+Vspace/float(n_rows)) - 2
	if img_zoom LT 1 then img_zoom = 1
	axis_log, 'Zoom factor = '  + strtrim(string(fix(img_zoom)),2)
; confirm choice with user
	img_zoom = get_num(prompt='Zoom *',val=img_zoom, group=axis_ID)
ENDELSE


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

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

; 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
	ixl = 0   &	ixh = n_cols
	iyl = 0   &	iyh = n_rows
	i_file = 0
;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, $
        clip_img: 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_emin_label: 0L, $
   		disp_emax_label: 0L, $
        disp_zmin_label: 0L, $
   		disp_zmax_label: 0L, $
        disp_zoom: 0L, $
        disp_reset: 0L, $
        disp_Ereset: 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)
        sub_constant: 0L, $				; added by aph   (feb05)
        gain: 0L, $						; added by aph   (feb05)
        map: 0L, $				; added by aph   (feb06)
        ratio_image: 0L, $				; added by aph   (may03)
        sub_image: 0L, $				; added by aph   (apr00)
        sub_stack: 0L, $				; added by aph   (apr00)
        avg_stack: 0L, $				; added by aph   (mar-04)
        ratio_spectrum: 0L, $			; added by aph   (jul-05)
        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, $
        remove_zeros_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, $
        pngimg_savefile_label: 0L, $		; REPLACED gifing with pngimg (aph jul04)
        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, $
        median_smooth: 0L, $               ; added by aph
        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, /scroll )

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)
tlabel = widget_label(row,value='x,y-scale')
; 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)
STACK_PROCESS_par.disp_zoom = $
	widget_button(row,value='Zoom')
STACK_PROCESS_par.disp_reset = $
	widget_button(row,value='Reset')
; Energy scale
row = widget_base(base,/row)
tlabel = widget_label(row,value='E:  min, max:        ')
STACK_PROCESS_par.disp_emin_label = $
  widget_text(row,/frame,/editable,xsize=10)
STACK_PROCESS_par.disp_emax_label = $
  widget_text(row,/frame,/editable,xsize=10)
tlabel = widget_label(row,value='  E,I-scale')
; Spectral intensity scale
row = widget_base(base,/row)
tlabel = widget_label(row,value='I:   min, max:        ')
STACK_PROCESS_par.disp_zmin_label = $
  widget_text(row,/frame,/editable,xsize=10)
STACK_PROCESS_par.disp_zmax_label = $
  widget_text(row,/frame,/editable,xsize=10)
STACK_PROCESS_par.disp_Ereset = $
	widget_button(row,value='Reset')

;row = widget_base(base,/row)
  movieBtns = ['Play  ', 'Stop  ', 'Pause/Step' ]
  STACK_PROCESS_par.Movie_Buts = CW_BGROUP(base,  $  ; Yoffset = 200, Xoffset= 200, $
  	movieBtns, row=1, set_value = 1, EXCLUSIVE=1,  LABEL_LEFT='Movie',UVALUE=1 )


; tlabel = widget_label(base,value='Image to display: ')
t = get_screen_size()
if t(1) GT 770 then ev_list_lines = 6 else ev_list_lines = 3	; variable size of list box
STACK_PROCESS_par.filename_ev_msec_list_label = $
  widget_list(base, value = filename_ev_msec_list, xsize=40, ysize= ev_list_lines )
base = widget_base(col1,/column,/frame)
row = widget_base(base,/row)
tlabel = widget_label(row,value='I:  ')
STACK_PROCESS_par.add_all_label = $
  widget_button(row,value='all')			; aph (25-may-03)
tlabel = widget_label(row,value=' Add  ')
STACK_PROCESS_par.add_i_roi_label = $
  widget_button(row,value='region')
STACK_PROCESS_par.add_i_pix_label = $
  widget_button(row,value='pixel')
tlabel = widget_label(row,value='   ')
STACK_PROCESS_par.reset_i_label = $
  widget_button(row,value='Reset')

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=12)
tlabel = widget_label(row,value='   ')
STACK_PROCESS_par.remove_zeros_label = $
  widget_button(row,value='remove zeros')

row = widget_base(base,/row)
tlabel = widget_label(row,value='I0: ')
STACK_PROCESS_par.i0_readin = $
  widget_button(row,value='file')
tlabel = widget_label(row,value=' Add  ')
STACK_PROCESS_par.add_i0_roi_label = $
  widget_button(row,value='region')
STACK_PROCESS_par.add_i0_pix_label = $
  widget_button(row,value='pixel')
tlabel = widget_label(row,value='   ')
STACK_PROCESS_par.reset_i0_label = $
  widget_button(row,value='Reset')
STACK_PROCESS_par.change_e = $
  widget_button(row,value='change energies')

;row = widget_base(base,/row)
;col = widget_base(base,/column)
;tlabel = widget_label(row,value='      ')


; 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')
  STACK_PROCESS_par.median_smooth = $
  widget_button(row,value='median smooth')		; (aph 27-mar-04)
STACK_PROCESS_par.eV_shift = $
  widget_button(row,value='E_cal')

row = widget_base(base,/row)					; (aph 09-apr-00)
col = widget_base(base,/column)
STACK_PROCESS_par.avg_stack = $
  widget_button(row,value='avg stack')		; (aph 27-mar-04)
STACK_PROCESS_par.remove_image = $
  widget_button(row,value='remove image')
STACK_PROCESS_par.gain = $						; (aph 19-feb-05)
  widget_button(row,value='gain')
tlabel = widget_label(row,value='        ')
STACK_PROCESS_par.map = $				; (aph 16-feb-06)
  widget_button(row,value='map')

row = widget_base(base,/row)
col = widget_base(base,/column)
tlabel = widget_label(row,value='Subtract: ')
STACK_PROCESS_par.sub_constant = $
  widget_button(row,value='constant')
tlabel = widget_label(row,value='  ')
STACK_PROCESS_par.sub_spectrum = $
  widget_button(row,value='spectrum')
tlabel = widget_label(row,value='  ')
STACK_PROCESS_par.sub_image = $
  widget_button(row,value='image')
tlabel = widget_label(row,value='  ')
STACK_PROCESS_par.sub_stack = $
  widget_button(row,value='stack')

row = widget_base(base,/row)
col = widget_base(base,/column)
tlabel = widget_label(row,value='Ratio to: ')
STACK_PROCESS_par.ratio_spectrum = $
  widget_button(row,value='spectrum')   ; (aph jul-05)
STACK_PROCESS_par.ratio_image = $
  widget_button(row,value='image')		; (aph may-03)
tlabel = widget_label(row,value='          ')
STACK_PROCESS_par.clip_img = $
  widget_button(row,value='clip images')   ; (aph dec-05)

base = widget_base(col1,/column,/frame)
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(s)')

row = widget_base(base,/row)
STACK_PROCESS_par.pngimg_savefile_label = $
  widget_button(row,value='Image ".png"')
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"')

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')

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

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.roi_filename_label, set_value='.roi'	;  (21-apr-06 aph - allow user to click file)
roi_filename = '.roi'

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.pngimg_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
disp_zmin = disp_min
disp_zmax = disp_max
disp_emin = ev(0)
disp_emax = ev(n_elements(ev)-1)
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)
widget_control, STACK_PROCESS_par.disp_emin_label, $
    set_value = strtrim(string(disp_emin,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_emax_label, $
    set_value = strtrim(string(disp_emax,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_zmin_label, $
    set_value = strtrim(string(disp_zmin,format='(f10.2)'),2)
widget_control, STACK_PROCESS_par.disp_zmax_label, $
    set_value = strtrim(string(disp_zmax,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

; ----------- start without 'echo' from past uses of the widget --------------
i_roi = 0
i0_roi = 0
i0_read=0                       ; zero out read-in data
i0_data=0
OD_flag = 0                     ; remove OD determination


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
