; Copyright (c) 1998-2001 A.P. Hitchcock  All rights reserved
;+
;NAME:
;	TIF2NCDF
;
;LAST CHANGED: ----------------------------------- 12-may-02
;
; PURPOSE:
;	This procedure converts one or a series of tif-format images
; into netCDF format FILES (nsls 'OLD' *.NC) using tifrd_im.pro
; Works for ALS PEEM-2 (12-bit and 16-bit via rd_peem.pro)
; and SRC Elmitech (De Stasio) 16-bit tif file formats
; optional binning, E-calibrate, dark-correction (using multiple files), gain-correction.
; Area of interest files from PEEM-2 camera can be used to select regions from
; full scale images (not working as of jul-01)
;
; CATEGORY:
;	Image readin
; called from stacks~convert format~TIF to netCDF~1 / many / file
;
; CALLING SEQUENCE:
;	TIF2NCDF [, file, list=list, bin=bin, outlist = outlist, $
;             delE=delE, fltr = fltr, delC=delC]
;
; INPUTS:
; 	FILE	path&name of tif file - optional
;
; KEYWORDS:
;	LIST	name of file with list of set of names of {path&file} (*.lst format)
;	BIN		average pixels in bocks of n (bin = 2 cuts size x4; bin=3 by 9 etc)
;	OUTLIST	name of stack list file (*.sl) to write list of files for later analysis
;	AOI		[x0, y0, x1, y1] defining region of interest
;	delE	shift in energy scale (linear re-calibration)
;	fltr	allow call line selection of filter (default = '*.tif')
;	delC	constant background to apply to all pixels
;
; OUTPUTS:
;	file as path+name+'.nc' written for each input file or list element
;
; COMMON BLOCKS:
;	AXIS_COM	standard set of common blocks
;
; SIDE EFFECTS:
;
; PROCEDURE:
; PEEM-2 and Elmitech formats are differentiated by
; convention in PEEM-2 of including a # to seperate sample name from sequence number
; The image and associated information are put into
; BSIF_COMMON variables:
;   image_data (the array which holds the image - possible several
;		planes deep for I, IO, CLOCK)
;   x_normal, y_normal, rotated, x_title, y_title
;
; MODIFICATION HISTORY:
; (13-May-99 aph) adapted from als2ncdf
; (08-jun-99 aph) add group to get_num calls
; (15-jun-99 aph) generalise to handle lists with no path or defective path
; (17-jul-99 aph) provision for dark count subtraction
; (18-jul-99 aph) improved checking for correct filenames (Get_path modified)
; (26-mar-00 aph) correct read in of ALS PEEM lists
; (24-oct-00 aph) option to use 12-bit or 16-bit PEEM data
; (03-oct-01 aph) allow subtraction of constant if needed (Mephisto PEEM)
; (30-mar-01 aph) set up for Elmitech stacks; bypass filename sorting
;				  default bgnd - 32768; different E read
; (19-apr-01 aph) changed sl format to match zimba (path/names)
; (22-apr-01 aph) AXIS standard header added; force extensions
; (08-may-01 aph) implement dark image for background correction; implement AOI
; (14-jul-01 aph) add option to subtract dark file (or a sum) from each image
; (31-jul-01 aph) add axis keyword to RD_PEEM call and to call to this routine
; (12-may-02 aph) correct invalid name format in header.
;-

pro tif2ncdf, file, list=list, bin=bin, outlist = outlist, $
     delE=delE, fltr = fltr, delC=delC, dark = dark, axis = axis

on_error,2
@axis_com
@bsif_com

; determine if AXIS is running (therefore may have called ax_read_peem)
; either when AXIS parameter in ax_peem_com is set or if any widget active
if keyword_set(axis) then axis_on = 1 else axis_on = widget_info(/active)

if keyword_set(list) then begin
   osname=strupcase(strmid(!version.os,0,3))
   stack_readlist, list, filename_list
endif else begin
	if n_elements(file) eq 0 then begin  ;popup file dialog box
	   if not keyword_set(fltr) then fltr='*.lst'
	   file=PICKFILE2(/Read, FILTER=fltr, /LPATH, DEFPATH=defpath)
	endif
	filename_list=file
endelse

; ----- assign type of data based on the filenames & put names in standard format
; **** ONLY FILENAMES (no path)  & MUST HAVE A # in filename ! *****
	data_from = 'PEEM2'
	if 	strpos(filename_list(0),'#') GT 0 then begin
; -----if ALS files:  sort the names by number between '#' and '.'
		n_files = n_elements(filename_list)
		numbs = intarr(n_files)
		for i = 0, n_files-1 do begin
			t = filename_list(i)
			npos=strpos(t,'#')
			dpos=strpos(t,'.')
			numbs(i) = strmid(t,npos+1,dpos-npos-1)
		endfor
		filename_list = filename_list(sort(numbs))
	ENDIF else data_from = 'Elmitech'
;	print, ' AFTER SORTING', filename_list

; -------------- check back for user to see if filename list is valid---------
	t = ax_name(filename_list(0))
	print, 'First file to process is ', t(0) + t(1) + '.' + t(2)

; ------- check that file names are valid - add Data_Path if needed
n_files = n_elements(filename_list)
data_path = get_path(filename_list(0))
if data_path NE '' then begin
	FOR i = 0,n_files-1 DO BEGIN
		t = ax_name(filename_list(i))
		filename_list(i)=Data_Path+t(1)+'.'+t(2)
	ENDFOR
endif else begin
	print, 'Cannot find data files'
	goto, terminate
endelse

if keyword_set(delE) then del_E = float(delE) else del_E=0.

; get Energy values from spectrum file - switch from pem_load to spc_load depending on source
if n_files GT 1 then begin
	WIDGET_CONTROL, Uprompt, Bad_ID = badID, SET_VALUE='Select Energy file'
	if data_from EQ 'Elmitech' then e_tmp = spc_load() $
	  else e_tmp = pem_load()
	E_vals = e_tmp.x4
endif else begin
	if axis_on then E_vals = get_num(Prompt='Energy',Val=E_vals, group = axis_id) $
		else E_vals = get_num(Prompt='Energy',Val=E_vals)
endelse
E_vals = E_vals + del_E(0)

; ------- calibrate image size -------
	if axis_on then $
	pix_siz = get_num(Prompt = 'Image size calibration  (um / pixel)', Val = pix_siz, group = axis_id) $
		else pix_siz = get_num(Prompt = 'Image size calibration  (um / pixel)', Val = pix_siz)

; determine type of data -----------------------------
if axis_on then bits12 = get_num(Prompt='1 = 12-bit; 0 = 16-bit data',Val=1, group = axis_id) $
		else bits12 = get_num(Prompt='1 = 12-bit; 0 = 16-bit data',Val=1)

; --------  select a sub-region ----------
WIDGET_CONTROL,UPrompt, Bad_ID = badID, SET_VALUE='Define sub-region'
; region = pix_siz*[0,1023,0,1023]
; load from common values
region = fltarr(4)
if cll(0) NE 0 then region(0) = cll(0) else region(0) = 0
if cur(0) NE 0 then region(1) = cur(0) else region(1) = 1024*pix_siz
if cll(1) NE 0 then region(2) = cll(1) else region(2) = 0
if cur(1) NE 0 then region(3) = cur(1) else region(3) = 1024*pix_siz
if widget_info(/active) EQ 1 then begin
	region(0) = get_num(Prompt='X_min(um)',Val=region(0), group = axis_id)
	region(1) = get_num(Prompt='X_max(um)',Val=region(1), group = axis_id)
	region(2) = get_num(Prompt='Y_min(um)',Val=region(2), group = axis_id)
	region(3) = get_num(Prompt='Y_max(um)',Val=region(3), group = axis_id)
endif else begin
	region(0) = get_num(Prompt='X_min(um)',Val=region(0))
	region(1) = get_num(Prompt='X_max(um)',Val=region(1))
	region(2) = get_num(Prompt='Y_min(um)',Val=region(2))
	region(3) = get_num(Prompt='Y_max(um)',Val=region(3))
endelse
; -------- save region values for future use
cll(0) = region(0) & cur(0) = region(1)
cll(1) = region(2) & cur(1) = region(3)

; ----------  read-in region.AOI file ----------------------
	text = 'Select Area Of Interest (AOI) file (assume BOX!)'
	print, text
	WIDGET_CONTROL, Uprompt, Bad_ID = badID, SET_VALUE=text
	aoifile = PICKFILE2(/Read, title = text, FILTER='*.aoi')
	if strlen(aoifile) NE 0 then begin
		openr, lun, aoifile, /get_lun
		txt = '' &	aoi = intarr(4)
		readf, lun, txt
		close, lun & free_lun, lun

;		print, 'input to Area of interest = ', txt
		start = strpos(txt,'Box1')
		txt = strmid (txt, start+5)
		reads, txt, aoi
;		print, 'Area of interest = ', aoi
; first version ----
;		space = strpos(txt,' ')
;		aoi_type = strmid(txt,0,space)
;		print, 'Area of interest = ', aoi_type, aoi
;		txt = strmid(txt, space+1)
;		space = strpos(txt,' ') & txt = strmid(txt, space+1)
;		space = strpos(txt,' ') & txt = strmid(txt, space+1)
;		space = strpos(txt,' ') & txt = strmid(txt, space+1)
;		reads, txt, aoi
	endif else aoi = [0,0, 1023,1023]
;	print, 'Size of image region is ', aoi(2)-aoi(0)+1,' x ',aoi(3)-aoi(1)+1

; ----------  set CCD background correction (value or image) -----
if data_from EQ 'Elmitech' then begin
	CCD_bgnd = 32768 		; fixed background subtraction for Elmitech
endif else begin
	text = 'Select CCD background correction file'
	print, text
	WIDGET_CONTROL, Uprompt, Bad_ID = badID, SET_VALUE=text
	background = PICKFILE2(/Read, title = text, FILTER='*.tif')
	if background ne '' then begin
		t = ax_name(background)
		tp = pix_siz
		tb = bits12
		if t(2) EQ 'tif' then $
			t = rd_peem(background, Energy = 300., bits12 = tb, scale=tp, axis = axis_on) $
		  else t = axb_load(background)
		CCD_bgnd = t.d
		dark_multi = Dialog_message(/question, 'Sum multiple files ?')
		if dark_multi EQ 'Yes' then begin
; read in and average multiple dark images
			background_end = PICKFILE2(/Read, FILTER='*.tif', title = 'Last background file')
			t = ax_name(background)  &  pound = strpos(t(1), '#')
			dark_base = t(0) + strmid(t(1),0,pound+1)
			dark_start = fix(strmid(t(1),pound+1,3))
			t = ax_name(background_end) & pound2 = strpos(t(1), '#')
			dark_end =  fix(strmid(t(1),pound2+1,3))
			print, 'dark files: ', dark_base, ' from ', $
			   strtrim (string(dark_start),2), ' to ', strtrim (string(dark_end),2)
			t = moment(CCD_Bgnd) & print, background, ' Mean of background = ', t(0)
			for i_file = dark_start+1, dark_end do begin
				zero = '000'
				t_num = strtrim(strcompress(string(i_file)),2)
				strput, zero, t_num, 3-strlen(t_num)
				file = strlowcase(dark_base + zero) + '.tif'
				t = rd_peem(file, Energy = 300., bits12 = tb, scale=tp, axis = axis_on)
			  	CCD_Bgnd = CCD_Bgnd + t.d
				t = moment(t.d) & print, file, ' Mean of background = ', t(0)
			endfor
			CCD_Bgnd = CCD_Bgnd/(dark_end - dark_start + 1)   ; normalize to number of images
			t = moment(CCD_Bgnd) & print, 'Mean of background = ', t(0)
		endif
	endif else begin
		if axis_on then $
			CCD_bgnd = get_num(Prompt = 'background counts', Val = CCD_bgnd, group = axis_id) $
		    else CCD_bgnd = get_num(Prompt = 'background count', Val = CCD_bgnd)
	endelse
endelse

; ----------  select CCD gain correction file -----
text = 'Select CCD gain correction file ("white")'
print, text
WIDGET_CONTROL, Uprompt, Bad_ID = badID, SET_VALUE=text
white = PICKFILE2(/Read, title = text, FILTER='*.tif')

; ----------- correct to be only Area of Interest if AOI set
; IF keyword_set(aoi) then begin
;	b = white(aoi(0):aoi(2), aoi(1):aoi(3))
;	white = b
; ENDIF

; -------------- allow user to apply a sensible name -----
npos=strpos(filename_list(0),'#')
t = ax_name(filename_list(0))
if npos GT 0 then filebase = strmid(t(1),0,npos-1) else filebase = t(1)
if axis_on then $
	filebase = strtrim(get_text(Prompt='Base name', Val = filebase, group=axis_ID),2) $
	else filebase = strtrim(get_text(Prompt='Base name', Val = filebase),2)
filebase=filebase+'_'
print, 'NEW base name: ',filebase
label(0) = filebase   ; KLUGE - use label(0) to keep name through switches

; ------ ensure binning parameter is set
if not keyword_set(bin) then bin = 1

; ---------- select median smoothing option
text = 'Median smooth ? (0=no, 1=yes)'
print, text
WIDGET_CONTROL, Uprompt, Bad_ID = badID, SET_VALUE=text
if axis_on then $
	smth = get_num(Prompt = text, Val = 1, group = axis_id) $
	else smth = get_num(Prompt = text, Val = 1)

; --------- execute conversion --------------------
FOR i_file = 0,n_files-1 DO BEGIN
	file = filename_list(i_file)
;	print, 'filename to read is . . ', file
	IF strlen(file) GT 0 THEN BEGIN
;		print,' Procesing file ', fix(i_file), '. . . ', file
		   tifrd_im, file, bin=bin, bits12 = bits12, scale=pix_siz, smth=smth, $
		       CCD_bgnd=CCD_bgnd, energy=E_vals(i_file), white=white, region = region
		sd.wavelength = 12398.0/E_vals(i_file)
; ----- historical additional background subtraction - superceded by CCD_bgnd ----
		if keyword_set(delC) then image_data(*,*,0) = image_data(*,*,0) - delC

;		print, Format = '(A, "  E=",F7.3, "(eV).  Dwell=", f4.2 ,"(ms)")', $
;			file, E_vals(i_file), sd.dwell_time
;	    print, 'filename = ', file, '  ext = ', ext

; FORCE 3-character scheme with no blanks !!
		zero = '000'
		t_num = strtrim(strcompress(string(i_file+1)),2)
		strput, zero, t_num, 3-strlen(t_num)
		file = strlowcase(filebase + zero) + '.nc'
		if !VERSION.OS_FAMILY EQ 'unix' then sep = '/' else sep = '\'
		spos=rstrpos(file,sep)
		fileshort = strmid(file,spos+1,strlen(file))
		data_title = byte(fileshort)
		x_title = 'X'
		y_title = 'Y'
		image_title = byte(fileshort)
		sd.clock_frequency = 1.
		file = data_path + file
		wrstx_ax,file
		print,'wrote nsls NetCDF format file: ', file
		text = string(fileshort, E_vals(i_file), format="('TIF_to_netCDF ',/,'file: ',a20,/,'E= ',f8.3)")
		WIDGET_CONTROL,UPrompt, Bad_ID = badID, SET_VALUE=text
	ENDIF
ENDFOR

; -------- WRITE-OUT stack list
if keyword_set(outlist) then begin
	t = ax_name(outlist)
	outlist = t(0) + t(1) + '.sl'
	openw,unitw, outlist,/get_lun
	printf, unitw, strcompress(data_Path)		; write path at top of file
	print, Outlist, ' file opened for stack list'
	for i_file = 0,n_files-1 DO BEGIN
		zero = '000'
		t_num = strtrim(strcompress(string(i_file+1)),2)
		strput, zero, t_num, 3-strlen(t_num)
		file = strlowcase(filebase + zero) + '.nc'
		if !VERSION.OS_FAMILY EQ 'unix' then sep = '/' else sep = '\'
		spos=rstrpos(file,sep)
	 	printf,unitw, strcompress(file)
	endfor
	close, unitw
	text = 'stack_list saved in ' + strcompress(outlist)
	print, text
	WIDGET_CONTROL, Uprompt, Bad_ID = badID, SET_VALUE= text
endif
close,/all		; useful to ensure logical units are available !

; ------- if a single file and AXIS is running, plot the converted result in CurBuf
if NOT keyword_set(list) AND axis_on then begin
	tmp = read_bnl(file)			; BUT only if AXIS is running
	Label(CurBuf) = tmp.dl
	HANDLE_VALUE, Data(CurBuf), tmp, /set
	PlotBuf, CurBuf
endif

terminate:

END

