; $Id: dm_grid_ebin.pro,v 1.7 2005/06/15 14:40:49 ymqiu Exp $
;#######################################################################
;
; NAME:
;  dm_grid_ebin
;
; PURPOSE:
;  rebin time channel, use idl rebin function
;
; CATEGORY:
;  general
;
; AUTHOR:
;  Yiming Qiu
;  NIST Center for Neutron Research
;  100 Bureau Drive, Gaithersburg, MD 20899-8562
;  United States
;  yiming.qiu@nist.gov
;  June, 2005
;
; LICENSE:
;  The software in this file is written by an employee of
;  National Institute of Standards and Technology
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used or if the code in this file is
;  included in another product.
;
;#######################################################################

; parameters:
;   ebin_size:    rebin size
;   qty,err [ntchan,ndet,[nfile]] emean [ntchan]
;     or
;   qty[ntchan]
; keyword:
;   avgsum:     0:average 1:sum
;   histdata:   [ntchan+1]
pro dm_grid_ebin,ebin_size,qty,err,emean,histdata=histdata,debug=debug,avgsum=avgsum
    if keyword_set(debug) then begin
       print,'@@grid ebin...'
       current= systime(/sec)
    endif

    n_par = n_params()
    if ebin_size le 0 then ebin_size=1L
    ebin_size = long(ebin_size)
    arr_size  = size(qty,/dimension) & if arr_size[0] eq 0 then arr_size[0]=1
    old_size  = arr_size[0]
    new_size  = (arr_size[0]+ebin_size-1L)/ebin_size      ;new E size
    dif_size  = new_size*ebin_size-arr_size[0]

    if dif_size gt 0 then begin   ;not integral factor
       new_size = new_size-1L
       dif_size = arr_size[0]-new_size*ebin_size
       old_size = arr_size[0]-dif_size
       factor0  = float(dif_size)
       if keyword_set(avgsum) then factor1=factor0 else factor1=1.0
       if n_par eq 4 then begin
          tmp_qty   = qty[old_size:(arr_size[0]-1),*,*,*]
          tmp_err   = err[old_size:(arr_size[0]-1),*,*,*]
          tmp_emean = emean[old_size:(arr_size[0]-1)]
          if old_size gt 0 then begin
             qty       = qty[0:(old_size-1),*,*,*]
             err       = err[0:(old_size-1),*,*,*]
             emean     = emean[0:(old_size-1)]
          endif
          if n_elements(arr_size) eq 2 then begin
             tmp_qty = rebin(tmp_qty,1,arr_size[1])*factor1
             tmp_err = sqrt(rebin(tmp_err^2,1,arr_size[1])/factor0)*factor1
          endif else begin
             tmp_qty = rebin(tmp_qty,1,arr_size[1],arr_size[2])*factor1
             tmp_err = sqrt(rebin(tmp_err^2,1,arr_size[1],arr_size[2])/factor0)*factor1
          endelse
          tmp_emean  = rebin(tmp_emean,1)
       endif else if n_par eq 2 then begin     ;qty[ntchan]
          tmp_qty = qty[old_size:(arr_size[0]-1)]
          if old_size gt 0 then $
             qty  = qty[0:(old_size-1)]
          tmp_qty = rebin(tmp_qty,1)*factor1
       endif
    endif

    if new_size ne 0 then begin
       factor0 = float(ebin_size)
       if keyword_set(avgsum) then factor1=factor0[0] else factor1=1.0
       if n_par eq 4 then begin
          if n_elements(arr_size) eq 2 then begin
             qty = rebin(qty,new_size,arr_size[1])*factor1
             err = sqrt(rebin(err^2,new_size,arr_size[1])/factor0)*factor1
          endif else begin
             qty = rebin(qty,new_size,arr_size[1],arr_size[2])*factor1
             err = sqrt(rebin(err^2,new_size,arr_size[1],arr_size[2])/factor0)*factor1
          endelse
          emean = rebin(emean,new_size)
          if dif_size ne 0 then begin
             if n_elements(arr_size) eq 2 then begin
                qty = transpose([[transpose(qty)],[transpose(tmp_qty)]])
                err = transpose([[transpose(err)],[transpose(tmp_err)]])
             endif else begin
                qty = transpose([[[transpose(qty)]],[[transpose(tmp_qty)]]])
                err = transpose([[[transpose(err)]],[[transpose(tmp_err)]]])
             endelse
             emean = [emean,tmp_emean]
          endif
       endif else if n_params() eq 2 then begin
          qty = rebin(qty,new_size)*factor1
          if dif_size ne 0 then $
             qty = [qty,tmp_qty]
       endif
    endif else begin
       qty = tmp_qty
       if n_par eq 4 then begin
          err   = tmp_err
          emean = tmp_emean
       endif
    endelse

    if n_elements(histdata) ne 0 then begin
       ndat     = n_elements(histdata)
       new_size = fix(float(ndat-1)/ebin_size+0.999,type=3)
       ind      = [ebin_size*lindgen(new_size),ndat-1]
       histdata = histdata[ind]
    endif

    if keyword_set(debug) then begin
       print,'@@grid ebin finished in ',systime(/sec)-current,' sec.'
    endif
end