; Copyright (c) 1998-2016 A.P. Hitchcock  All rights reserved
;+
;NAME:
;		SPC_LOAD.PRO
;
;LAST CHANGED: ----------------------------------- 20-Apr-16 (aph)
;
; PURPOSE:
;   This function reads a variety of ascii-format files
;  spectra (and ascii images) from AXIS2000
;  (x,y) single spectra data file; and multi-column
;   smart read-in - uses first line to determine type
;
; CATEGORY:
;	utility; stand-alone or used through axis2000
;
; CALLING SEQUENCE:
; for functions:a
;	Result = spc_load (file=file, filter=filter, xcol=xcol, ycol=ycol, print = print, $
;         multi=multi, skip=skip, int_factor=int_factor, title=title, typ=typ, NOF=nof, _extra=e)
;
; INPUTS: only by keyword
;
; KEYWORDS:
; FILE		filename
; FILTER  	filter extension
; TITLE		optional title on filename dialog
; XCOL		number of x-axis (if multi-column)
; YCOL		number of y-axis (if multi-column)
; SKIP		number of header lines to skip  (if multi-column)
; MULTI		returns number of columns -1 = number of spectra
; PRINT     if set, print
; TYP		type of file ('UN','MC', '1d', '2d') - use to select for multicolumn file
;           AND also for type of data file ('mca' (Amptek), 'msa' (Oxford)
; NOF		no filter (*.*)
; _EXTRA	pass through keywords
;
; OUTPUTS:
;	Result is the (e,d) 1-d spectral or I(x,y) 2-d image array
;
; COMMON BLOCKS:
;	AXIS_COM	standard set of common blocks
;
; MODIFICATION HISTORY:
; (08-may-02 aph) AXIS standard header added
; ( 9-aug-97 aph) broke out of spectral; TYPE defined
; (21-jan-98 aph) added s.dn component to 1d structure to be axis-compatible
; (20-feb-98 aph) set-up to read 2-col only data
; ( 6-mar-98 aph) read *.txt - 2 column ascii files
; ( 7-jun-98 aph) corrected read *.txt ('un' case) to get all data points
; (10-jul-98 aph) retired "*.spc" nomenclature - use *.txt extension
; (24-may-99 aph) accomodate non-AXIS files with multi-line headers
; ( 8-Jun-99 aph) remove tag line; adapt for group in get_num
; ( 9-jun-99 aph) fix up ascii image read in error
; (11-jun-99 aph) fix up widget_info error
; (25-jun-99 aph) strip path fromfile name
; ( 6-jul-99 aph) FREE_LUN as well as close !
; ( 9-sep-99 aph) silent read-in if filename is supplied
; (08-may-02 aph) explicit definition of columns in multicolumn; standard header
; (14-may-02 aph) reverse order spectra
; (30-Oct-02 aph) adapt for Sphinx spectra
; (12-Feb-03 aph) correct Sphinx.multi to handle single spectrum
; (13-Feb-03 aph) introduce TYP keyword to read in multi-column files  explicitly
; (15-aug-04 aph) explicitly define X-label for 1d data to get around problem
;                 when reading non-monotonic data
; (21-mar-05 aph) add integer factor keyword to allow read-in of non-integer ascii images
; (16-Jun-05 aph) correct multi-column read-in - was missing last point ! - argh !! correction wrong
;                 convert print to axis_log
; (15-feb-10 aph) read in EMSA/MSA spectral files (1-column); Amptek (*.mca), XGLabs (*.dta)
; (10-Apr-10 aph) deal with situation when Amptek *.mca file does not have calibration info
; (22-Nov-12 aph) implement multi-column, read all columns
; (25-Nov-12 aph) handle cases where file does not exist better
; (21-Jul-14 aph) corrected header
; (24-Jul-14 aph) desensitize to end of file not being a blank line
; (19-Apr-16 aph) fix '2D' ascii read-in to match format written by spc_save
; (20-Apr-16 aph) add nx for regular read-in (fix 1 thing and break another!)
;-

Function spc_load,  file=file, filter=filter, title=title, xcol=xcol, ycol=ycol, $
           skip=skip, NOF=nof, int_factor=int_factor,print = print, typ = typ, multi=multi, _extra=e
@axis_com
on_error,2

fltr='*.txt'
if keyword_set(nof) then fltr='*'
if keyword_set(typ) then begin
	if typ EQ 'msa' then fltr='*.msa'
	if typ EQ 'mca' then fltr='*.mca'
	if typ EQ 'dta' then fltr='*.dta'
endif
if keyword_set(filter) then fltr=filter
if not keyword_set(file) then file = pickfile2(/READ, FILTER=fltr, /LPATH, DEFPATH=defpath, TITLE = TITLE)
; print, 'File to open is ', file
if strlen(file) GT 0 THEN BEGIN  ; bail-out if no filename
	openr, iunit, file, /get_lun, error=err
	if (err NE 0) then begin
		file = pickfile2(/READ, FILTER=fltr, /LPATH, DEFPATH=defpath)
		openr, iunit, file, /get_lun
	endif
	if keyword_set(typ) then goto, continue
	typ = 'un'
	on_ioerror, continue
	readf, iunit, typ
	loc=strpos(typ,'% ')
	if loc GE 0 then begin
	    typ = strmid(typ,2,2)     ; remove '% ' TEXT LABEL identifier
	endif else begin
;		print, 'not an AXIS standard file'
	    typ='un' & goto, continue
	endelse
	header = ''
	readf, iunit, header
	loc=strpos(header,'% ')
	if loc GE 0 then header = strmid(header,2,strlen(header)-2)
	print, 'Reading from file ', file
	print, 'header is         ', header
	continue:
	print, 'File type is ', typ
	on_ioerror, finish

	CASE strcompress(strlowcase(typ)) OF

; read in unknown file type using best guess procedures
; -----------------------------------------------------
	'un' : begin       ; UNknown file type - assume Ban output - (x,y) pairs only
		close, iunit  & free_lun, iunit   ; close & re-open to position at top
		if keyword_set(skip) then begin   ; advance in file to start of multi-column
			print, 'skipping rows ', skip
			openr, iunit, file, /get_lun
			s=''
			for i = 0, skip-1 do begin
				readf,iunit,s
				if keyword_set(print) then print, s
			endfor
			while not eof(iunit) do begin
			     readf,iunit,s
			     fa=parsestring(s) & sfa=size(fa)
			     if keyword_set(print) and sfa(0) EQ 0 then print, s
			     if sfa(0) gt 0 then begin
			        ;line contains numbers
					nrows=6000
			        ans=fltarr(sfa(1), nrows)
			        ans(*,0)=fa
			        j=long(1)
			        while not eof(iunit) do begin
			           ;if j/100 eq j/100. then print,j
			           readf,iunit,fa
			           ans(*,j)=fa
			           j=j+1
			        endwhile
			     endif
	   		endwhile
	   		close,iunit
	   		free_lun,iunit
	   		a = ans
		endif else begin
; check for one or multi column files
			a = text_read1(file)   ; , /print)
		endelse
		a_siz = size(a) & nc=a_siz(1)
		np= a_siz(2)
		if keyword_Set(multi) then begin
			s = nc-1
			return, s
		endif
		if nc gt 2 then begin
			if keyword_Set(xcol) and keyword_Set(ycol) then begin
				if keyword_set(skip) then first_row = skip-1 else first_row = 0
				tmp = a
				a = fltarr(2,np-first_row)
				a(0,*) = tmp(xcol-1,first_row:np-1)
				a(1,*) = tmp(ycol-1,first_row:np-1)
				np = np-first_row
			endif else begin
				t = 0 & i = -1
				while t EQ 0 do begin
					i = i +1
					text = ''
					for j = 0, nc-1 do text = text + ' ' + string(a(j,i))
					axis_log, text
					text = 'Select: 0 to skip line, 1 to define columns'
					axis_log, text
					wid_exist = WIDGET_INFO(/active)
					if wid_exist EQ 1 then begin
;						WIDGET_CONTROL, Uprompt, SET_VALUE=text
						 t=get_num(Prompt='action',Val=1, group = axis_id)
					endif else t=get_num(Prompt='action',Val=1)
				endwhile
				AXIS_LOG, 'Select columns for x, y'
				if wid_exist EQ 1 then begin
					cx=get_num(Prompt='x-col',Val=1, group = axis_id)
					cy=get_num(Prompt='y-col',Val=2, group = axis_id)
				endif else begin
					cx=get_num(Prompt='x-col',Val=1)
					cy=get_num(Prompt='y-col',Val=2)
				endelse
				tmp = a
				a = fltarr(2,np-i)
				a(0,*) = tmp(cx-1,i:np-1)
				a(1,*) = tmp(cy-1,i:np-1)
				np = np - i
			endelse
		endif
		if nc eq 1 then begin
			tmp = a
			x = findgen(np)
			a = fltarr(2,np)
			a(0,*) = x  & a(1,*) = tmp(0,*)
		endif
		name_bits = ax_name(file)
		x = reform(a(0,*))
		d = reform(a(1,*))
; check if in reverse order - if so, reverse
		if x(1) LT x(0) then begin
			x = reverse(x)
			d = reverse(d)
		endif
		nx = np		; (160420 aph - added for a tag line at end)
		s={t:'1d', d:d, x: x, xl: '', dn: reform(a(1,*)), dl: name_bits(1)}
        axis_log, strtrim(string(np),2) + ' pointspectrum read from file: ' + file
	 end

;read in EMSA/MAS spectral file
; -----------------------
; start of data is marked by #SPECTRUM;  end by: #ENDOFDATA
	'msa' : begin
		close, iunit  & free_lun, iunit   ; close & re-open to position at top
		openr, iunit, file, /get_lun
		test = '#'        & text = ' '
		xl = '' &  yl = '' & title = '' & num_cols = 1
		n_header_lines  = 0
		while test EQ '#' do begin		; get useful header information
			readf, iunit, text
			n_header_lines  = n_header_lines +1
;			print, text
			test = strmid(text,0,1)
			len = strpos(text, ':')
			par_label = strcompress(strmid(text,1,len-1), /remove_all)
			CASE par_label OF
				'NPOINTS' : npts = fix(strmid(text,len+1))
				'TITLE' : title = strmid(text,len+1)
				'XUNITS' : xl = strmid(text,len+1)
				'YUNITS' : yl = strmid(text,len+1)
				'OFFSET' : xmin = strmid(text,len+1)
				'BEAMKV' : beamkv = strmid(text,len+1)
				'LIVETIME' : dwell = strmid(text,len+1)
				'NCOLUMNS' :begin
					num_cols = strmid(text,len+1)
					num_cols = fix(num_cols)
	;				print, 'number of columns = ', num_cols
					if num_cols NE 1 then begin
						axis_log, 'This routine can only read 1-column EMSA/MAS data. This file has ' + num_cols + ' columns'
						return, num_cols
					endif
				  end
				ELSE : GOTO, header_continue
			ENDCASE
			header_continue:
		endwhile
; -------- position at start of data
		close, iunit  & free_lun, iunit   ; close & re-open to position at top
		openr, iunit, file, /get_lun
		skip_lun, iunit, n_header_lines-1, /lines

; ------------ develop later for multi-column data (comma separated)  aph 12-feb-10
;		x =fltarr(npts) & y = fltarr(num_cols,npts)
;		for i = 0, npts-1 do begin
;			readf, iunit, x(i),(y(j,i),j=0,num_cols-1)
;		endfor

; -------- one column data read-in
;		print, 'number of points ', npts
		x =fltarr(npts) & y = fltarr(npts)
		line = ''
		for i = 0, npts-1 do begin
			readf, iunit, line
;			print, line
			reads, line, xt, yt
			x(i) = xt &  y(i) = yt
		endfor
		if n_elements(dwell) GT 0 then xl = xl + '   dwell= ' + string(dwell, format='(F8.2)') + ' s'
		if n_elements(beamkv) GT 0 then yl = yl + '  beam E= ' + string(beamkV, format='(F4.1)') + ' kV'
		t = ax_name(file)
		s={t:'1d', d:y, x: x, xl: xl,  yl: yl, dn: y, dl: t(1) + ' ' + title}
        axis_log, strtrim(string(npts),2) + ' point  EMSA/MAS spectrum read from file: ' + t(1)
		close, iunit  & free_lun, iunit
	end


;read in Amptek spectral file
; -----------------------
; 1-column XRF spectrum with optional calibration information
; <<CALIBRATION>>
; LABEL - Channel
; 100 525
; 266 1485
; start of data is marked by <<DATA>>  end by: <<END>> has lots of parameters AFTER
	'mca' : begin
		close, iunit  & free_lun, iunit   ; close & re-open to position at top
		openr, iunit, file, /get_lun
		test = -1  & text = ''
		while test LT 0 do begin	; skip  to live_time
			readf, iunit, text
			test = strpos(text,'LIVE_TIME')
		endwhile
		len = strpos(text,'- ')
		dwell = float(strcompress(strmid(text,len+2), /remove_all))
		print, 'dwell = ', dwell
		test = -1
		while test LT 0 do begin	; skip  to calibration
			if EOF(iunit) then goto, end_file
			readf, iunit, text
			test = strpos(text,'<<CALIBRATION>>')
		endwhile

; ----------- deal with situation where CALIBRATION has not been set
		end_file:
		if EOF(iunit) then begin
			print, 'Amptek SDD file: no energy calibration info - read as channels'
			c1 = 0. & c2 = 1.
			e1 = 0. & e2 = 1.
			close, iunit  & free_lun, iunit
			openr, iunit, file, /get_lun		; reopen
		endif else begin
			readf, iunit, text		; shoulld be LABEL for x-axis
			print, 'Amptek SDD file: x-axis - calibration info'
			print, text
			readf, iunit, text		; shoulld be (c,e) pair
			reads, text, c1,e1
			print, c1,e1
			readf, iunit, text		; shoulld be (c,e) pair
			reads, text, c2,e2
			print, c2,e2
		endelse
		test = -1
		while test LT 0 do begin	; skip  to Data
			readf, iunit, text
			test = strpos(text,'<<DATA>>')
		endwhile
; ----- now at start of data - begin reading
		xrf = intarr(1)
		npts=0
		while text NE '<<END>>' do begin	;use <<END>> to stop read-in ; nb lots of parameters after
			readf, iunit, text
;			print, text
			if text NE '<<END>>' then begin
				reads, text, yt
				xrf(npts) =  yt
				xrf = [xrf,1]
				npts = npts + 1
			endif
		endwhile
		x = findgen(npts)				; energy is E = int + slope*c
		slope = float(e2-e1)/float(c2-c1)
		int = float(e1) - slope*c1
		x = int + slope*x

		xl = 'X-ray energy (eV)   Dwell (s) = ' +string(dwell, format='(F6.2)')
		yl = ' Amptek XRF signal'
		t = ax_name(file)
		xrf=float(xrf)
		s={t:'1d', d: xrf, x: x, xl: xl,  yl: yl, dn: xrf, dl: t(1)}
        axis_log, strtrim(string(npts),2) + ' point Amptek XRF spectrum read from file: ' + t(1)
		close, iunit  & free_lun, iunit
	end


; read in multi-column file with defined columns and rows to skip
; -----------------------------------------------------------------
    'mc' : begin
		close, iunit  & free_lun, iunit   ; close & re-open to position at top
		openr, iunit, file, /get_lun
		if keyword_set(skip) then first_row = skip-1 else first_row = 0
		for i = 0, first_row do begin
			text = ''
			readf, iunit, text
		endfor
		if not keyword_Set(xcol) then xcol = 1
		if not keyword_Set(ycol) then ycol = 2
		maxcol = max([xcol,ycol])
		tmp = fltarr(maxcol)
		np = 0 & x=fltarr(1) & d=fltarr(1)
		WHILE NOT EOF(iunit) DO BEGIN
		 	readf, iunit, tmp
;		 	print, tmp
		 	x(np) = tmp(xcol-1)
		 	d(np) = tmp(ycol-1)
		 	x = [x,1]	&  d = [d,1]
		 	np = np + 1
		ENDWHILE
		x = x[0:np-2]  ; -------- remove last point
		d = d[0:np-2]

; check if in reverse order - if so, reverse
		if x(1) LT x(0) then begin
			x = reverse(x)
			d = reverse(d)
		endif
		name_bits = ax_name(file)
		s={t:'1d', d:d, x: x, xl: '', dn: d, dl: name_bits(1)}
        axis_log, strtrim(string(np),2) + ' point spectrum read from file: ' + file
        end

	'1d' : begin
;load 1-D structure {d:, x:, xl:, dn:, dl:} from a 2 column text file
		text = ''
		readf, iunit, text
		loc=strpos(text,'% ')
		if loc GE 0 then np = fix(strmid(text,2,strlen(text)-2))else np = fix(text)
		xlbl = 'Energy (eV)'
		readf, iunit, xlbl
		loc=strpos(xlbl,'% ')
		if loc GE 0 then xlbl = strmid(xlbl,2,strlen(xlbl)-2)
		s={t:'1d', d: FLTARR(np), x: FLTARR(np), xl: xlbl, dn:FLTARR(np), dl: header}
		for i = 0, np-1 do begin
			readf, iunit, dx, dy
			s.x(i) = dx & s.d(i) = dy
		endfor
		s.dn = s.d                      ; set dn (OSA normalise signal) identical to data
        axis_log, strtrim(string(np),2) + ' point spectrum read from file: ' + file
	  end

	'2d' : begin
;load 2-D structure {d:, x:, xl:, y:, yl:, d:, dl:} from a 2 column text image file
		close, iunit & free_lun, iunit	; start again !
		openr, iunit, file, /get_lun
		text=''
		readf, iunit, text
		readf, iunit, text
		nx = 1 & ny = 1
		readf, iunit, nx, ny
		nx = abs(nx) & ny = abs(ny)
	    s={t:'2d', d: FLTARR(nx,ny), E: 0, x: FLTARR(nx), y: FLTARR(ny), xl: '', yl: '', dl: header}
		tmp = ''
		readf, iunit, tmp  &  s.xl = tmp
		a = fltarr(nx)
		readf, iunit, a    &  s.x = a
		readf, iunit, tmp  &  s.yl = tmp
		a = fltarr(ny)
		readf, iunit, a    &  s.y = a
; ------ read header
	  	tmp = ' '
	  	readf, iunit, tmp
	  	print, tmp
; ------ read integer factor if keyword_set
		fact = 1.
		if keyword_set(int_factor) then begin
		  	readf, iunit, fact
		  	text = 'Integer data read-in and scaled by ' + string(strtrim(fact,2))
		  	axis_log, text
		endif
		if fact eq 0 then fact = 1  ; to avoid /0 errors
	  	tmp = fltarr(nx)
	  	on_ioerror, end_2d
      	for j = 0, ny-1 do begin
      		readf, iunit, tmp
      		s.d(*,j) = float(tmp)/fact
      	endfor
      	end_2d:
      	print, STRCOMPRESS(STRING(nx)),' x ', STRCOMPRESS(STRING(ny)) ,' Image read from file: ', file

	 end
    else : axis_log, 'Unidentified file type. Read-in aborted'
    endcase
    finish:
	close, iunit & free_lun, iunit
endif else begin 	; go here if user pushes 'cancel'
    axis_log, ' file read aborted'
    s=0
endelse
return, s
end