 ; Copyright (c) 2003-2010 A.P. Hitchcock  All rights reserved
;+
;NAME:
;		READ_LOX
;
;LAST CHANGED: ----------------------------------- 20-Jul-10 (aph)
;
; PURPOSE:
;	This function reads Lox format data files used in CLS CaPeRS PEEM.
; Spectra, images, stacks and linescans have *.lox and a set of associated files
; Image and image sequences are 16-bit TIF format, and can have associated saved signals.
; Spectra are a *#.xsp file for each region (#) containing multi-column spectra.
;
; CATEGORY:
;	Input / output utilty; stand alone or from axis2000
;
; CALLING SEQUENCE:
;	Result = READ_LOX(file=file, filter=filter, channel = channel, region = region, verbose=verbose, $
;             group=group, header_only=header_only, map=map, one_image, _extra=e)
;
; INPUTS:
; 	FILE	optional file name
;
; KEYWORDS:
;	FILE		name of file (if not given, use pickfile2 to obtain filename
;	FILTER	   	user defined filter
;	CHANNEL		preselected data channel
;	MULTI		read all channels
;	REGION		preselected region
;	ALL_REGIONS read in all regions
;	VERBOSE		print out details of parsing structure (testing)
;	GROUP		group leader (Axis_ID if called from aXis2000 and axis)
;	TYPE		 extract and return header contents only
;	MAP			treat NEXAFS Image Scan as a set of 2 images to derive OD difference as a map
;   ONE_IMAGE	if defined, index of image to be read
;	_EXTRA		other passed through parameters
;
; OUTPUTS:
;	structure variable; either 1d (spectra) or 2d (image, linescan) or 3d (stack, as *.ncb)
;
; COMMON BLOCKS:
;	@AXIS_COM	standard set of common blocks
;	@BSIF_COM	stack common
;	VOLUME_DATA	stack data set
;	LOX_COM		common for LOX read in
;	@stack_process_com	common for stack_process ()NB used to be analcom - ONLY CHANGED 29-Jul-09)
;
; MODIFICATION HISTORY:
; (16-Oct-05 aph)  first adapted from read_sdf (Aug-05 version)
;        CAUTION  - previously a procedure with this name (READ_LOX) only read spectra
;				  - that routine was re-named READ_LOX_SPECTRA
;                 - calls from axis_c, tif_convert were changed - other uses may exist !!
; (29-Oct-05 aph) - adapt for stack read in (partial)
; (13-nov-05 aph) - finsih stack read in ; channels, spectrum
; (16-nov-05 aph) - accomodate binning
; (18-mar-06 aph) only print binning of camera in verbose mode; fix channel read in
; (05-jun-06 aph) error of IDL5.2 reading Lox files solved - line 122 - need to use t(0) (SCALAR) not t (ARRAY)
; (13-aug-06 jso) adapt to new format of Lox files
; (07-jan-07 aph) check if DarkImageSubtracted="True", if so, set lox.dark=0
; (15-jan-07 aph) correct stack read to give correct size
; (11-jun-08 aph) fix first image mis-match array dimension problem - KLUGE  on hbin, vbin !!!
; (31-Jul-09 aph) add stack_process_com to see if it solves, ' no eV error ' (since Jun-08)
;                 add sorting data types by ScanType label ('XPS' or 'Energy'-> NEXAFS or SEEM (??) )
;				  include Ring current normalization (switched)
; (03-Aug-09 aph) remove bail on read-error so a Lox structure is passed back
; (20-Jul-10 aph) get lox.energy to read correctly; dark current to subtract correctly 
;-
;
; ======================================================================
;                   READ_LOX
; ======================================================================

function read_lox, file=file, filter=filter, channel=channel, region = region, $
         all_regions = all_regions,  verbose=verbose, group=group, multi=multi, $
         type=type,map=map, one_image = one_image, _extra=e
on_error,2
@axis_com
@bsif_com
@lox_com
@stack_process_com

COMMON volume_data, image_stack

if keyword_set(verbose) then verbose = 1 else verbose = 0
s = 0
; --------- get filename if needed and check it exists
if NOT keyword_set(file) then begin		; get new filename
	Filter = '*.lox'
	file_lox = pickfile2(Title='Select LOX file', /READ, FILTER=filter, /LPATH, DEFPATH=defpath)
	lox = 0		; assume if the filename needs to be read, the content of the lox structure is meaningless
endif else file_lox  = file
if strlen(file_lox(0)) EQ 0 then RETURN, s	;For compatibility with 5.2, explicit dimensioning
t = ax_name(file_lox)
fileshort = t(1)          ; ensure the filename is saved for future use
file_lox  = t(0) + t(1) + '.lox'  ; force extension to *.lox
check = findfile(file_lox)		 ; bail-out if non-existent file
if strlen(check(0)) EQ 0 then begin
	axis_log =  'Cannot find ' + file_lox
	return, s
endif

; ----------------- need a default value for region --------- (17-jun-05 aph)
if n_elements(region) EQ 0 then region = 1
; print, 'Region is ', region

; print, 'Read_lox: aXis_ID, lox_ID ', aXis_ID, lox_ID

axis_on=0
if n_elements(axis_ID) NE 0 then begin
	if axis_ID NE 0 then axis_on=1
endif
 if NOT keyword_set(group) then group = 0
;	if n_elements(lox_ID) NE 0 then begin
;		if lox_ID NE 0 then group = lox_ID
;	endif
;endif
; print, 'axis_on, group, axis_ID, lox_ID', axis_on, group, axis_ID, lox_ID

; the preceding is a kluge !!
; want to make the group be flexible - if just called from ax_sdf widget, group is lox_ID, otherwise
; should be axis_ID.


; -Read in the header information if requested or if not known ---

if n_tags(lox) EQ 0 OR keyword_set(type) then begin
; ------------------ Set up the Lox structure that stores info ---
	Lox = {type: 'null', ScanType: 'null', Tracking: 'false', Voltage: 0., filename: file_lox}
	Lox = create_struct(lox,'PrimaryAxis','null')
	Lox = create_struct(lox,'SecondaryAxis','null')
;	t = findfile(file_lox)
;	if t(0) EQ '' then return, lox
; -----------
;	on_ioerror,nofile

;	print,'Getting parameters from ', file_lox

; ----- Read Lox Header file (*.lox) first line to determine key paramaters
	get_lun,lun
	openr,lun,file_lox
	line = ' '
	readf,lun, line
	close, lun & free_lun, lun
;	print, line				; debug to ensure full file read-in
	test = strpos(line,'type')
	t_begin = strpos(line, '"', test)
	t_end = strpos(line, '"',t_begin+1)
	Lox.type = strmid(line, t_begin+1, t_end-t_begin-1)

; NB early (pre-2007 ???) Lox files only had 'type' on the first line
	test = strpos(line,'ScanType')
	if test GT 0 then begin
		t_begin = strpos(line, '"', test)
		t_end = strpos(line, '"',t_begin+1)
		Lox.ScanType = strmid(line, t_begin+1, t_end-t_begin-1)
		if Lox.ScanType EQ 'Energy' then Lox.ScanType='NEXAFS'
	endif
	test = strpos(line,'TrackingStartVoltage')
	if test GT 0 then begin
		t_begin = strpos(line, '"', test)
		t_end = strpos(line, '"',t_begin+1)
		Lox.tracking = strmid(line, t_begin+1, t_end-t_begin-1)
	endif
	test = strpos(line,'VoltageConstant')
		if test GT 0 then begin
		t_begin = strpos(line, '"', test)
		t_end = strpos(line, '"',t_begin+1)
		Lox.voltage = float(strmid(line, t_begin+1, t_end-t_begin-1))
	endif
; ------------ additional parameters if ScanType = '4D Scan'
	IF Lox.ScanType EQ '4D Scan' then begin
		test = strpos(line,'PrimaryAxis')
			if test GT 0 then begin
			t_begin = strpos(line, '"', test)
			t_end = strpos(line, '"',t_begin+1)
			Lox.PrimaryAxis = strmid(line, t_begin+1, t_end-t_begin-1)
		endif
		test = strpos(line,'SecondaryAxis')
			if test GT 0 then begin
			t_begin = strpos(line, '"', test)
			t_end = strpos(line, '"',t_begin+1)
			Lox.SecondaryAxis = strmid(line, t_begin+1, t_end-t_begin-1)
		endif
	ENDIF

	print, 'Lox file ', fileshort
	print, '     Type: ', Lox.type
	print, '     ScanType: ', Lox.ScanType
	IF Lox.ScanType EQ '4D Scan' then begin
		print, '    	 Primary Axis:   ', Lox.PrimaryAxis
		print, '    	 Secondary Axis: ', Lox.SecondaryAxis
	ENDIF
	print, '     TrackingStartVoltage: ', Lox.Tracking
	print, '     VoltageConstant: ', Lox.Voltage

; ------ get Energy if an image file
	if Lox.type EQ 'image' then begin
		energy = 0.
		get_lun,lun
		openr,lun,file_lox
		while not  eof(lun) do begin
			readf,lun, line
			test = strpos(line,'Energy(eV)')
			if test GE 0 then begin
			   test2 = strpos(line,'"', test)
			   test3 = strpos(line,'"', test2+1)
			   Energy = float(strtrim(strmid(line, test2+1, (test3-test2-1)),2))
				print, 'Energy (eV) = ', energy
			endif
		endwhile
		lox = create_struct(lox,'energy',energy)
		close, lun & free_lun, lun
	endif

; ------- get dwell time if found
	dwell = 1
	get_lun,lun
	openr,lun,file_lox
	while not  eof(lun) do begin
		readf,lun, line
		test = strpos(line,'dwell')
		if test GT 0 then begin
			t_begin = strpos(line, '"', test)
			t_end = strpos(line, '"',t_begin+1)
			dwell = strmid(line, t_begin+1, t_end-t_begin-1)
	;		print, 'dwell (s) = ', dwell
		endif
	endwhile
	lox = create_struct(lox,'dwell',float(dwell))
	close, lun & free_lun, lun

; ------- read RingCurrent if it exists ----------------------
	get_lun,lun
	openr,lun,file_lox
	RingCurrent =0.
	while not  eof(lun) do begin
		readf,lun, line
		test = strpos(line,'RingCurrent')
		if test GE 0 then begin
;			print, 'extracted string is ',  strmid(line, 12)
			RingCurrent = float(strtrim(strmid(line, 12),2))
			goto, RC_continue		; kluge since the XPS file format has RingCurrent TWICE !!
		endif
	endwhile
	RC_continue:
; ---- if does not exist then set to Norm_value
; ------- so even if try to normalize to i-ring (=Norm_value/RingCurrent)
; ------- the result will be no change in values
	print, 'RingCurrent = ', RingCurrent
	if n_elements(RingCurrent) NE 0 then begin
		if RingCurrent EQ 0. then RingCurrent = Norm_value
	endif else RingCurrent = Norm_value
	lox = create_struct(lox,'RingCurrent',RingCurrent)
	close, lun & free_lun, lun

; ------ get CaPeRS dark value - NB as of 12-Nov-05  Camera_dark is not stored in the Lox header
	dark = 0.
	get_lun,lun
	openr,lun,file_lox
	while not  eof(lun) do begin
		readf,lun, line
		test = strpos(line,'Dark')
		if test GT 0 then begin
;			print, line
			t_begin = strpos(line, '"', test)
			t_end = strpos(line, '"',t_begin+1)
			dark = strmid(line, t_begin+1, t_end-t_begin-1)
			axis_log, 'Dark Value = '+ dark
			t_begin = strpos(line, '=', t_end) +1            ; DarkImageSubtracted="True"
			t_end = strpos(line, '"',t_begin+1)
			test_true = strmid(line, t_begin+1, t_end-t_begin-1)
;			print, test_true
			if test_true EQ 'True' then begin
			   dark = 0
			   axis_log, 'Dark current already subtracted'
			endif
		endif
	endwhile
	lox = create_struct(lox,'dark',float(dark))
	close, lun & free_lun, lun

; ------ get Bin values for camera --------------------
	hBin = 2
	vBin = 2
	get_lun,lun
	openr,lun,file_lox
	while not  eof(lun) do begin
		readf,lun, line
		test = strpos(line,'hBin')
		if test GT 0 then begin
			t_begin = strpos(line, '"', test)
			t_end = strpos(line, '"',t_begin+1)
			hBin = strmid(line, t_begin+1, t_end-t_begin-1)
			test = strpos(line,'vBin')
			t_begin = strpos(line, '"', test)
			t_end = strpos(line, '"',t_begin+1)
			vBin = strmid(line, t_begin+1, t_end-t_begin-1)
			if keyword_set(verbose) then axis_log, 'Binning = ' + hBin + ' x ' + vBin
		endif
	endwhile
	lox = create_struct(lox,'Hbin',fix(Hbin))
	lox = create_struct(lox,'Vbin',fix(Vbin))
	close, lun & free_lun, lun

; ------ get FoV if found
	FoV = 100.
	get_lun,lun
	openr,lun,file_lox
	line = ' '
	while not eof(lun) do begin
		readf,lun, line
		test = strpos(line,'CurrentFoV FoV')
		if test GT 0 then begin
			t_begin = strpos(line, '"', test-1)
			t_end = strpos(line, '"',t_begin+1)
			FoV = strmid(line, t_begin+1, t_end-t_begin-1)
;			print, 'FoV (microns) = ', FoV
		endif
	endwhile
	lox = create_struct(lox,'FoV',float(FoV))
	close, lun & free_lun, lun

	if Lox.type NE 'image' then begin
; ------- identify number of signals from the number of columns after <Spectra>
		get_lun,lun
		openr,lun,file_lox
		line = ' '
		Nsignals = 1
		while not  eof(lun) do begin
			readf,lun, line
			test = strpos(line,'<spectra>')
			if test GT 0 then begin
				readf,lun, line
				if keyword_Set(verbose) then print, line
				t=parsestring(line) & nt = size(t)
				Nsignals = fix(nt(1)-1)
			endif
		endwhile
		lox = create_struct(lox,'Nsignals',Nsignals)
		if keyword_Set(verbose) then axis_log, 'There are ' + strtrim(string(lox.Nsignals),2) + ' signals'
		close, lun & free_lun, lun

; ------- Read Lox header file (*.hdr) to get labels of data channels (= the signals stored in spectral part)
		get_lun,lun
		openr,lun,file_lox
		line = ' '
		while not  eof(lun) do begin
			readf,lun, line
			test = strpos(line,'<Signals>')
			if test GT 0 then begin
				readf,lun, line
				if keyword_Set(verbose) then print, line	; echo back the list of labels
				line=strcompress(line)						; remove multiple white spaces
				test = 0
				ch_labels=strarr(Nsignals+1)
				for i = 0, Nsignals do begin  ; NB the first label is the label for the X-axis
					t_begin = test
					t_end = strpos(line, ' ',t_begin+1)
					ch_labels(i) = strmid(line, t_begin, t_end-t_begin)
					if keyword_Set(verbose) then print, 'label ', i, '     ', ch_labels(i)
					test = t_end
				endfor
				lox = create_struct(lox, 'xl', ch_labels(0))
				t = strarr(Nsignals)
				t = ch_labels(1:n_elements(ch_labels)-1)
				lox = create_struct(lox,'labels', t)
			endif
		endwhile
		close, lun & free_lun, lun

; --------- make array of energies in lox structure for use for Lox_image_list
		lox_data = read_lox_spectra(file = lox.filename, /multi, /silent, group = lox_ID)
		lox = create_struct(lox,'image_list', reform(lox_data(0,*)))
	endif

	; ----- set other parameters
	 n_regions = 1
	lox = create_struct(lox,'n_regions', n_regions)		; ignore regions for now
	lox = create_struct(lox,'channel', 1)				; start with first channel as default
	close, lun & free_lun, lun
	close, /all
	on_ioerror,null


; -------- OK let's see what we have for header !!
	if keyword_set(verbose) then help, /struct, lox
	if keyword_set(type) then  return, lox		; got what was requested - do not read data

endif

; *************************************************************************************************
; END read-in of parameters - START - read-in of specific file types
; *************************************************************************************************


; for spectra and stacks (but not image) select a specific channel, if not pre-identified by keyword

; if keyword_set(multi) then print, 'multi keyword is set'

if NOT keyword_set(multi) AND lox.type NE 'image' then begin; for spectra & stacks let user select channel, if not defined
	if NOT keyword_set(channel) then begin
		n_channels = lox.Nsignals
		if n_channels EQ 0 then n_channels = 1
		if keyword_Set(verbose) then axis_log, 'Lox data from '+ fileshort
		if keyword_Set(verbose) then axis_log,  strtrim(string(n_channels),2)+ 'channels'
		channel =  0
		while channel LT 1 OR channel GT n_channels do begin
			if keyword_set(group) then $
			  channel = get_num(prompt='Choose data channel', val=channel, group=group) $
			   else channel = get_num(prompt='Choose data channel', val=channel)
		endwhile
endif
	case channel of
		1 : let = 'a'		; this is a carry over from ax_sdf where letters were used as part
		2 : let = 'b'		; of the filenaming convention to differentiate images from different channels
		3 : let = 'c'
		4 : let = 'd'
		5 : let = 'e'
		6 : let = 'f'
		7 : let = 'g'
		8 : let = 'h'
		9 : let = 'i'
		10 : let = 'j'
		11 : let = 'k'
		12 : let = 'l'
		13 : let = 'm'
		14 : let = 'n'
		15 : let = 'o'
		16 : let = 'p'
		17 : let = 'q'
		18 : let = 'r'
		19 : let = 's'
		20 : let = 't'
		21 : let = 'u'
		22 : let = 'v'
		23 : let = 'w'
		24 : let = 'x'
		25 : let = 'y'
		26 : let = 'z'    ; pronounced 'zee'
	else : print, 'Only set up for 26 channels max'
	endcase
endif

; -------  identify number of regions and allow user to select a region
if  NOT keyword_set(region) then begin
	n_regions = fix(lox.n_regions)
	if n_regions GT 1 and not keyword_set(all_regions) then begin
			if keyword_Set(verbose) then axis_log, strtrim(string(n_regions),2) + ' regions'
		if keyword_set(group) then $
		  region = get_num(prompt='Choose region', val=region, group=group) $
			   else region = get_num(prompt='Choose region', val=region)
	endif else region = 1
endif
region = region - 1

if keyword_set(all_regions) then region = 0
;print, ' Region to be read in is ', fix(region)


; ------- get axes for desired region  - NEEDS TO BE Developed FOR -
;	full image size
;   multiple sub-regions within full image (should be able to re-assemble selection map)


; --------- Read in data according to the type of scan -----

; print, 'reading in region ', string(region+1, format='(I2)'),'.    ', nx, '  x  ', ny, '  points '

TYPE = lox.type
if keyword_set(verbose) then axis_log, 'reading  Lox data file of type ' + type

CASE TYPE of

  'spectra': BEGIN
	test = ''
 	t = ax_name(lox.filename) &	fileshort = t(1)
 	if keyword_set(verbose) then axis_log, 'lox.channel = ' + lox.channel
	if lox.channel EQ 0 then lox_data = read_lox_spectra(file = lox.filename, /multi) $
		else lox_data = read_lox_spectra(file = lox.filename, channel = lox.channel)
	tmp = lox_data
	if n_tags(tmp) NE 0 then begin		; single spectrum was read into axis 1d structure
		if keyword_set(verbose) then help, tmp, /struct
; ------------ Ring current normalization ---------------------
		if norm_flag EQ 1 then begin
			tmp.d=tmp.d*norm_value/lox.RingCurrent
			t=tag_names(tmp)
			if total(strmatch(t,'YL',/fold_case)) GT 0 then $
				tmp.yl = tmp.yl + 'N - ' + strtrim(fix(norm_value),2) + ' mA' $
			  else tmp = create_struct(tmp, 'yl', 'N - ' + strtrim(fix(norm_value),2) + ' mA')
		endif
		if axis_on then begin
			HANDLE_VALUE, Data(Curbuf), tmp, /SET
	 		Plotbuf, CurBuf
		endif
	 	if keyword_set(verbose) then axis_log, 'Lox spectrum read from ' + fileshort
	  	return, tmp

	 endif else begin				; multicolumn data read into an array - need to separate
		if keyword_set(verbose) then help, tmp
		if axis_on EQ 0 then return, tmp   ; bail since rest of this is to put data in axis buffers
		energy = lox_data(0,*)
		npts = n_elements(energy)
		print, 'E-axis', npts, ' points from ', energy(0), ' to ', energy (n_elements(energy)-1), ' eV.'
		d = fltarr(npts)  & i = 0
		dwell_time = lox.dwell
		if dwell_time EQ 0 then dwell_time = 1.
		CurBuf = CurBuf - 1
		n_read = lox.Nsignals
	; ------- read from multi-column data into successive buffers
		for jj = 0, n_read-1 DO BEGIN
			print, 'reading in spectrum of channel ', lox.labels(jj)
			CurBuf = CurBuf + 1 & if CurBuf EQ 9 then CurBuf = 0
			x = energy
			y = lox_data(jj+1,*)   ; region number is column number
			d = {x:x, d:y}
			d = ax_sort_mono(d, /axis)
			energy = d.x  & y = d.d

	; --------------- generate axis 1d structure -----
			xl = string(FORMAT='("Energy(eV)    dwell = ",f7.2," ms")', dwell_time)
			yl = 'Lox: CHANNEL ' + lox.labels(jj) + '.  intensity '
			dl = fileshort
;			if n_regions GT 1 then dl = dl + ' region ' + strtrim(string(region+1),2)
			tmp = {t:'1d', x:energy, d:y, dn:y, xl:xl, yl:yl, dl:dl}
; ------------ Ring current normalization ---------------------
			if norm_flag EQ 1 then begin
				tmp.d=tmp.d*norm_value/lox.RingCurrent
				t=tag_names(tmp)
				if total(strmatch(t,'YL',/fold_case)) GT 0 then $
					tmp.yl = tmp.yl + 'N - ' + strtrim(fix(norm_value),2) + ' mA' $
				  else tmp = create_struct(tmp, 'yl', 'N - ' + strtrim(fix(norm_value),2) + ' mA')
			endif
			npts = n_elements(tmp.x)
			text = string(format='(i4," pts. ",f9.4," to ",f9.4," eV. Dwell= ",f7.2," ms.")', $
			    npts, tmp.x(0), tmp.x(npts-1), dwell_time)
			axis_log, text
			HANDLE_VALUE, Data(Curbuf), tmp, /SET
	 		Plotbuf, CurBuf
		endfor
		return, tmp
	endelse
	END

 'image' : BEGIN
; ----------- read in a single Lox format image ------------------------------------
  	tmp = img_load(file=lox.filename, DEFPATH=defpath, /tif, /lox, /values)
	IF n_tags(tmp) EQ 0 THEN RETURN, 0
	tmp.d = tmp.d - lox.dark		; remove dark value
; ------------ Ring current normalization ---------------------
	if norm_flag EQ 1 then begin
		tmp.d=tmp.d*norm_value/lox.RingCurrent
		t=tag_names(tmp)
		if total(strmatch(t,'YL',/fold_case)) GT 0 then $
			tmp.yl = tmp.yl + 'N - ' + strtrim(fix(norm_value),2) + ' mA' $
		  else tmp = create_struct(tmp, 'yl', 'N - ' + strtrim(fix(norm_value),2) + ' mA')
	endif
	energy = lox.energy
	dwell = lox.dwell
	tmp.xl = string(FORMAT='("x (um)     E = ",f8.3," eV     dwell = ",f7.2," s")', $
  		energy, dwell)
	pix_siz = lox.FoV
	max_x = tmp.x(n_elements(tmp.x)-1)
	tmp.x = tmp.x*(pix_siz/max_X)
	tmp.y = tmp.y*(pix_siz/max_X)
	if energy NE 0 then sd.wavelength = 12398./energy
	sd.dwell_time = dwell
	if axis_on EQ 1 then begin
		HANDLE_VALUE, Data(Curbuf), tmp, /SET
		Label(CurBuf) = tmp.dl
	endif
	return, tmp
  END


 'stack': BEGIN
 ; ---------- read in a Lox STACK (NEXAFS, XPS or SEEM) ---------------------
;		help, one_image
	if keyword_Set(map) then goto, stack_map
	if keyword_Set(one_image) then goto, stack_image
	t = ax_name(lox.filename)
	sourcepath = t(0)
	fileshort = t(1)
	if Lox.ScanType EQ 'Energy' then axis_log, 'Reading in Lox format NEXAFS stack ' + fileshort
	if Lox.ScanType EQ 'XPS'    then axis_log, 'Reading in Lox format XPS stack '    + fileshort
	dwell_time = lox.dwell
	if dwell_time EQ 0 then dwell_time = 1.

; ------------- read in energy from header file -- (DONE LATER) ---------------
	lox_data = read_lox_spectra(file = lox.filename, /multi, silent=1)
	energy = lox_data(0,*)
	npts = n_elements(energy)
	if keyword_set(verbose) then print, 'E-axis', npts, ' points from ', energy(0), ' to ', energy (n_elements(energy)-1), ' eV.'

; ---- if ScanType = XPS, read in the Energy (photon energy) and present E-scale as a BINDING ENERGY
	if Lox.ScanType EQ 'XPS' then begin
		lox = create_struct(lox,'PhotonEnergy', max(energy))	; default to maximum of energies in case of no photon energy
		get_lun,lun
		openr,lun,file_lox
		while not  eof(lun) do begin
			line=' '
			readf,lun, line
			print, line
			test = strpos(line,'Energy')
			if test GE 0 then begin
				PhotonEnergy = float(strmid(line, test+6))
				axis_log, 'Photon Energy (eV) = ' + string(PhotonEnergy, format='(F7.3)')
				Lox.PhotonEnergy=PhotonEnergy
			endif
		endwhile
		close, lun & free_lun, lun
; ask user if they want to convert to KE scale or leave as Start_Voltage scale
		test = dialog_message(/question,'Convert E-scale to Binding Energy (Yes) or lave as Start_voltage (No) ?')
		if test EQ 'Yes' then energy = PhotonEnergy-energy
	endif

; -------- set (x,y) axes for the region to be read in -------
; (individual region axes not developed as of 29-oct-05 - aph)
; - extract all this into a suroutine as used by (image, stack, map, 1-image)
	pix_siz = lox.FoV/1024.


; ------- get image size -------------
	t = findfile(lox.filename)
	if t(0) EQ '' then begin
		axis_log, 'Cannot open Lox header file' + lox.filename
		return, null
	endif
	get_lun,lun
	openr,lun, lox.filename
	width = 1024
	done = 0
	line = ' '
	while not  eof(lun) AND done EQ 0 do begin
		readf,lun, line
		test = strpos(line,'width')
		if test GT 0 then begin
			t_begin = strpos(line, '"', test-1)
			t_end = strpos(line, '"',t_begin+1)
			width = 16*(fix(strmid(line, t_begin+1, t_end-t_begin-1)) + 1)
			done = 1
			axis_log, 'width (pixels) = ' + strtrim(fix(width),2)
		endif
	endwhile
	lox = create_struct(lox,'width',float(width*pix_siz))
	close, lun & free_lun, lun

	get_lun,lun
	openr,lun, lox.filename
	height = 1024
	done = 0
	line = ' '
	while not  eof(lun) AND done EQ 0 do begin
		readf,lun, line
		test = strpos(line,'height')
		if test GT 0 then begin
			t_begin = strpos(line, '"', test-1)
			t_end = strpos(line, '"',t_begin+1)
			height = 16*(fix(strmid(line, t_begin+1, t_end-t_begin-1)) +1)
			done = 1
			axis_log, 'height (pixels) = '+ strtrim(fix(height),2)
		endif
	endwhile
	lox = create_struct(lox,'height',float(height*pix_siz))
	close, lun & free_lun, lun

 ;	if hbin LE 2 thrn  nx = width & ny = height   else $ ; works for 2x2 and 1x1 but not 4x4
 	  nx =width*2/lox.hBin & ny = height*2/lox.vBin  ; works for 2x2 and 4x4

 	x = pix_siz*findgen(nx)*lox.hBin
 	y = pix_siz*findgen(ny)*lox.vBin

	t = ax_name(lox.filename) & sourcepath = t(0) & filebase = t(1)
    widget_control,hourglass=1

; ------- establish list of expected filenames (NB will check if all files really are there)
	filename_list = strarr(npts)
	FOR i= 0, npts-1 DO filename_list(i) = fileshort + '#' + strtrim(string(i+1),2)
; ------- set up arrays for label and data
	filename_ev_msec_list = strarr(npts)
	image_stack = fltarr(nx,ny,npts)
;	print, 'nx, ny, npts ', nx, ny, npts
; ------- read in the successive images of the stack
	n_files = 0
	FOR i_file = 0, npts-1 DO BEGIN
		file_in = sourcepath + filename_list(i_file) + '.tif'
; ----------- check if file exist - if not, assume a part stack
		t = findfile(file_in)
		if t(0) EQ '' then begin
			axis_log, 'Cannot open Lox header file' + file_in
;			return, null
		endif else begin
; ------- add to list of filenames, energies and dwells
			filename_ev_msec_list(i_file) = filename_list(i_file) + ' ' $
			       + strtrim(string(energy(i_file),2)) + '  '  + strtrim(string(lox.dwell),2)
			print, 'adding: ', filename_ev_msec_list(i_file)
			n_files = n_files+1
			axis_log,' Reading ' + filename_list(i_file)
			lox_img = img_load(file=file_in, /tif,  /lox, /values)
; ----- reduce size - NB not available for now (oct-05, aph) ----------
;			t_img = lox_img.d(tif_Region(0):tif_region(1)-1,tif_Region(2):tif_region(3)-1)
;			if  smth EQ 1 then t_img = median(t_img,3)
;			help,lox_img.d, lox.dark
			tmp = lox_img.d - lox.dark
;			help, tmp
;			help, image_stack
			image_stack(*,*,i_file) = reform(tmp)
		endelse
	ENDFOR
;	if n_files LT npts then axis_log, 'Incomplete stack'

; write Lox stack as an aXis2000 binary format stack
    filename = pickfile2(filter = '*.ncb', title = 'binary stack file')
    if strlen(filename) GT 0 then begin
	t = ax_name(filename)
    filename = t(0) + t(1) +'.ncb'
    endif else return, filename
    widget_control,hourglass=1
; define parameters needed for stack write out
	x_start = x(0) & x_stop = x(nx-1)
	y_start = y(0) & y_stop = y(ny-1)
	ev = energy(0:npts-1)

; ---- give user option to reverse energy --------------
;	t_dir = dialog_message(/question,'Scanned high-E to low-E ?')
;	if t_dir EQ 'Yes' then begin
;		ev = reverse(ev)
;		image_stack = reverse(image_stack,3,/overwrite)
;	endif

	; ------------ Ring current normalization ---------------------
	if norm_flag EQ 1 then begin
		image_stack=image_stack*norm_value/lox.RingCurrent
		axis_log, ' Normalized stack to ' + strtrim(fix(norm_value),2) + ' mA'
	endif

	stack_wb, filename
    widget_control,hourglass=0
	return, filename

stack_image:
; ***************************  read-in 1 image  from a stack  *********

;		if keyword_set(all_regions) then begin
;			n_read = n_regions & region = -1
;		endif else begin
;			n_read = 1 & region = region - 1
;		endelse
;		CurBuf = CurBuf - 1
; -------- define image file name
	t = ax_name(file_lox)
	file = t(0) + t(1) + '#' + strtrim(string(one_image),2) + '.tif'
  	tmp = img_load(file=file, DEFPATH=defpath, /tif, /lox, /values)
	IF n_tags(tmp) EQ 0 THEN RETURN, 0
	tmp.d = tmp.d - lox.dark		; remove dark value
	energy = lox.energy
	dwell = lox.dwell
; ------------ Ring current normalization ---------------------
	if norm_flag EQ 1 then begin
		tmp.d=tmp.d*norm_value/lox.RingCurrent
		t=tag_names(tmp)
		if total(strmatch(t,'YL',/fold_case)) GT 0 then $
			tmp.yl = tmp.yl + 'N - ' + strtrim(fix(norm_value),2) + ' mA' $
		  else tmp = create_struct(tmp, 'yl', 'N - ' + strtrim(fix(norm_value),2) + ' mA')
	endif
	tmp.xl = string(FORMAT='("x (um)     E = ",f8.3," eV     dwell = ",f7.2," s")', $
  		energy, dwell)
	pix_siz = lox.FoV
	max_x = tmp.x(n_elements(tmp.x)-1)
	tmp.x = tmp.x*(pix_siz/max_X)
	tmp.y = tmp.y*(pix_siz/max_X)
	if energy NE 0 then sd.wavelength = 12398./energy
	sd.dwell_time = dwell
	if axis_on EQ 1 then begin
		HANDLE_VALUE, Data(Curbuf), tmp, /SET
		Label(CurBuf) = tmp.dl
	endif
	return, tmp


stack_map:
; -------- stub - NOT WRITTEN ----------------
	axis_log, 'stack map for Lox not written'
	return, s
  END

; --------  bailout  if Type not determined  -------------------------
	ELSE: 	axis_log, 'Unknown scan type'
ENDCASE

return, s

nofile:
axis_log, 'Open or read error on ' + file_lox
close,/all
return, s
end

