; Copyright (c) 1998-2016 A.P. Hitchcock   All rights reserved
;+
;NAME:
;	STACK_PROCESS.PRO
;
;LAST CHANGED: ----------------------------------- 26-Mar-16 (aph)
;
; 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
; RENAMED 17-Sep-08 (old name: stack_analyze - conflicted with CJJ).
;
; CATEGORY:
;	Stack processing.
; Called from aXis2000 by stacks~analyse~AXIS or stacks~analyse~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
; debug			extensive printing to track progress
;
; 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_analyze_readroi
; stack_analyze_writeroi
; stack_analyze_gifmovie
; stack_analyze_roi_event,event
; stack_analyze_roi
; stack_analyze_desensitive
; stack_analyze_sensitive
; stack_analyze_graphics
; stack_analyze_bar
; stack_analyze_makespectrum
; stack_analyze_plotspectrum, i_file
; stack_analyze_imgdisp,i_file
; stack_analyze_event,event
; stack_analyze_maximg

; 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_analyze_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_analyze 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
; (31-may-06 jso) adapt Readroi to read *.png type ROI files from Lox stacks
; (10-jun-06 aph) integrate Jacob's alternate Lox ROI, using *.png images
; (07-jul-06 rec) add stack_analyze_maximg
; (22-Sep-06 aph) correct multi-image write out to get *.sl file
; (22-Sep-06 aph) cosmetic changes
; (12-Nov-06 aph) correct multi-image write out to get *.sl file (again)
;                 put energy sort into binary read; add ratio to constant (gain)
; (11-jan-07 aph) multiply constant, image
; (26-feb-07 aph) replaced direct use of interpolate with ax_mesh to get subtraction of spectra correct
; (17-jul-07 aph) optimize read-in from memory rather than disk; leave widget on top
; (17-Sep-07 aph) do remove_zeros image-by-image
; (29-Dec-07 aph) correct name in header; leave widget on top - TRY #2
; (03-Mar-08 MJ)  keyword /SCROLL in widget_base() needs X_SCROLL_SIZE
; (21-mar-08 aph) fix up stack_analyze subtract stack (missing read-in !!); merged MJ version
; (13-apr-08 aph) turn on pre-set window size (X_Scroll_size, Y_Scroll_size) only for non-Windows OS
;                 over-write warning when writing spectra or images
; (17-sep-08 aph) convert name from stack_analyze to stack_process; change analcom to stack_process_com
; (21-sep-08 aph) add ability to revert to tranmsission, given the Io signal
; (22-Nov-08 aph) add file overwrite check to saving spectra & make it work
; (19-Dec-08 aph) write out only images in range of E displayed (shrink stacks)
; (29-jul-09 aph) auto-transfer name of roi to name of output
; (11-Aug-09 aph) fixe wrong variable name for filename for image write
; (17-Aug-09 aph) mods to chase why VM version does not work if try to build in align info
;                move shifting part of stack_align into stack_process
; (16-Feb-10 aph) add calibrate (x-axis - full range)
; (22-Jul-10 aph) modify energies in stack filename_ev_msec list
; (23-Jul-10 aph) add no_read option for situations where image_stack exists
; (03-Feb-11 aph) corrected no-read stacks (was error on stack_rb introduced 20-Feb-10
;                rescale_flag = 1 set for all stacks
;				 now displays io files read from disk
; (19-Feb-11 aph) remove annoying HELP, image_stack display
; (22-Apr-11 aph) add replace bad lines (for STXM5321 data)
; (17-May-11 aph) add work around for ID5.2 in energy calibration routine; reset energy limits when E-cal
; (31-Jul-11 aph) remove commented out reference to wt_spec (old writer)
; (04-Oct-11 aph) add ROTATE 90 CW, CCW
; (22-Nov-11 aph) stop using old CurBuf index when placing resultants (avg, map) into aXis buffers
;				  desensitivze OD control when TEY is ON; add 'exchange x,y axes'
; (24-Nov-11 aph) enable reading stack list with *.axb files
; (07-Dec-11 aph) limits for write-out in IDL notation (0 to #-1); add tooltips; add adjustable Path
; (08-Dec-11 aph) preserve aspect ratio in the zoom
; (14-Feb-16 aph) shrink size of command structure to work better on a Mac
;                 introduce process command (WIDGET_DROPLIST)
; (13-Mar-16 aph) stop avg._stack from placing result in CurBuf (re-order save to disk, and save to aXis buffer)
; (20-Mar-16 aph) increase size of box to display z-axis values; try using UNIX specfic fonts (no go)
; (26-Mar-16 aph) fix problem of reading sl lists of *.axb files
;-

PRO stack_analyze_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_analyze_readroi_bailout

roi_filename = PICKFILE2(/read,FILTER = '*.roi;*.png', /LPATH, DEFPATH=defpath)	;JSO forces it to pick a file always
t = ax_name(roi_filename)
widget_control, stack_analyze_par.roi_filename_label, set_value = t(1)
; ---------- auto-transfer roi name to filesave name
filesave = t(1)
widget_control, stack_analyze_par.filename_label, set_value = filesave
widget_control, stack_analyze_par.spec_savefile_label, sensitive = 1
widget_control, stack_analyze_par.stack_savefile_label, sensitive = 1
widget_control, stack_analyze_par.save_image_label, sensitive = 1
widget_control, stack_analyze_par.pngimg_savefile_label, sensitive = 1
widget_control, stack_analyze_par.gifmov_savefile_label, sensitive = 1
widget_control, stack_analyze_par.roi_savefile_label, sensitive = 1
temp_string = ''
widget_control, stack_analyze_par.filename_label, get_value = temp_string
filesave = strtrim(temp_string(0),2)
widget_control, stack_analyze_par.filename_path,get_value = temp_string
filepath = strtrim(temp_string(0),2)      ; remove blanks
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))
n_i_roi = long(0)
n_i0_roi = long(0)

IF (t(2) EQ 'roi') then begin			;JSO if filetype is ROI then read as normal
   	get_lun,lun
   	openr,lun,roi_filename,/xdr
   	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

ENDIF ELSE BEGIN						;Otherwise assume image file

   	roi_img = make_array(n_cols,n_rows,/integer,value = 0)
   	img_ROI_PNG = read_png(roi_filename)
	for i = 0, n_cols-1 do begin
		for j = 0, n_rows-1 do begin
			if img_ROI_PNG(2,i,j) EQ 1 then begin		;if blue component of pixel is equal to 1 then
				roi_img(i, j) = 1						;point on the image is also equal to 1
			endif
		endfor
	endfor

i_roi = where(roi_img EQ 1)		;JSO transfer image data into i_roi pixel list
ENDELSE

if sa_debug EQ 1 then begin
	 axis_log, 'Read ROI file "'+roi_filename+'"'
	axis_log, 'path & file name for output set to ' + filename_header
endif

return

stack_analyze_readroi_bailout:
axis_log,'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_analyze_writeroi, _EXTRA = e
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

on_ioerror,stack_analyze_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

if sa_debug EQ 1 then $
	print,'Wrote ROI file "'+filename_header+'.roi"'

stack_analyze_writeroi_bailout:
close,lun
free_lun,lun

return
END

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

PRO stack_analyze_gifmovie, _extra = e
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

if sa_debug EQ 1 then $
	 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_analyze_par.main_base)			; allow user to get subset
	 n_xmax = img_zoom*get_num(prompt='xmax',val = n_cols, group=stack_analyze_par.main_base)
	 n_ymin = get_num(prompt='ymin',val = 0, group=stack_analyze_par.main_base)
	 n_ymax = img_zoom*get_num(prompt='ymax',val = n_rows, group=stack_analyze_par.main_base)
endif
if sa_debug EQ 1 then $
	 print, 'x,y, limits ' , gifmx, gifmy
FOR i_file=0,(n_elements(filename_list)-1) DO BEGIN
    stack_analyze_imgdisp, i_file
    stack_analyze_plotspectrum, i_file
    wset,stack_analyze_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_analyze_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 axis_log, 'temp*.gif files are likely in c:\axis !'
if sa_debug EQ 1 then $
	print,'Created GIF movie "'+gifmovie_filename+'"'

stack_analyze_imgdisp, displayed_file_index
stack_analyze_plotspectrum, displayed_file_index
widget_control,stack_analyze_par.main_base,show=1,map=1

return
END

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

PRO stack_analyze_roi_event,event, _extra = e
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

CASE event.id OF
   stack_analyze_par.roi_accept_label: BEGIN
; add i0-values to roi pixel list
; in (x,y) zoom mode, need to rescale the cursor co-ordinates to the data co-ordinates
; (22-feb-04 aph)
        IF (stack_analyze_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_analyze_par.roi_base,/destroy
        stack_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
        widget_control, stack_analyze_par.main_base,show=1
        stack_analyze_sensitive
    END

    stack_analyze_par.roi_reject_label: BEGIN
        widget_control, stack_analyze_par.roi_base,/destroy
        stack_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
        widget_control, stack_analyze_par.main_base,show=1
        stack_analyze_sensitive
    END
ENDCASE
END

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

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

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_analyze_makespectrum
    stack_analyze_plotspectrum,displayed_file_index
    stack_analyze_imgdisp,displayed_file_index
    widget_control, stack_analyze_par.main_base,show=1
    stack_analyze_sensitive
	return
ENDIF

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

stack_analyze_par.roi_base = widget_base(title=title_string,/column)
tlabel = $
  widget_text( stack_analyze_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_analyze_par.roi_accept_label = $
  widget_button( stack_analyze_par.roi_base, value='ACCEPT region')
stack_analyze_par.roi_reject_label = $
  widget_button( stack_analyze_par.roi_base, value='REJECT region')

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

wset,stack_analyze_par.image_win

; get pixels from user-selected cursor region
; IDL 6.3 HELP has warning under DEFROI description that the routine
;           does not work right when used with draw widgets.
; I think the following was trying to fix that but it must not have worked
;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 sa_debug EQ 1 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_analyze_par.roi_accept_label, sensitive=1
widget_control, stack_analyze_par.roi_reject_label, sensitive=1
widget_control, stack_analyze_par.roi_base,show=1,map=1
xmanager, 'stack_analyze_roi', stack_analyze_par.roi_base, $
  group_leader = stack_analyze_par.main_base

return
END

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

PRO stack_analyze_desensitive, _extra = e
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

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

return
END

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

PRO stack_analyze_sensitive, _extra = e
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

widget_control,stack_analyze_par.disp_min_label, sensitive=1
widget_control,stack_analyze_par.disp_max_label, sensitive=1
widget_control,stack_analyze_par.disp_gamma_label, sensitive=1
widget_control,stack_analyze_par.filename_ev_msec_list_label, sensitive=1
widget_control,stack_analyze_par.add_i0_roi_label, sensitive=1
widget_control,stack_analyze_par.Movie_buts, sensitive=1
widget_control,stack_analyze_par.i0_readin, sensitive=1
widget_control,stack_analyze_par.i0_norm, sensitive=1
WIDGET_CONTROL, stack_analyze_par.OD_tran, sensitive=1
widget_control, stack_analyze_par.save_image_label, sensitive=1
widget_control,stack_analyze_par.add_i0_pix_label, sensitive=1
widget_control,stack_analyze_par.reset_i0_label, sensitive=1
widget_control,stack_analyze_par.eV_shift, sensitive=1
widget_control,stack_analyze_par.add_all_label, sensitive=1
widget_control,stack_analyze_par.add_i_roi_label, sensitive=1
widget_control,stack_analyze_par.add_i_pix_label, sensitive=1
widget_control,stack_analyze_par.reset_i_label, sensitive=1
widget_control,stack_analyze_par.roi_filename_label, sensitive=1
; WIDGET_CONTROL, stack_analyze_par.sub_spectrum, sensitive=1
; widget_control, stack_analyze_par.ratio_image, sensitive=1
; widget_control, stack_analyze_par.sub_image, sensitive=1
; widget_control, stack_analyze_par.sub_stack, sensitive=1

;IF (strlen(roi_filename) NE 0) THEN BEGIN
    widget_control,stack_analyze_par.roi_readfile_label, sensitive=1
;ENDIF ELSE BEGIN
;    widget_control,stack_analyze_par.roi_readfile_label, sensitive=0
;ENDELSE
widget_control,stack_analyze_par.filename_path, sensitive=1
widget_control,stack_analyze_par.filename_label, sensitive=1
IF (strlen(filename_header) NE 0) THEN BEGIN
    widget_control, stack_analyze_par.spec_savefile_label, sensitive = 1
    widget_control,stack_analyze_par.stack_savefile_label, sensitive = 1
     widget_control, stack_analyze_par.save_image_label, sensitive = 1
    widget_control, stack_analyze_par.pngimg_savefile_label, sensitive = 1
	widget_control,stack_analyze_par.rotate_label, sensitive = 1
    widget_control, stack_analyze_par.gifmov_savefile_label, sensitive = 1
    widget_control, stack_analyze_par.roi_savefile_label, sensitive = 1
ENDIF ELSE BEGIN
    widget_control, stack_analyze_par.spec_savefile_label, sensitive = 0
     widget_control, stack_analyze_par.save_image_label, sensitive = 0
    widget_control, stack_analyze_par.pngimg_savefile_label, sensitive = 0
    widget_control, stack_analyze_par.gifmov_savefile_label, sensitive = 0
	widget_control,stack_analyze_par.rotate_label, sensitive = 0
    widget_control, stack_analyze_par.stack_savefile_label, sensitive = 0
    widget_control, stack_analyze_par.roi_savefile_label, sensitive = 0
ENDELSE
widget_control,stack_analyze_par.exit_label, sensitive=1
widget_control,stack_analyze_par.slicer_label, sensitive=1
widget_control,stack_analyze_par.slicer3_label, sensitive=1
widget_control,stack_analyze_par.tey_label, sensitive=1
return
END

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

; This routine sets up color maps and graphics parameters

PRO stack_analyze_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_analyze_bar

return
END

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

PRO stack_analyze_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)
; ---------------------------- aph commented out report on sizes (nov-06)
;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
 ; normalize using either Beers Law (for trasmission) or ratio (for a yield signal)
      if tey_flag NE 1 then begin
        	spectrum = -alog(i_signal/i0_signal)
	        spectrum_title = 'Optical Density'
	  endif else begin
	        spectrum_title = 'Yield (I/Io)'
      		spectrum = i_signal/i0_signal
	  endelse

;	    print, 'spectrum ', spectrum
;		print, 'energies', ev
;		plot,ev,spectrum,color=white_color_index  ; no plot at this point - line color issue ?

    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_analyze_par.disp_zmin_label, $
set_value = strtrim(string(disp_zmin,format='(f10.2)'),2)
widget_control, stack_analyze_par.disp_zmax_label, $
set_value = strtrim(string(disp_zmax,format='(f10.2)'),2)

return
END

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

PRO stack_analyze_plotspectrum, i_file, _extra = e
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

wset,stack_analyze_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_analyze_imgdisp, i_file, _extra = e

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

@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

wset,stack_analyze_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)
	 widget_control, stack_analyze_par.disp_max_label, sensitive = 0  ; force desensitive 28-jan-11
     widget_control, stack_analyze_par.disp_min_label, sensitive = 0
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
	t(i_roi) = 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
    endif
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_analyze_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_analyze_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_analyze_event, event, _extra = e
@axis_com
@bsif_com
@stack_process_com
@region_analyze_common
COMMON volume_data, image_stack
COMMON pix_shift, xpix_shift, ypix_shift

on_error,2

CASE event.id OF


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

    stack_analyze_par.disp_min_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_min_label, $
          set_value = strtrim(string(disp_min,format='(f10.2)'),2)
        stack_analyze_imgdisp,displayed_file_index
        stack_analyze_plotspectrum,displayed_file_index
    END

    stack_analyze_par.disp_max_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_max_label, $
          set_value = strtrim(string(disp_max,format='(f10.2)'),2)
        stack_analyze_imgdisp,displayed_file_index
        stack_analyze_plotspectrum,displayed_file_index
    END

    stack_analyze_par.disp_gamma_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_gamma_label, $
          set_value = strtrim(string(disp_gamma,format='(f10.2)'),2)
        stack_analyze_imgdisp,displayed_file_index
    END

    stack_analyze_par.disp_xmin_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_xmin_label, $
          set_value = strtrim(string(disp_xmin,format='(f10.2)'),2)
        stack_analyze_imgdisp,displayed_file_index
    END

    stack_analyze_par.disp_xmax_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_xmax_label, $
          set_value = strtrim(string(disp_xmax,format='(f10.2)'),2)
        stack_analyze_imgdisp,displayed_file_index
    END

    stack_analyze_par.disp_ymin_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_ymin_label, $
          set_value = strtrim(string(disp_ymin,format='(f10.2)'),2)
        stack_analyze_imgdisp,displayed_file_index
    END

    stack_analyze_par.disp_ymax_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_ymax_label, $
          set_value = strtrim(string(disp_ymax,format='(f10.2)'),2)
        stack_analyze_imgdisp,displayed_file_index
    END

  stack_analyze_par.disp_emin_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_emin_label, $
          set_value = strtrim(string(disp_emin,format='(f10.2)'),2)
        stack_analyze_plotspectrum,displayed_file_index
    END

    stack_analyze_par.disp_emax_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_emax_label, $
          set_value = strtrim(string(disp_emax,format='(f10.2)'),2)
        stack_analyze_plotspectrum,displayed_file_index
    END


  stack_analyze_par.disp_zmin_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_zmin_label, $
          set_value = strtrim(string(disp_zmin,format='(f10.2)'),2)
        stack_analyze_plotspectrum,displayed_file_index
    END

    stack_analyze_par.disp_zmax_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.disp_zmax_label, $
          set_value = strtrim(string(disp_zmax,format='(f10.2)'),2)
        stack_analyze_plotspectrum,displayed_file_index
    END

    stack_analyze_par.disp_zoom: BEGIN
		wset,stack_analyze_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)

; modify so the area has same aspect ratio as the full images
		if (w/h) GT (n_cols/n_rows) then begin
			w = floor(0.5 + h/(n_cols/n_rows))    ; height determines width
		endif else begin
			h = floor(0.5 + w*(n_cols/n_rows))    ; height determines width
		endelse
	; 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_analyze_par.disp_xmin_label, $
		    set_value = strtrim(string(disp_xmin,format='(f10.2)'),2)
		widget_control, stack_analyze_par.disp_xmax_label, $
		    set_value = strtrim(string(disp_xmax,format='(f10.2)'),2)
		widget_control, stack_analyze_par.disp_ymin_label, $
		    set_value = strtrim(string(disp_ymin,format='(f10.2)'),2)
		widget_control, stack_analyze_par.disp_ymax_label, $
		    set_value = strtrim(string(disp_ymax,format='(f10.2)'),2)
		stack_analyze_bar
        stack_analyze_imgdisp,displayed_file_index
    END

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

stack_analyze_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_analyze_par.disp_emin_label, $
		    set_value = strtrim(string(disp_emin,format='(f10.2)'),2)
		widget_control, stack_analyze_par.disp_emax_label, $
		    set_value = strtrim(string(disp_emax,format='(f10.2)'),2)
        stack_analyze_plotspectrum,displayed_file_index
   	    widget_control, stack_analyze_par.disp_zmin_label, $
	    	set_value = strtrim(string(disp_zmin,format='(f10.2)'),2)
		widget_control, stack_analyze_par.disp_zmax_label, $
    		set_value = strtrim(string(disp_zmax,format='(f10.2)'),2)

    END

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

    stack_analyze_par.filename_ev_msec_list_label: BEGIN
        displayed_file_index = event.index
        stack_analyze_imgdisp, displayed_file_index
        stack_analyze_plotspectrum, displayed_file_index
    END

    stack_analyze_par.add_i0_roi_label: BEGIN
        stack_analyze_desensitive
        stack_analyze_par.is_i0_roi = 1L
        stack_analyze_roi
    END

    stack_analyze_par.add_i0_pix_label: BEGIN
        stack_analyze_desensitive
        stack_analyze_par.add_pix = 1
    END

    stack_analyze_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_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
    END

    stack_analyze_par.add_all_label: BEGIN
        stack_analyze_par.is_i0_roi = 0L
        stack_analyze_roi,/all
    END
    stack_analyze_par.add_i_roi_label: BEGIN
        stack_analyze_desensitive
        stack_analyze_par.is_i0_roi = 0L
        stack_analyze_roi
    END

    stack_analyze_par.add_i_pix_label: BEGIN
        stack_analyze_desensitive
        stack_analyze_par.add_pix = 2
    END

    stack_analyze_par.reset_i_label: BEGIN
        i_roi = 0
        stack_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
    END

; (APH 16-apr-98) -------- allow read-in of Io from file (assumed AXIS) ----
	stack_analyze_par.i0_readin: BEGIN
        stack_analyze_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,2]
        endif
		stack_analyze_makespectrum
		stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
        stack_analyze_sensitive
    END


; (APH 30-jun-98) ------set/reset  FLAG to force byte-rescale  ----
	stack_analyze_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_analyze_par.disp_max_label, sensitive = 1
            widget_control, stack_analyze_par.disp_min_label, sensitive = 1
        ENDIF ELSE BEGIN
            widget_control, stack_analyze_par.disp_max_label, sensitive = 0
            widget_control, stack_analyze_par.disp_min_label, sensitive = 0
        ENDELSE
     stack_analyze_imgdisp,displayed_file_index
    END

stack_analyze_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_analyze_imgdisp, framenum
		stack_analyze_plotspectrum, framenum
		framenum = framenum + 1

		if framenum EQ n_elements(ev) or moviestate EQ 1 then begin
			moviestate = 1
			WIDGET_CONTROL, stack_analyze_par.Movie_Buts, Set_Value=moviestate
			framenum = 0
			stack_analyze_imgdisp, displayed_file_index
			stack_analyze_plotspectrum, displayed_file_index
		endif

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

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

	endif	else begin
	   WIDGET_CONTROL, stack_analyze_par.Movie_Buts, Get_Value=moviestate
		if moviestate EQ 0 then begin
	   		WIDGET_CONTROL, stack_analyze_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_analyze_par.Movie_buts, TIMER = framerate
	   endif
   endelse

END

    stack_analyze_par.roi_filename_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.roi_readfile_label, $
                sensitive = 1
        ENDIF ELSE BEGIN
            widget_control, stack_analyze_par.roi_readfile_label, $
                sensitive = 0
        ENDELSE
        roi_filename_label_oops:
        widget_control, stack_analyze_par.roi_filename_label, $
          set_value = roi_filename
    END

    stack_analyze_par.roi_readfile_label: BEGIN
        widget_control,hourglass=1
        stack_analyze_readroi
        stack_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
        stack_analyze_sensitive
        widget_control,hourglass=0
    END

    stack_analyze_par.image_label: BEGIN
        CASE stack_analyze_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_analyze_par.add_pix = 0
                stack_analyze_makespectrum
                stack_analyze_plotspectrum,displayed_file_index
                stack_analyze_imgdisp,displayed_file_index
                stack_analyze_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_analyze_par.add_pix = 0
                stack_analyze_makespectrum
                stack_analyze_plotspectrum,displayed_file_index
                stack_analyze_imgdisp,displayed_file_index
                stack_analyze_sensitive
            END
        ENDCASE
    END

    stack_analyze_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_analyze_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_analyze_makespectrum				; removed as crashes plot on read in
		    stack_analyze_plotspectrum,displayed_file_index
		    stack_analyze_imgdisp,displayed_file_index
		    stack_analyze_sensitive
	    endif
    END

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


; APH 6-jul-98 ------- Energy calibration ----------------------------
    stack_analyze_par.eV_shift: BEGIN          ; added 6-jul-98
	    E_shift = get_num(Prompt='E shift',val=0, group=stack_analyze_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)
	    	if fix(strmid(!version.release,0,1)) GE 6 then begin
	    		t=strsplit(str,/extract)                  ; updated method 22-Jul-10
	    		t(1) = strtrim(string(ev(i),format='(f8.2)'),2)
		    	filename_ev_msec_list(i) = strjoin(t,' ')
	    	endif else begin
; --------- STRSPLIT not in IDL5.2  so this is an alternative for IDL5.2
				t0 = ax_strmid(str,'',' ')		;  name of this image
	    		t1 = ax_strmid(str,' ',' ')		; old energy
	    		t2 = strmid(str,strlen(t0)+strlen(t1)+1)	; rest of string
	    		t1 = strtrim(string(ev(i),format='(f8.2)'),2)	; new energy
		    	filename_ev_msec_list(i) = t0 + ' '+ t1 + ' ' + t2
			endelse
		ENDFOR
        WIDGET_CONTROL,stack_analyze_par.filename_ev_msec_list_label, $
 			Set_Value = filename_ev_msec_list
 			disp_emin = ev(0)
 			disp_emax =ev(n_elements(ev)-1)
 		widget_control, stack_analyze_par.disp_emin_label, $
            set_value = strtrim(string(disp_emin,format='(f10.2)'),2)
        widget_control, stack_analyze_par.disp_emax_label, $
            set_value = strtrim(string(disp_emax,format='(f10.2)'),2)
	    stack_analyze_makespectrum
	    stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
    END

; (APH 30-jun-98) ------set/reset FLAG to convert to OD (divide all pixels by Io)  ----
	stack_analyze_par.i0_norm: BEGIN
	if i0_signal(0) EQ 0 then begin
		axis_log, '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_analyze_par.OD_tran, set_value=' T(E)'
	    	sub_flag = 0
	    	disp_min = min(image_stack)
			disp_max = max(image_stack)
		 	WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
		 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
    	endif
    	if OD_flag EQ 1 then begin
	    	widget_control,/hourglass
	    	WIDGET_CONTROL, stack_analyze_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_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
		 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
		endif
    stack_analyze_imgdisp,displayed_file_index
    endelse
    END

; (APH 21-Sep-088) ------convert OD data back to transmission data  ----
	stack_analyze_par.convert_t: BEGIN
;	    stack_analyze_desensitive
        tmp = spc_load(DEFPATH=DefPath, TITLE="select Io file", 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
;  convert stack from OD to I-transmission
	if i0_data(0) EQ 0 then begin
		axis_log, 'You must define the Io signal before converting OD to tranmsission'
		return
	endif else BEGIN
		for i = 0, n_elements(eV)-1 do $
		  image_stack(*,*,i) = exp(-1.0*image_stack(*,*,i))*I0_data(i)
		stack_analyze_makespectrum
		stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
 ;       stack_analyze_sensitive
		OD_flag = 0
    	WIDGET_CONTROL, stack_analyze_par.OD_tran, set_value=' T(E)'
    	sub_flag = 0
    	disp_min = min(image_stack)
		disp_max = max(image_stack)
	 	WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
	 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
    endelse
    END

; (APH 14-Feb-16) ---------- modify the stack with  a {+ - * / } {constant, spectrum, image} command
    stack_analyze_par.mod_list: BEGIN
;     mod_values = strarr(10)                ; (aph 13-Feb-16)
;     mod_values(0) = 'select command'
;      mod_values(1) = '+/- constant'
;      mod_values(2) = '+/- spectrum'
;      mod_values(3) = '+/- image'
;      mod_values(4) = '* constant'
;      mod_values(5) = '* spectrum'
;      mod_values(6) = '* image'
;      mod_values(7) = '/ constant'
;      mod_values(8) = '/ spectrum'
;      mod_values(9) = '/ image'
    WIDGET_CONTROL, stack_analyze_par.mod_list, get_value = proc_list
    mod_command = WIDGET_INFO(stack_analyze_par.mod_list, /droplist_select)
     print, "Process command = ", proc_list(mod_command)
      CASE mod_command of
         '1': BEGIN    ; +/- constant
           const = 0.0
           const=get_num(prompt='constant',val=const, group=stack_analyze_par.main_base)
           image_stack = image_stack + const
        END
        '2': BEGIN   ; +/- spectrum
          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_analyze_par.main_base)
            tmp2=tmp
            tmp2.x = ev
            tmp2.d=fltarr(n_elements(ev))
            tmp2.d = 1
            tmp2.dn = tmp2.d
            tmp3 = ax_mesh(tmp2, tmp, 1, /first)     ; corrected 26-feb-07
            ref_spectrum = weight*tmp.d
            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)
           sub_flag = 1
          endif else  sub_flag = 0
        END
          '3': BEGIN  ; '+/- image
            last_image_ext = '*.axb'
            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_analyze_par.main_base)
                for i = 0, n_elements(ev)-1 do $
                  image_stack(*,*,i) = image_stack(*,*,i) + tmp.d*weight
              endif else axis_log, 'Reference image not same size'
            endif
          END
          '4': BEGIN  ; * constant
            gain = 1.0
            gain=get_num(prompt='multiplier',val=gain, group=stack_analyze_par.main_base)
            image_stack = image_stack * gain
          END
          '5': BEGIN  ; * spectrum
            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
          END
         '6': BEGIN  ; * image
            last_image_ext = '*.axb'
            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_analyze_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)
              endif else axis_log, 'Reference image not same size'
            endif
         END
          '7': BEGIN  ; / constant
            gain = 1.0
            gain=get_num(prompt='divisor',val=gain, group=stack_analyze_par.main_base)
            image_stack = image_stack / gain
          END
          '8': BEGIN  ; / spectrum
            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
        END
        '9': BEGIN  ; / image
            last_image_ext = '*.axb'
            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_analyze_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_analyze_par.disp_max_label, $
                  set_value = strtrim(string(disp_max,format='(f10.2)'),2)
                widget_control, stack_analyze_par.disp_min_label, $
                  set_value = strtrim(string(disp_min,format='(f10.2)'),2)
              endif else axis_log, 'Reference image not same size'
            endif
          END
      ENDCASE

  ;  adjust to new min/max values
      disp_min = min(image_stack, max=disp_max)
      WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
      WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
      stack_analyze_makespectrum
      stack_analyze_plotspectrum,displayed_file_index
      stack_analyze_imgdisp,displayed_file_index
      WIDGET_CONTROL, stack_analyze_par.mod_list, set_droplist_select =0
    END


; (APH 16-feb-06) ------ generate maps = background subtracted images = (I - a*A-b*B)
    stack_analyze_par.map: BEGIN
;  ---- get  info on image numbers (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_analyze_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_analyze_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_analyze_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_analyze_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_analyze_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
;		print, 'CurBuf before change ', CurBuf
		CurBuf = fix(bt(0))
;		print, 'CurBuf after change ', CurBuf
		HANDLE_VALUE, Data(CurBuf), tmp, /set
  		Label(CurBuf) = tmp.dl
		PlotBuf,CurBuf
    END



; (APH 9-Apr-00) ------ subtract stored stack from this stack (to remove background)  ----
    stack_analyze_par.sub_stack: BEGIN
	    tmp = image_stack
		stack_rb		; ----- read in stack from disk
; ---- check if the dimensions are the same - flag if not
		t1 = size(tmp)
		t2 = size(image_stack)
		if t1(1) NE t2(1) OR t1(2) NE t2(2) OR t1(3) NE t2(3) then begin
			if sa_debug EQ 1 then begin
				print, 'existing stack dimensions: ', t1(1), t1(2), t1(3)
				print, 'stored stack dimensions:   ', t2(1), t2(2), t2(3)
			endif
			axis_log, ' stack dimensions incompatible - try stacks~add'
			image_stack = tmp
			return
		endif
	    weight = get_num(Prompt = 'scale for second stack (-1 = add)', val = 1.0, group=AXIS_ID)
        image_stack = tmp - weight*image_stack
	    disp_max = max(image_stack, min = disp_min)
		widget_control, stack_analyze_par.disp_max_label, $
        	set_value = strtrim(string(disp_max,format='(f10.2)'),2)
    	widget_control, stack_analyze_par.disp_min_label, $
        	set_value = strtrim(string(disp_min,format='(f10.2)'),2)
;	adjust to new min/max values
    	disp_min = min(image_stack, max=disp_max)
	 	WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
	 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
        stack_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
    END



; (APH 15-Dec-05) ------ clip all images to user defined limits  ----
    stack_analyze_par.clip_img: BEGIN
    	img_min = min(image_stack,max=img_max)
		low_limit=get_num(prompt='low_limit',val=img_min, group=stack_analyze_par.main_base)
		hi_limit= get_num(prompt= 'hi_limit',val=img_max, group=stack_analyze_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
;	adjust to new min/max values
    	disp_min = min(image_stack, max=disp_max)
	 	WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
	 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
        stack_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
    END

; (APH 16-feb-10) ------ callibrate X,Y axis   ----
    stack_analyze_par.cal_XY: BEGIN
    	x_width_old = x_stop - x_start
		x_width =get_num(prompt='width(X) of image (um)',val=X_width_old, group=stack_analyze_par.main_base)
		x_stop = x_width + x_start
		y_width_old = y_stop - y_start
		y_stop = (x_width/x_width_old)*y_width_old + y_start
; update limits in x, y control boxes
    	disp_xmin = x_start
		disp_xmax = x_stop
		disp_ymin = y_start
		disp_ymax = y_stop
        widget_control, stack_analyze_par.disp_xmax_label, $
                set_value = strtrim(string(x_stop,format='(f10.2)'),2)
        widget_control, stack_analyze_par.disp_ymax_label, $
                set_value = strtrim(string(y_stop,format='(f10.2)'),2)
		stack_analyze_bar
        stack_analyze_imgdisp,displayed_file_index
    END

; (10-apr-04 APH) REMOVE ZEROS  (DEPSIKE)  (17-Sep-07 aph)  ADD remove_hot, remove_cold options
	stack_analyze_par.remove_zeros_label: BEGIN
		htest=dialog_message('Remove hot spots ? ', /question)
		if htest EQ 'Yes' then rh = 1 else rh = 0
		ctest=dialog_message('Remove cold spots ? ', /question)
		if ctest EQ 'Yes' then rc = 1 else rc = 0
		for i = 0, n_elements(ev)-1 do begin
			image_stack(*,*,i) = remove_zeros(image_stack(*,*,i),/silent, remove_hot=rh, remove_cold = rc)
		endfor
;	adjust to new min/max values
    	disp_min = min(image_stack, max=disp_max)
	 	WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
	 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
		stack_analyze_makespectrum
		stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
    END


; (22-apr-11 APH) REMOVE BAD LINES  (for stxm5321)
	stack_analyze_par.remove_badlines_label: BEGIN
	; generate image frame
		t = size(image_stack)
		x = findgen(t(1))
		y = findgen(t(2))
		d = reform(image_stack(*,*,displayed_file_index))
		energy = ev(displayed_file_index)
		tmpx = 'x' & tmpy = 'y'
		tmp = {t:'2d', x:x, y:y, d:d, e: energy, xl:tmpx, yl:tmpy, dl: 'tmp'}
		tmp = remove_lines(tmp)
		if tmp.dl EQ 'tmp RL' then image_stack(*,*,displayed_file_index)=tmp.d
; *************************  23-Apr-11 ****************************
; auto all does not work as regular images get distorted
; for now, just do it image-by-image
; *****************************************************************
;		for each image, apply remove_lines
;		for i = 0, n_elements(ev)-1 do begin
;			print, 'Image ', i,' Energy = ', ev(i)
;			print, '-----------------------------------------'
;			tmp.e = ev(i)
;			tmp.d = reform(image_stack(*,*,i))
;			splot2d, tmp
;			tmp = remove_lines(tmp)
;			if tmp.dl EQ 'tmp RL' then image_stack(*,*,i)=tmp.d		; dl has ' RL' appended if there are changes
;		endfor
;	adjust to new min/max values
    	disp_min = min(image_stack, max=disp_max)
	 	WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
	 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
		stack_analyze_makespectrum
		stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_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_analyze_par.avg_stack: BEGIN
    	tmp = fltarr(n_cols,n_rows,1)
; get current energy limits and associated image indices
	    widget_control, stack_analyze_par.disp_emin_label,$
          get_value = temp_string
        reads,temp_string(0),disp_emin
		widget_control, stack_analyze_par.disp_emax_label,$
          get_value = temp_string1
        reads,temp_string1(0),disp_emax
        num_img = 0
		if sa_debug EQ 1 then $
	        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
				if sa_debug EQ 1 then $
		    		print, num_img, ev(i)
	    	endif
	    endfor
	    t = tmp/num_img
		if sa_debug EQ 1 then $
		    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}
		axis_log, ': Averaged stack from ' + temp_string + ' to ' + temp_string1
; ----- 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
;  -------- save to disk if wished
		file = axb_save(tmp)

    END

; ------- median smooth all images to remove extrema ('salt & pepper' noise)
    stack_analyze_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
    	print, 'stack subjected to median smoothing in the spatial domain'
;	adjust to new min/max values
    	disp_min = min(image_stack, max=disp_max)
	 	WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
	 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
        stack_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
        stack_analyze_imgdisp,displayed_file_index
    END

; ----------------- swap all energies with those in external file: aph 15-jun-03 -------
    stack_analyze_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_analyze_par.filename_ev_msec_list_label, $
 			Set_Value = filename_ev_msec_list
	        stack_analyze_makespectrum
	        stack_analyze_plotspectrum,displayed_file_index
    	    stack_analyze_imgdisp,displayed_file_index
    	    axis_log, 'E scale of stack changed to that of ' + strtrim(tmp.dl)
		endif else begin
			    axis_log,'Not the same number of E-values: no change made."
		   endelse
    END

; ----------------- swap (x,y) values with those in external file: aph 22-Nov-11 -------
    stack_analyze_par.change_xy: BEGIN
		tmp = axb_load(title='file with new X,Y values (same pixelation!)')
		if n_elements(tmp.x) EQ n_cols and n_elements(tmp.y) EQ n_rows then begin
			x_start = tmp.x(0) & x_stop = tmp.x(n_elements(tmp.x)-1)
			y_start = tmp.y(0) & y_stop = tmp.y(n_elements(tmp.y)-1)
        	WIDGET_CONTROL,stack_analyze_par.filename_ev_msec_list_label, $
 			Set_Value = filename_ev_msec_list
	        stack_analyze_makespectrum
	        stack_analyze_plotspectrum,displayed_file_index
    	    stack_analyze_imgdisp,displayed_file_index
    	    axis_log, 'X,Y scale of stack changed to that of ' + strtrim(tmp.dl)
		endif else begin
			    axis_log,'Not the same number of X or Y pixels: no change made."
		   endelse
    END
; ----------------- remove current image from stack: aph 15-jun-03 -------
    stack_analyze_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 ------------------
		displayed_file_index = displayed_file_index + 1
		if displayed_file_index GE n_elements(eV) then $
		    displayed_file_index = displayed_file_index -1
;	adjust to new min/max values
    	disp_min = min(image_stack, max=disp_max)
	 	WIDGET_CONTROL, stack_analyze_par.disp_min_label, set_value=strcompress(string(disp_min))
	 	WIDGET_CONTROL, stack_analyze_par.disp_max_label, set_value=strcompress(string(disp_max))
        stack_analyze_makespectrum
        stack_analyze_plotspectrum,displayed_file_index
	    stack_analyze_imgdisp,displayed_file_index
     	WIDGET_CONTROL,stack_analyze_par.filename_ev_msec_list_label, $
		Set_Value = filename_ev_msec_list
		axis_log, 'removed image at E = ' + strtrim(string(deleted_E,2))
    END

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

 stack_analyze_par.path: BEGIN
       temp_string = ''
        widget_control, stack_analyze_par.filename_path,$
          get_value = temp_string
        on_ioerror, filename_path_oops1
        filepath = strtrim(temp_string(0),2)      ; remove blanks
        test = pickfile2(title='select path', value=filepath, prompt='click on any file in desired folder')
        t =ax_name(test)
        filepath = t(0)
        print, 'changing path to ', filepath
        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))
		if sa_debug EQ 1 then $
			print, 'Path  set to: ', filepath, '.   Next file called: ', filename_header
        filename_path_oops1:
        widget_control, stack_analyze_par.filename_path, $
          set_value = filepath
	END

; -------- APH - added to allow path definition while using STACK_Analyze -----------
 stack_analyze_par.filename_path: BEGIN
        temp_string = ''
        widget_control, stack_analyze_par.filename_path,$
          get_value = temp_string
        on_ioerror, filename_path_oops
        filepath = strtrim(temp_string(0),2)      ; remove blanks
		if sa_debug EQ 1 then $
			print,'pre-filter filepath = ', filepath
        dotpos = strpos(filepath,'.')              ; abort if have dot
        IF (dotpos NE (-1)) THEN begin
        	axis_log,'Path name can not contain a dot or spaces'
        	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))
		if sa_debug EQ 1 then $
			print, 'Path  set to: ', filepath, '.   Next file called: ', filename_header
        filename_path_oops:
        widget_control, stack_analyze_par.filename_path, $
          set_value = filepath
	END

    stack_analyze_par.filename_label: BEGIN
        temp_string = ''
        widget_control, stack_analyze_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_analyze_par.spec_savefile_label, sensitive = 1
            widget_control, stack_analyze_par.stack_savefile_label, sensitive = 1
            widget_control, stack_analyze_par.save_image_label, sensitive = 1
           	widget_control,stack_analyze_par.rotate_label, sensitive = 1
            widget_control, stack_analyze_par.pngimg_savefile_label, sensitive = 1
            widget_control, stack_analyze_par.gifmov_savefile_label, sensitive = 1
            widget_control, stack_analyze_par.roi_savefile_label, sensitive = 1
        ENDIF ELSE BEGIN
            widget_control, stack_analyze_par.spec_savefile_label, sensitive = 0
            widget_control, stack_analyze_par.stack_savefile_label, sensitive = 0
            widget_control,stack_analyze_par.rotate_label, sensitive = 0
            widget_control, stack_analyze_par.save_image_label, sensitive = 0
            widget_control, stack_analyze_par.pngimg_savefile_label, sensitive = 0
            widget_control, stack_analyze_par.gifmov_savefile_label, sensitive = 0
            widget_control, stack_analyze_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_analyze_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))
		if sa_debug EQ 1 then $
			print, 'Next file called: ', filename_header
        filename_label_oops:
        widget_control, stack_analyze_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  ---- last changed: 11-nov-06 (aph)
    stack_analyze_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
	if sa_debug EQ 1 then $
	 print, 'writing ' + strtrim(string(fix(abs(i_stop - i_start))),2) + 'images'
	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, /silent)
		      END
		  'axb': BEGIN
		  		t=ax_name(filename)
		  		filename = t(0) + t(1) + '.axb'
		  		fileshort = t(1) + '.axb'
				file = axb_save(tmp, file=filename, /silent)
		      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
		  		if scale NE 1.0 then axis_log, 'Tif files: scaled by ' + string(scale)
		      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
		if sa_debug EQ 1 then $
	 		print, strtrim(string(i_wr),2) + '    ' + fileshort
	endfor

; --- write filename_header.sl file if more than one image written
	if abs(i_stop - i_start) GT 1 then begin
		filename_sl = strcompress((filename_header+'.sl'),/remove_all)
		t = ax_name(filename_sl) & filename_sl_short = t(1)
		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
		t=ax_name(filename_sl)
		axis_log, 'wrote stack list file: ' + t(1)
	endif
    widget_control,hourglass=0

    END

    stack_analyze_par.rotate_label: BEGIN
; ----------------  Rotate CW  or CCW, as requested (aph, 04-Oct-11)
	test = dialog_message('Rotate CW (yes, No = rotate CCW)', /cancel, /question)
	n_rot = 3
	if test EQ 'Yes' then n_rot = 3
	if test EQ 'No'  then n_rot = 1
	if test EQ 'Cancel' then return

	t = size(image_stack)
	nx = t(1)
	ny = t(2)
	n_E = t(3)
    widget_control,hourglass=1
    tmp_stack = fltarr(ny, nx, n_E)
	for i = 0, n_E-1 do begin
		tmp_stack(*,*,i) = rotate(image_stack(*,*,i), n_rot)
	endfor
	image_stack = tmp_stack
	n_rows = nx
	n_cols = ny

; - save the rotated stack - copy of  stack_analyze_par.stack_savefile_label (aph 04-oct-11)
; --------- consider making it a separate procedure

; ------ if the min / max E's are not at the limits then write out reduced range
		nimg = n_elements(ev)
        if disp_Emin GT ev(0) OR disp_Emax LT ev(nimg-1) then begin
        	t_ind = where(ev GE disp_Emin AND ev LE disp_Emax, count)
        	if count GT 0 then begin	; shrink the stack
        		image_stack = image_stack(*,*, t_ind)
        		ev = ev(t_ind)
        		filename_ev_msec_list = filename_ev_msec_list(t_ind)
        	endif
        endif
        svec = size(image_stack)
        if sa_debug EQ 1 then $
			       print, xpix_shift, ypix_shift
        nx_min = fix(-1*xpix_shift(0))			; (aph 8-may-00 - adjust stack_process_com 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(fix(nx_min)),2) + ')',$
            group = stack_analyze_par.main_base)
        nx_max = get_num(val=nx_max-1, $
        	Prompt='keep columns(x) < (' + strtrim(string(fix(nx_max-1)),2) + ')',$
         	group = stack_analyze_par.main_base)
        ny_min = get_num(val=ny_min, $
        	Prompt='keep rows(y) > (' + strtrim(string(fix(ny_min)),2) + ')',$
        	group = stack_analyze_par.main_base)
        ny_max = get_num(val=ny_max-1, $
        	Prompt='keep rows(y) < (' + strtrim(string(fix(ny_max-1)),2) + ')',$
        	group = stack_analyze_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_analyze_par.main_base,/destroy
    END

    stack_analyze_par.pngimg_savefile_label: BEGIN
        widget_control,hourglass=1
        wset,stack_analyze_par.image_win
        bytimg = tvrd(0,0,n_cols*img_zoom,n_rows*img_zoom+textregion_ypix)
        filename = filename_header+'.png'
        test = findfile(filename)
	  	if test(0) EQ filename then begin
	  		filename = pickfile2(/write, fltr='*.png', LFILE = filename, title = 'Alternate file name')
	  	endif
        write_png,filename,bytimg,r,g,b
        print,'Wrote PNG image file "'+filename+'"'
        widget_control,hourglass=0
    END

    stack_analyze_par.gifmov_savefile_label: BEGIN
        widget_control,hourglass=1
        stack_analyze_gifmovie
        widget_control,hourglass=0
    END

    stack_analyze_par.stack_savefile_label: BEGIN	; APH 22-may-99; 21-jan-05 - shut down once write

        widget_control,hourglass=1

; ------ if the min / max E's are not at the limits then write out reduced range
		nimg = n_elements(ev)
        if disp_Emin GT ev(0) OR disp_Emax LT ev(nimg-1) then begin
        	t_ind = where(ev GE disp_Emin AND ev LE disp_Emax, count)
        	if count GT 0 then begin	; shrink the stack
        		image_stack = image_stack(*,*, t_ind)
        		ev = ev(t_ind)
        		filename_ev_msec_list = filename_ev_msec_list(t_ind)
        	endif
        endif
        svec = size(image_stack)
        if sa_debug EQ 1 then $
			       print, xpix_shift, ypix_shift
        nx_min = fix(-1*xpix_shift(0))			; (aph 8-may-00 - adjust stack_process_com 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(fix(nx_min)),2) + ')',$
            group = stack_analyze_par.main_base)
        nx_max = get_num(val=nx_max-1, $
        	Prompt='keep columns(x) < (' + strtrim(string(fix(nx_max-1)),2) + ')',$
         	group = stack_analyze_par.main_base)
        ny_min = get_num(val=ny_min, $
        	Prompt='keep rows(y) > (' + strtrim(string(fix(ny_min)),2) + ')',$
        	group = stack_analyze_par.main_base)
        ny_max = get_num(val=ny_max-1, $
        	Prompt='keep rows(y) < (' + strtrim(string(fix(ny_max-1)),2) + ')',$
        	group = stack_analyze_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_analyze_par.main_base,/destroy
    END

    stack_analyze_par.roi_savefile_label: BEGIN
        widget_control,hourglass=1
		stack_analyze_writeroi
        widget_control,hourglass=0
    END

    stack_analyze_par.tey_label: BEGIN		; APH 14-may-99; modified to avoid applying both
        if tey_flag EQ 0 then begin			;    ratio and Beers law normalization (19-nov-11)
        	tey_flag = 1
        	widget_control, stack_analyze_par.tey_label, $
          		set_value = 'YIELD'
          	widget_control, stack_analyze_par.i0_norm, sensitive = 0
          	widget_control, stack_analyze_par.OD_tran, set_value = ' '
          	widget_control, stack_analyze_par.convert_t, sensitive = 0
        endif else begin
        	tey_flag = 0
        	widget_control, stack_analyze_par.tey_label, $
          		set_value = 'transmission'
          	widget_control, stack_analyze_par.i0_norm, sensitive = 1
          	widget_control, stack_analyze_par.OD_tran, set_value = 'T(E)'
          	widget_control, stack_analyze_par.convert_t, sensitive = 1
        endelse

    END

    stack_analyze_par.slicer_label: BEGIN
       slicer
    END

    stack_analyze_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_analyze_par.exit_label: BEGIN
;    	loadct,0,/silent
		ax_color
        widget_control,stack_analyze_par.main_base,/destroy
    END
	stack_analyze_par.start_region_analyze: BEGIN
		region_analyze
	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, no_read=no_read, debug = debug, _extra = e
; (20-may-99 aph) - BINARY keyword added to call
; (28-oct-99 aph) - no_align keyword added to call
; (17-sep-08 aph) convert name from stack_analyze to stack_process

@axis_com
@bsif_com
@stack_process_com

COMMON volume_data, image_stack
COMMON pix_shift, xpix_shift, ypix_shift

axis_on = widget_info(/active)	; allows switching get_num groupID

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

rescale_flag = 1          ; set so automatically rescales each image (27-Jan-2010)

IF keyword_set(help) THEN BEGIN
    print,'stack_process,[list_filename,shift_filename, fpath=fpath, binary=binary]'
    print,'              [zoom=integer, text_height=pixels, realign=realign]'
    print,'              [no_align = no_align, debug = debug, help=help]'
    print,'  where'
    print,'        [list_filename]		is an optional list of files'
    print,'        [shift_filename] 	is a MAPPER-type file for pixel shifts'
    print,'        [fpath=fpath] 		is path to data files'
    print,'        [binary=binary] 		read in as *.ncb binary (all images in one file);
    print,'        [zoom = zoom] 		is zoomm factor (integer)'
    print,'        [text_height = #]	is size of text'
    print,'        [realign = realign]	applys shifs then launches stack_align'
    print,'        [no_align = no_align]	go to stack_process directly'
    print,'        [no_read = no_read]  go to stack_process without reading file'
    print,'        [debug = debug] 	extensive printing to track progress'
    print,'        [help = help] 		prints this text'      ;
    return
ENDIF

; --------- (20-Mar-16 aph - set font - an attempt to make Unix version of stack_process prettier
; --------- does not change - the widget generator forces ? or need to do at beginning of aXis2000
; if !version.os_family EQ 'UNIX' then begin
;  BufLblFont = !p.font    ; default for IDL is -1 which means Hershey vector graphics
;  !p.font = 0             ; must set !p.font to 0 to allow set_font to work
;  DEVICE, SET_FONT = '6x9'
; endif

; ---------- initialize variables
IF (n_elements(shift_filename) EQ 0) THEN shift_filename = ''
IF (n_elements(realign) EQ 0) THEN realign = 0
if keyword_set(debug) then sa_debug = 1 else sa_debug = 0

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

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'
    if sa_debug EQ 1 then $
	         print,'ROI filename is now "'+roi_filename+'"'

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 = 1 ; indicates if intensity of each image should be min-maxed

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
  if sa_debug EQ 1 then $
     print, 'Incoming = ', fpath, ' filepath= ',filepath
endif

if keyword_set(no_read) then goto, direct_entry ; skip file read-in and align

    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

IF NOT keyword_set(binary) then begin					; switch out file-list stuff
	stack_readlist, list_filename, filename_list
;	print, filename_list
	n_files = n_elements(filename_list)
	IF (n_files LT 2) THEN BEGIN
	    axis_log,'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_analyze SHOULD be OK !
;
ENDIF

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

if keyword_set(binary) then begin
;	help, image_stack			;degug inability to read stacks
	stack_rb, list_filename
;	help, image_stack			;degug inability to read stacks

	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

if NOT keyword_set(binary) then begin
	if sa_debug EQ 1 then $
	 	print,'Reading in the images'
	WIDGET_CONTROL, /Hourglass

; -- adapt to read a set of *.axb images ------  (24-nov-11  aph)
	t=ax_name(filename_list(0))
	img_type = t(2)
	if img_type NE 'nc' AND img_type NE 'axb' then begin
		axis_log, 'sl file lists image types that cannot be read ' + img_type
		return
	endif
; ------- read in 1 image to establish array sizes
	CASE img_type OF
		'nc': read_stxm,filename_list(0),sd,khz
		'axb': BEGIN
			print, 'reading *.abx file ',filename_list(0)
		    tmp = axb_load(file=filename_list(0), /silent)
		    n_cols = n_elements(tmp.x) & n_rows = n_elements(tmp.y)
		    end
		ENDCASE

	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
		CASE img_type OF
		'nc': BEGIN
		    read_stxm,filename_list(i),sd,khz
		    ev(i) = 12398.52/sd.wavelength
		    image_stack(0:(n_cols-1),0:(n_rows-1),i) = khz
		    dwell = sd.dwell_time
			end
		'axb': BEGIN
			print, 'reading *.abx file ',filename_list(i)
			tmp = axb_load(file=filename_list(i), /silent)
		    ev(i) = tmp.e
		    sd.wavelength = 12398.52/ev(i)
		    n_cols = n_elements(tmp.x) & n_rows = n_elements(tmp.y)
		    x_start = tmp.x(0) & x_stop = tmp.x(n_elements(tmp.x)-1)
		    y_start = tmp.y(0) & y_stop = tmp.y(n_elements(tmp.y)-1)
		    image_stack(0:(n_cols-1),0:(n_rows-1),i) = tmp.d
		    d_pos =  strpos(tmp.xl, 'dwell =')
		    if d_pos GT 0 then begin
		    	t_string = strmid(tmp.xl,d_pos+7)
		    	t = strsplit(t_string, ' ', /extract)
		    	dwell = float(t(0))
		    endif else dwell = 1.
		    sd.dwell_time = dwell
		    end
		ENDCASE
	; 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(dwell,format='(f7.2)'),2)+' msec'
	; APH - end of changes
	ENDFOR
ENDIF

; 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
    	axis_log, '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
		axis_log, '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))
	if sa_debug EQ 1 then $
	 	print, filename_ev_msec_list
	end_ev_sort:

if not keyword_set(no_align) then begin
	if sa_debug EQ 1 then begin
	 	print,'Aligning the images'
		axis_log, 'shift_filename is ' + shift_filename
		axis_log, 'filename_ev_msec_list is ' + filename_ev_msec_list(0)
		axis_log, 'img_zoom is ' + string(img_zoom)
	endif
; 16-Aug-09, aph - VM gets to here then does not enter stack_align
; ---------------------------------------------------------------
; so just do not transfer !!
;	stack_align,filename_ev_msec_list,shift_filename,zoom=img_zoom    ;,realign=realign

; ------------
; SECTION TRANSFERRED FROM STACK_PROCESS
; this is a kluge because VM (post 6.3, post 03-Aug-09 changes)
; refused to transfer from stack_process to stack_align,
; even though all call parameters were OK
; suspect somethig wrong with stack_align - missing or conflicting commons ?
; (aph 17-Aug-09)
; ===================================================================
	IF (NOT keyword_set(realign)) THEN realign = 0
	filename_info_list = filename_ev_msec_list

	shift_file = ''
	have_shift_file = 0
	IF (n_elements(shift_filename) NE 0) THEN BEGIN
	    shift_file = shift_filename
	    IF (strlen(shift_file) NE 0) THEN have_shift_file = 1
	ENDIF

	IF (have_shift_file EQ 1) THEN BEGIN
	    it = findfile(shift_file)
		if sa_debug EQ 1 then $
	 		axis_log, ' found ', it
	    IF ( (strpos(strupcase(it(0)), strupcase(shift_file)) NE (-1)) AND $
	         (realign EQ 0)) THEN BEGIN
; What we want to do is to read in the shifts
; and use them for alignment without recalculating alignment
; read_mapper,shift_file, indices, shifts
; APH  7-Mar-09  zstack_read_mapper,stack_align_filename, indices, shifts, parameters
; USE  zstack_read_mapper instead to make compatible with zimba align
	        zstack_read_mapper,shift_file, indices, shifts, parm
	        n_files = n_elements(image_stack(0,0,*))
	        svec = size(shifts)
	        test1 = 0
	        IF (svec(0) EQ 2) THEN test1 = 1
	        test2 = 0
	        IF (svec(1) EQ 2) THEN test2 = 1
	        test3 = 0
	        IF (svec(2) EQ n_files) THEN test3 = 1
	        test4 = 0
	        IF (n_elements(indices) EQ n_elements(image_stack(0,0,*))) THEN test4 = 1
	        IF ((test1 EQ 1) AND (test2 EQ 1) AND (test3 EQ 1) AND $
	            (test4 EQ 1)) THEN BEGIN
	              	if sa_debug EQ 1 then $
	 					axis_log,'Shifting images to stored shift values'
	            FOR i=0,(n_files-1) DO BEGIN
	                xcenter = shifts(0,i)
	                ycenter = shifts(1,i)
	                IF ((abs(xcenter) GT 0.2) OR (abs(ycenter) GT 0.2)) THEN BEGIN
	                    p = [xcenter,0.,1.,0.]
	                    q = [ycenter,1.,0.,0.]
	                    this_image = image_stack(*,*,i)
	                    missing = total(this_image)/float(n_cols*n_rows)
	                    this_image = poly_2d(this_image,p,q,1,missing=missing)
	                    image_stack(*,*,i) = this_image
	                ENDIF
	            ENDFOR
	            if sa_debug EQ 1 then $
	 				axis_log,'Completed image shifting'
	; ----- aph added 8-may-00
				xpix_shift=fltarr(2) & ypix_shift=fltarr(2)
				t = reform(shifts(0,*))
				xpix_shift(0) = min(t, max = t1)
				xpix_shift(1) = t1
				t = reform(shifts(1,*))
				ypix_shift(0) = min(t, max = t1)
				ypix_shift(1) = t1
				if sa_debug EQ 1 then begin
	 				text =  'Shifted x by ' + string(xpix_shift(0), format='(F6.2)') + ' to '
					text = text +  string(xpix_shift(1), format='(F6.2)')
					axis_log, text
					text =  'Shifted y by ' + string(ypix_shift(1), format='(F6.2)') + ' to '
					text = text +  string(ypix_shift(1), format='(F6.2)')
					axis_log, text
				endif
			ENDIF
		ENDIF
	ENDIF ELSE axis_log, 'Cannot read shift file '
; ------------
; END OF SECTION TRANSFERRED FROM STACK_PROCESS
; ===================================================================
	if sa_debug EQ 1 then axis_log,' .... done'
endif

direct_entry: ; continue here if have all of stack in memory

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

; print, 'screen size is ',  screen_size(0),'  x  ', screen_size(1)
; print, 'image size is ', n_cols, ' x ', n_rows
; establish zoom based on larger of the HORIZONTAL or VERTICAL sizes
estimated_max_zoomH = $
    0.05+float(screen_size(0)-estimated_leftcol_pixels)/float(n_cols)

estimated_max_zoomV = $
    0.05+float(screen_size(1)-200.)/float(n_rows)

; print, 'estimated max zooms (H, V) are ', estimated_max_zoomH, estimated_max_zoomV

estimated_max_zoom= min([estimated_max_zoomV,estimated_max_zoomH])

; adapt to large stacks by using fractional zooms
IF estimated_max_zoom LT 1. then begin
	IF estimated_max_zoom LT 0.25 then estimated_max_zoom = 0.1
	IF estimated_max_zoom GE 0.25 AND estimated_max_zoom LE 0.5 then estimated_max_zoom = 0.25
	IF estimated_max_zoom GE 0.5 then estimated_max_zoom = 0.5
ENDIF

; if > 1, round to appropriate integer
IF estimated_max_zoom GT 1.0 AND estimated_max_zoom LE 2.0 then estimated_max_zoom = fix(1)
if estimated_max_zoom GE 2.0 then estimated_max_zoom = fix(estimated_max_zoom-1)
if estimated_max_zoom GE 4.0 then estimated_max_zoom = fix(estimated_max_zoom-1)
if estimated_max_zoom GT 10. then estimated_max_zoom = 10.

if (estimated_max_zoom - fix(estimated_max_zoom)) EQ 0 $
    then estimated_max_zoom = fix(estimated_max_zoom)
axis_log,'Maximum zoom: '+ strtrim(string(estimated_max_zoom),2)

img_zoom = estimated_max_zoom

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

; 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
;  if img_zoom GT 5 then img_zoom = 5

; ----  CHECK if the above code is used ! ----
; print, 'IMG_ZOOM = ', img_zoom
; confirm choice with user
  if axis_on then begin
    img_zoom = get_num(prompt='suggested zoom',val=img_zoom, group=axis_ID)
  endif else img_zoom = get_num(prompt='suggested zoom',val=img_zoom)
ENDELSE


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

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

IF (n_tags(stack_analyze_par) EQ 0) THEN BEGIN
    stack_analyze_par = $
      { stack_analyze_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)
        mod_list: 0L, $  ; added by aph   (feb16)
        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_constant: 0L, $			; added by aph   (nov-06)
 ;       ratio_spectrum: 0L, $			; added by aph   (jul-05)
 ;       mult_constant: 0L, $			; added by aph   (jan07)
 ;       mult_image: 0L, $				; added by aph   (jan07)
        cal_XY: 0L, $					; added by aph   (feb10)
        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, $
   	    remove_badlines_label: 0L, $	; added by aph   (apr11)
         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)
        rotate_label: 0L, $			    ; added by aph   (oct11)
        roi_savefile_label: 0L, $
        slicer_label: 0L, $
        slicer3_label: 0L, $			; added aby aph (jan02)
        tey_label:  0L, $				; added by aph   (may99)
        change_e:   0L, $
        change_xy:  0L, $				; added by aph   (nov11)
        convert_t:   0L, $				; added by aph   (sep08)
        remove_image:   0L, $
        median_smooth: 0L, $               ; added by aph
        exit_label: 0L, $
        image_win: 0L, $
        image_label: 0L, $
        plot_win: 0L, $
        path: 0L, $						; added by aph (dec-11)
        spectrum_label: 0L, $
        roi_base: 0L, $
        is_i0_roi: 0L, $
        roi_accept_label: 0L, $
        roi_reject_label: 0L, $
        start_region_analyze:0L $     ;add 9 Aug R.C.
      }
ENDIF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
comp_screen_res=GET_SCREEN_SIZE()

IF !version.os_family EQ 'Windows' then begin
	stack_analyze_par.main_base = $
   		widget_base(title='Stack Analyze', /column, /scroll)
ENDIF else begin
	stack_analyze_par.main_base = $
   		widget_base(title='Stack Analyze', /column, /scroll, X_SCROLL_SIZE=comp_screen_res(0)*.80,Y_SCROLL_SIZE=comp_screen_res(1)*.88)
ENDELSE

row1 = widget_base(stack_analyze_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_analyze_par.disp_min_label = $
  widget_text(row,/frame,/editable,xsize=10)
stack_analyze_par.disp_max_label = $
  widget_text(row,/frame,/editable,xsize=10)
row = widget_base(base,/row)
tlabel = widget_label(row,value='Gamma: ')
stack_analyze_par.disp_gamma_label = $
  widget_text(row,/frame,/editable,xsize=10)
stack_analyze_par.xloadct_label = $
  widget_button(row,value='Colors',tooltip='select B-W  to give correct colors to I (green), Io (red)' )
col = widget_base(base,/column)
stack_analyze_par.disp_rescale = $
	widget_button(row,value='Rescale')

; X-scale
row = widget_base(base,/row)
tlabel = widget_label(row,value='X:  min, max:        ')
stack_analyze_par.disp_xmin_label = $
  widget_text(row,/frame,/editable,xsize=10)
stack_analyze_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_analyze_par.disp_ymin_label = $
  widget_text(row,/frame,/editable,xsize=10)
stack_analyze_par.disp_ymax_label = $
  widget_text(row,/frame,/editable,xsize=10)
stack_analyze_par.disp_zoom = $
	widget_button(row,value='Zoom', tooltip='adjust rectangle to same aspect ratio')
stack_analyze_par.disp_reset = $
	widget_button(row,value='Reset')
; Energy scale
row = widget_base(base,/row)
tlabel = widget_label(row,value='E:  min, max:        ')
stack_analyze_par.disp_emin_label = $
  widget_text(row,/frame,/editable,xsize=10)
stack_analyze_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_analyze_par.disp_zmin_label = $
  widget_text(row,/frame,/editable,xsize=14)      ; (20-mar-16 aph) increased 10 -> 14 for Unix
stack_analyze_par.disp_zmax_label = $
  widget_text(row,/frame,/editable,xsize=14)
stack_analyze_par.disp_Ereset = $
	widget_button(row,value='Reset')

;row = widget_base(base,/row)
  movieBtns = ['Play  ', 'Stop  ', 'Pause/Step' ]
  stack_analyze_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
if !version.os_family EQ 'unix' then ev_list_lines = 3
stack_analyze_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_analyze_par.add_all_label = $
  widget_button(row,value='all', tooltip='select all pixels')			; aph (25-may-03)
tlabel = widget_label(row,value=' Add  ')
stack_analyze_par.add_i_roi_label = $
  widget_button(row,value='region')
stack_analyze_par.add_i_pix_label = $
  widget_button(row,value='pixel')
tlabel = widget_label(row,value=' ')
stack_analyze_par.reset_i_label = $
  widget_button(row,value='Reset')
  tlabel = widget_label(row,value='             ')
stack_analyze_par.map = $				; (aph 16-feb-06)
  widget_button(row,value='map', tooltip='compute difference of any TWO (I2-I1) or THREE ([I2 -(I1+I3)/2] images')

row = widget_base(base,/row)
stack_analyze_par.roi_readfile_label = $
  widget_button(row,value='ROI file',tooltip='generate spectrum from a Region Of Interest file')
col = widget_base(base,/column)
stack_analyze_par.roi_filename_label = $
  widget_text(row,/frame,/editable,xsize=12)
tlabel = widget_label(row,value='   ')
stack_analyze_par.remove_zeros_label = $
  widget_button(row,value='despike',tooltip='remove single bad points')
stack_analyze_par.remove_badlines_label = $
  widget_button(row,value='remove bad lines')

row = widget_base(base,/row)
tlabel = widget_label(row,value='I0: ')
stack_analyze_par.i0_readin = $
  widget_button(row,value='file')
tlabel = widget_label(row,value=' Add  ')
stack_analyze_par.add_i0_roi_label = $
  widget_button(row,value='region')
stack_analyze_par.add_i0_pix_label = $
  widget_button(row,value='pixel')
tlabel = widget_label(row,value=' ')
stack_analyze_par.reset_i0_label = $
  widget_button(row,value='Reset')
tlabel = widget_label(row,value='    ')
stack_analyze_par.remove_image = $
    widget_button(row,value='remove image')

; -------- row dealing with data format and interconversion of OD(E) and I(E)
row = widget_base(base,/row)					; (aph 09-apr-00)
col = widget_base(base,/column)
tlabel = widget_label(row,value='T/y= ')
stack_analyze_par.tey_label = $
  widget_button(row,value='transmission', tooltip='click to change data type')
  ; add button to generate OD from current Io (APH 30-jun-98)
tlabel = widget_label(row,value='  ')
stack_analyze_par.i0_norm = $
  widget_button(row,value='  ->OD  ', tooltip='convert transmission images to OD using -ln(I/Io)')
stack_analyze_par.OD_tran = $
  widget_text(row,/frame,xsize=6, value=' T(E)')
; add generation of transmission data from OD data, given Io
stack_analyze_par.convert_t = $
  widget_button(row,value='convert OD -> I-t ', tooltip='convert OD images to transmission using Io from file')

row = widget_base(base,/row)
col = widget_base(base,/column)
stack_analyze_par.avg_stack = $
  widget_button(row,value='avg stack',tooltip='generates average of all images within the selected energy range')		; (aph 27-mar-04)
  tlabel = widget_label(row,value=' ')
  stack_analyze_par.median_smooth = $
  widget_button(row,value='median smooth')		; (aph 27-mar-04)

stack_analyze_par.eV_shift = $
  widget_button(row,value='E_cal')
;  row = widget_base(base,/row)
  stack_analyze_par.change_e = $
    widget_button(row,value='change energies', tooltip='replace existing energy axis with that from a file')
  tlabel = widget_label(row,value='    ')

;stack_analyze_par.gain = $						; (aph 19-feb-05)
;  widget_button(row,value='gain')

mod_values = strarr(10)                ; (aph 13-Feb-16)
mod_values(0) = 'select command'
mod_values(1) = '+/- constant'
mod_values(2) = '+/- spectrum'
mod_values(3) = '+/- image'
mod_values(4) = '* constant'
mod_values(5) = '* spectrum'
mod_values(6) = '* image'
mod_values(7) = '/ constant'
mod_values(8) = '/ spectrum'
mod_values(9) = '/ image'

row = widget_base(base,/row)
stack_analyze_par.mod_list = widget_droplist(row, title='process', value=mod_values)

 ; ---------- change x,y scale
;tlabel = widget_label(row,value='  ')
; stack_analyze_par.sub_stack = $
; widget_button(row,value='stack')
tlabel = widget_label(row,value=' ')
stack_analyze_par.cal_xy = $
  widget_button(row,value='X,Y calibrate',tooltip='modify (x,y) scales by defining a new x-axis width')
stack_analyze_par.change_xy = $
    widget_button(row,value='change X,Y axes', tooltip='replace existing (x,y) axes with those from a file')

; output results ------------------
base = widget_base(col1,/column,/frame)
row = widget_base(base,/row)
; tlabel = widget_label( row, value = 'Path  : ')
stack_analyze_par.path = $
  widget_button(row,value='Path')

stack_analyze_par.filename_path = $
  widget_text(row,/frame,/editable,xsize=30)

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

row = widget_base(base,/row)
stack_analyze_par.spec_savefile_label = $
  widget_button(row,value='Spectrum ".txt"')
stack_analyze_par.roi_savefile_label = $
  widget_button(row,value='Region ".roi"')
stack_analyze_par.save_image_label = $
  widget_button(row,value='Image(s)')
stack_analyze_par.rotate_label = $
  widget_button(row,value=' Rotate 90',tooltip='rotate stack by 90 deg and write out')

row = widget_base(base,/row)
stack_analyze_par.pngimg_savefile_label = $
  widget_button(row,value='Image ".png"')
stack_analyze_par.gifmov_savefile_label = $
  widget_button(row,value='Movie "m.gif"', $
      tooltip='use a movie generator (e.g. Platypus) to make movie from *.gifs (result may be in the aXis2000 source folder)')
stack_analyze_par.stack_savefile_label = $
  widget_button(row,value='Stack ".ncb"',$
      tooltip='write out all images within the present energy range as a binary stack file; (x,y) clip using row & column values')
;ADD AUG 9 R.C.
; row=widget_base(base,/row)
; stack_analyze_par.start_region_analyze= $
; widget_button(row,value='Start Region Analyze')

row = widget_base(col2,/row)
stack_analyze_par.exit_label = $
  widget_button(row,value='Dismiss')	; moved up
stack_analyze_par.slicer_label = $
  widget_button(row,value='IDL Slicer', tooltip='old 3-D viewer')
stack_analyze_par.slicer3_label = $
  widget_button(row,value='IDL Slicer3', tooltip='current 3-D viewer')

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

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

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

;Device, get_screen_size=screen_size
screen_size=get_screen_size()
screen_center = [ screen_size(0) / 2 , screen_size(1) / 2 ]
geom = Widget_Info(stack_analyze_par.main_base, /Geometry)
base_size = [geom.scr_xsize,geom.scr_ysize]
x_base_size = (fix(0.90*screen_size[0]) < base_size[0])
y_base_size = (fix(0.95*screen_size[1]) < base_size[1])
halfsize = [ x_base_size / 2 , y_base_size / 2 ]
widget_control, stack_analyze_par.main_base, $
	XOffset = screen_center[0] - halfsize[0], $
	YOffset = screen_center[1] - halfsize[1], $
	scr_xsize = x_base_size, $
	scr_ysize = y_base_size

widget_control, stack_analyze_par.main_base, /realize

widget_control, stack_analyze_par.roi_filename_label, set_value='.roi'	;  (21-apr-06 aph - allow user to click file)
roi_filename = '.roi'

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

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

widget_control,stack_analyze_par.spectrum_label,get_value=window
stack_analyze_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_analyze_par.disp_min_label, $
    set_value = strtrim(string(disp_min,format='(f10.2)'),2)
widget_control, stack_analyze_par.disp_max_label, $
    set_value = strtrim(string(disp_max,format='(f10.2)'),2)
widget_control, stack_analyze_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_analyze_par.disp_xmin_label, $
    set_value = strtrim(string(disp_xmin,format='(f10.2)'),2)
widget_control, stack_analyze_par.disp_xmax_label, $
    set_value = strtrim(string(disp_xmax,format='(f10.2)'),2)
widget_control, stack_analyze_par.disp_ymin_label, $
    set_value = strtrim(string(disp_ymin,format='(f10.2)'),2)
widget_control, stack_analyze_par.disp_ymax_label, $
    set_value = strtrim(string(disp_ymax,format='(f10.2)'),2)
widget_control, stack_analyze_par.disp_emin_label, $
    set_value = strtrim(string(disp_emin,format='(f10.2)'),2)
widget_control, stack_analyze_par.disp_emax_label, $
    set_value = strtrim(string(disp_emax,format='(f10.2)'),2)
widget_control, stack_analyze_par.disp_zmin_label, $
    set_value = strtrim(string(disp_zmin,format='(f10.2)'),2)
widget_control, stack_analyze_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
rescale_flag = 1

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


stack_analyze_makespectrum
stack_analyze_plotspectrum,displayed_file_index
stack_analyze_imgdisp,displayed_file_index



xmanager, 'stack_analyze', stack_analyze_par.main_base, $
  group_leader = stack_analyze_par.main_base

widget_control, stack_analyze_par.main_base  ;, /show

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

return
end
