; $Id: eis_hdr__read.pro 405 2010-07-04 11:21:38Z viggoh $
;+
; NAME:
;       EIS_HDR__READ
;
; PURPOSE:
;       EIS_HDR__READ reads EIS headers from SOLAR-B EIS packet data
;       files and stores header info in the instance
;       data of objects of class 'eis_hdr'
;
;
; CATEGORY:
;       Hansteen/Wikstol Data analysis SW
;
; CALLING SEQUENCE:
;       An object of class EIS_HDR is declared with this statement:
;                   eis_hdr = obj_new('eis_hdr')
;
;       EIS_HDR__READ reads the EIS header part of EIS data files and
;       stores header information into the header object, with this statement:
;                     eis_hdr-> read, lu (logical unit of EIS data file)
;
; INPUTS:
;       lu:  Logical unit number of EIS data file
;
; KEYWORD PARAMETERS:
;
; OUTPUTS:
;       Reads EIS header data and fills the parameters of the EIS_HDR
;       object with information.
;
; CALLS:
;       MKUINTLE
;       MKU24LE
;       MKULONGLE
;
; COMMON BLOCKS:
;
;
; PROCEDURE:
;       EIS_HDR__READ first reads 256 byte of data from data
;       packets. From these 256 bytes, all the various parameters of the
;       header object is filled with it's correct bits and bytes
;       according to the definitions of the EIS header. IDL only
;       has 8, 16 and 32 bit variables, while the different fields of
;       the EIS header can be any nymber of bits (2, 3, 4, 14, 24
;       etc..). Thus we store the header parameters with these data types:
;                Up to 8 bits: Byte variables
;                9-16 bits: Unsigned integers
;                17-32 bits: Unsigned long.
;       The MKUINTLE, MKU24LE and MKULONGLE functions are used to
;       craete the unsigned integers, 24 bit unsigned longs and 32 bit
;       unsigned longs from the bit stream. In addition the
;       bitshifting performed by ishft is used when the header data
;       have bit lengths other than 16, 24 and 32.
;
;
; RESTRICTIONS:
;
;
; MODIFICATION HISTORY:
;       XX-Jan-2001: Oivind Wikstol.
;       26-Sep-2001: Oivind Wikstol. Added documentation.
;       15-Feb-2005: Øivind Wikstøl. Added new hdr parameters.
;       03-Mar-2005: Øivind Wikstøl. Added new hdr parameters.
;       29-Nov-2006: Viggo Hansteen. Fixed bug in reading fmirr_pos.
;        4-Jul-2008: A. Gardini.     Added init keyword.
;-
pro eis_hdr::read, lu, swap = swap, init=init
  if n_elements(init) eq 1 then return
  eis_hdr_length = 256              ; header size in bytes
  header=bytarr(eis_hdr_length)
                                ; OW 18.10.04 : 8 bytes extra added to
                                ; hdr in Japan october 2004. Read
                               ; extra 8 byes if ver_no = 1
  if (self.ver_no) eq 1 then begin
    dum = bytarr(8)
    readu,lu,dum
  endif

  if n_elements(swap) eq 0 then swap = 0
  readu,lu,header
  ; swap bytes in header in order to convert to big endian
  if swap ne 0 then begin
    for i=0,eis_hdr_length-2,2 do begin
      buf=header[i]
      header[i]=header[i+1]
      header[i+1]=buf
    endfor
  endif

  ; raw 256 bytes of data:
  self.raw = header
  ; extract the correct bits and store the in various header parameters:
  self.datatype=header(0)           ; one byte (8 bit)
  self.packet_size = mku24le(header,1)
  dum=mkulongle(header,4)
  *self.serial_packet_no=ulong(dum)
  self.main_id=mkuintle(header,8)
  self.main_seq_flag=ishft(header(10),-6)
  self.main_seq_count=ishft(ishft(mkuintle(header,10),2),-2)
  self.reserved_1=ishft(header(12),-6)
  self.nr_of_packets=ishft(ishft(mkuintle(header,12),2),-8)
  self.img_type=ishft(ishft(header(13),2),-2)
  self.sub_id=mkuintle(header,14)
  self.sub_seq_flag=ishft(header(16),-6)
  self.sub_seq_count=ishft(ishft(mkuintle(header,16),2),-2)
  self.x_f=mkuintle(header,18)
  self.y_f=mkuintle(header,20)
  self.b_x=mkuintle(header,22)
  self.b_y=mkuintle(header,24)
  self.x_p=mkuintle(header,26)
  self.y_p=mkuintle(header,28)
  self.reserved_3=ishft(header(30),-7)
  self.bit_compr_mode=ishft(ishft(header(30),1),-4)
  self.img_compr_mode=ishft(ishft(header(30),5),-5)
  self.reserved_4=ishft(header(31),-7)
  self.huffman_ac=ishft(ishft(header(31),1),-6)
  self.huffman_dc=ishft(ishft(header(31),3),-6)
  self.quant_tab=ishft(ishft(header(31),5),-5)
  ; exposure information :
  self.exp_info.ti_1=mkulongle(header,32)
  self.exp_info.ti_2=mkulongle(header,36)
  self.exp_info.exp_mhc=mkulongle(header,40)
  self.exp_info.exp_dur=mkuintle(header,44)
  self.exp_info.seq_nr=header(46)
  self.exp_info.ll_nr=header(47)
  self.exp_info.seq_id=mkuintle(header,48)
  self.exp_info.rast_id=mkuintle(header,50)
  self.exp_info.nwin=ishft(header(52),-3)
  self.exp_info.ccd_sides=ishft(ishft(header(52),5),-5)
  self.exp_info.ccd_length=ishft(mkuintle(header,53),-4)
  self.exp_info.xws=ishft(ishft(mkuintle(header,54),4),-4)
  self.exp_info.xw=ishft(mkuintle(header,56),-4)
  self.exp_info.yws=ishft(ishft(mkuintle(header,57),4),-6)
  self.exp_info.yw=ishft(ishft(mkuintle(header,58),6),-6)
  ; Line window specific parameters:
  nwin = 25
  i=0
  j=60       ; loop starts at byte 60 of header
  repeat begin
    k=fix(j)
    self.exp_info.win_hdr(i)=header(k)
    self.exp_info.ccd_nr(i)=ishft(ishft(header(k),6),-6)
    self.exp_info.x_s(i)=ishft(mkuintle(header,k+1),-4)
    self.exp_info.x_l(i)=ishft(ishft(mkuintle(header,k+2),4), -4)
    j = j+4
    self.line_id[i] = 'Line ' + strtrim(string(i),2)
    i=i+1
  endrep until (i eq nwin)
  k=fix(j)
  self.exp_info.cmirr_pos=mkuintle(header,k)
  self.exp_info.fmirr_pos_mode=ishft(header(k+2),7)
  self.exp_info.fmirr_pos=ishft(ishft(mkuintle(header,k+2),4),-4)
  self.exp_info.slit_nr=mkuintle(header,k+4)
  self.exp_info.x_ocb=header(k+6)
  self.exp_info.y_ocb=header(k+7)
  self.exp_info.nexp=mkulongle(header,k+8)
  self.exp_info.nexpc=mkulongle(header,k+12)
  self.exp_info.nrepr=ishft(mkuintle(header,k+16),-4)
  self.exp_info.nrepp=ishft(ishft(mkuintle(header,k+17),4), -4)
  self.exp_info.nseqr=header(k+19)
  self.exp_info.nseqp=header(k+20)
  self.exp_info.ron_ccdar=ishft(ishft(header(k+21), 4),-7)
  self.exp_info.ron_ccdal=ishft(ishft(header(k+21), 5),-7)
  self.exp_info.ron_ccdbr=ishft(ishft(header(k+21), 6),-7)
  self.exp_info.ron_ccdbl=ishft(ishft(header(k+21), 7),-7)
 ; self.exp_info.hsl=mkuintle(header[k+22])
  self.exp_info.hsl_ccdbl=ishft(ishft(header(k+22), 1),-7)
  self.exp_info.hsl_ccdbr=ishft(ishft(header(k+22), 2),-7)
  self.exp_info.hsl_ccdal=ishft(ishft(header(k+22), 3),-7)
  self.exp_info.hsl_ccdar=ishft(ishft(header(k+22), 4),-7)
  self.exp_info.hsl_ccdbank=ishft(ishft(header(k+22), 5),-7)
  self.exp_info.hsl_link_err=ishft(ishft(header(k+22), 6),-7)
  self.exp_info.hsl_eof=ishft(ishft(header(k+22), 7),-7)
  self.exp_info.hsl_last=header(k+23)
  self.exp_info.xrt_fltr_st=ishft(ishft(header(k+24), 2), -7)
  self.exp_info.eis_aec_st=ishft(ishft(header(k+24), 3), -7)
  self.exp_info.eis_evtr_st=ishft(ishft(header(k+24), 4), -7)
  self.exp_info.eis_fltr_st=ishft(ishft(header(k+24), 5), -7)
  self.exp_info.xrt_flfl=header(k+25)
  self.exp_info.xrt_fl_x=header(k+26)
  self.exp_info.xrt_fl_y=header(k+27)
  self.exp_info.aec_npix_h=mkulongle(header, k+28)
  self.exp_info.aec_npix_l=mkulongle(header, k+32)
  self.exp_info.eis_x_sign=ishft(header(k+36),-7)
  self.exp_info.eis_xrt_fl_x=ishft(ishft(mkuintle(header, k+36),1),-1)
  self.exp_info.eis_y_sign=ishft(header(k+38),-7)
  self.exp_info.eis_xrt_fl_y=ishft(ishft(mkuintle(header, k+38),1),-1)
  self.exp_info.mhc_fmirr_sg=mkuintle(header, k+40)
  self.exp_info.eis_fltr_x = mkuintle(header, k+42)
  self.exp_info.eis_fltr_y = mkuintle(header, k+44)
  self.exp_info.eis_evtr_x = mkuintle(header, k+46)
  self.exp_info.eis_evtr_y = mkuintle(header, k+48)
  self.exp_info.asrc_dir = ishft(header(k+50),-7)
  self.exp_info.asrc_nr = ishft(ishft(header(k+50),1),-1)
  self.exp_info.asrc_skip = header(k+51)
  self.exp_info.exp_prp = header(k+52)
  self.exp_info.fmir_step = mkuintle(header, k+53)
  return
end
