; Copyright (c) 1998-2018 A.P. Hitchcock, Ben Watts  All rights reserved
;+
;NAME:
;	AX_NEXUS
;
;LAST CHANGED: ----------------------------------- 15-May-2018  (aph)
;
;PURPOSE:
;	This set of procedures is a widget to manage the read in files
; in the HDF5 NeXus file format developed for STXM
; The widget uses read_nexus to read the data and convert to aXis2000 internal formats.
;
;CATEGORY:
;	AXIS: utility
;
; AX_NEXUS_EVENT ROUTINES:
; TEXT_NEXUS_FNAME			modify filename; when changed, execute BUT_NEXUS_FNAME_BROWSE to get parameters
; BUT_NEXUS_PARAMETERS  	display scan and microscope parameters
; BUT_NEXUS_FNAME_BROWSE 	browse for new filename; if found, load new parameters
; BUT_NEXUS_STACK_IMAGE    	proceed to read single image from stack
; BUT_NEXUS_OK				proceed with loading NEXUS file into AXIS
; BUT_NEXUS_CANCEL			abort read in
; BUT_NEXUS_NORMALIZE 		toggle flag to enable normalising data to ring current
; BUT_NEXUS_XY_CORRECT 		toggle flag to enable correcting per-pixel positions
; WID_DLIST_CHANNEL			drop list used to display and select the data channel
; BASE_NEXUS_UPDATE   		update widgets
; WID_DLIST_REGION    		drop list to display and select region
; WID_DLIST_IMAGE     		drop list to display and select image
;
;COMMON BLOCKS:
;	@AXIS_COM	standard set of common blocks
;	@NEXUS_COM 	structure with header info
;
;MODIFICATION HISTORY:
; (27-Apr-15 bw)  First version written using ax_sdf.pro as a template
; (13-Jul-15 aph) integrated into 02-July-15 version of aXis2000
; (15-Mar-16 BW) correct switch to display stack image number when reading in
; (27-Mar-16 aph) get multi-region working
; (05-Apr-16 aph) add view and parameter display
; (12-Apr-16 aph) get working for line and stack display; broken after introduction of ax_interp_square
; (25-Apr-16 aph) re-start viewer - had stopped due to doubles problem
; (08-May-16 aph) get to read multi-channel files
; (25-Aug-16 bw ) make file preview more robust and improve calculation of elapsed time
; (05-Sep-16 aph) remember channel and region choices
; (25-Jul-17 aph) allow 'clear' of filename; entry of name only;
;                 add 'reset' to GUI to allow recover via file in CodePath if LastFile does not exist or read-in freezes
; (17-Mar-18 aph) fix lock-up if bad read, add preview/no-preview button
; (13-Apr-18 aph) add 'preview' switch to GUI; fix single image read; implement 'pixelator' / 'pySTXM' switching
; (01-May-18 aph) force channel to 'counter0' if pySTXM
; (15-May-18 aph) fix error of non-structure nexus_head parameter on first read; add nexus_i_norm (200 mA for CLS, 500 for Soleil)
;-

pro TEXT_NEXUS_FNAME, Event
on_error,2
@axis_com
@nexus_com

; get the changed name
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
; IF fname(0) EQ nexus_lastfile then return
t = ax_name(fname(0))
fname = t(1) +'.hdf5'		; force extension   NB do not know path !
; ----- generate full name with path
pfname = nexus_path + fname
; -- check if the filename exists - if not use Browse to get full name and path
t = findfile(pfname(0), count=t_count)
if t_count EQ 0 then begin
	axis_log, pfname + ' does not exist'
	pfname = pickfile2(Title='Select NEXUS file', Filter = '*.hdf5', group = aXis_ID)
endif
t = ax_name(pfname)
nexus_path = t(0)
nexus_lastfile = t(1) +'.hdf5'
print, 'New filename is ', pfname(0)

; update details of GUI
BASE_NEXUS_UPDATE, Event.Top, /new_file

end

;-----------------------------------------------------------------
pro BUT_NEXUS_FNAME_BROWSE, Event, file=file
on_error,2
@axis_com
@nexus_com
; get new filename
if NOT keyword_set(file) then begin
	fname = pickfile2(Title='Select NEXUS file', Filter = '*.hdf5', group = aXis_ID)
endif else fname = file
if strlen(fname) GT 0 then begin
	t = ax_name(fname)
	nexus_path = t(0)
	nexus_lastfile = t(1) +'.hdf5'          ; force extension & save name for future use
; update nexus_path and file_name in the text box
BASE_NEXUS_UPDATE, Event.Top, /new_file
endif
end

;-----------------------------------------------------------------
pro BUT_NEXUS_RESET, Event
on_error,2
@axis_com
@nexus_com
; set path and filename to BLANK ; (or known values)
axis_log, 'Reset AX_NEXUS GUI'
nexus_lastfile = ''    ; 'nexus.hdf5'
nexus_path =  ''        ; CodePath
;  update nexus_path and file_name in the text box
    id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_PATH')
WIDGET_CONTROL,id, Set_value = nexus_path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
WIDGET_CONTROL,id, Set_value = nexus_lastfile
end

;-----------------------------------------------------------------
pro WID_DLIST_SOURCE, Event			; (11-Apr-18 aph)  added to set default switches
on_error,2
@axis_com
@nexus_com
; ---------- get the changed data source
nexus_source_tmp = strtrim(nexus_source,2)
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_SOURCE')
nexus_source_num = fix(WIDGET_INFO(id, /Droplist_select))
print, 'nexus_source_num = ', nexus_source_num
if nexus_source_num EQ 0 then nexus_source = 'pixelator'
if nexus_source_num EQ 1 then nexus_source = 'pySTXM'

; ------ change parameters to default for new source type
if nexus_source NE nexus_source_tmp then begin
	CASE strtrim(nexus_source) OF
	'pixelator': BEGIN
		print, nexus_source  + ': Changing defaults to pixelator (no i-ring norm, no preview, no flip)'
		norm_flag = 0
		id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_NORMALIZE')
		WIDGET_CONTROL,id, set_button=norm_flag
		preview_flag = 0
		id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_PREVIEW')
 		WIDGET_CONTROL,id, set_button=preview_flag
		nexus_flip = 0
		id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_FLIP')
		WIDGET_CONTROL,id, set_button=nexus_flip
		id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_RING_CURRENT')
		nexus_norm_value = 500.
		WIDGET_CONTROL, id, set_value =string(nexus_norm_value, format='(F5.1)')
		WIDGET_CONTROL,id, sensitive = 0
	END
	'pySTXM' : BEGIN
		print, nexus_source  + ': Changing defaults to pySTXM (i-ring norm, preview, flip)'
		norm_flag = 1
		id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_NORMALIZE')
		WIDGET_CONTROL,id, set_button=norm_flag
		preview_flag = 1
		id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_PREVIEW')
 		WIDGET_CONTROL,id, set_button=preview_flag
		nexus_flip = 1
		id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_FLIP')
		WIDGET_CONTROL,id, set_button=nexus_flip
		id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_RING_CURRENT')
		nexus_norm_value = 200.
		WIDGET_CONTROL, id, set_value =string(nexus_norm_value, format='(F5.1)')
		WIDGET_CONTROL,id, sensitive = 1
	END
	ENDCASE
endif
print, 'NeXUS source changed from ', nexus_source_tmp , ' to ', nexus_source
BASE_NEXUS_UPDATE, Event.Top		; update ax_nexus display
end

;-----------------------------------------------------------------
pro WID_DLIST_CHANNEL, Event
on_error,2
@axis_com
@nexus_com
; get the changed data channel
nexus_ch_tmp = nexus_ch
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_ch
WIDGET_CONTROL,id, SET_DROPLIST_SELECT = nexus_ch
print, 'changing from ', nexus_ch_tmp , ' to ', nexus_ch
BASE_NEXUS_UPDATE, Event.Top		; update ax_nexus display

end

;-----------------------------------------------------------------
pro WID_DLIST_REGION, Event
on_error,2
@axis_com
@nexus_com
; get the changed region
nexus_region_tmp = nexus_region
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_region_list
nexus_region = fix(WIDGET_INFO(id, /Droplist_select))
print, 'changing from ', nexus_region_list(nexus_region_tmp) , ' to ', nexus_region_list(nexus_region)
BASE_NEXUS_UPDATE, Event.Top		; update ax_nexus display

end

;-----------------------------------------------------------------
pro WID_DLIST_IMAGE, Event
on_error,2
@axis_com
@nexus_com
; get the selected image
nexus_image_tmp = nexus_image
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_image
print, 'changing from ', nexus_image_tmp , ' to ', nexus_image
help, nexus_image		; the energies of a stack are in nexus_head.stackaxis
print, nexus_imge
;WIDGET_CONTROL,id, SET_DROPLIST_SELECT = nexus_region

BASE_NEXUS_UPDATE, Event.Top		; update ax_nexus display

end

;-----------------------------------------------------------------
pro BUT_NEXUS_OK, Event
on_error,2
@axis_com
@nexus_com
; get the path & filename
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
fname = path + fname(0) + '.hdf5'
print, ' Reading in NEXUS file: ', fname

; ------- read header if preview was off
if preview_flag EQ 0 then nexus_head = read_nexus(nexus_path + nexus_lastfile , /header_only)

; get the data channel
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
nexus_ch = WIDGET_INFO(id, /Droplist_select)
nchnls = n_elements(nexus_ch)
widget_control, /hourglass
; get the region
n_regions = nexus_head.n_regions
id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_REGION')
nexus_region = WIDGET_INFO(id, /Droplist_select)
region = nexus_region(0) + 1
if  region LE n_regions then begin
; read the data file for a defined region
	nchnls=n_elements(NEXUS_Channel_List)
	print, 'Reading channel ', string(nexus_ch(0)+1,format='(i2)'), ' of ', string(nchnls,format='(i2)'), $
	' channels.  Region ', string(region,format='(i2)'), ' of ', string(n_regions,format='(i2)'), ' regions.'
	nexus = read_nexus(fname(0), channel=nexus_ch(0)+1, region=region, group=NEXUS_ID, xy_correct=xy_correct_flag)
endif else begin		; read all regions
	print, 'Reading channel ', string(nexus_ch(0)+1,format='(i2)'), ' of ', string(nchnls,format='(i2)'), $
	' channels.  All ', string(n_regions,format='(i2)'), ' regions.'
  nexus = read_nexus(fname(0), channel=nexus_ch(0)+1, region=0,xy_correct=xy_correct_flag, /all_regions, group=NEXUS_ID)
endelse

WIDGET_CONTROL, Event.Top, /DESTROY
return
end

;-----------------------------------------------------------------
pro BUT_NEXUS_NORMALIZE, Event
@axis_com
@nexus_com
on_error,2
 if norm_flag EQ 1 then norm_flag = 0 else  norm_flag = 1
 print, ' normalzation status changed to ', norm_flag
 id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_NORMALIZE')
 WIDGET_CONTROL,id, set_button=norm_flag
  id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_RING_CURRENT')
  if norm_flag EQ 1 then widget_control, id, sensitive = 1 else widget_control, id, sensitive = 0
end

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

pro TEXT_RING_CURRENT, Event			; (15-May-18 added, aph)
@axis_com
@nexus_com
on_error,2
; get the changed value  - it is save and passed to other code in nexus_com

id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_RING_CURRENT')
WIDGET_CONTROL,id, Sensitive=1, Get_value = tmp
nexus_norm_value = float(tmp)
print, 'New ring current normalization value (mA) = ', nexus_norm_value
IF nexus_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_NEXUS_PREVIEW, Event
@axis_com
@nexus_com
on_error,2
  if preview_flag EQ 1 then preview_flag = 0 else  preview_flag = 1
  print, ' preview status changed to ', preview_flag
 id = widget_info(Event.top, FIND_BY_UNAME = 'BUT_NEXUS_PREVIEW')
 WIDGET_CONTROL,id, set_button=preview_flag
end

;-----------------------------------------------------------------
pro BUT_NEXUS_XY_CORRECT, Event
@axis_com
@nexus_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_NEXUS_XY_CORRECT')
 WIDGET_CONTROL,id, set_button=xy_correct_flag
end

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

;----------Display Pramters -------------------------------------------------------

pro BUT_NEXUS_PARAMETERS, Event
@axis_com
@nexus_com
on_error,2
; get the path & filename
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
fname = path + fname
print, ' Opening h5_browser on file: ', fname
tmp = h5_browser(fname)

end

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

id = widget_info(Event.top, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
nexus_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 = nexus_image

; print, 'Extracting single image at E = ', nexus_image(nexus_image_index)
nexus_image_index = fix(nexus_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_NEXUS_PATH')
WIDGET_CONTROL,id, Get_value = path
id = widget_info(Event.top, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
WIDGET_CONTROL,id, Sensitive=1, Get_value = fname
fname = path + fname ;+ '.hdf5'
;; 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
;print, 'ax_nexus calls read_nexus with channel#, region#, image# ', this_channel, this_region, nexus_image_index
nexus = read_nexus(fname(0), channel= this_channel, region = this_region, one_image=nexus_image_index, group=NEXUS_ID)

WIDGET_CONTROL, Event.Top, /DESTROY
end

;-----------------------------------------------------------------
pro BUT_NEXUS_CANCEL, Event
@axis_com
@nexus_com
on_error,2
nexus = 0

WIDGET_CONTROL, Event.Top, /DESTROY
end


;-----------------------------------------------------------------
; ****************************************************************
;-----------------------------------------------------------------
PRO BASE_NEXUS_UPDATE, Widget_id, new_file = new_file ; Update widgets with file info
on_error,2
@axis_com
@nexus_com

IF keyword_Set(new_file) then begin	; only do first part if the filename was changed
	; ------------ get new filename
	axis_log, 'BASE_NEXUS_UPDATE:  ' + nexus_path + '  --   ' +  nexus_lastfile
	t = file_search(nexus_path + nexus_lastfile, count=t_count)
	  IF t_count EQ 0 THEN BEGIN
; ------ SET to Nexus file in CodePath,  if the file canNOT be found
	   		axis_log, 'NeXus filename is not valid.'
			nexus_lastfile = 'nexus.hdf5'
			nexus_path = CodePath
	  ENDIF
; ------ update nexus_path and file_name in the text box
    id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_PATH')
    WIDGET_CONTROL,id, Set_value = nexus_path
    id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_FNAME')
    t=ax_name(nexus_lastfile)			; strip off extension for ease of changing in text box
    WIDGET_CONTROL,id, Set_value =t(1)

;	------------ if NEXUS_Source is pySTXM then force channel to be 'counter0', [if not set]  (01-May-18  aph)
	if NEXUS_Source EQ 'pySTXM' then begin
		print, 'NEXUS_Channel_List: ', NEXUS_Channel_List
		if n_elements(nexus_ch) LE 0 then begin				; if was set to different value do not force to counter0
			nexus_ch = 0
			for i = 0, nchnl(0)-1 do if NEXUS_Channel_List EQ 'counter0' then nexus_ch  = i
			WIDGET_CONTROL,id, SET_DROPLIST_SELECT = nexus_ch
		endif
	endif


if preview_flag EQ 0 then return		; try a real extreme, NO PREVIEW !!  15-May-18

; --------- read file and update type
    widget_control, /hourglass
    nexus_head = read_nexus(nexus_path + nexus_lastfile, /header_only)
;	    help, nexus_head.stackaxis,/struct
;	    print, nexus_head.stackaxis


; =============  KLUGE, KLUGE, KLUGE ========= 24-Jul-17;  15-May-18  (aph) ================
;  pySTXM frequently sets nexus_head.Type to 'sample image stack' when only one image is acquired
;  OR  the type is set to 'sample image' when in fact there is more than 1 image
;  read_nexus reads these correctly, so just need to identify this to user by changing the scan type label to 'sample image (*)'
;  ONLY DO THIS FOR CLS (pySTXM)

;	print, '***** nexus_source = ', nexus_source
	IF nexus_source EQ 'pySTXM' then begin
;		print, 'KLUGE !! Type of file ', nexus_head.Type[0]
		IF nexus_head.Type[0] EQ 'sample image stack' AND n_elements(nexus_head.stackaxis.points) EQ 1 then begin
			print, 'type before  = ', nexus_head.Type[0]
			print, 'Dimension of stack_Axis ', n_elements(nexus_head.stackaxis.points)
			nexus_head.Type[0] = 'sample image (*)'
			print, 'type after  = ', nexus_head.Type[0]
		ENDIF
	IF nexus_head.Type[0] EQ 'sample image' AND n_elements(nexus_head.stackaxis.points) GT 1 then begin
			print, 'type before  = ', nexus_head.Type[0]
			print, 'Dimension of stack_Axis ', n_elements(nexus_head.stackaxis.points)
			nexus_head.Type[0] = 'sample image atack'
			print, 'type after  = ', nexus_head.Type[0]
		ENDIF
; update the type
    id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_TYPE')
    WIDGET_CONTROL,id, Sensitive=1, Set_value = nexus_head.Type
	ENDIF
; =============  END  KLUGE, KLUGE, KLUGE ========= 24-Jul-17 (aph) ================

;  ------------- update data channel information
    unpack_Channel_labels = nexus_head.Channel_labels  ; (08-may-16 aph; removed (0) which restricted read to 0th channel only
    nchnl = n_elements(unpack_Channel_labels)
    NEXUS_Channel_List = strarr(nchnl)
    for i = 0, nchnl(0)-1 do NEXUS_Channel_List(i) = unpack_Channel_labels[i]
    id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
    WIDGET_CONTROL,id, Set_VALUE = NEXUS_Channel_List, sensitive = 1

    ; ------------- update region information
    ; currently there are no names associated with regions; can only set number of elements
    n_regions = nexus_head.n_regions
    if n_regions GT 1 then NEXUS_region_List = strarr(n_regions+1) else NEXUS_region_List = ' '
    for i = 0, n_regions-1 do NEXUS_Region_List(i) = 'Region '+ strtrim(string(i+1),2)
    if n_regions GT 1 then NEXUS_Region_List(n_regions) = 'all regions'
    id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_REGION')
    WIDGET_CONTROL,id, Set_VALUE = NEXUS_Region_List, Sensitive=1

    ; ---------- update image number information (for NEXAFS image sequences)
    if preview_flag EQ 1 then axis_log, 'data is ' + nexus_head.Type[0]


    if TOTAL(STRLOWCASE(nexus_head.Type[0]) EQ ['sample image stack','sample']) then begin
    ;  (BW 160310) the '[0]' on the end of 'Type' is required for the EQ comparison to be done on the entire list!
	      NEXUS_Image_List = strtrim(string(nexus_head.StackAxis.Points, format='(F7.2)'),2)
	      id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
	      widget_control, id, Set_Value=NEXUS_Image_List, sensitive = 1
	      id = widget_info(Widget_id, FIND_BY_UNAME = 'BUT_NEXUS_STACK_IMAGE')
	      widget_control, id, sensitive = 1
    endif else begin
	      id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
	      widget_control, id, sensitive = 0
	      id = widget_info(Widget_id, FIND_BY_UNAME = 'BUT_NEXUS_STACK_IMAGE')
	      widget_control, id, sensitive = 0
	endelse

; ---------- update display of images & other 2D data types
; print, 'AX_NEXUS: STARTING UPDATE OF IMAGE ', nexus_lastfile
 if preview_flag EQ 1 then begin
	 nexus_head = read_nexus(nexus_path + nexus_lastfile , /header_only)
	if TOTAL(STRLOWCASE(nexus_head.Type[0]) EQ ['sample image stack','sample']) then begin	 ; find number of stack image selected
		id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_IMAGE')
		nexus_image_index = WIDGET_INFO(id, /Droplist_select)		; get the index
		WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_image		; get the list of energies
		; get the selected image
	;	 print, 'Extracting single image at E = ', nexus_image(nexus_image_index)
		nexus_image_index = fix(nexus_image_index) +1	; kluge to avoid problem that IDL uses 0 as false !
	endif else begin
	  nexus_image_index = 1
	endelse
	ENDIF			;  End of \newfile processing
  endif

; ------ set the default microscope type   (13-Apr-18 aph)
; ----------- set current value of nexus-source
if n_elements(NEXUS_source) EQ 0 then begin		; if for some reason NEXUS_Source was not set, set the flags
	NEXUS_Source = 'pixelator'
	print, nexus_source  + ': Changing defaults to pixelator (no i-ring norm, no preview, no flip)'
	norm_flag = 0
    id = widget_info(Widget_id, FIND_BY_UNAME = 'BUT_NEXUS_NORMALIZE')
	WIDGET_CONTROL,id, set_button=norm_flag
	preview_flag = 0
	id = widget_info(Widget_id, FIND_BY_UNAME = 'BUT_NEXUS_PREVIEW')
	WIDGET_CONTROL,id, set_button=preview_flag
	nexus_flip = 0
	id = widget_info(Widget_id, FIND_BY_UNAME = 'BUT_NEXUS_FLIP')
	WIDGET_CONTROL,id, set_button=nexus_flip
endif
if NEXUS_Source EQ 'pixelator' then nexus_source_num = 0
if NEXUS_Source EQ 'pySTXM'    then nexus_source_num = 1
id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_SOURCE')
WIDGET_CONTROL,id, SET_DROPLIST_SELECT = nexus_source_num

; ------ get/set the data channel		; APH update 5-Sep-16
; print, 'nexus_channel coming in to get/set ', nexus_ch
id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_CHANNEL')
if n_Elements(nexus_ch) GT 0 then begin
	WIDGET_CONTROL,id, SET_DROPLIST_SELECT =nexus_ch
endif else begin
	nexus_ch = fix(WIDGET_INFO(id, /Droplist_select)) + 1
endelse
; print, 'nexus_channel = ', nexus_ch

; ----- get/set the region			; APH update 5-Sep-16
id = widget_info(Widget_id, FIND_BY_UNAME = 'WID_DLIST_REGION')
WIDGET_CONTROL,id, Sensitive=1, Get_value = nexus_region_list
; print, ' ****** '
; print, nexus_region_list
; print, ' ****** '
n_regions = n_elements(nexus_region_list)
; print, 'nexus_region coming in to get/set ', nexus_region
if n_Elements(nexus_region) GT 0 then begin
	if nexus_region GT n_regions then nexus_region = 0
	WIDGET_CONTROL,id, SET_DROPLIST_SELECT =nexus_region
endif else begin
	nexus_region = fix(WIDGET_INFO(id, /Droplist_select)) + 1
endelse
; print, 'nexus region = ', nexus_region_list(nexus_region-1)
; if nexus_region_list(n_regions - 1) EQ 'all regions' then nexus_region = 1


; -------- DISPLAY data on the ax_nexus plot window  if requested by user (preview_flag = 1)
IF preview_flag EQ 1 then begin
	widget_control, /hourglass
	if n_elements(nexus_lastfile) EQ 1 then nexus_file = nexus_path + nexus_lastfile else nexus_file = ''
	tmp = read_nexus(nexus_file, channel= nexus_ch+1, region = nexus_region+1,$
			xy_correct=xy_correct_flag, one_image = nexus_image_index, /no_save)
; help, tmp ,/struct
	wset, NexusImg
	tmp.dl = ''
	make_square,tmp
	if tmp.t EQ '2d' then splot2d, tmp
	if tmp.t EQ '1d' then plot, tmp.x, tmp.d
;; -------- update parameter information
	et = nexus_head.end_time  ; ISO format is: '2016-03-25T20:02:51+01:00'
	;print, 'et:  ', et
	end_date = strmid(et,0,10)
	q =strarr(3)
	q(0)=strmid(et,11,2)
	q(1)=strmid(et,14,2)
	q(2)=strmid(et,17,2)
	et = fix(q(0))*3600+fix(q(1))*60+fix(q(2))
	end_time = q(0) + ':' + q(1)+ ':' +q(2)
	st = nexus_head.start_time   ; ISO format is: '2016-03-25T20:02:51+01:00'
	;print, 'st:  ', st
	start_date = strmid(st,0,10)
	q =strarr(3)
	q(0)=strmid(st,11,2)
	q(1)=strmid(st,14,2)
	q(2)=strmid(st,17,2)
	st = fix(q(0))*3600+fix(q(1))*60+fix(q(2))
	start_time = q(0) + ':' + q(1)+ ':' +q(2)
	IF start_date EQ end_date THEN BEGIN
	  elapsed_time = fix(et) - fix(st)
	ENDIF ELSE BEGIN
	  elapsed_time = 86400 + fix(et) - fix(st)
	ENDELSE
	;print, 'end = ', end_time, '   start ', start_time, '  elasped ', elapsed_time
	id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_START')
	WIDGET_CONTROL,id, Set_value = ' ' + start_time
	id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_ELAPSED')
	WIDGET_CONTROL,id, Set_value = ' ' + strtrim(string(elapsed_time),2)

	IF TOTAL(STRLOWCASE(TAG_NAMES(tmp)) EQ 'e') THEN BEGIN
	  id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_ENERGY')
	  WIDGET_CONTROL,id, Set_value = ' ' + strtrim(string(tmp.e, format='(F8.2)'),2)
	ENDIF
; ******* KLUGE !   KLUGE !  KLUGE !  KLUGE !  KLUGE !  KLUGE !  *******
	if n_elements(nexus_image_index) EQ 0 then nexus_image_index = 1
; ****** END KLUGE ! ******
	dwell = float(nexus_head.count_time[nexus_image_index-1])  ; dwell time in seconds
	n_pixels = nexus_head.data_size ; # of pixels
	data_time = dwell*n_pixels
	efficiency = 100.*data_time/elapsed_time
	;print, 'data taking time = ', data_time, '  efficiency = ', efficiency
	id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_DATA_TIME')
	WIDGET_CONTROL,id, Set_value = ' ' + strtrim(string(data_time, format='(I5)'),2)
	id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_EFFICIENCY')
	WIDGET_CONTROL,id, Set_value = ' ' + strtrim(string(efficiency, format='(F4.1)'),2)
	id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_DWELL')
	WIDGET_CONTROL,id, Set_value = ' ' + strtrim(string(1000*dwell, format='(F5.2)'),2)
	;polarization = t.entry1.collection.polarization.value._data
	polarization = nexus_head.polarization
	id = widget_info(Widget_id, FIND_BY_UNAME = 'TEXT_NEXUS_POLARIZATION')
	WIDGET_CONTROL,id, Set_value = ' ' + strtrim(string(polarization, format='(F5.2)'),2)
ENDIF
END

pro BASE_NEXUS_event, Event
@axis_com
@nexus_com

  case Event.id of

    Widget_Info(Event.Top, FIND_BY_UNAME='TEXT_NEXUS_FNAME'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_CH' )then $
        TEXT_NEXUS_FNAME, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='WID_DLIST_SOURCE'): begin
        WID_DLIST_SOURCE, Event
    end
      Widget_Info(Event.Top, 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(Event.Top, 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(Event.Top, 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(Event.Top, FIND_BY_UNAME='BUT_NEXUS_FNAME_BROWSE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_FNAME_BROWSE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_RESET'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_RESET, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='TEXT_NEXUS_TYPE_TITLE_0'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_TEXT_DEL' )then $
        BUT_NEXUS_FNAME_BROWSE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_OK'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_OK, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_CANCEL'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_CANCEL, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_STACK_IMAGE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_Stack_IMAGE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_NORMALIZE'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_NORMALIZE, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_XY_CORRECT'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_XY_CORRECT, Event
    end
        Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_FLIP'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_FLIP, Event
    end
    Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_PARAMETERS'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_PARAMETERS, Event
    end
        Widget_Info(Event.Top, FIND_BY_UNAME='BUT_NEXUS_PREVIEW'): begin
      if( Tag_Names(Event, /STRUCTURE_NAME) eq 'WIDGET_BUTTON' )then $
        BUT_NEXUS_PREVIEW, Event
    end
        Widget_Info(Event.Top, FIND_BY_UNAME='TEXT_RING_CURRENT'): begin
        TEXT_RING_CURRENT, Event
    end


    else: print, 'Undefined action'
  endcase

end

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


pro BASE_NEXUS, GROUP_LEADER=wGroup,  file=file, _EXTRA=_VWBExtra_
@axis_com
@nexus_com

t = size(wGroup)
IF t(1) EQ 0 THEN modal_val=0 else modal_val=1

BASE_NEXUS = Widget_Base( GROUP_LEADER=wGroup, UNAME='BASE_NEXUS', TITLE='Read NeXus HDF5 files', modal = modal_val, /column)
row1 = widget_base(base_nexus,/row)
col1 = widget_base(row1,/column)
row = widget_base(base_nexus,/row)

; --------- display window
top_row = widget_base(base_nexus,/row)
col1 = widget_base(top_row,/col)
col2 = widget_base(top_row,/col)
row = widget_base(col1,/row,/align_right)
DRAW_NEXUS = widget_draw(row, retain = 2, uvalue = 'NeXus display', xsize = 180, ysize = 180) ;, /align_centre)

; row = widget_base(col1,/row,/align_center)
; tlabel = widget_label(row,value=' ')
; BUT_NEXUS_PARAMETERS = Widget_Button(row, UNAME='BUT_NEXUS_PARAMETERS', /ALIGN_CENTER ,VALUE='Parameters')

row = widget_base(col2,/row,/align_left)
tlabel = widget_label(row,value='Path ')
TEXT_NEXUS_PATH = Widget_Text(row, UNAME='TEXT_NEXUS_PATH', /FRAME,  XSIZE=50)

row = widget_base(col2,/row)
tlabel = widget_label(row,value='File ')
TEXT_NEXUS_FNAME = Widget_Text(row, UNAME='TEXT_NEXUS_FNAME', /FRAME,/EDITABLE ,ALL_EVENTS = 1 , KBRD_FOCUS_EVENTS = 0, XSIZE=50)
tlabel = widget_label(row,value=' ')
BUT_NEXUS_FNAME_BROWSE = Widget_Button(row, UNAME='BUT_NEXUS_FNAME_BROWSE', /ALIGN_CENTER ,VALUE=' Browse ')
tlabel = widget_label(row,value='   ')
BUT_NEXUS_RESET = Widget_Button(row, UNAME='BUT_NEXUS_RESET', /ALIGN_CENTER ,VALUE=' Reset ')

row = widget_base(col2,/row)
tlabel = widget_label(row,value='Type ')
TEXT_NEXUS_TYPE = Widget_Text(row, UNAME='TEXT_NEXUS_TYPE', EDITABLE=0 ,/ALL_EVENTS ,VALUE='Type', /ALIGN_CENTER , XSIZE=30)
tlabel = widget_label(row,value='   ')
tlabel = widget_label(row,value='   ')
BUT_NEXUS_Stack_Image = Widget_Button(row, UNAME='BUT_NEXUS_STACK_IMAGE',  VALUE='1 image')
tlabel = widget_label(row,value='   ')
BUT_NEXUS_CANCEL = Widget_Button(row, UNAME='BUT_NEXUS_CANCEL', /ALIGN_CENTER ,VALUE='Cancel')
tlabel = widget_label(row,value='       ')
BUT_NEXUS_OK = Widget_Button(row, UNAME='BUT_NEXUS_OK',  /ALIGN_CENTER, VALUE='  OK  ')

row = widget_base(col2,/row)

WID_BASE_1 = Widget_Base(row, UNAME='WID_BASE_1',COLUMN=3 ,/NONEXCLUSIVE)

BUT_NEXUS_PREVIEW = Widget_Button(wid_base_1, UNAME='BUT_NEXUS_PREVIEW', VALUE='Preview ?')


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

NEXUS_source_list =['pixelator  ','pySTXM      ']
WID_DLIST_SOURCE = Widget_Droplist(row, /DYNAMIC_RESIZE, VALUE = NEXUS_SOURCE_List, UNAME='WID_DLIST_SOURCE', TITLE='NEXUS source')

row = widget_base(col2,/row)
WID_BASE_2 = Widget_Base(row, UNAME='WID_BASE_2',COLUMN=3 ,/NONEXCLUSIVE)

BUT_NEXUS_XY_CORRECT = Widget_Button(wid_base_2, UNAME='BUT_NEXUS_XY_CORRECT', VALUE='xy correct ?')

BUT_NEXUS_FLIP = Widget_Button(wid_base_2, UNAME='BUT_NEXUS_FLIP', VALUE='flip image')

NEXUS_Channel_List =['PMT','OSA','Analog']
if n_Elements(NEXUS_ch) EQ 0 then NEXUS_Ch = 0
WID_DLIST_CHANNEL = Widget_Droplist(row, /DYNAMIC_RESIZE, VALUE = NEXUS_Channel_List, UNAME='WID_DLIST_CHANNEL', TITLE='Channel')

NEXUS_Region_List =['region 1']
if n_Elements(NEXUS_region) EQ 0 then NEXUS_region = 0
WID_DLIST_REGION = Widget_Droplist(row, /DYNAMIC_RESIZE, VALUE = NEXUS_Region_List, $
                   event_pro='WID_DLIST_REGION', UNAME='WID_DLIST_REGION', TITLE='Region')

NEXUS_Image_List =[' ']
NEXUS_Im = 0
WID_DLIST_IMAGE = Widget_Droplist(row, /DYNAMIC_RESIZE, VALUE = NEXUS_Image_List, UNAME='WID_DLIST_IMAGE', TITLE='Image #')

; ------ parameter display
row = widget_base(col2,/row)
tlabel = widget_label(row,value='Start time')
TEXT_NEXUS_start = Widget_Text(row, UNAME='TEXT_NEXUS_START', frame=0, xsize=8)
tlabel = widget_label(row,value='  Elapsed time (s)')
TEXT_NEXUS_elapsed = Widget_Text(row, UNAME='TEXT_NEXUS_ELAPSED', xsize=6)
tlabel = widget_label(row,value='  Data time (s)')
TEXT_NEXUS_data_time = Widget_Text(row, UNAME='TEXT_NEXUS_DATA_TIME', xsize=6)
tlabel = widget_label(row,value='  Efficiency (%)')
TEXT_NEXUS_efficiency = Widget_Text(row, UNAME='TEXT_NEXUS_EFFICIENCY', xsize=6)

row = widget_base(col2,/row)
tlabel = widget_label(row,value='Energy (eV)')
TEXT_NEXUS_energy = Widget_Text(row, UNAME='TEXT_NEXUS_ENERGY', frame=0, xsize=8)
tlabel = widget_label(row,value='  Dwell time (ms)')
TEXT_NEXUS_dwell = Widget_Text(row, UNAME='TEXT_NEXUS_DWELL', frame=0, xsize=8)
tlabel = widget_label(row,value='  Polarization')
TEXT_NEXUS_dwell = Widget_Text(row, UNAME='TEXT_NEXUS_POLARIZATION', frame=0, xsize=8)


; ----------- 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_NEXUS_TYPE, sensitive = 0
widget_control, BUT_NEXUS_Stack_Image, sensitive = 0
; GTK crash with RedHat6 on next line if NEXUS_Image_List is a zero length string
Widget_Control, /REALIZE, BASE_NEXUS

; ----------- get info needed to access the draw_window
widget_control, DRAW_NEXUS, GET_value=NexusImg

; ----------- set current value of normalization flag
if norm_flag EQ 1 then widget_control, BUT_NEXUS_Normalize, set_button = 1 $
  else widget_control, BUT_NEXUS_Normalize, set_button = 0

; ----------- set current value of xy_correct_flag
if xy_correct_flag EQ 1 then widget_control, BUT_NEXUS_xy_correct, set_button = 1 $
  else widget_control, BUT_NEXUS_xy_correct, set_button = 0

; ----------- set current value of nexus-flip_flag
if n_elements(nexus_flip) EQ 0 then nexus_flip = 0
if nexus_flip EQ 1 then widget_control, BUT_NEXUS_flip, set_button = 1 $
  else widget_control, BUT_NEXUS_flip, set_button = 0

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

; ----------- set current value of nexus-source
if n_elements(NEXUS_source) EQ 0 then begin		; if for some reason NEXUS_Source was not set, set the flags
	NEXUS_Source = 'pixelator'
	print, nexus_source  + ': Changing defaults to pixelator (no i-ring norm, no preview, no flip)'
	norm_flag = 0
	WIDGET_CONTROL, BUT_NEXUS_NORMALIZE, set_button=norm_flag
	preview_flag = 0
	WIDGET_CONTROL,BUT_NEXUS_PREVIEW, set_button=preview_flag
	nexus_flip = 0
	WIDGET_CONTROL,BUT_NEXUS_FLIP, set_button=nexus_flip
endif
CASE strtrim(NEXUS_Source,2) of
	'pixelator' : nexus_source_num = 0
	'pySTXM'    : nexus_source_num = 1
ENDCASE
WIDGET_CONTROL,WID_DLIST_SOURCE, SET_DROPLIST_SELECT = nexus_source_num

; ----------- set default value of ring current normalization value if not modified by user
if n_elements(nexus_norm_value) EQ 0 then begin
	nexus_norm_value = 1.
	if nexus_source_num EQ 0 then nexus_norm_value = 500.
	if nexus_source_num EQ 1 then nexus_norm_value = 200.
endif
WIDGET_CONTROL, TEXT_RING_CURRENT, set_value =string(nexus_norm_value, format='(F5.1)')
if preview_flag EQ 0 then widget_control, TEXT_RING_CURRENT, sensitive = 0


; ------ set last path and file name if they exist
; ------ use keyword file if provided
if keyword_set(file) then begin		; assume file contains path and extension
	t = ax_name(file)
	nexus_path = t(0)
	nexus_lastfile = t(1)+ '.hdf5'
	BASE_NEXUS_UPDATE, BASE_NEXUS, /new_file
endif

XManager, 'BASE_NEXUS', BASE_NEXUS
NEXUS_ID = BASE_NEXUS

end

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

function ax_nexus, file = file, GROUP_LEADER=wGroup, _EXTRA=_VWBExtra_
on_error,2
@axis_com
@nexus_com

nexus = ' '
if keyword_set(file) then begin
	BASE_NEXUS, GROUP_LEADER=wGroup, file=file, _EXTRA=_VWBExtra_
endif else begin
	BASE_NEXUS, GROUP_LEADER=wGroup, _EXTRA=_VWBExtra_
endelse

return, nexus
end
