; Copyright (c) 1998-2011 A.P. Hitchcock  All rights reserved
;+
;NAME:
;  STACK_RB
;
;LAST CHANGED: ----------------------------------- 24-Nov-11
;
; PURPOSE:
;	This procedure reads in a whole stack (3d (E,x,y) array) from binary
; places data into image_stack (Common volume_data)
; Re-Scales data to restore a factor used to avoind integer loss of detail
;
; CATEGORY:
;	stack processing; stand alone operation
;
; CALLING SEQUENCE:
;	STACK_RB, FILE
;
; INPUTS:
; 	FILE	name of the output file
;
; KEYWORDS: none
;
; OUTPUTS: 	none
;
; COMMON BLOCKS:
; AXIS_COM	standard set of common blocks
; stack_process_com
; BSIF_com
; volume_data, image_stack
;
; RESTRICTIONS: none
;
; MODIFICATION HISTORY:
; (22-may-99 aph) first version
; (08-jun-99 aph) add group ID to get_num calls
; (06-jul-99 aph) free_lun !; reverses image_stack for -ve axes
; (27-oct-99 aph) print scale factor; preserve (x,y) axes
; (28-feb-02 aph) AXIS standard header added
; (02-may-04 aph) error recovery if file name error; fix header
; (19-feb-05 aph) close *.dat file to release it !
; (10-nov-06 aph) use axis_log
; (25-dec-07 aph) correct header
; (17-Sep-08 aph) replace analcom with stack_process_com
; (27-Jan-10 aph) generate filenae_list from filename_ev__msec_list
;                 since it is used by stack_append
; (20-Feb-10 aph) adapt to reading in reals
; (02-Feb-11 aph) corrected no-read - if scale = 1.0 never loaded image_stack !
; (24-Nov-11 aph) increased size of field to display stack size
;-

PRO stack_rb, file, nof=nof, _extra_e
@axis_com
@stack_process_com
@bsif_com

COMMON volume_data, image_stack

on_error,2

if n_elements(file) eq 0 then begin
	fltr='*.ncb'
	if keyword_set(nof) then fltr='*'
	file = pickfile2(/READ, FILTER=fltr, /LPATH, DEFPATH=defpath)
ENDIF

if strlen(file) GT 0 THEN BEGIN  ; bail-out if no filename

; ----------------------- Establish image stack paramaters
	e_read = 0
	t = ax_name(file)
	fileshort = t(1)
	E_file = t(0)+t(1) + '.dat'

; ---------- read in paramaters from E_file
;	init_sd,sd
	on_ioerror, e_file_error
	openr, iunit, E_file, /get_lun
	axis_log, 'Reading stack: ' + fileshort
	readf, iunit, n_cols, n_rows, scale
	if scale LT 0 then axis_log, 'Stack data is stored as REALS'
	axis_log, string(format='("size: ", i4," x ",i4," pixels")',n_cols,n_rows)
	readf, iunit, x_start, x_stop
	readf, iunit, y_start, y_stop
	axis_log, string(format='("X (um):  ",f7.3,"  to  ",f7.3)',x_start, x_stop)
	axis_log, string(format='("Y (um):  ",f7.3,"  to  ",f7.3)',y_start, y_stop)
	readf, iunit, n_energies
	axis_log, ' #  images = ' + strtrim(string(fix(n_energies)),2)
	ev = fltarr(n_energies)
	dwell = fltarr(n_energies)
	filename_ev_msec_list = strarr(n_energies)
	readf,iunit, ev
	axis_log, string(format='("E (eV):  ",f7.2,"  to  ",f7.2)', min(ev), max(ev))
	readf,iunit, filename_ev_msec_list
	filename_list = strarr(n_energies)
	for i = 0, n_energies - 1 do begin			; add 27-jan-10 to fix stack_append problem
;		print, filename_ev_msec_list(i)
		n_bl = strpos(filename_ev_msec_list(i),' ')
		filename_list(i)= strmid(filename_ev_msec_list(i),0,n_bl)
;		print, filename_list(i)
	endfor
	e_read = 1
	close, iunit & free_lun, iunit
	goto, skip_e_file_error

	e_file_error:
	svec = size(iunit)
	if (svec(0) EQ 0) THEN begin
		axis_log,'Error on reading binary stack file - check names & existence (*.dat, *.ncb)'
		return
	endif else begin
		close, iunit & free_lun, iunit
; get dimensions of array if not specified in call or if not provided from E_file
		IF e_read NE 1 then begin
			n_cols = get_num(Prompt = '#_x-pixels', Val=n_cols, group=axis_id)
			n_rows = get_num(Prompt = '#_y-pixels', Val=n_rows, group=axis_id)
			x_start = get_num(Prompt = 'x_start', Val= x_start, group=axis_id)
			x_stop = get_num(Prompt = 'x_stop', Val=x_stop, group=axis_id)
			y_start = get_num(Prompt = 'y_start', Val= y_start, group=axis_id)
			y_stop = get_num(Prompt = 'y_step', Val=y_stop, group=axis_id)
			n_energies = get_num(Prompt = '# of E', Val=n_energies, group=axis_id)
		ENDIF
	endelse

skip_e_file_error:
  if scale LT 0 then big_array = fltarr(n_cols, n_rows, n_energies) $
    else	big_array = intarr(n_cols, n_rows, n_energies)
	on_ioerror, error
	widget_control, /Hourglass
	openu, iunit, file, /get_lun
	readu, iunit, big_array
	close, iunit & free_lun, iunit
	if scale GT 0 AND scale NE 1 then begin
    image_stack = float(big_array)/scale
	  print, strtrim(string(format='("data rescaled by ",g13.6)', 1./scale),2)
  endif else image_stack = float(big_array)
; (29-jan-11 aph) forgot to add ELSE term in Feb 2010 !
; so from Feb10 to Feb11 versions would not read stacks if  the integer rescale was used
; 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
; ------- check if not square pixels - first do this in read_sdf

	return
ENDIF
error:
	axis_log, 'STACK_RB: Size info disagrees with data dimensions in ' + fileshort
	close, iunit & free_lun, iunit
	return
END
