;---------------------------------------------------------------------------
; Document name: S_EDGE_WAVE.PRO
; Created by:    Dietmar Germerott, MPAE Lindau, February 18, 2004
;
; Last Modified: Mon Nov 28 11:57:34 2011 (germerott.nospam@linmpi.mpg.de)
;---------------------------------------------------------------------------
;
FUNCTION s_edge_wave, bin_header, struct_header=struct_header, errmsg=errmsg
;+
; PROJECT:
;       SOHO - SUMER
;
; NAME:
;       S_EDGE_WAVE()
;
; PURPOSE: 
;       Compute the wavelength at the readout windoe edges
;
; CATEGORY:
;       SUMER analysis
; 
; EXPLANATION:
;       
; SYNTAX: 
;       Result = s_edge_wave(bin_header)
;
; EXAMPLES:
;       image_header=read_bin_header('sumer_image_header.hdr')
;       result=s_edge_wave(image_header [,errmsg=errmsg])
;       
; INPUTS:
;       bin_header - sumer binary image header
;
; OPTIONAL INPUTS: 
;       None.
;
; OUTPUTS:
;       result - structure with tags w1 and w2, dl_0 and lam511.
;                where w1 is the low end wavelength of image and
;                w2 is the high end wavelength of current image.
;                dl_0 the dispersion and lam511 the calculated wavelength
;                on detector A pixel 511.
;
; OPTIONAL OUTPUTS:
;       None.
;
; KEYWORDS: 
;       struct_header - SUMER decoded header structure as input
;
; COMMON:
;       None.
;
; RESTRICTIONS: 
;       None.
;
; SIDE EFFECTS:
;       If keyword struct_header and bin_header are present as input
;       the headers are taken from the struct_header keyword !
;
; HISTORY:
;       Version 1, February 18, 2004, Dietmar Germerott, MPAE Lindau. Written
;       Version 2, December 5, 2006, Dietmar Germerott, MPAE Lindau
;          Corrected the ordering of wavelength in case of second order
;          Added dl_0 and lam511 to result structure
;       Version 3, November 28, 2011, Dietmar Germerott, MPS
;          Made processing in case of no Detector images more efficient.
;
; CONTACT:
;       Dietmar Germerott, MPAE Lindau (germerott.nospam(at)linmpi.mpg.de)
;-
;
;   ON_ERROR, 2
   
   errmsg = ''
   IF ((N_PARAMS() LT 1) AND (NOT KEYWORD_SET(struct_header)))  THEN BEGIN
      PRINT, 'S_EDGE_WAVE -- Syntax error.'
      PRINT, '   Usage: result=S_EDGE_WAVE( bin_header)'
      PRINT, '      or: result=S_EDGE_WAVE( struct_header=struct_header)'
      PRINT, ' '
      RETURN, -1
      
   ENDIF
   
   IF NOT KEYWORD_SET(struct_header)  THEN BEGIN
      
      struct_header = sid_mindec_head(bin_header,errmsg=errmsg)
      IF errmsg NE '' THEN BEGIN
         PRINT,' Maybe you entered a structure - then use'
         PRINT,' result=S_EDGE_WAVE( struct_header=struct_header)'
         PRINT,''
         GOTO,handle_error
      ENDIF
      
   ENDIF
   
   
   hnum = N_ELEMENTS(struct_header)
   
   deta = WHERE(struct_header.ssdet_t EQ 'A', cnta)
   detb = WHERE(struct_header.ssdet_t EQ 'B', cntb)

   res = {w1:0.0, w2:0.0, dl_0:0.0, lam511:0.0}

   IF hnum GT 1 THEN BEGIN 
     
     res = REPLICATE(res, hnum)
   ENDIF
   
   IF ((cnta+cntb) LE 0) THEN BEGIN
;      leave here because of no needed further processing
;      looks like all RSC images.     
;      PRINT, ' No Detector Images'
      RETURN, res
   ENDIF

   dl_0 = 0
   nx = 3600.0/1e7
   dispr = 3200.78*1e7
   detpixsize = FLTARR(hnum)
   detpixsize(*) = 266000.
   
   IF cntb GT 0 THEN detpixsize(detb) = 265000. ; B- detector
      
   lambda_511 = DOUBLE(struct_header.sswavel)
   
                                ;reorder lambda ???
   ocnt = 0l
   bopos = WHERE((struct_header.sswavel LT 750.0) AND (struct_header.ssdet_t EQ 'B'),tcnt)
   IF tcnt GT 0 THEN BEGIN 
      ocnt = ocnt+tcnt
      opos = bopos
   ENDIF
   
   aopos = WHERE((struct_header.sswavel LT 805.0) AND (struct_header.ssdet_t EQ 'A'),tcnt)
   IF tcnt GT 0 THEN BEGIN
      IF ocnt NE 0 THEN opos = [opos,aopos] ELSE opos = aopos
      ocnt = ocnt+tcnt
   ENDIF
   
   IF ocnt GT 0 THEN lambda_511(opos) = lambda_511(opos)*2.0
   
   dl_0 = s_mul_disperse(lambda_511, nx, detpixsize, dispr)
   
   xn = WHERE(struct_header.ssrefpix NE 511, cnt)
   IF cnt GT 0 THEN BEGIN
      
      dx = struct_header(xn).ssrefpix-511
      FOR i=0,2 DO BEGIN
         lambda_n = lambda_511(xn)+(dx*dl_0(xn))
         dl_0(xn) = s_mul_disperse(lambda_n, nx, detpixsize(xn),dispr)
      ENDFOR
      
      lambda_511(xn) = lambda_n
   ENDIF
   
;   dl_0 = s_mul_disperse(lambda_511, nx, detpixsize, dispr)
   
   cc = s_det_absolute(struct_header = struct_header)   
   cc.low = cc.low-511
   cc.high = cc.high-511

   IF hnum GT 1 THEN BEGIN 
      res.w2 = lambda_511+(-cc.low)*dl_0 ;high pixel --> low  wavelength
      res.w1 = lambda_511+(-cc.high)*dl_0 ;low pixel  --> high wavelength
      res.dl_0 = dl_0
      res.lam511 = lambda_511
   ENDIF ELSE BEGIN
      
      res.w2 = lambda_511(0)+(-cc(0).low)*dl_0(0)  ;high pixel --> low  wavelength
      res.w1 = lambda_511(0)+(-cc(0).high)*dl_0(0) ;low pixel  --> high wavelength
      res.dl_0 = dl_0(0)
      res.lam511 = lambda_511(0)
      
   ENDELSE
   
   IF ocnt NE 0 THEN BEGIN
      res(opos).w2 = res(opos).w2/2.0
      res(opos).w1 = res(opos).w1/2.0
      res(opos).dl_0 = res(opos).dl_0/2.0
      res(opos).lam511 = res(opos).lam511/2.0
   ENDIF
   
   ;Look for images where wavelength is 0.0 (format 34,35,36)
   nulpos = WHERE((struct_header.sswavel LE 0.0),nulcnt)
   IF nulcnt NE 0 THEN BEGIN
      
      res(nulpos).w1 = 0.0
      res(nulpos).w2 = 0.0
      res(nulpos).dl_0 = 0.0
      res(nulpos).lam511 = 0.0
   ENDIF
   
   
   RETURN, res
handle_error:
   res = {w1:0.0,w2:0.0}
   PRINT,' S_EDGE_WAVE Error: ',errmsg
   RETURN,res
END

;---------------------------------------------------------------------------
; End of 'S_EDGE_WAVE.PRO'.
;---------------------------------------------------------------------------
