;+
; NAME:
;         p3d_tracing_expand_traces
;
;         $Id: p3d_tracing_expand_traces.pro 79 2010-03-04 14:24:25Z christersandin $
;
; PURPOSE:
;         This routine calculates spectrum cross-dispersion positions for all
;         wavelength bins, starting with an array of positions which was
;         calculated for a scaled-down array (in the dispersion direction;
;         REFPOS). For every spectrum, totally MAXPOS in number, positions
;         along the dispersion direction are linearly interpolated between the
;         already calculated positions of REFTRACES.
;
; AUTHOR:
;         Christer Sandin
;         Astrophysikalisches Institut Potsdam (AIP)
;         An der Sternwarte 16
;         D-14482 Potsdam, GERMANY
;
; COPYRIGHT:
;         p3d: a general data-reduction tool for fiber-fed IFSs
;
;         Copyright 2009,2010 Astrophysikalisches Institut Potsdam (AIP)
;
;         This program is free software; you can redistribute it and/or modify
;         it under the terms of the GNU General Public License as published by
;         the Free Software Foundation; either version 3 of the License, or
;         (at your option) any later version.
;
;         This program is distributed in the hope that it will be useful, but
;         WITHOUT ANY WARRANTY; without even the implied warranty of
;         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;         General Public License for more details.
;
;         You should have received a copy of the GNU General Public License
;         along with this program; if not, see <http://www.gnu.org/licenses>.
;
;         Additional permission under GNU GPL version 3 section 7
;
;         If you modify this Program, or any covered work, by linking or
;         combining it with IDL (or a modified version of that library),
;         containing parts covered by the terms of the IDL license, the
;         licensors of this Program grant you additional permission to convey
;         the resulting work.
;
; CATEGORY:
;         p3d :: tracing of spectra on the CCD
;
; CALLING SEQUENCE:
;         p3d_tracing_expand_traces,reftraces,refpos,maxpos,out, $
;             topwid=,logunit=,verbose=,error=,/debug,/help
;
; INPUTS:
;         reftraces       - A two-dimensional array of floating point numbers,
;                           which provide the spectrum cross-dispersion
;                           positions for every spectrum and a number of
;                           wavelength bins, which has to be the same as the
;                           number of elements in REFPOS.
;         refpos          - A one-dimensional array of integers specifying the
;                           pixels along the dispersion direction in the OUT
;                           array (and original data array), which were used to
;                           create the scaled-down array. The number of
;                           elements in REFPOS must be the same as the number
;                           of wavelength bins in REFTRACES.
;         maxpos          - A scalar integer specifying the number of
;                           wavelength bins in the output array.
;
; KEYWORD PARAMETERS:
;         topwid          - If set, then error messages are displayed using
;                           DIALOG_MESSAGE, using this widget id as
;                           DIALOG_PARENT, instead of MESSAGE.
;         logunit         - Messages are saved to the file pointed to by this
;                           logical file unit, if it is defined.
;         verbose         - Show more information on what is being done.
;         error           - Returns an error code if set.
;         debug           - The error handler is not setup if debug is set.
;         help            - Show this routine documentation, and exit.
;
; OUTPUTS:
;         out             - A two-dimensional array of floating point type
;                           which holds the linearly interpolated spectrum
;                           cross-dispersion positions for every spectrum
;                           (1...NSPEC) and wavelength bin (1...MAXPOS).
;
; COMMON BLOCKS:
;         none
;
; SIDE EFFECTS:
;         none
;
; RESTRICTIONS:
;         IDL version 6.2 or higher is required.
;
; MODIFICATION HISTORY:
;         07.10.2008 - Converted from the original routine expand_traces of
;                      Thomas Becker. /CS
;-
PRO p3d_tracing_expand_traces,reftraces,refpos,maxpos,out,topwid=topwid, $
        logunit=logunit,verbose=verbose,error=error,debug=debug,help=help
  compile_opt hidden,IDL2

  if !version.release lt 6.2 then message,'IDL Version <6.2. Cannot continue.'
  error=0 & rname='p3d_tracing_expand_traces: '
  if ~n_elements(verbose) then verbose=0
  debug=keyword_set(debug)

  if keyword_set(help) then begin
    doc_library,'p3d_tracing_expand_traces'
    return
  endif

  ;;========================================------------------------------
  ;; Setting up an error handler:

  if ~debug then begin
    catch,error_status
    if error_status ne 0L then begin
      p3d_misc_errors,error_status,rname=rname,topwid=topwid
      catch,/cancel
      error=-1
      return
    endif
  endif ;; ~debug

  ;;========================================------------------------------
  ;; Checking the input arguments:

  s=size(reftraces)
  if s[0L] ne 2L and s[0L] ne 1L or $
    (s[s[0L]+1L] ge 6L and s[s[0L]+1L] le 11L) then begin
    errmsg='REFTRACES must be set; to a one- or two-dimensional array of f' + $
           'loating point values.'
    goto,error_handler
  endif
  nspec=s[0L] eq 1L?1L:s[2L]

  s=size(refpos)
  if s[0L] ne 1L or (s[s[0L]+1L] ge 6L and s[s[0L]+1L] le 11L) then begin
    errmsg='REFPOS must be set; to a one-dimensional array.'
    goto,error_handler
  endif
  sp=s[s[0L]+2L]

  s=size(maxpos)
  if s[s[0L]+2L] ne 1L or (s[s[0L]+1L] ge 4L and s[s[0L]+1L] le 11L) then begin
    errmsg='MAXPOS must be set to a scalar integer; >=1.'
    goto,error_handler
  endif
  if maxpos lt 1L then begin
    errmsg='MAXPOS must be set to a scalar integer; >=1.'
    goto,error_handler
  endif

  ;;========================================------------------------------
  ;; Creating the output array, considering the dispersion direction:

  out=fltarr(maxpos,nspec)

  ;;========================================------------------------------
  ;; The first element of REFPOS:

  if refpos[0L] gt 0L then begin

    if sp ge 2L then begin

      tmp=findgen(refpos[0L]+1L)/(refpos[1L]-refpos[0L])

      ;; Looping over all spectra:
      for k=0L,nspec-1L do begin
        out[0L:refpos[0L],k]=tmp*(reftraces[1L,k]-reftraces[0L,k])
        out[0L:refpos[0L],k]+=-out[refpos[0L],k]+reftraces[0L,k]
      endfor

    endif else begin

      ;; Looping over all spectra, for the only wavelength bin available:
      out[0L:refpos[0L],*]=rebin(out[refpos[0L],*],refpos[0L]+1L,nspec)

    endelse

  endif ;; refpos[0L] gt 0L

  ;;========================================------------------------------
  ;; Looping over all intermediate elements of REFPOS:

  ;; Looping over all wavelength bins:
  for L=0L,sp-2L do begin
    tmp=findgen(refpos[L+1L]-refpos[L]+1L)/(refpos[L+1L]-refpos[L])

    ;; Looping over all spectra:
    for k=0L,nspec-1L do begin
      out[refpos[L]:refpos[L+1L],k]=tmp*(reftraces[L+1L,k]-reftraces[L,k])
      out[refpos[L]:refpos[L+1L],k]+=-out[refpos[L],k]+reftraces[L,k]
    endfor
  endfor

  ;;========================================------------------------------
  ;; The last element of REFPOS:

  if refpos[sp-1L] lt maxpos-1L then begin
    if sp ge 2L then begin

      tmp=findgen(maxpos-refpos[sp-1L])/(refpos[sp-1L]-refpos[sp-2L])

      ;; Looping over all spectra:
      for k=0L,nspec-1L do begin
        out[refpos[sp-1L]:maxpos-1L,k]=tmp* $
          (reftraces[sp-1L,k]-reftraces[sp-2L,k])
        out[refpos[sp-1L]:maxpos-1L,k]+= $
          -out[refpos[sp-1L],k]+reftraces[sp-1L,k]
      endfor

    endif else begin

      ;; Looping over all spectra, for the only wavelength bin available:
      out[refpos[sp-1L]:maxpos-1L,*]= $
        rebin(out[refpos[sp-1L],*],maxpos-refpos[sp-1L],nspec)

    endelse ;; sp ge 2L
  endif ;; refpos[sp-1L] lt maxpos-1L

  ;;===================----------
  ;; Logging the performed operations:

  msg=['Expand traces :: Step 2c [finding positions for all wavelength b' + $
       'ins]', $
       '  '+strtrim(sp,2L)+' -> (linear interpolation) -> '+ $
       strtrim(maxpos,2L)+' wavelength bins.']
  error=p3d_misc_logger(msg,logunit,loglevel=1,rname=rname, $
      verbose=verbose ge 1)

  return

error_handler:
  error=p3d_misc_logger(errmsg,logunit,rname=rname,topwid=topwid, $
      verbose=verbose,/error)
  return
END ;;; procedure: p3d_tracing_expand_traces
