; Copyright (c) 1998-2021 A.P. Hitchcock  All rights reserved
;+
;NAME:
;		read_pynx_stack.pro
;
;LAST CHANGED: ----------------------------------- 	6-Jul-2021 (aph)
;
; PURPOSE:
;	This function reads a set of ptycho reconstructed tif files
; (object_amplitude, object_phase, probe_amplitude, probe_phase)
;  from a set of folders with syntax:  yyyymmdd_###_stack_nrj## (e.g. 20201206_010_stack_nrj01)
; It stores the assembled stack in {*.ncb, *.dat} files
; Note that the PYNX reconstruction generates different sized results as E changes; largest array is at highest E
; Since aXis2000 stacks  require each miage to have same (x,y) dimensions, the images are meshed to largest size
;
; CATEGORY:
;	Read-in. Runs stand alone or inside aXis2000.
;
; CALLING SEQUENCE:
;	tmp = READ_PYNX_STACK(file=file)
;
; INPUTS: none	.
;
; KEYWORDS:
;	PATH 	path to folder
;	VERBOSE	print intermediate content
;	GROUP	group ID
;
; OUTPUTS:
;	*.(dat,ncb) written
;
; COMMON BLOCKS:
; AXIS.COM    standard set of common blocks
; DUV_COM     DUV data specific common block
;  volume_Data
; BSIF_COM
; stack_process_com
;
; PROCEDURE:
;	Reads list of directories (akafolders) inside a directory
;   Reads an energies and other parameters from the associated *.hdf5 file
;   Writes {*.ncb, *.dat} files
;   Launches stack_process with the stack
;
; MODIFICATION HISTORY:
; (28-Dec-20 aph) first version (modifed from read_duv_stack.pro)
; (31-Dec-20 aph) add kluge to treat cases where ax_interpret results in 1 less y pixel
; (15-Jun-21 aph) adapt for cases where nx .NE ny in the last file
; (24-Jun-21 aph) force default path for writing out stack to be same as folder data came from; save partial stacks
; (06-Jul-21 aph) adapt to revised storage of reconstruction, all in 1 file; ask user to identify mode
;-

FUNCTION  read_pynx_stack, path=path, verbose=verbose, group = group
@axis_com
@stack_process_com
COMMON volume_data, image_stack
@bsif_com

on_error,2

null = 0

; ------------ get energies, (x,y) and dwell values from *.hdf5 file
f_stxm = dialog_pickfile(title='Select STXM *.hdf5 file',filter=['*.hdf5'], path=DefPath, get_path=folder_path)

if strlen(f_stxm) EQ 0 then RETURN, null
if keyword_Set(verbose) then print, 'STXM stack  = ' ,f_stxm

; --- force path for writing to be the source folder
DefPath=folder_path

stxm = h5_parse(f_stxm, /read_data)

ev = stxm.entry1.camera.energy._data
if keyword_Set(verbose) then  print, '# of energies in this stack is ', n_elements(ev)
if keyword_Set(verbose) then  print, ev

if keyword_Set(verbose) then  print, 'Energies', ev
x = stxm.entry1.camera.sample_x._data
if keyword_Set(verbose) then  print, 'x-values',x
y = stxm.entry1.camera.sample_y._data
if keyword_Set(verbose) then  print, 'y-values',y
t = stxm.entry1.camera.count_time._data  & dwell = t(0)		; for now will get '0' but Stefan may change
if keyword_Set(verbose) then  print, 'dwell (ms)',dwell

;---------  extract folder_path -  name of the folder containing tif files or set of folders with reconstruction results
t = ax_name(f_stxm) & folder_path=t(0)

; ---- SWITCH depending on pre-June 25, 2021  or post-June 25, 2021 format

 pynx_mode =dialog_message('Seperate folders ?', /question, /default_no, dialog_parent= aXis_ID, title='identify format of PYNX results')

IF pynx_mode EQ 'Yes' then begin

; ============= FIRST version ========  images in separate folders ========
	; -----------  get list of the folders with reconstruction results
	folder_names=file_search(folder_path,'*',/test_dir,count=cc)
	if n_elements(folder_names) EQ 0 then RETURN, null
	if keyword_Set(verbose) then print, 'folder_names = ' ,folder_names

	;------ for the last (highest energy) reconstruction (largest #pixels)
	;   ask user to select the type of reconstructed data to read (object_amplitude, object_phase, probe_amplitude, probe_phase)
	last_image = n_elements(folder_names)-1
	fname = dialog_pickfile(title='Select type of tif', path= folder_names(last_image))
	if fname EQ ''  then return, null

	; ---- generate array of folder&file names
	n_images = n_elements(folder_names)
	file_names = strarr(n_images)
	t = ax_name(fname)
	for i = 0, n_images-1 do begin
		file_names(i) = folder_names(i)  + ax_sep() + t(1) + '.tif'
	endfor
	if keyword_Set(verbose) then print,file_names

ENDIF ELSE begin

; =========== SECOND version ========  images all in one folders - use nrj## to make loop ========

	;   ask user to select a file to identify the type of reconstructed data to read (object_amplitude, object_phase, probe_amplitude, probe_phase)

	test  = dialog_pickfile(title='Select type of data', filter=['*.tif'], path=DefPath)
 	if strlen(test) EQ 0 then RETURN, null

;	EXAMPLE name  stack_20210609_045_nrj01_run01_Object_Amplitude		go back 2 '_' to identify type of data
;	CAUTION  - /reverse_Search  was only introduced in IDL 6.0  so will not work on  IDL 5.2

	t = ax_name(test) & t2 = t(1)
	if keyword_Set(verbose) then  print,'identifying type of data from string ', test
	main_name=strmid(t2, 0, strpos(strmid(t2, 0,strpos(t2,'_',/reverse_search)),'_',/reverse_search))
	d_type= strmid(t2, strpos(strmid(t2, 0,strpos(t2,'_',/reverse_search)),'_',/reverse_search))
	d_type=strmid(d_type,1)

	if keyword_Set(verbose) then  print, 'main name:  ', main_name, '       type of data: ' , d_type

; get list of all files and filter those with d_type in their name

	d_wild = '*'+d_type +'.tif'
	file_names=file_search(folder_path,d_wild,count=cc, /fold_case)
	if keyword_Set(verbose) then begin
		print, 'list of all files containing  ', d_wild
		for i = 0, n_elements(file_names)-1 do begin
			print, file_names(i)
		endfor
	endif

ENDELSE

; ----------- load last image to get maximum image size  (assumes energies will always be scanned from lower to higher values)
fname = file_names(n_elements(file_names)-1)
tmp1 = img_load(file=fname, /TIF, /VALUES, /silent)

nx = n_elements(tmp1.x)
ny = n_elements(tmp1.y)
if ny NE nx then ny=nx	; KLUGE 0 : sometimes the last file is non-square !!  15 June 2021
n_energies = n_elements(file_names)
img_name=strarr(n_energies)
image_stack=fltarr(nx, ny, n_energies)


axis_log, 'generate stack from PYNX ptycho images'
axis_log, ' image size = ' + strtrim(string(nx),2) +' * ' + strtrim(string(ny),2)
axis_log, ' # energies = ' + strtrim(string(n_energies),2)

WIDGET_CONTROL, /Hourglass

t = ax_name(fname)
fname=t(1)+'.'+ t(2)

; -------- process only files that are in folder_names
n_images = n_elements(file_names)
for i = 0, n_images-1 do begin
	if keyword_Set(verbose) then $
		print, 'reading image ', i+1
	tmp = img_load(file=file_names(i),/TIF, /VALUES, /silent)

;  KLUGE 1:  to get around fact that PYNX does not gnerate identical sized tif files - re-bin to match (nx, ny) if close
	if n_elements(tmp.x) NE nx then begin
;		if keyword_Set(verbose) then $
;				print, 'image ', i, '   ', size(tmp.d)
;				print, 'image ', i, '  remeshed from ', n_elements(tmp.x), ' by ', n_elements(tmp.y),' to ', nx, ' by ', ny
		tmp = ax_interp(tmp, mesh=[nx,ny])
;				print, 'image ', i, '   ', size(tmp.d)
	endif
; KLUGE 2 - to get around fact that there is occcasionally 1 less value of the y-index
	t = size(tmp.d)
	if t(1) NE t(2) then begin
;		help, tmp, /struct
		print, 'Using kluge #2. . . for image ',i, '  redoing ax_interp with ny+1'
		tmp = ax_interp(tmp, mesh=[nx,ny])
;		help, tmp, /struct
	endif

	image_stack(*,*,i) = tmp.d
endfor

; ---- generate information needed for stack

x_start= x(0) & x_step = (x(n_elements(x)-1) - x(0))/nx
y_start= y(0) & y_step = (y(n_elements(y)-1) - y(0))/ny
x = findgen(nx)  & y = findgen(nx)

x = x_start+ x_step*x
y = y_start+ y_step*y
x_stop = x(nx-1) & y_stop = y(ny-1)


FILENAME_EV_MSEC_LIST = strarr(n_images)

; t=strsplit(folder_path,ax_sep(),/extract)
; name = t(n_elements(t)-1)
name ='pynx'
for i = 0, n_elements(file_names)-1 do begin
	FILENAME_EV_MSEC_LIST(i) = name +'_' + string(i+1) + ' ' + string(ev(i)) + ' ' + string(dwell)
endfor

; ---- construct and write stack file
t = ax_name(fname)
sname = name + '.ncb'

sname=pickfile2(title='Choose name of stack file', file = sname, filter='*.ncb', path = DefPath, lpath=DefPath)

if sname NE '' then  stack_wb, sname

return, sname
END
