; Copyright (c) 1998-2015 A.P. Hitchcock  All rights reserved
;+
;NAME:
;	AX_BIN
;
;LAST CHANGED: ----------------------------------- 13-Jan-15
;
;PURPOSE:
;	This procedure bins one or more image files in various formats
; BIN times (2 implies (2x2) pixels merged to 1 pixel ETC
;	If NetCDF image files (*.nc) it reads one or a sequence of files
; If the energy keyword is set, the data is binned in energy rather than spatial dimensions
; The smoothed image is written into b______.nc
; where _____ is all but first letter of name suplied
;
;CATEGORY:
;	AXIS: stack analysis
;
;CALLING SEQUENCE:
;	AX_BIN, list [, bin=bin, one=one, energy=energy, stack=stack, lox = lox ]
;
;CALLED FROM AXIS:
;	->Stacks->bin.{current image, NSLS.{1,file}, stack (*.ncb,lox)}
;
;INPUTS:
;	LIST = file containing list of *.nc files (typically a *.sl stack list)
;
;KEYWORDS:
;	BIN =  number of (#x#) pixels (or energies)  to average
; ENERGY - if set, bins stack data in energy rather than spatial dimension
;	ONE     - if set, read in only a single file (use pickfile dialog if needed)
;	LOX		- lox stack data set
; STACK   - process a *.ncb binary stack file
;
;OUTPUTS:
;	b_____.nc binned file written in default subdirectory
;   stack____s.ncb
;
;COMMON BLOCKS:
;	AXIS_COM	standard set of common blocks
;	BSIF_COM	NetCDF common block
;	STACK_PROCESS_COM
;	VOLUME_DATA
;
;MODIFICATION HISTORY:
; (aph 12-jan-99) first written - adapted from ax_rd_im, bin
; (aph 17-May-99) corrected to resize on x as well as y
; (31-dec-99 aph) AXIS standard documentation
; (09-jan-00 aph) fixed up output filename to remove ___nc.nc
; (20-nov-04 aph) add bin of stacks; activate read one *.nc file
; (10-dec-07 aph) add lox stack binning
; (23-Jul-10 aph) add energy binning
; (13-Jan-15 aph) correct code errors in energy binning
;-

PRO ax_bin, list, bin=bin, energy = energy, one=one, stack = stack, lox = lox
@axis_com
@bsif_com
@stack_process_com
COMMON volume_data, image_stack

IF bin EQ 1 OR not Keyword_Set(bin) THEN RETURN

if widget_info(/active) EQ 1 then widget_control, /hourglass

IF keyword_set(stack)then begin
	IF keyword_set(lox) then BEGIN
; -----------  get lox stack
		tmp = ax_lox(group_leader=axis_ID)
		if  n_tags(tmp) NE 0 THEN RETURN
;		help, image_stack
	ENDIF ELSE BEGIN
		ncb_file = pickfile2(/READ, FILTER='*.ncb',/LPATH, DEFPATH=defpath, $
		    TITLE = 'Select binary stack file')
		Write_path = Lpath
		IF strlen(ncb_file(0)) EQ 0 THEN BEGIN
			print, 'no file to process'
			return  ; bail-out if no filename
		ENDIF
		stack_rb, ncb_file(0)
	ENDELSE
	t = size(image_stack)
	n_cols = t(1)    &   n_rows = t(2)   &    n_data = t(3)
	print, 'Input stack  (cols, rows, energies)  ', n_cols, n_rows, n_data
	; ----------- bin stack in energy dimension -----------
  if Keyword_set(energy) then begin
    axis_log, 'Warning: energy scale should be uniformly spaced!'
    if (float(n_data)/float(bin))-fix(n_data/bin) GT 0 then begin
      ndt =fix(n_data/bin)*bin
      xtra_data = n_data - ndt + 1
      tmp = image_stack                      ;force size to integer mutiple of bin
      image_stack = fltarr(n_cols,n_rows,ndt)
      image_stack = tmp(*,*,0:n_data-xtra_data)
    endif
    t = size(image_stack)
    n_cols = t(1)    &   n_rows = t(2)   &    n_data = t(3)
    image_stack = rebin(image_stack,n_cols,n_rows,n_data/bin)
    e_start = ev(0) & e_stop = ev(n_data-1)
    e_slope = (e_stop-e_start)/(n_data/bin)
    ev = e_start + e_slope*findgen(n_data/bin)
    n_data = fix(n_data/bin)
    print, 'E-bin: Output stack  (cols, rows, energies)  ', n_cols, n_rows, n_data

  endif else begin

  	if (float(n_cols)/float(bin))-fix(n_cols/bin) GT 0 $
      		OR (float(n_rows)/float(bin))-fix(n_rows/bin) then begin
  	    nct =fix(n_cols/bin)*bin  &  nrt = fix(n_rows/bin)*bin
  	    xtra_c = n_cols - nct + 1
  	    xtra_r = n_rows - nrt + 1
  	    print, 'truncating image to ', fix(nct), fix(nrt)
  	    x_stop = x_stop*float(nct)/float(n_cols)  ; correct axis length for truncation
  	    y_stop = y_stop*float(nrt)/float(n_rows)
  	        tmp = image_stack                      ;force size to integer mutiple of bin
  	    	image_stack = fltarr(nct,nrt,n_data)
  			image_stack = tmp(0:n_cols-xtra_c,0:n_rows-xtra_r,0:n_data-1)
  	 endif
        n_cols = fix(n_cols/bin)
        n_rows = fix(n_rows/bin)
        print, 'bin image ', fix(bin), ' times,  to ',n_cols,'  x', n_rows
        image_stack = rebin(image_stack,n_cols,n_rows,n_data)
		print, 'Output stack  (cols, rows, energies)  ', n_cols, n_rows, n_data
   endelse

; ---------------------- write out the binned data
;   help, image_stack
	outfile = pickfile2(/write, filter='*.ncb', /Lpath, Title = 'Filename for binned stack', $
       defpath = WritePath) ;, get_path=WritePath)
	if outfile EQ '' then return
	t = ax_name(outfile)
	fileshort = t(1)
	outfile = t(0)+t(1)+'.ncb'	; force extension to '.ncb'
	stack_wb, (outfile)
	text =  'Wrote binned stack data to ' + fileshort
	axis_log, text
    return
ENDIF

IF keyword_set(one) then BEGIN
	file = list
;	print, 'Reading in ', file
	read_stxm,file, sd, kHz
    if (float(n_cols)/float(bin))-fix(n_cols/bin) GT 0 $
		OR (float(n_rows)/float(bin))-fix(n_rows/bin) then begin
        nct =fix(n_cols/bin)*bin  &  nrt = fix(n_rows/bin)*bin
        xtra_c = n_cols - nct + 1
        xtra_r = n_rows - nrt + 1
;        print, 'truncate image to ', fix(nct), fix(nrt)
        x_stop = x_stop*float(nct)/float(n_cols)  ; correct axis length for truncation
        y_stop = y_stop*float(nrt)/float(n_rows)
        tmp = image_data                      ;force size to integer mutiple of bin
        image_data = intarr(nct,nrt,n_data)
		image_data = tmp(0:n_cols-xtra_c,0:n_rows-xtra_r,0:n_data-1)
    endif
    n_cols = fix(n_cols/bin)
    n_rows = fix(n_rows/bin)
;      print, 'bin image ', fix(bin), ' times,  to ',n_cols,'  x', n_rows
    image_data = rebin(image_data,n_cols,n_rows,n_data)
; write out the binned data
	outfile = pickfile2(/write, filter='*.ncb', /Lpath, $
       defpath = WritePath) ;, get_path=WritePath)
	if outfile EQ '' then return
	t = ax_name(outfile)
	fileshort = t(1)
	outfile = t(0)+t(1)+'.ncb'
	wrstx_ax, (outfile)
	text =  'Wrote binned data to ' + fileshort
	axis_log, text
	return
ENDIF ELSE BEGIN	; assume there is a stacklist (*.sl) of *nc files

	stack_readlist, list, filelist
	svec = size(filelist)
	IF (svec(0) EQ 0) THEN BEGIN
	    print,'Could not find the list file'
	    return
	ENDIF
	n_files = n_elements(filelist)
	on_ioerror,bailout
	FOR i_file = 0, (n_files-1) DO BEGIN
		file = filelist(i_file)
;			print, 'Reading in ', file
		read_stxm,file, sd, kHz
	    if (float(n_cols)/float(bin))-fix(n_cols/bin) GT 0 $
    		OR (float(n_rows)/float(bin))-fix(n_rows/bin) then begin
	        nct =fix(n_cols/bin)*bin  &  nrt = fix(n_rows/bin)*bin
	        xtra_c = n_cols - nct + 1
	        xtra_r = n_rows - nrt + 1
;        print, 'truncate image to ', fix(nct), fix(nrt)
	        x_stop = x_stop*float(nct)/float(n_cols)  ; correct axis length for truncation
	        y_stop = y_stop*float(nrt)/float(n_rows)
	        tmp = image_data                      ;force size to integer mutiple of bin
	        image_data = intarr(nct,nrt,n_data)
			image_data = tmp(0:n_cols-xtra_c,0:n_rows-xtra_r,0:n_data-1)
	    endif
	    n_cols = fix(n_cols/bin)
	    n_rows = fix(n_rows/bin)
;      print, 'bin image ', fix(bin), ' times,  to ',n_cols,'  x', n_rows
	    image_data = rebin(image_data,n_cols,n_rows,n_data)
; write out the binned data
     	t = ax_name(file)
	 	file_path = t(0)          ; aligned data in same subdirectory
	 	fileshort = t(1)
	 	fileshort = strmid(fileshort,1,strlen(fileshort)-1)
	 	outfile = strlowcase('b'+ fileshort + '.nc') ; force 'nc' extension
		wrstx_ax, (file_path + outfile)
		WIDGET_CONTROL, Uprompt, Bad_ID = badID, $
		  Set_Value = 'Bin *'+strcompress(string(fix(bin)))+'.  Wrote to file ' + outfile
		print, 'Wrote binned data to ', file_path + outfile
	ENDFOR
	print, 'Output stack  (cols, rows, energies)  ', n_cols, n_rows, n_files
ENDELSE
return

bailout:
print,'Bailing out of AX_BIN because of an error'
close,/all
return
END
