; Copyright (c) 1998-2022 A.P. Hitchcock  All rights reserved
;+
;NAME:
;	AX_SDF
;
;LAST CHANGED: ----------------------------------- 27-Feb-2022 (aph)
;PURPOSE:
;	This set of procedures is a widget to read in files
; in the ascii self defining format (SDF) developed initally for ALS BL 5.3.2 STXM
; The widget uses read_sdf and parse_sdf to perform the file input.
;
;CATEGORY:
;	AXIS: utility
;
; AX_SDF_EVENT ROUTINES:
; TEXT_SDF_FNAME		modify filename; when changed, execute BUT_SDF_FNAME_BROWSE to get parameters
; BUT_SDF_FNAME_BROWSE 	browse for new filename; if found, load new parameters
; BUT_SDF_DISPLAY_HDR   show parameters
; BUT_SDF_OK			proceed with loading SDF file into AXIS
; BUT_SDF_CANCEL		abort read in
; WID_DLIST_CHANNEL		drop list used to display and select the data channel
; WID_DLIST_REGION		drop list to display and select region
;
;COMMON BLOCKS:
;	@AXIS_COM	standard set of common blocks
;	@SDF_COM 	structure with header info
;
;MODIFICATION HISTORY:
; (25-feb-01 aph) first written using IDL 5.2 GUIBuilder
; (27-jun-01 aph) add groupID for better feedback on reads
; (29-jul-01 aph) add regions selector to the panel; introduced sdf_com; reverted to pickfile2
; (19-aug-01 aph) adapt to regions change & change in structure names; define regions & channels
; (04-nov-01 aph) add sdf_lastfile to sdf_com to save last name
; (09-nov-01 aph) activate all_regions read-in for spectra and images
; (26-nov-01 aph) complete use of name label as a way to select file
; 				  add specific image read-in for stacks - incomplete !!
; (31-dec-01 aph) make defaut width of display parameters = 132
; (17-feb-02 aph) 'motor scan'; single images from sequences
; (11-dec-02 aph) VLM images read-in
; (17-oct-04 aph) separate PATH box; reload last file info  if possible
; (28-oct-04 aph) ensure works if SDF_Path or SDF_lastfile are not defined (at startup)
; (19-feb-05 aph) stack-map, single image read in added
; (12-mar-05 aph) make single image read-in work with IDL5.2
; (17-Jun-05 aph) channels and regions working for map and 1-image read-in
; (13-Nov-05 aph) got rid of last call involving 'group=SDF_ID'
; (22-Mar-06 aph) add Normalize indicator on panel
; (11-mar-07 aph) add normalization control to panel (sets norm_flag)
; (18-May-07 aph) correct read-in of 1-image for multi-channel data (B. Watts)
; (01-Feb-09 aph) add xy_correct option
; (19-Feb-10 aph) correct number of channels in print tag
; (20-Jul-10 aph) replace TEXT_SDF_(CHANNEL, REGION, IMAGE)
;                 with WID_DLIST_(CHANNEL, REGION, IMAGE) (routine name error)
; (20-May-13 bw)  Make string value of the "Image #" selection box longer than zero characters to fix GTK bug
; (19-Dec-13 aph) only display sdf_lastfile if it is a string
; (13-Jan-14 aph) make selector pick last file as default
; (30-Jun-14 aph) make sure that the file refered to in the ax_sdf widget actually exists
;                 in the Apr-14 edition, BROWSE  crashed if there was not a valid path & filename
; (23-Jul-14 aph) put normalization value on widget; adapt to IDL 8.3
;                 start with last file loaded to gui IF ax_sdf used last
; (02-Jul-15 aph) add option to view ring normalization signal; re-arrange widget
;                 change SDF_silent (=1, no traceback) from this widget
; (20-Mar-16 aph) ensure norm_String is defined when normalization is turned off  (found reading aXis_pass_tes_data\read\sdf\linescan)

; (17-May-16 aph) remove auto-start file browsing - gets rid of ax_sdf freezing (cancel not working)
; (19-Feb-17 aph) try again to fix ax_sdf freezing (cancel not working)
; (16-Feb-19 aph) no change; but explored ways to put stacks  called from read_sdf above the main axis window
; (20-Jul-19 aph) 	; change default normalize current to 200, to match CLS
; (27-Feb-22 aph) trying to stop opening a stack when the ax_sdf widget is ended by top rifgt widget 'eXit' button
;                 set sdf to the number 0, not the ' ' string as use type=7
;				to identify when read_sdf returns a stack name not an aXis2000 structure . OK annoying behaviour on cancel' fixed
;			    but still have problem:a hdf5 stucture is returned when ax_sdf widget is ended by top right widget 'eXit' button
;-

pro TEXT_SDF_FNAME, Event
on_error,2
@axis_com
@sdf_com

; get the changed name
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
IF fname(0) EQ sdf_lastfile then return
; generate full name with path
pfname = sdf_path + fname

; -- check if the filename exists - if not assume this is just a trap out of
; -- the user starting to type a changed name or a mistake
t = findfile(pfname(0), count=t_count) & if t_count EQ 0 then return
print, 'New filename is ', fname(0)
sdf_lastfile = fname(0)

; update details
 BUT_SDF_FNAME_BROWSE, Event, file = fname(0)

end

;-----------------------------------------------------------------
pro BUT_SDF_FNAME_BROWSE, Event, file=file
on_error,2
@axis_com
@sdf_com

; get a new file - THAT IS THE PURPOSE OF THIS routine
; switch to sdf_lastpath if it exists
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_PATH')
WIDGET_CONTROL,id, Set_value = sdf_path
if n_elements(sfd_path) GT 0 then begin
	if file_test(sdf_lastpath, /directory) then cd, sdf_lastpath
endif
if keyword_set(file) then begin
	test = file_info(file)
	if test.exist EQ 1 then begin
		fname = pickfile2(Title='Select SDF file',file=sdf_lastfile, Filter = '*.hdr')
	endif else fname = pickfile2(Title='Select SDF file', Filter = '*.hdr')
endif else begin
	fname = pickfile2(Title='Select SDF file', Filter = '*.hdr')
endelse

; print, 'Fname if cancel = ', fname

; print, 'inside BUT_SDF_FNAME_BROWSE'		; anal checking (30-Jun-14, aph)
; print, 'fname = ', fname					; sdf_path is saved in axis.ini BUT NOT sdf_lastfile
; print, 'sdf_path = ', sdf_path
; print, 'sdf_lastfile = ', sdf_lastfile


if strlen(fname) GT 0 then begin
	t = ax_name(fname)
	sdf_path = t(0)
	sdf_lastfile = t(1)          ; ensure the filename is saved for future use
; update sdf_path and file_name in the text box
	id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_PATH')
	WIDGET_CONTROL,id, Set_value = sdf_path
	id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_FNAME')
	WIDGET_CONTROL,id, Set_value = sdf_lastfile
; read file and update type
	fname = sdf_path + sdf_lastfile + '.hdr'
	print, ' Reading in SDF file: ', fname
	widget_control, /hourglass
	sdf = read_sdf(fname, /header_only)
; update the type
	id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_TYPE')
	WIDGET_CONTROL,id, Sensitive=1, Set_value = sdf.Type

	if sdf.Type NE 'VLM Image' then begin
	;  ------------- update data channel information
		nchnl = n_elements(sdf.Channel_labels)
		SDF_Channel_List = strarr(nchnl)
		for i = 0, nchnl(0)-1 do SDF_Channel_List(i) = sdf.Channel_labels[i].Name
		id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
		WIDGET_CONTROL,id, Set_VALUE = SDF_Channel_List, sensitive = 1
	; ------------- update region information
	; currently there are no names associated with regions; can only set number of elements
		n_regions = sdf.n_regions
		if n_regions GT 1 then SDF_region_List = strarr(n_regions+1) else SDF_region_List = ' '
		for i = 0, n_regions-1 do SDF_Region_List(i) = 'Region '+ strtrim(string(i+1),2)
		if n_regions GT 1 then SDF_Region_List(n_regions) = 'all regions'
		id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
		WIDGET_CONTROL,id, Set_VALUE = SDF_Region_List, Sensitive=1

	; ---------- update image number information (for NEXAFS image sequences)
		if sdf.Type EQ 'NEXAFS Image Scan' then begin
			SDF_Image_List = strtrim(string(sdf.StackAxis.Points, format='(F7.2)'),2)
			id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
			widget_control, id, Set_Value=SDF_Image_List, sensitive = 1
			id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_STACK_MAP')
			widget_control, id, sensitive = 1
			id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_STACK_IMAGE')
			widget_control, id, sensitive = 1
			id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_SAVE_I_RING')
			widget_control,id, sensitive = 1
		endif else begin
		id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
			widget_control, id, sensitive = 0
			id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_STACK_MAP')
			widget_control, id, sensitive = 0
			id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_STACK_IMAGE')
			widget_control, id, sensitive = 0
			id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_SAVE_I_RING')
			widget_control,id, sensitive = 0
		endelse
	endif

; ----------- activate 'Show parameters' button
	id = widget_info(Event.top, FIND_BY_UNAME ='BUT_SDF_DISPLAY_HDR')
  widget_control, id, sensitive = 1

endif
end

pro WID_DLIST_CHANNEL, Event
on_error,2
@axis_com
@sdf_com
; get the changed data channel
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
WIDGET_CONTROL,id, Sensitive=1, Get_value = sdf_ch
WIDGET_CONTROL,id, SET_DROPLIST_SELECT = sdf_ch
print, 'New channel selected ', sdf_ch
end

pro WID_DLIST_REGION, Event
on_error,2
@axis_com
@sdf_com
; get the changed region
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
WIDGET_CONTROL,id, Sensitive=1, Get_value = sdf_region
WIDGET_CONTROL,id, SET_DROPLIST_SELECT = sdf_region
end

pro WID_DLIST_IMAGE, Event
on_error,2
@axis_com
@sdf_com
; get the selected image
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
WIDGET_CONTROL,id, Sensitive=1, Get_value = sdf_image
;WIDGET_CONTROL,id, SET_DROPLIST_SELECT = sdf_region
end

;-----------------------------------------------------------------
pro BUT_SDF_DISPLAY_HDR, Event, group=wGroup
on_error,2
@axis_com
@sdf_com
; get the path & filename
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_FNAME')
WIDGET_CONTROL,id, Get_value = fname
if strlen(fname(0)) GT 0 then begin
	fname = sdf_path + fname(0) + '.hdr'
	XDisplayfile,fname, done_button = 'dismiss', title = fname, group = wGroup, width=132
endif
end

;-----------------------------------------------------------------
pro BUT_SDF_STACK_MAP, Event
@axis_com
@sdf_com
on_error,2

print, 'Analysing stack as a 2-image map'
; ----------- get the path & filename ----------
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
fname = path + fname + '.hdr'
print, ' Reading in SDF file: ', fname
; -------------- get the data channel ------------------
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
this_channel = 1+ WIDGET_INFO(id, /Droplist_select)
; print, 'channel is ', this_channel
; ----------- get the region -------
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
this_region = 1 + widget_info(id, /DROPLIST_SELECT)
; print, 'region is ', this_region

widget_control, /hourglass
sdf = read_sdf(fname(0), channel= this_channel, region = this_region, /map, group=SDF_ID)

WIDGET_CONTROL, Event.Top, /DESTROY
end

;-------------------------Read in a single image from a stack ----------------------------------------
pro BUT_SDF_STACK_IMAGE, Event
@axis_com
@sdf_com
on_error,2

id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
sdf_image_index = WIDGET_INFO(id, /Droplist_select)

; get the selected image
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
WIDGET_CONTROL,id, Sensitive=1, Get_value = sdf_image

 print, 'Extracting single image at E = ', sdf_image(sdf_image_index)
sdf_image_index = fix(sdf_image_index) +1	; kluge to avoid problem that IDL uses 0 as false !
; get the path & filename
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
fname = path + fname + '.hdr'
; print, ' Reading in SDF file: ', fname
;; get the data channel
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
this_channel = 1 + WIDGET_INFO(id, /Droplist_select)
 print, 'channel is ', this_channel
; nchnls = n_elements(sdf_ch)		; from pre-17jun05 version - WHY ??
; get the region
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
this_region = 1 + widget_info(id, /DROPLIST_SELECT)
 print, 'region is ', this_region

widget_control, /hourglass
sdf = read_sdf(fname(0), channel= this_channel, region = this_region, one_image=sdf_image_index, group=SDF_ID)

WIDGET_CONTROL, Event.Top, /DESTROY
end


;-----------------------------------------------------------------
pro BUT_SDF_OK, Event
on_error,2
@axis_com
@sdf_com

; get the norm_value if norm_flag is on, since only update if the user pushes 'enter'
if norm_Flag EQ 1 then begin
	id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_RING_CURRENT')
	WIDGET_CONTROL,id, Sensitive=1, Get_value = tmp
	norm_value = float(tmp)
	print, 'norm_value = ', norm_value
endif

; get the path & filename
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_SDF_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
fname = path + fname + '.hdr'
print, ' Reading in SDF file: ', fname

; get the data channel
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
sdf_ch = WIDGET_INFO(id, /Droplist_select)
nchnls = n_elements(sdf_ch)
widget_control, /hourglass
; -------------- kluge to adapt for VLM images -----------
if sdf.Type NE 'VLM Image' then begin
	; get the region
	n_regions = sdf.n_regions
	id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
	sdf_region = WIDGET_INFO(id, /Droplist_select)
	region = sdf_region(0) + 1
	if  region LE n_regions then begin
	; read the data file for a defined region
		nchnls=n_elements(SDF_Channel_List)
		print, 'Reading channel ', string(sdf_ch(0)+1,format='(i2)'), ' of ', string(nchnls,format='(i2)'), $
		' channels.  Region ', string(region,format='(i2)'), ' of ', string(n_regions,format='(i2)'), ' regions.'
		sdf = read_sdf(fname(0), channel=sdf_ch(0)+1, region = region, group=SDF_ID)
	endif else begin		; read all regions
		print, 'Reading channel ', string(sdf_ch(0)+1,format='(i2)'), ' of ', string(nchnls,format='(i2)'), $
		' channels.  All ', string(n_regions,format='(i2)'), ' regions.'
		sdf = read_sdf(fname(0), channel=sdf_ch(0)+1, region = 0, /all_regions, group=SDF_ID)
	endelse

; ************ seems like this is set to read only channel 1 !! **************************

endif else sdf = read_sdf(fname(0), channel= 1, group=SDF_ID, /silent)

WIDGET_CONTROL, Event.Top, /DESTROY
on_error,2
@axis_com
@sdf_com
return
end

;-----------------------------------------------------------------
pro BUT_SDF_SILENT, Event
@axis_com
@sdf_com
on_error,2
id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_SILENT')
if SDF_silent EQ 0 then begin
	SDF_silent = 1
;	print, ' details turned OFF'
 	widget_control, id,  set_button = 0
endif else begin
	SDF_silent = 0
;	print, ' details turned ON'
 	widget_control, id,  set_button = 1
endelse
; print, 'SDF_silent = ', SDF_silent
end

;-----------------------------------------------------------------
pro BUT_SDF_NORMALIZE, Event
@axis_com
@sdf_com
on_error,2
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_RING_CURRENT')
if norm_flag EQ 1 then begin	; desensitize
	norm_flag = 0
	norm_string = '   not ring current normalized'
	print, ' I-ring normalization turned OFF'
 	WIDGET_CONTROL,id, sensitive=0
endif else begin						; sensitize
	norm_flag = 1
	print, ' I-ring normalization turned ON'
 	WIDGET_CONTROL,id, sensitive=1
endelse
id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_NORMALIZE')
WIDGET_CONTROL,id, set_button=norm_flag
end

;-----------------------------------------------------------------

pro TEXT_RING_CURRENT, Event
@axis_com
@sdf_com
on_error,2
; get the changed value

id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_RING_CURRENT')
WIDGET_CONTROL,id, Sensitive=1, Get_value = tmp
norm_value = float(tmp)
print, 'New norm_value = ', norm_value
IF norm_value LE 0 then norm_value = 1.		; don't allow 0 or negative
WIDGET_CONTROL,id, set_value = string(norm_value, format='(F5.1)')
end

;-----------------------------------------------------------------

pro BUT_SDF_SAVE_I_RING, Event
@axis_com
@sdf_com
on_error,2
	print, ' Extract ring current and store in user-defined aXis2000 buffer'
	fname = sdf_path + sdf_lastfile + '.hdr'
	widget_control, /hourglass
	ScanDef=read_sdf(fname, /header_only, /silent)
	ev = float(ScanDef.stackaxis.points)
	npts = n_elements(ev)
	x = findgen(npts)
	I_ring=fltarr(npts)
	for i = 0, npts - 1 do I_ring(i)= float(sdf_stack_cur(i))
	tmp = {t:'1d', x:x, xl:'image #', d:I_ring, dn:I_ring, yl:'Ring current', dl:sdf_lastfile}
;	help, tmp, /struct
	Curbuf = Buffer(group = aXis_ID)
	if  n_tags(tmp) NE 0 THEN BEGIN
		HANDLE_VALUE, Data(Curbuf), tmp, /SET
		PlotBuf, Curbuf
	endif

end

;-----------------------------------------------------------------

pro BUT_SDF_XY_CORRECT, Event
@axis_com
@sdf_com
on_error,2
if xy_correct_flag EQ 1 then xy_correct_flag = 0 else  xy_correct_flag = 1
; print, ' xy_correct status changed to ', xy_correct_flag
 id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_SDF_XY_CORRECT')
 WIDGET_CONTROL,id, set_button=xy_correct_flag
end
;-----------------------------------------------------------------

pro BUT_SDF_CANCEL, Event
@axis_com
@sdf_com
on_error,2
sdf = 0
WIDGET_CONTROL, Event.Top, /DESTROY
end


;-----------------------------------------------------------------
; ****************************************************************
;-----------------------------------------------------------------

pro BASE_SDF_event, Event
@axis_com
@sdf_com

  wWidget =  Event.top
; note (20-Jul-14 - text change events do not have a structure name so the check blocks
  case Event.id of

    Widget_Info(wWidget, FIND_BY_UNAME='TEXT_SDF_FNAME'): begin
;      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_CH' )then $
        TEXT_SDF_FNAME, Event
    end
      Widget_Info(wWidget, FIND_BY_UNAME='WID_DLIST_CHANNEL'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_STR' )then $
        WID_DLIST_CHANNEL, Event
    end
      Widget_Info(wWidget, FIND_BY_UNAME='WID_DLIST_REGION'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_STR' )then $
        WID_DLIST_REGION, Event
    end
      Widget_Info(wWidget, FIND_BY_UNAME='WID_DLIST_IMAGE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_STR' )then $
        WID_DLIST_IMAGE, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_FNAME_BROWSE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_FNAME_BROWSE, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='TEXT_SDF_TYPE_TITLE_0'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_DEL' )then $
        BUT_SDF_FNAME_BROWSE, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_DISPLAY_HDR'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_DISPLAY_HDR, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_OK'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_OK, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_CANCEL'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_CANCEL, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_STACK_MAP'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_STACK_MAP, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_STACK_IMAGE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_Stack_IMAGE, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_SILENT'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_SILENT, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_NORMALIZE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_NORMALIZE, Event
    end
    Widget_Info(wWidget, FIND_BY_UNAME='TEXT_RING_CURRENT'): begin
;      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_CH' )then $
        TEXT_RING_CURRENT, Event
    end
        Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_SAVE_I_RING'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_SAVE_I_RING, Event
    end

    Widget_Info(wWidget, FIND_BY_UNAME='BUT_SDF_XY_CORRECT'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_SDF_XY_CORRECT, Event
    end
    else: print, 'Undefined action'
  endcase

end

;-----------------------------------------------------------------
; ****************************************************************
;-----------------------------------------------------------------


pro BASE_SDF, GROUP_LEADER=wGroup,  file=file, _EXTRA=_VWBExtra_
@axis_com
@sdf_com
;  Resolve_Routine, 'ax_sdf_eventcb'     ; Load event callback routines
t = size(wGroup)
IF t(1) EQ 0 THEN modal_val=0 else modal_val=1

;print, wgroup, 'modal_val = ' , modal_val

BASE_SDF = Widget_Base( GROUP_LEADER=wGroup, UNAME='BASE_SDF',  $
      TITLE='Read Self Defining Format files', $
       modal = modal_val, /column)
row1 = widget_base(base_sdf,/row)
col1 = widget_base(row1,/column)
row = widget_base(base_sdf,/row)

tlabel = widget_label(row,value='Path ')
TEXT_SDF_PATH = Widget_Text(row, UNAME='TEXT_SDF_PATH',  $
     /FRAME,  XSIZE=50)

row = widget_base(base_sdf,/row)
tlabel = widget_label(row,value='File   ')
TEXT_SDF_FNAME = Widget_Text(row, UNAME='TEXT_SDF_FNAME',  $
      /FRAME,/EDITABLE, KBRD_FOCUS_EVENTS = 0, XSIZE=30)
tlabel = widget_label(row,value='')
BUT_SDF_FNAME_BROWSE = Widget_Button(row,  $
      UNAME='BUT_SDF_FNAME_BROWSE', /ALIGN_CENTER ,VALUE='Browse', SCR_YSIZE=30)
tlabel = widget_label(row,value='    ')
BUT_SDF_DISPLAY_HDR = Widget_Button(row,  $
      UNAME='BUT_SDF_DISPLAY_HDR' ,  $    ;XOFFSET=320,
      /ALIGN_CENTER ,VALUE='Parameters')

row = widget_base(base_sdf,/row)
tlabel = widget_label(row,value='Type ')
TEXT_SDF_TYPE = Widget_Text(row, UNAME='TEXT_SDF_TYPE',  $
      EDITABLE=0 ,/ALL_EVENTS ,VALUE=[ 'Type', '', '', '' ], $
      /ALIGN_CENTER ); , SCR_YSIZE=30, XSIZE=20)
tlabel = widget_label(row,value='   ')
BUT_SDF_Stack_Map = Widget_Button(row, $
       UNAME='BUT_SDF_STACK_MAP', VALUE='Map')
tlabel = widget_label(row,value='   ')
BUT_SDF_Stack_Image = Widget_Button(row, $
       UNAME='BUT_SDF_STACK_IMAGE',  VALUE='1 image')
tlabel = widget_label(row,value='   ')
BUT_SDF_CANCEL = Widget_Button(row, UNAME='BUT_SDF_CANCEL',  $
      /ALIGN_CENTER ,VALUE='Cancel', SCR_YSIZE=36)
tlabel = widget_label(row,value='       ')
BUT_SDF_OK = Widget_Button(row, UNAME='BUT_SDF_OK',  SCR_YSIZE=40,  $ ;SCR_YSIZE=40,
      /ALIGN_CENTER, VALUE='  OK  ')

row = widget_base(base_sdf,/row)
SDF_Channel_List =['PMT','OSA','Analog']
SDF_Ch = 0
WID_DLIST_CHANNEL = Widget_Droplist(row, /DYNAMIC_RESIZE,  $
       VALUE = SDF_Channel_List,   $  ; XOFFSET=21, /ALIGN_LEFT,
      UNAME='WID_DLIST_CHANNEL', TITLE='Channel')

SDF_Region_List =['region 1']
SDF_region = 0
WID_DLIST_REGION = Widget_Droplist(row, /DYNAMIC_RESIZE, $
       VALUE = SDF_Region_List, $  ; XOFFSET=170,
      UNAME='WID_DLIST_REGION', TITLE='Region')

tlabel = widget_label(row,value='       ')
BUT_SDF_XY_CORRECT = Widget_Button(row, UNAME='BUT_SDF_XY_CORRECT', $
     VALUE='xy correct ?')
tlabel = widget_label(row,value='       ')
SDF_Image_List =[' ']
SDF_Im = 0
WID_DLIST_IMAGE = Widget_Droplist(row, /DYNAMIC_RESIZE, $
   VALUE = SDF_Image_List,UNAME='WID_DLIST_IMAGE', TITLE='Image #')


row = widget_base(base_sdf,/row)
WID_BASE_1 = Widget_Base(row, UNAME='WID_BASE_1',COLUMN=2 ,/NONEXCLUSIVE)

BUT_SDF_SILENT = Widget_Button(wid_base_1, UNAME='BUT_SDF_SILENT', $
        VALUE='Give details')
tlabel = widget_label(row,value = 'I-ring norm value =')
TEXT_RING_CURRENT = Widget_Text(row, UNAME='TEXT_RING_CURRENT',  $
      /EDITABLE, KBRD_FOCUS_EVENTS = 0, XSIZE=6, YSIZE=0.25)

BUT_SDF_NORMALIZE = Widget_Button(wid_base_1, UNAME='BUT_SDF_NORMALIZE', $
        VALUE='I-ring norm?')
        tlabel = widget_label(row,value='       ')
BUT_SDF_SAVE_I_RING = Widget_Button(row, UNAME='BUT_SDF_SAVE_I_RING', $
        VALUE='View I-ring')

; ----------- start display without active displays / controls
  widget_control, WID_DLIST_CHANNEL, sensitive = 0
  widget_control, WID_DLIST_REGION, sensitive = 0
  widget_control, WID_DLIST_IMAGE, sensitive = 0
  widget_control, TEXT_SDF_TYPE, sensitive = 0
  widget_control, BUT_SDF_DISPLAY_HDR, sensitive = 0
  widget_control, BUT_SDF_Stack_Map, sensitive = 0
  widget_control, BUT_SDF_Stack_Image, sensitive = 0
  widget_control, BUT_SDF_SILENT, sensitive = 1

  if n_elements(SDF_silent) EQ 0 then begin
 	 SDF_silent = 1				; default state
  	 widget_control, BUT_SDF_SILENT,  set_button = 0
  endif else begin
  	if SDF_silent EQ 1 then widget_control, BUT_SDF_SILENT,  set_button = 0 $
  	    else widget_control, BUT_SDF_SILENT,  set_button = 1
  endelse
;print, 'GTK crash on next line!!!' ;if SDF_Image_List is a zero length string then GTK will crash on RedHat6
  Widget_Control, /REALIZE, BASE_SDF

; ----------- set current value of ring current normalization and state of flag
  if n_elements(norm_flag) EQ 0 then begin ;  for stand_alone operation
  	norm_flag = 1
  	print, 'Norm_Flag set to ', norm_flag
  endif
  if norm_flag EQ 1 then begin
  		widget_control, BUT_SDF_Normalize, set_button = 1
  		widget_control, TEXT_RING_CURRENT, sensitive = 1
  		widget_control,BUT_SDF_SAVE_I_RING, sensitive = 0
  endif else begin
     	widget_control, BUT_SDF_Normalize, set_button = 0
     	widget_control, TEXT_RING_CURRENT, sensitive = 0
     	widget_control,BUT_SDF_SAVE_I_RING, sensitive = 0
  endelse

  if n_elements(norm_value) EQ 0 then norm_value = 200.			; change default to match CLS
  widget_control, TEXT_RING_CURRENT, set_value = string(norm_value, format='(F5.1)')

; ----------- set to current value of xy_correct_flag
  if n_elements(xy_correct_flag) EQ 0 then xy_correct_flag = 0
  if xy_correct_flag EQ 1 then widget_control, BUT_SDF_xy_correct, set_button = 1 $
     else widget_control, BUT_SDF_xy_correct, set_button = 0

; ------ set last path and file name if they exist
; ------ use keyword file if provided
; NB this order means the 'file' supplied in call trumps any values of sdf_lasfile, sdf_lastpath
if keyword_set(file) then begin		; assume file contains path
	print, 'setting last path and last file names from ', file, ' supplied in call to ax_sdf'
	t = ax_name(file)
	sdf_path = t(0)
  	sdf_lastfile = t(1)
endif
; ------ check if sdf_lastfile is a combined path_fname_extension - if so, split (KLUGE, 19-Dec-13, updated 16-Jun-14)
if n_elements(sdf_lastfile) NE 0 then begin
	if strpos(sdf_lastfile,path_sep()) NE -1 then begin
		print, 'SDF_lastfile is actually a path & filename. Separating them.', sdf_lastfile
		t = ax_name(sdf_lastfile)
		sdf_path = t(0)
	  	sdf_lastfile = t(1)
	endif
endif

; ----- set path -------
; goto, continue		;  t KLUGE !  the following  results in a hung state if user cancels on file dialog
if n_elements(sdf_path) EQ 0 then begin
		if n_elements(code_path) NE 0 then begin
			axis_log, 'path to sdf files not defined. Changing directory to Code_path'
			sdf_path = code_path
		endif else begin
			axis_log, 'path to sdf files not defined. Please choose a file'
			file = pickfile2(Title='Path was not valid or not defined. Please select an SDF file', Filter = '*.hdr')
			if file_test(file) NE 0 then begin
				t = ax_name(file)
				sdf_path = t(0)
				sdf_lastfile = t(1)
			endif else begin
				if !version.os_family EQ 'Windows' then sdf_path='c:\aXis2000'		; KLUGE - hard wiring in the Windows default code path !
        if !version.os_family EQ 'unix' then sdf_path='/users/'
				return		; bail if user decides not to select a file
			endelse
		endelse
endif


; OK, we now should have a valid path BUT it may not be valid
if file_test(sdf_path, /directory) then cd, sdf_path else begin
	axis_log, 'path to sdf files not defined. Please choose a file'
	file = pickfile2(Title='Path was not valid or not defined. Please select an SDF file', Filter = '*.hdr')
	if file_test(file) NE 0 then begin
		t = ax_name(file)
		sdf_path = t(0)
		sdf_lastfile = t(1)
	endif else return		; bail if user decides not to select a file
endelse

; continue:  ; end of by-passing the annoying code

; load last path information & change path to that folder

widget_control, TEXT_SDF_PATH, set_value = sdf_path
cd, sdf_path

; OK, we now should have a valid path and we MIGHT have a file name

; NB on first starting aXis2000 sdf_lastfile is NOT defined since axis.ini only contains the last path
; load last file information if it exists (it does not for the first use of ax_sdf after starting axis2000)
; , 'sdf_path, sdf_lastfile = ', sdf_path ,'    ',  sdf_lastfile
if n_elements(sdf_lastfile) GT 0 then begin
	if strlen(sdf_lastfile) GT 0 then begin
		t = ax_name(sdf_lastfile)
		fname = sdf_path + t(1) + '.hdr'
	endif else fname = 'not_a_file'
; 	print, 'testing existence of sdf_file: ', fname, ' exists ? ', file_test(fname)
	if file_test(fname) NE 0	then begin
		t = ax_name(sdf_lastfile)
		widget_control, TEXT_SDF_FNAME, set_value = t(1)
	; get details of this file if it is valid
;		print, ' ax_sdf: reading sdf file ', fname
	; read file and update type
		widget_control, /hourglass
		sdf = read_sdf(fname, /header_only, /silent) ; Assume the file is actually an SDF type file and read its header
	;update the type
		WIDGET_CONTROL,TEXT_SDF_TYPE, Sensitive=1, Set_value = sdf.Type
		if sdf.Type NE 'VLM Image' then begin
	;  ------------- update data channel information
			nchnl = n_elements(sdf.Channel_labels)
			SDF_Channel_List = strarr(nchnl)
			for i = 0, nchnl(0)-1 do SDF_Channel_List(i) = sdf.Channel_labels[i].Name
			WIDGET_CONTROL,WID_DLIST_CHANNEL, Set_VALUE = SDF_Channel_List, sensitive = 1
	; ------------- update region information
	; currently there are no names associated with regions; can only set number of elements
			n_regions = sdf.n_regions
			if n_regions GT 1 then SDF_region_List = strarr(n_regions+1) else SDF_region_List = ' '
			for i = 0, n_regions-1 do SDF_Region_List(i) = 'Region '+ strtrim(string(i+1),2)
			if n_regions GT 1 then SDF_Region_List(n_regions) = 'all regions'
			WIDGET_CONTROL,WID_DLIST_REGION, Set_VALUE = SDF_Region_List, Sensitive=1

	; ---------- update image number information (for NEXAFS image sequences)
			if sdf.Type EQ 'NEXAFS Image Scan' then begin
				SDF_Image_List = strtrim(string(sdf.StackAxis.Points, format='(F7.2)'),2)
				widget_control, WID_DLIST_IMAGE, Set_Value=SDF_Image_List, sensitive = 1
				widget_control, BUT_SDF_Stack_Map, sensitive = 1
				widget_control, BUT_SDF_Stack_Image, sensitive = 1
				widget_control,BUT_SDF_SAVE_I_RING, sensitive = 1
			endif else begin
				widget_control, WID_DLIST_IMAGE, sensitive = 0
				widget_control, BUT_SDF_Stack_Map, sensitive = 0
				widget_control, BUT_SDF_Stack_Image, sensitive = 0
				widget_control,BUT_SDF_SAVE_I_RING, sensitive = 0
			endelse
	; ----------- activate 'Show parameters' button
		  widget_control, BUT_SDF_DISPLAY_HDR, sensitive = 1
	    endif
	endif else axis_log, 'SDF_lastfile not defined'
endif else axis_log, 'SDF_lastfile not defined'

XManager, 'BASE_SDF', BASE_SDF
SDF_ID = BASE_SDF

end

;-----------------------------------------------------------------
; ****************************************************************
;-----------------------------------------------------------------

function ax_sdf, file = file, GROUP_LEADER=wGroup, _EXTRA=_VWBExtra_
on_error,2
@axis_com
@sdf_com

sdf = 0
if keyword_set(file) then begin
;	print, 'ax_Sdf: file name supplied ', file
	BASE_SDF, GROUP_LEADER=wGroup, file=file, _EXTRA=_VWBExtra_
endif else begin
	BASE_SDF, GROUP_LEADER=wGroup, _EXTRA=_VWBExtra_
endelse

return, sdf
end
