 ; Copyright (c) 1998-2017 A.P. Hitchcock  All rights reserved
;+
;NAME:
;		WRITE_SDF.PRO
;
;LAST CHANGED: ----------------------------------- 18-Feb-17
;
; PURPOSE:
;	This function writes a self-defining format ascii file
; as used in STXM microscopes using the STXM_control acquisition code.
; This is also used to write VLM images to be read into STXM_control
; AXIS 2d format buffers are written as images
; Axis 1d format buffers are written as NEXAFS point (spectra)
;
; CATEGORY:
;	Input / output utilty; stand alone or from ax_sdf / axis2000
;
; CALLING SEQUENCE:
;	Result = WRITE_SDF(structure,[ file=file, group=group, _extra=e])
;
; INPUTS:
;   STRUCTURE	axis format structure
;
; KEYWORDS:
; 	FILE		optional file name
;	GROUP		group leader (Axis_ID if called from aXis2000 and axis)
;	_EXTRA		other passed through parameters
;
; OUTPUTS:
;	file written to disk
; 1d (spectra) - *.hdr, *.xsp
; 2d (image, linescan) - *.hdr, *.xim
;
; COMMON BLOCKS:
;	STACK_PROCESS_COM  common for stack_process
;	AXIS_COM	standard set of common blocks
;	BSIF_COM	stack common
;
; MODIFICATION HISTORY:
; (18-oct-01 aph) first version
; (02-may-04 aph) add spectrum write-out
; (30-jul-09 aph) changed analcom to stack_process_com (update to stack_process)
; (22-Jul-14 aph) corrected header
; (18-Feb-17 aph) write (x,y) cordinates to 3 decimal places (1 nm)
;-

function write_sdf, structure, file=file,  group=group,  _extra=e
on_error,2
@stack_process_com
@axis_com
@bsif_com

on_error, 2

if NOT keyword_set(group) then group = 0
if n_elements(file) eq 0 then $
   file=PICKFILE2(/Read, FILTER='*.hdr', /LPATH, DEFPATH=defpath)
tmp = ''
if strlen(file) LE 0 THEN return, tmp  ; bail-out if no filename

s = structure
if n_tags(s) EQ 0 THEN return, tmp

IF s.t EQ '2d' then BEGIN
; ------- write out image file -----
	widget_control, /hourglass
; ---- force file name to be *.hdr
	t = ax_name(file)
	tpath = t(0)
	fileshort = t(1)
	file = tpath + fileshort + '.hdr'
	; -------- check if requested file exists; if so launch overwrite dialog
	check_flag = 1
	if widget_info(/active) EQ 1 then begin
		if overwrite_all EQ 1 then check_flag = 0
	endif
	if check_flag EQ 1 then begin
		test = findfile(file)
  		if test(0) EQ file then begin
  			if widget_info(/active) EQ 1 then $
		    	t = file_overwrite(group = axis_ID, val = 1) else $
		    	t = file_overwrite(val = 1)
		    if t EQ 0 then file = pickfile2(/write, fltr='*.axb', $
		                      LFILE = file, title = 'Alternate file name')
		    if t EQ 2 then overwrite_all = 1
		endif
	endif
; ---- force file name to be *.hdr
	t = ax_name(file)
	tpath = t(0)
	fileshort = t(1)
	file = tpath + fileshort + '.hdr'
; ---- write header file
	openw, lun, file, /get_lun
	text1 = 'ScanDefinition = { Label = "'
	text2 = '"; Type = "Image Scan"; Flags = "Image"; Dwell = 2;'
	text = text1 + strtrim(file,2) + text2
	printf, lun, text
	printf, lun, '	Regions = (1,'
	printf, lun, '{'
	text1 = '			PAxis = { Name = "Sample X"; Unit = "um"; Min = '
	text2 = '; Max = '
	text3 = '; Dir = 1;'
	t  = n_elements(s.x) & n_cols = t(0)
	text = text1 + strtrim(string(s.x(0), format='(G13.6)'),2) + text2 $
	       + strtrim(string(s.x(n_cols-1), format='(G13.6)'),2) + text3
	printf, lun, text
; --- output positions of columns (x-axis)
	text1 = '				Points = ('
	text = text1 + strtrim(string(n_cols),2) +','
	for i = 0, n_cols-2 do text = text + string(s.x(i),format='(F9.3,",")')
	text = text + string(s.x(n_cols-1),format='(F8.2)') + ');'
	printf, lun, text
	printf, lun, '};'

	text1 ='			QAxis = { Name = "Sample Y"; Unit = "um"; Min = '
	text2 = '; Max = '
	text3 = '; Dir = 1;'
	t = n_elements(s.y) & n_rows = t(0)
	text = text1 + strtrim(string(s.y(0), format='(G13.6)'),2) + text2 $
	       + strtrim(string(s.y(n_rows-1), format='(G13.6)'),2) + text3
	printf, lun, text
; --- output positions of rows (y-axis)
	text1 = '				Points = ('
	text = text1 + strtrim(string(n_cols),2) +','
	for i = 0, n_rows-2 do text = text + string(s.y(i),format='(F9.3,",")')
	text = text + string(s.y(n_rows-1),format='(F8.2)') + ');'
	printf, lun, text
	printf, lun, '};'
	printf, lun, '});'
	text = '	StackAxis = { Name = "Energy"; Unit = "eV"; Min = '
	etex = strtrim(string(s.e, format='(F8.3)'),2)
	text = text + etex + '; Max = ' + etex + '; Dir = -1;'
	printf, lun, text
	printf, lun, '	Points = (1, ' + etex + ');'
	printf, lun, '};'
	printf, lun, '	Channels = (1,'
	printf, lun, '{ Name = "Counter0"; Unit = "Hz";});'
	printf, lun, '};'
	printf, lun, ' BeamFeedback = false; SampleXFeedback = false; SampleYFeedback = false; SampleZFeedback = false; ShutterAutomatic = false;'
	printf, lun, 'Channels = (1,'
	printf, lun, '{ ID = 0; Type = 0; Name = "Counter0"; Controller = 0; DeviceNumber = 0; UnitName = "Hz"; LinearCoefficient = 1; ConstantCoefficient = 0; ProcessString = "I";});'
	printf, lun, 'ImageScan = { ScanType = "Image (Line - unidirection)"; Stage = "Automatic"; Shutter = "Automatic"; Interferometry = "On"; SingleEnergy = true;'
	printf, lun, '	EnergyRegions = (1,'
	printf, lun, '{ StartEnergy = 286.51; EndEnergy = 321.51; Range = 35; Step = 7; Points = 6; DwellTime = 2;});'
	printf, lun, ' PointDelay = 0.04; LineDelay = 0; AccelDist = 6.48058; MultipleRegions = true;'
	printf, lun, '	SpatialRegions = (1,'
	printf, lun, '{ CentreXPos = -5714.95; CentreYPos = 9.25; XRange = 100; YRange = 100; XStep = 0.5; YStep = 0.5; XPoints = 200; YPoints = 200;});'
	printf, lun, '};'
	close, lun
; ---- write image as ascii file
	dfile = tpath + fileshort + '_a.xim'
	openw, lun, dfile, /get_lun
; scale data if less than 1000 or greater than 1e5
	tmax = max(s.d, min = tmin)
	test = max([abs(tmin), abs(tmax)])
	scale = 1.
	if test GT 3e4 OR test LT 1e3 then  scale = 10.^(3-fix(alog10(test)))
	if scale NE 1 then print, 'Stack write: data values rescaled by ', scale

	for i = 0, n_rows-1 do begin
		text =''
		for j = 0, n_cols-1 do begin
			text = text + string(scale*s.d(j,i), format='(i5)') + '	'
		endfor
		printf, lun, text
	endfor
	close, lun
	print, 'image written as self-defining format file:  ', file
	return, file
ENDIF
;
;  =======================================================
;
IF s.t EQ '1d' then BEGIN
; ------- write out spectrum file -----
; ---- force file name to be *.hdr
	t = ax_name(file)
	tpath = t(0)
	fileshort = t(1)
	file = tpath + fileshort + '.hdr'
; -------- check if requested file exists; if so launch overwrite dialog
	check_flag = 1
	if widget_info(/active) EQ 1 then begin
		if overwrite_all EQ 1 then check_flag = 0
	endif
	if check_flag EQ 1 then begin
		test = findfile(file)
  		if test(0) EQ file then begin
  			if widget_info(/active) EQ 1 then $
		    	t = file_overwrite(group = axis_ID, val = 1) else $
		    	t = file_overwrite(val = 1)
		    if t EQ 0 then file = pickfile2(/write, fltr='*.axb', $
		                      LFILE = file, title = 'Alternate file name')
		    if t EQ 2 then overwrite_all = 1
		endif
	endif
; ---- force file name to be *.hdr
	t = ax_name(file)
	tpath = t(0)
	fileshort = t(1)
	file = tpath + fileshort + '.hdr'
; ---- write header file
	openw, lun, file, /get_lun
	text1 = 'ScanDefinition = { Label = "'
	text2 = '"; Type = "NEXAFS Point Scan"; Flags = "Single-Region Spectra"; ScanType = "Spectra"; Dwell = 1;'
	text = text1 + strtrim(file,2) + text2
	printf, lun, text
	printf, lun, '	Regions = (1,'
	printf, lun, '{'
	text1 = '			PAxis = {  "Energy"; Unit = "eV"; Min = '
	text2 = '; Max = '
	text3 = '; Dir = 1;'
	t  = n_elements(s.x) & n_pts = t(0)
	text = text1 + strtrim(string(s.x(0), format='(G13.6)'),2) + text2 $
	       + strtrim(string(s.x(n_pts-1), format='(G13.6)'),2) + text3
	printf, lun, text
; --- output energies (x-axis)
	text1 = '				Points = ('
	text = text1 + strtrim(string(n_pts),2) +','
	for i = 0, n_pts-2 do text = text + string(s.x(i),format='(F9.3,",")')
	text = text + string(s.x(n_pts-1),format='(F9.3)') + ');'
	printf, lun, text
	printf, lun, '};'

	printf, lun, '	Channels = (1,'
	printf, lun, '{ Name = "Counter0"; Unit = "Hz";});'
	printf, lun, '};'
	printf, lun, ' BeamFeedback = false; SampleXFeedback = false; SampleYFeedback = false; SampleZFeedback = false; ShutterAutomatic = false;'
	printf, lun, 'Channels = (1,'
	printf, lun, '{ ID = 0; Type = 0; Name = "Counter0"; Controller = 0; DeviceNumber = 0; UnitName = "Hz"; LinearCoefficient = 1; ConstantCoefficient = 0; ProcessString = "I";});'
	printf, lun, 'ImageScan = { ScanType = "Image (Line - unidirection)"; Stage = "Automatic"; Shutter = "Automatic"; Interferometry = "On"; SingleEnergy = true;'
	printf, lun, '	EnergyRegions = (1,'
	printf, lun, '{ StartEnergy = 286.51; EndEnergy = 321.51; Range = 35; Step = 7; Points = 6; DwellTime = 1;});'
	printf, lun, ' PointDelay = 0.04; LineDelay = 0; AccelDist = 6.48058; MultipleRegions = true;'
	printf, lun, '	SpatialRegions = (1,'
	printf, lun, '{ CentreXPos = -5714.95; CentreYPos = 9.25; XRange = 100; YRange = 100; XStep = 0.5; YStep = 0.5; XPoints = 200; YPoints = 200;});'
	printf, lun, '};'
	close, lun
; ---- write spectrum as ascii file
	dfile = tpath + fileshort + '_0.xsp'
	openw, lun, dfile, /get_lun
	for i = 0, n_elements(s.x)-1 do begin
		printf, lun, float(s.x(i)),'   ',float(s.d(i))
	endfor
	close, lun
	print, 'spectrum written as self-defining format file:  ', fileshort
	return, file
ENDIF ELSE BEGIN
	print, 'WRITE_SDF: only writes spectra and image data'
	return, tmp
ENDELSE

END


