;---------------------------------------------------------------------------
; Document name: SUM_IMAGE_HEAD.PRO
; Created by:    Dietmar Germerott, MAPE Lindau, December 1, 1996
;
; Last Modified: Fri Apr  4 19:31:09 2008 (GERMEROTT@sumop1.nascom.nasa.gov)
;---------------------------------------------------------------------------
;
FUNCTION sum_image_head, header,num_of_header=num_of_header, errmsg=errmsg
;+
; PROJECT:
;       SOHO - SUMER
;
; NAME:
;       SUM_IMAGE_HEAD()
;
; PURPOSE: 
;       Decode SUMER Image Head to Structure
;
; CATEGORY:
;       SUMER - DATA
; 
; EXPLANATION:
;       
; SYNTAX: 
;       Result = sum_image_head(header [,num_of_header=num_of_header])
;
; EXAMPLES:
;       
; INPUTS:
;       header - SUMER Image header BYTARR(92..)
;
; OPTIONAL INPUTS: 
;       None.
;
; OUTPUTS:
;       Result - Structure or -1.0 in case of error
;
; OPTIONAL OUTPUTS:
;       None.
;
; KEYWORDS: 
;       num_of_header - returns the number of headers
;       errmsg - returns the ERROR String   
;
; COMMON:
;       None.
;
; RESTRICTIONS: 
;       CALL TAI2UTC, OBT2TAI, IEEE_TO_HOST, DATATYPE
;       The Structure Tag UTC_VMS contains a string only
;       if the number of headers is less 1024.
;   
; SIDE EFFECTS:
;       None.
;
; HISTORY:
;       Version 1, December 1, 1996, Dietmar Germerott, MAPE Lindau. Written
;       Version 2, April 28, 1998, Dietmar Germerott, MPAE Lindau
;         modified ret_head.ssdet_t entry to RSC in case of format = 34,35   
;       Version 3, August 6, 1998, Dietmar Germerott, MPAE Lindau
;         correct the case of only one header input - do not double
;         header input variable itself
;       Version 4, August 5, 1999, Dietmar Germerott, MPAE Lindau
;         added calculation of X- and Y-events   
;       Version 5, March 3, 2008, Dietmar Germerott, MPS Lindau
;         corrected ssdtetyp entry for RSC to 3b
;         modified binheader size to 120 byte
;       Version 6, March 26, 2008, Dietmar Germerott, MPS Lindau
;         added new tags for more information on raw tm file
;
; CONTACT:
;       Dietmar Germerott, MAPE Lindau (germerott.nospam(at)linmpi.mpg.de)
;-
;
   
   ON_ERROR, 2                  ; Return to the caller of this procedure if error occurs.
   MESSAGE = ''                 ; Error message that is returned if ERRMSG keyword set.
   num_of_header = 0
;
;  Check the input array.
;
   IF N_PARAMS() NE 1 THEN BEGIN
      MESSAGE = 'Syntax:  Result = SUM_IMAGE_HEAD( HEADER [,num_of_header=num_of_header] )'
   ENDIF ELSE BEGIN
      IF DATATYPE(header, 1) NE 'Byte' THEN BEGIN
         MESSAGE = 'HEADER must be a byte array.'
      ENDIF ELSE BEGIN
         SZ = SIZE(header)
         IF ((SZ(1) LT 92) OR (sz(1) GT 255)) THEN MESSAGE = $
            'The first dimension of HEADER must at least be 92.'
         IF SZ(0) EQ 0 THEN MESSAGE = 'HEADER must be an array.'
      ENDELSE
   ENDELSE
   IF MESSAGE NE '' THEN GOTO, HANDLE_ERROR
   
;---------------------------------------------------------------------------
;  Reform header into a size(1) by N array
;---------------------------------------------------------------------------
   
   num_of_header = N_ELEMENTS(header) /sz(1)
   
;---------------------------------------------------------------------------
;  prevent error in case of one single header make two headers
;---------------------------------------------------------------------------
   
   single_flag = 0
   
   IF num_of_header LT 2 THEN BEGIN
      
      single_flag = 1
      num_of_header = 2
      
      header_x = [header,header]
      head = REFORM(header_x, SZ(1), num_of_header)
      
   ENDIF ELSE BEGIN
   
      head = REFORM(header, SZ(1), num_of_header)
   
   ENDELSE
   
   ev_factor = [0.0, 6.988, 7.123, 0.0]
   
   ret_head = {SUMERHEADER,$
               SSYNC0:0b, $
               SSYNC1:0b, $
               img_rec:0b, $
               sstypimg:0b, $
               ssopcnt:0b, $
               sspopudp:0b, $
               ssloc:0b, $
               sstarget:0b, $
               ssstat:0b, $
               ssdetsta:0b, $
               ssslitn:0b, $
               s_mcpv:0b, $
               simcpi:0b, $
               ssmcerr:0b, $
               ssmc1err:0b, $
               ssmc2err:0b, $
               ssmc3err:0b, $
               ssmc4err:0b, $
               ssmc5err:0b, $
               ssmc6err:0b, $
               ssmc8err:0b, $
               sscomprm:0b, $
               sseetrig:0b, $
               ssff:0b, $
               ssff_t:'OFF', $
               ssdettyp:0b, $
               ssdet_t:'None', $
               ssintsta:0b, $
               ssimgcnt:0, $
               ssfldate:0, $
               ssflreqn:0, $
               ssrefpix:0, $
               relrefpix:0, $
               ssiidz:0, $
               ssiidy:0, $
               ssbpaddy:0, $
               ssbpaddz:0, $
               ssbpcnts:0l, $
               ssacimgc:0l, $
               ssbinny:0, $
               ssbinnz:0, $
               ssxcnt:0l, $
               ssycnt:0l, $
               x_evcnt:0.0, $
               y_evcnt:0.0, $
               sscompp1:0l, $
               sscompp2:0l, $
               sscompp3:0l, $
               ssadmcnt:0, $
               sssuny:0, $
               sssunz:0, $
               p_suny:0.0, $
               p_sunz:0.0, $
               ssstepn:0, $
               ssstepsz:0, $
               ssmc2pos:0, $
               ssmc3pos:0, $
               ssmc4pos:0, $
               ssmc8pos:0, $
               ssmc6pos:0, $
               ssexptim:0.0, $
               ssrotcomp:0.0, $
               sswavel:0.0, $
               s_mcpvf:0.0, $
               simcpif:0.0, $
               tai:0.0d, $
               ssimgtot:0l, $
               utc_vms:' ', $
               utc_ecs:' ', $
               utc_s:' ', $
               utc_d:' ', $
               utc_t:' ',$
               mdu:0b, $
               qac:0b, $
               fid:-1, $
               fptr:-1l, $
               cdid:0, $
               seqid:0b, $
               tmfilename:-1l, $
               binhead:BYTARR(120)}
   
   
   ret_head = REPLICATE(ret_head, num_of_header)
   
   
   
;---------------------------------------------------------------------------
;  first all byte values
;---------------------------------------------------------------------------
   
   ret_head(*).img_rec = REFORM(head(2,*))
   ret_head(*).sstypimg = imgform(head);REFORM(head(3,*))
   ret_head(*).ssopcnt = opcnt(head);REFORM(head(10, *))
   ret_head(*).sspopudp = popudp(head);REFORM(head(11, *))
   ret_head(*).ssloc = REFORM(head(14, *))
   ret_head(*).sstarget = target(head);REFORM(head(15, *))
   ret_head(*).ssstat = REFORM(head(22, *))
   ret_head(*).ssdetsta = detstat(head);REFORM(head(23, *))
   ret_head(*).ssslitn = slitnum(head);REFORM(head(55,*))
   ret_head(*).ssmcerr = mcerr(head);REFORM(head(74,*))
   ret_head(*).sscomprm = comprm(head);REFORM(head(75,*))
   ret_head(*).s_mcpv = REFORM(head(64,*))
   ret_head(*).simcpi = REFORM(head(65,*))
   
;   tmp_real = head(76:79, *)
;   BYTEORDER, tmp_real, /lswap
;   BYTEORDER, tmp_real, /sswap
   
   ret_head(*).sswavel = wavel(head);REFORM(FLOAT(tmp_real, 0, num_of_header))
   
;   tmp_real = head(28:31,*)
;   BYTEORDER, tmp_real, /lswap
;   BYTEORDER, tmp_real, /sswap
   
   ret_head(*).ssexptim = exptim(head);REFORM(FLOAT(tmp_real, 0, num_of_header))
   
;   tmp_real = head(44:47,*)
;   BYTEORDER, tmp_real, /lswap
;   BYTEORDER, tmp_real, /sswap
   
   ret_head(*).ssrotcomp = rotcomp(head);REFORM(FLOAT(tmp_real, 0, num_of_header))
   
;   ret_head(*).ssfldate = REFORM(FIX(head(16:17,*),0,num_of_header))
   ret_head(*).ssfldate = fldate(head)

;   ret_head(*).ssflreqn = REFORM(FIX(head(18:19,*),0,num_of_header))
   ret_head(*).ssflreqn = flreq(head)
;   ret_head(*).ssrefpix = REFORM(FIX(head(20:21,*),0,num_of_header))
    ret_head(*).ssrefpix = pixpos(head, /original)
;   ret_head(*).sssuny = REFORM(FIX(head(24:25,*),0,num_of_header))
    ret_head(*).sssuny = suny(head, /rawform)
;   ret_head(*).sssunz = REFORM(FIX(head(26:27,*),0,num_of_header))
    ret_head(*).sssunz = sunz(head, /rawform)
;   ret_head(*).ssiidz = REFORM(FIX(head(32:33,*),0,num_of_header))
   ret_head(*).ssiidz = iidz(head)
;   ret_head(*).ssiidy = REFORM(FIX(head(34:35,*),0,num_of_header))
   ret_head(*).ssiidy = iidy(head)
;   ret_head(*).ssbpaddy = REFORM(FIX(head(36:37,*),0,num_of_header))
    ret_head(*).ssbpaddy = brightpy(head)
;   ret_head(*).ssbpaddz = REFORM(FIX(head(38:39,*),0,num_of_header))
   ret_head(*).ssbpaddz = brightpz(head)
;;   ret_head(*).ssbpcnts = REFORM(FIX(head(48:49,*),0,num_of_header))
;   ret_head(*).ssstepn = REFORM(FIX(head(52:53,*),0,num_of_header))
    ret_head(*).ssstepn = rasstp(head)
;   ret_head(*).ssbinny = REFORM(FIX(head(56:57,*),0,num_of_header))
    ret_head(*).ssbinny = biny(head)
;   ret_head(*).ssbinnz = REFORM(FIX(head(58:59,*),0,num_of_header))
    ret_head(*).ssbinnz = binz(head)
;   ret_head(*).ssmc2pos = REFORM(FIX(head(66:67,*),0,num_of_header))
    ret_head(*).ssmc2pos = mc2pos(head)
;   ret_head(*).ssmc3pos = REFORM(FIX(head(68:69,*),0,num_of_header))
    ret_head(*).ssmc3pos = mc3pos(head)
;   ret_head(*).ssmc4pos = REFORM(FIX(head(70:71,*),0,num_of_header))
   ret_head(*).ssmc4pos = mc4pos(head)
;   ret_head(*).ssmc8pos = REFORM(FIX(head(72:73,*),0,num_of_header))
   ret_head(*).ssmc8pos = mc8pos(head)
;;   ret_head(*).sscompp1 = REFORM(FIX(head(80:81,*),0,num_of_header))
;;   ret_head(*).sscompp2 = REFORM(FIX(head(82:83,*),0,num_of_header))
;;   ret_head(*).sscompp3 = REFORM(FIX(head(84:85,*),0,num_of_header))
;   ret_head(*).ssadmcnt = REFORM(FIX(head(86:87,*),0,num_of_header))
   ret_head(*).ssadmcnt = admin(head)
;   ret_head(*).ssmc6pos = REFORM(FIX(head(88:89,*),0,num_of_header))
    ret_head(*).ssmc6pos = mc6pos(head)
   
;   ret_head(*).ssimgcnt = REFORM(FIX(head(12:13,*),0,num_of_header))
   
;---------------------------------------------------------------------------
;  Put all values for ieee_to_host before this comment
;---------------------------------------------------------------------------
   
 ;  ieee_to_host, ret_head
   
   ret_head(*).ssimgcnt = imgcnt(head);REFORM(head(12,*) * 256l + head(13,*))
   ret_head(*).ssbpcnts = bpcnt(head);REFORM(head(48,*) * 256l + head(49,*))
   ret_head(*).sscompp1 = cmp1(head);REFORM(head(80,*) * 256l + head(81,*))
   ret_head(*).sscompp2 = cmp2(head);REFORM(head(82,*) * 256l + head(83,*))
   ret_head(*).sscompp3 = cmp3(head);REFORM(head(84,*) * 256l + head(85,*))
   
;---------------------------------------------------------------------------
;  Fill the X- and Y-event / calibrate later
;---------------------------------------------------------------------------
   
   ret_head(*).x_evcnt = xevent(head, /rawform);REFORM(head(60,*) * 256. + head(61,*))
   ret_head(*).y_evcnt = yevent(head, /rawform);REFORM(head(62,*) * 256. + head(63,*))
   
;---------------------------------------------------------------------------
;  Fill Sync (EB 90 hex)
;---------------------------------------------------------------------------
   
   ret_head(*).ssync0 = REFORM(head(0, *))
   ret_head(*).ssync1 = REFORM(head(1, *))
   
;---------------------------------------------------------------------------
;  TAI is an Host valid Double Value
;---------------------------------------------------------------------------
   
   tmp_tai = tai_head(head)

   ret_head(*).tai = tmp_tai
   
   tmp_utc = tai2utc(tmp_tai,/date_only)
   ret_head(*).utc_d = utc2str(tmp_utc,/date_only)
   ret_head(*).utc_t = utc2str(tmp_utc,/time_only)
   
   ret_head(*).utc_s = ret_head(*).utc_d + ' ' + $
      STRMID(ret_head(*).utc_t,0,11)
   
   ret_head(*).utc_ecs = utc2str(tmp_utc, /ecs)

;---------------------------------------------------------------------------
;  Because of limit in UTC2STR fill string only if le 1024
;---------------------------------------------------------------------------
   
   IF num_of_header LE 1024 THEN BEGIN
      
      ret_head(*).utc_vms = utc2str(tmp_utc, /vms)
      
   ENDIF
   
;---------------------------------------------------------------------------
;  fill 1Byte Integer
;---------------------------------------------------------------------------
   
;   tmp_int = head(54:55, *)
;   tmp_int(1) = 0b
;   ret_head(*).ssstepsz = REFORM(FIX(tmp_int,0,num_of_header))
;   tmp_idx = WHERE(ret_head(*).ssstepsz GT 127, tmp_cnt)
;   IF tmp_cnt GT 0 THEN ret_head(tmp_idx).ssstepsz = $
;      ret_head(tmp_idx).ssstepsz - 256  

   ret_head(*).ssstepsz = delstp(head)

;---------------------------------------------------------------------------
;  fill some 2Byte values in IDL long
;  take 4 Bytes and set 2 not needed to 0b
;---------------------------------------------------------------------------
   
;   tmp_lon = head(50:53,*)
;   tmp_lon(2:3,*) = 0b
;   BYTEORDER, tmp_lon, /sswap
   ret_head(*).ssacimgc = acimgc(head);REFORM(LONG(tmp_lon, 0, num_of_header))
   
;   tmp_lon = head(60:63,*)
;   tmp_lon(2:3,*) = 0b
;   BYTEORDER, tmp_lon, /sswap
   ret_head(*).ssxcnt = xevent(head, /rawform);REFORM(LONG(tmp_lon,0,num_of_header))
   
;   tmp_lon = head(62:65, *)
;   tmp_lon(2:3, *) = 0b
;   BYTEORDER, tmp_lon, /sswap
   ret_head(*).ssycnt = yevent(head, /rawform);REFORM(LONG(tmp_lon, 0, num_of_header))
   
;---------------------------------------------------------------------------
;  Total Image counts
;---------------------------------------------------------------------------
   
;   tmp_lon = head(40:43,*)
;   BYTEORDER, tmp_lon, /sswap
   ret_head(*).ssimgtot = imgtot(head);REFORM(LONG(tmp_lon,0,num_of_header))
   
   ret_head(*).s_mcpvf = mcpv(head);ret_head(*).s_mcpv * (-22.18)
   ret_head(*).simcpif = mcpi(head); ret_head(*).simcpi * 0.98 - $
;      0.668 * ret_head(*).s_mcpv + 81.02
   
;---------------------------------------------------------------------------
;  Prepare pointing in arcsec
;---------------------------------------------------------------------------
   
   ret_head(*).p_suny = suny(head);ret_head(*).sssuny / 16.
   ret_head(*).p_sunz = sunz(head);ret_head(*).sssunz / 16.
   
;---------------------------------------------------------------------------
;  Bit processing of status
;---------------------------------------------------------------------------
   
   ret_head(*).ssmc1err = ret_head(*).ssmcerr AND 01b
   ret_head(*).ssmc2err = (ret_head(*).ssmcerr AND 02b)/2
   ret_head(*).ssmc3err = (ret_head(*).ssmcerr AND 04b)/4
   ret_head(*).ssmc4err = (ret_head(*).ssmcerr AND 08b)/8
   ret_head(*).ssmc5err = (ret_head(*).ssmcerr AND 16b)/16
   ret_head(*).ssmc6err = (ret_head(*).ssmcerr AND 32b)/32
   ret_head(*).ssmc8err = (ret_head(*).ssmcerr AND 64b)/64
   
   ret_head(*).sseetrig = (ret_head(*).ssstat AND 128b)/128
   ret_head(*).ssff = (ret_head(*).ssstat AND 64b)/64
   ret_head(*).ssdettyp = ((ret_head(*).ssstat AND 16b)/8 + $
                           (ret_head(*).ssstat AND 32b)/32)
   ret_head(*).ssintsta = (ret_head(*).ssstat AND 12b)/4
   
;   ret_head(*).relrefpix = ret_head(*).ssrefpix
    ret_head(*).relrefpix = pixpos(head)
   
;---------------------------------------------------------------------------
;  fill ascii fields
;---------------------------------------------------------------------------
   
   tmp_idx = WHERE (ret_head(*).ssff GT 0, tmp_cnt)
   IF tmp_cnt GT 0 THEN ret_head(tmp_idx).ssff_t = 'ON'
   
   tmp_idx = WHERE (ret_head(*).ssdettyp EQ 1b, tmp_cnt)

   ret_head.x_evcnt = xevent(head)
   ret_head.y_evcnt = yevent(head)

   IF tmp_cnt GT 0 THEN BEGIN
      ret_head(tmp_idx).ssdet_t = 'A'
      
;      ret_head(tmp_idx).x_evcnt = ret_head(tmp_idx).x_evcnt * ev_factor(1)
;      ret_head(tmp_idx).y_evcnt = ret_head(tmp_idx).y_evcnt * ev_factor(1)
      
      
   ENDIF
   
   
   tmp_idx = WHERE (ret_head(*).ssdettyp EQ 2b, tmp_cnt)
   IF tmp_cnt GT 0 THEN BEGIN
      
      ret_head(tmp_idx).ssdet_t = 'B'
;---------------------------------------------------------------------------
;  Make Relative Reference Pixel
;---------------------------------------------------------------------------
;      ret_head(tmp_idx).relrefpix = ret_head(tmp_idx).ssrefpix - 2653
      
;      ret_head(tmp_idx).x_evcnt = ret_head(tmp_idx).x_evcnt * ev_factor(2)
;      ret_head(tmp_idx).y_evcnt = ret_head(tmp_idx).y_evcnt * ev_factor(2)
      
   ENDIF

;   tmp_idx = WHERE (ret_head(*).ssdettyp EQ 3b, tmp_cnt)
   
;   because ssstat entry is not correct if detector is on
   
   tmp_idx = WHERE (((ret_head(*).ssdettyp EQ 3b) OR $
                     (ret_head(*).sstypimg EQ 34) OR $
                     (ret_head(*).sstypimg EQ 35)), tmp_cnt)
   IF tmp_cnt GT 0 THEN BEGIN 
      ret_head(tmp_idx).ssdet_t = 'RSC'
      ret_head(tmp_idx).ssdettyp=3b ;make it conform to RSC (s.a.)
      ret_head(tmp_idx).x_evcnt = ret_head(tmp_idx).x_evcnt * ev_factor(3) ;make 0
      ret_head(tmp_idx).y_evcnt = ret_head(tmp_idx).y_evcnt * ev_factor(3)
   ENDIF
   
;---------------------------------------------------------------------------
;  fill the fields of information about cd
;---------------------------------------------------------------------------
   
   IF sz(1) GT 92 THEN BEGIN
      
     ret_head(*).fid = sum_get_fid(head) ;REFORM(FIX(head(92:93,*),0,num_of_header))
     ret_head(*).fptr = sum_get_hptr(head) ;REFORM(LONG(head(94:97,*),0,num_of_header))
     ret_head(*).qac = check_qac(head) ;REFORM(head(98,*))
     ret_head(*).mdu = check_mdu(head) ;REFORM(head(99,*))
     
     ret_head(*).binhead(0:sz(1)-1) = REFORM(head(0:sz(1)-1, *))
     ret_head(*).binhead(91) = sz(1)
     IF sz(1) GT 100 THEN BEGIN 
        ret_head(*).tmfilename = REFORM(head(100, *)+ $
                                        head(101, *)*256l+ $
                                        head(102, *)*2l^16+ $
                                        head(103, *)*2l^24)
        ret_head(*).cdid = REFORM(head(104, *)+ $
                                  head(105, *)*256l)
        ret_head(*).seqid = REFORM(head(106, *))
     ENDIF
   ENDIF ELSE BEGIN
     
     ret_head(*).binhead = REFORM(head(0:91, *))
   ENDELSE
   IF single_flag NE 0 THEN BEGIN
      
      num_of_header = 1
      ret_head = ret_head(0)
      
   ENDIF
   
   
   RETURN, ret_head
   
HANDLE_ERROR:
   IF N_ELEMENTS(ERRMSG) EQ 0 THEN MESSAGE, MESSAGE
   ERRMSG = MESSAGE
   RETURN, -1.D0

END

;---------------------------------------------------------------------------
; End of 'SUM_IMAGE_HEAD.PRO'.
;---------------------------------------------------------------------------
