;+
; NAME:
;       EIS_MKFITS
;
; PURPOSE:
;	Makes FITS files out of telemetry packets for the 
;	EIS instrument on Solar-B.
;
;
; CATEGORY:
;       Data Processing Software
;
; CALLING SEQUENCE:
;       eis_mkfits, filename
;
; INPUTS:
;       data: eis data object
;       hdr: eis hdr oject array
;
; KEYWORD PARAMETERS:
;       plan: Input planning tool data object
;       spcd: Space craft data object
;	hk:   House keeping data object
;       lev: FITS level, eg 'l0'. set to default ('lev0') if not specified
;       fitsdir: Input variable. Directory to write fits file in
;       fitsfile: Input name of fits file (otherwise created automatically 
;                 from date)
;       outfile: Output name of fits file (if not given as input, 
;                this is the way for an outside program to get the
;                name).
;       datatype: Type of data (pixel data, moments)
;
;
; OUTPUTS:
;       A FITS file
;
; CALLS:
;	GET_UTC.PRO (Solar-Soft)
;
; COMMON BLOCKS:
;
;
; PROCEDURE:
;
; RESTRICTIONS:
;
;
; MODIFICATION HISTORY:
;       November 2002: 1. version by Oivind Wikstol and Viggo Hansteen
;       2004-04-21: Oivind Wikstol - Added file name functionality
;       2004-06-25: Oivind Wikstol - Added keywords calstat and datatype
;       2005-01-11: Oivind Wikstol - Added numerous new keywords from mission 
;                                    data hdr. Both main hdr keywords as well 
;                                    as new BTE columns and BTE hdr keywords.
;       2005-11-15: Oivind Wikstol - Added spacecraft data and house keeping data.
;                                    Added, removed and changed keywords, according
;                                    to list of Solar-B wide keywords list, as 
;                                    described in document by
;                                    Shimojo-san. 
;       2006-11-13: Viggo H/Matt W - Changes to calls of
;                                    eis_mkfilename and eis_fits_obstime.
;       2006-11-16: Viggo H        - Added pointing information as function of 
;                                    shutter open time
;       2006-11-22: Viggo H        - Recast ti_1,ti_2,mhcdur,exp_dur
;                                    as double to prevent rollover
;       2006-11-23: Viggo H        - Added calls to plan->getsaa (gets
;                                    SAA and HLZ "flags")
;       2006-12-16: Viggo H        - Added call to eis_add_fits_file for as run database
;       2007-03-09: Viggo H        - Moved xcen, ycen in main header to middle of raster
;                                    instead of middle of FOV.
;       2007-04-29: Viggo H        - Added noaocs keyword
;       2007-10-07: A. Gardini     - Added Doppler vel columns; velocities 
;                                    and mhc temp are computed by average.
;       2008-04-02: A. Gardini/Matt W - Fixed misstyped 
;                                    eis_convert_ccdb_temperature 
;       2008-07-16: Viggo H        - Changed xcen, ycen in main header to median of values to 
;                                    avoid problems with bad data.
;       2009-04-30: A. Gardini     - Fixed 1 pixel shift error.
;       2009-04-30: A. Gardini     - Set keywords to eis_cal.
;       2010-02-25  V. Hansteen     - Implemented John Mariska's 
;                                    "EIS pointing" ver 0.95 document.
;    
;
;  VERSION: 1.18  !! Remember to update this number in the code when changed!!
;
;  $Id: eis_mkfits.pro 4179 2014-09-17 15:32:40Z viggoh $
; 
;-
pro eis_mkfits, data, hdr, doplan = doplan, dospcd = dospcd, doasrun = doasrun, dohk = dohk, $
                fitsdir = fitsdir, lev = lev, $
                fitsfile = fitsfile, outfile = outfile, noaocs=noaocs, rescued=rescued, $
                error_occurred

  debug = 1
  error_occurred=0
;  catch,error_status
;  if error_status ne 0 then begin
;      error_occurred=error_status
;      !quiet=0
;;;;;mcrw
;;      message,'ERROR: '+strim(string(error_status),2),/info
;      message,'ERROR: '+strtrim(string(error_status),2)+' ERR_STRING: '+!ERR_STRING+' ('+strtrim(string(!ERROR),2)+')',/info
;      !quiet=1
;; mcrw 20100927
;;      if error_status ne -225 then $
;      return
;  endif

  time_obs=(data->gethdr())->getdate_obs()
  slit_ind=data->getinfo('slit_ind')
  cal = obj_new('eis_cal',time_obs = time_obs, slit_ind = slit_ind)  
    
  if n_elements(doplan) eq 0 then doplan=0
  if n_elements(dospcd) eq 0 then dospcd=0
  if n_elements(dohk) eq 0 then dohk=0
  if n_elements(doasrun) eq 0 then doasrun=0
  if n_elements(verbose) eq 0 then verbose=1
  if n_elements(rescued) eq 0 then rescued=0
;
; Default is to use aocs pointing, if pointing of older data is required (for which the
; aocs hk data is not available) please set aocs to 0 or call eis_mkfits with /noaocs
;
  aocs=0
  if n_elements(noaocs) eq 0 then aocs=1
  
; NB!!! 290407/viggoh: for now turned off as the relation between the mhc_t15 and 
;       the orbital variation of the line shift is unclear
; 1009207/viggoh+alessandro: Put mhc_t10 and mhc_t15 back in after request from Hiro & 
;                            others.
; 081007/alessandro: Added Doppler vel.
  mhc_temp=1
  doppler_v=1
  
  if debug then print,'constructing plan object'
  if not doplan then begin
; no planning informations available:
    print, 'EIS_MKFITS: No planning information, using defaults'
    plan = obj_new('eis_plan')
  endif else begin     
    exp_info = (hdr[0])->getexp_info()
    seq_id = exp_info.seq_id
    rast_id = exp_info.rast_id
;; 20130220 mcrw
    !quiet=0
    message, 'Creating eis_plan with seq_id = '+strtrim(string(seq_id),2)+', rast_id = '+strtrim(string(rast_id),2),/info
    !quiet=1
;    plan = obj_new('eis_plan')
    plan = obj_new('eis_plan', seq_id, rast_id)
  endelse
 
;  if not dohk then begin 
; no house keeping data available:
;    print, 'EIS_MKFITS: No house keeping data available, using defaults'
;    hk = obj_new('eis_hk')
;  endif

; set fits level:
  if n_elements(lev) eq 0 then lev = 'l0'

; set FITS reformatter 0 version:
  data-> setfits_reformat, 'ver_rf0', 'EIS_Lev0_Reformatter $Revision: 4179 $'

  if n_elements(calstat) eq 0 then calstat = 'NONE'
; get wavelength scales and dispersion of the two detectors
  lambda_struct = data-> getlambda()
  lambda_a = lambda_struct.scale_a
  lambda_b = lambda_struct.scale_b
  disp = cal ->getdisp()

;  date = string((hdr[0]-> getexp_info()).ti_1)
   get_utc, date, /ccsds ; date in correct format WHEN FILE IS WRITTEN

; create fits file name from MD file name and time conversion:
  if n_elements(fitsfile) eq 0 then begin
    fitsfile = eis_mk_fitsname(lev, data, hdr, yrhr_str=yrhr_str)
  endif else begin
    fitsfile = fitsfile
  endelse

  outfile = fitsfile
  if n_elements(fitsdir) ne 0 then fitsfile = fitsdir+fitsfile

; get data for line window 0
  data->getwin, 0, wd, pos

; Create the primary FITS header with Binary Table Extensions:
  if debug then print,'create primary fits header'
  fxhmake, header, /initialize, /date, /extend
 
; Add keywords to the primary header. One subroutine for each 
; category of header data

; calstat structure:

  if debug then print,'dataid and obstime'
  eis_fits_dataid, header, hdr, data, plan
  eis_fits_obstime, header, hdr, plan, yrhr_str, data, ot=ot
  
  if verbose then begin
    datestring='date_obs '+ot.start_ut_str+' date_end '+ot.end_ut_str
    !quiet=0
    message,'processing '+data->getfilename()+' '+datestring,/info
    !quiet=1
  endif
  if debug then print,'create spcd object'
  if not dospcd then begin
; no spacecraft data available:
    print, 'EIS_MKFITS: No data from spacecraft available, using defaults'
    spcd = obj_new('eis_spcd')
  endif else begin
; correct dates are computed, spacecraft data can be accessed
    spcd = obj_new('eis_spcd',ot.start_ut_str,ot.end_ut_str,ot.start_obs,ot.end_obs)
    spcd->construct_pointing,aocs=aocs
    spcd->construct_ccdtemp
    if mhc_temp then spcd->construct_mhctemp
  endelse
;
; now check if both plan and spacecraft data are available: 
; we can then do hlz and saa
;
  if dospcd and doplan then begin
    plan->getsaa,ot.start_ut_shi,ot.end_ut_shi
  endif
  
  if debug then print,'coord and calib'
  eis_fits_coord, header, hdr, data, spcd, cal, ot
  eis_fits_calib, header, hdr, data, plan, rescued=rescued
;  eis_fits_dqual, header, hdr

  mhdr = header

; Define the FITS Binary Table Extension
  if debug then print,'define binary table extension'
  nexp = data->getnexp()   ; number of exposures in raster
  fxbhmake, header, nexp, 'DATA', 'Binary Table Extension Data'

; Create the columns for the line windows
  nwin=data->getnwin() 
  exp_info = hdr[0]-> getexp_info()

; get line ids from PT
  line_id = plan->get_line_id()

  for iwin=0, nwin-1 do begin
    data->getwin, iwin, wd, pos
    ccd_nr = fix(exp_info.ccd_nr[iwin])
    wdmin = min(wd)  ; minimum value in line window       
    wdmax = max(wd)  ; maximum value in line window       

; get wavelength scale 
    if pos[0] gt 2147 then begin 
      addpix = -2148
      lambda = lambda_a
      ccd_disp = disp.a
      wband = 'A'
    endif else begin 
      addpix = 0
      lambda = lambda_b
      ccd_disp = disp.b
      wband = 'B'
   endelse

    lstart = string(lambda[pos[0]+addpix])
    cdelt1 = 1.0
    cdelt2 = 1.0
    tdelt = '('+strtrim(string(ccd_disp), 2)+',' +strtrim(cdelt1, 2) + ',' +strtrim(cdelt2, 2)+')'

    ttype = line_id[iwin]
    fxbaddcol, col, header, fix(wd[*,*,0]), ttype, $
               'Data window', tunit = 'ADC', $
                tdesc = '(Wavelength, solar_x, solar_y)', $
                tcuni = '(Angstrom, arcsec, arcsec)', $
                tdmin = wdmin, tdmax = wdmax

; add keywords that are not standard to fxbaddcol, 
; using fxaddpar.
    detx = pos[0]  ; line window start x position
    detxw = pos[1] ; line window width (pixels)
    dety = pos[2]  ; line window start y position
    cwave = lambda[pos[0]+addpix] ; this should be taken from planning tool, 
                           ; since it should be central wavelength, 
                           ; and not lambda start in line window.
    wmin = lambda[pos[0]+addpix]  ; minimum wavelength
    wmax = lambda[pos[0] + pos[1]-1+addpix]  ; maximum wavelength
    winhdr = exp_info.win_hdr[iwin]
    ccdron = exp_info.ccd_nr[iwin]
    col=strtrim(col,2)
    fxaddpar,header,'tdetx'+col,detx, $
		'detector start column'
    fxaddpar, header, 'tdetxw'+col, detxw, $
                'Line width (x) in pixels'
    fxaddpar,header,'tdety'+col,dety, $
		'Detector start row'
    fxaddpar,header,'tdelt'+col,tdelt, $
		'Axis increments'
    fxaddpar,header,'twave'+col,cwave, $
		'Principal wavelength in Angstrom'
    fxaddpar,header,'twmin'+col,wmin, $
		'Preliminary minimum wavelength in Angstrom'
    fxaddpar,header,'twmax'+col,wmax, $
		'Preliminary maximum wavelength in Angstrom'
    fxaddpar,header,'twbnd'+col,wband, $
		'Wavelength band'
    fxaddpar,header,'winhdr'+col,fix(winhdr), $
		'Line window hdr'
    fxaddpar,header,'ccdron'+col,fix(ccdron), $
		'CCD Read Out Node'
  endfor
;
; Add columns for EIS Hdr data.
;
  if debug then print,'columns for EIS hdr data'
  nhdr = 12
  t1=lonarr(nexp)
  t2=lonarr(nexp)
  durmhc=lonarr(nexp)
  dursec=intarr(nexp)
  fmirr=intarr(nexp)
  hsl=intarr(nexp)
  xrt_flfl = bytarr(nexp)
  xrt_fl_x = bytarr(nexp)
  xrt_fl_y = bytarr(nexp)
  aec_hepc = lonarr(nexp)
  aec_lepc = lonarr(nexp)
  mhcsg = intarr(nexp)
  
  ipack = 0
  nrppexp = hdr[0]->getnr_of_packets() ; number of packets pr. exposure
  for i = 0, nexp -1 do begin
    ipack = i*nrppexp
    t1[i] = ((hdr[ipack]-> getexp_info()).ti_1)
    t2[i] = ((hdr[ipack]-> getexp_info()).ti_2)
    durmhc[i] = (hdr[ipack]-> getexp_info()).exp_mhc
    dursec[i] = (hdr[ipack]-> getexp_info()).exp_dur
    fmirr[i] = (hdr[ipack]-> getexp_info()).fmirr_pos
    hsl[i] =   (hdr[ipack]-> getexp_info()).hsl
    xrt_flfl[i] = (hdr[ipack]-> getexp_info()).xrt_flfl
    xrt_fl_x[i] =   (hdr[ipack]-> getexp_info()).xrt_fl_x
    xrt_fl_y[i] =   (hdr[ipack]-> getexp_info()).xrt_fl_y
    aec_hepc[i] = long((hdr[ipack]-> getexp_info()).aec_npix_h)
    aec_lepc[i] = long((hdr[ipack]-> getexp_info()).aec_npix_l)
    mhcsg[i] = (hdr[ipack]-> getexp_info()).mhc_fmirr_sg
  endfor
  
  print, 'xrt_flfl[0]', xrt_flfl[0]
  print, 'xrt_fl_x[0]', xrt_fl_x[0]
  print, 'xrt_fl_y[0]', xrt_fl_y[0]

  fxbaddcol, col, header, double(ulong(t1[0])), 'TI_1', 'Shutter open time', $
                tunit = 'TI', $
                tdmin = min(double(ulong(t1))), $
                tdmax = max(double(ulong(t1)))
  fxbaddcol, col, header, double(ulong(t2[0])), 'TI_2', 'Shutter close time', $
                tunit = 'TI', $
                tdmin = min(double(ulong(t2))), $
                tdmax = max(double(ulong(t2)))
  fxbaddcol, col, header, double(ulong(durmhc[0])), 'mhc_dur', $
                'Exposure duration as measured by the MHC', $
                tunit = '1 microsec', $
                tdmin = min(double(ulong(durmhc))), $
                tdmax = max(double(ulong(durmhc)))
  fxbaddcol, col, header, double(ulong(dursec[0])), 'exp_dur', $
                'Exposure time as specified by the sequence', $
                tunit = '10 ms', $
                tdmin = min(double(ulong(dursec))), $
                tdmax = max(double(ulong(dursec)))
  fxbaddcol, col, header, fmirr[0], 'fmirr', $
                'Fine mirrror position', $
                tunit = '0.1248 arcsec', $
                tdmin = min(fmirr), $
                tdmax = max(fmirr)
  fxbaddcol, col, header, hsl[0], 'hslstat', $
                'HSL Status', $
                tunit = 'integer'
  fxbaddcol, col, header, xrt_flfl[0], 'xrt_flfl', $
                'XRT Flare Flag Received', $
                tunit = '0 or 1',$
                tdmin=min(fix(xrt_flfl)), $
                tdmax=max(fix(xrt_flfl)) 
  fxbaddcol, col, header, xrt_fl_x[0], 'xrt_fl_x', $
                'XRT Flare X-Coordinate', $
                tunit = 'arcsec? (byte)',$
                tdmin=min(fix(xrt_fl_x)), $
                tdmax=max(fix(xrt_fl_x)) 
  fxbaddcol, col, header, xrt_fl_y[0], 'xrt_fl_y', $
                'XRT Flare Y-Coordinate', $
                tunit = 'arcsec? (byte)',$
                tdmin=min(fix(xrt_fl_y)), $
                tdmax=max(fix(xrt_fl_y)) 
  fxbaddcol, col, header, aec_hepc[0], 'aec_hepc', $
                'AEC High Energy Pixel Count', $
                tunit = '32 bit long',$
                tdmin=min(aec_hepc), $
                tdmax=max(aec_hepc) 
  fxbaddcol, col, header, aec_lepc[0], 'aec_lepc', $
                'AEC Low Energy Pixel Count', $
                tunit = '32 bit long',$
                tdmin=min(aec_lepc), $
                tdmax=max(aec_lepc) 
  fxbaddcol, col, header, mhcsg[0], 'mhcfmsgo', $
                'MHC Fine Mirror Strain Gauge output', $
                tunit = '? integer',$
                tdmin=min(mhcsg), $
                tdmax=max(mhcsg)                 
;
; Add 2 columns for SC/EIS pointing
;
  nhdr = nhdr + 2
  if debug then print,'columns for SC data'
;
; interpolate xcen, ycen onto shutter open times
  first_packet_ti=ulong((data->getccsds_packet_time()).first)
  last_packet_ti=ulong((data->getccsds_packet_time()).last)
  t1ccsds=double(ulong(t1))
  for it=0,n_elements(t1)-1 do begin
    if first_packet_ti gt t1[it]/16 then top_bits=last_packet_ti else top_bits=first_packet_ti
    t1ccsds[it]=(top_bits/ulong(2)^28)*ulong(2)^28+t1ccsds[it]/16
  endfor
  t2ccsds=double(ulong(t2))
  for it=0,n_elements(t2)-1 do begin
    if first_packet_ti gt t2[it]/16 then top_bits=last_packet_ti else top_bits=first_packet_ti
    t2ccsds[it]=(top_bits/ulong(2)^28)*ulong(2)^28+t2ccsds[it]/16
  endfor
;
  time_sc = ulong(reform(spcd->gettime_pt()))
  xcen_sc = spcd->getxcen()
  ycen_sc = spcd->getycen()
  sub=where(time_sc-shift(time_sc,-1) ne 0)

  if not spcd->getioerror() and n_elements(sub) ge 2 then begin
    time_sc=time_sc[sub]
    xcen_sc=xcen_sc[sub]
    ycen_sc=ycen_sc[sub]
    xcen = interpol(xcen_sc,time_sc,t1ccsds)
    ycen = interpol(ycen_sc,time_sc,t1ccsds)
  endif else begin
    xcen = fltarr(nexp)+xcen_sc[0]
    ycen = fltarr(nexp)+ycen_sc[0]
  endelse
;
  crpix1 = 1
  crpix2 = 1
; pixel sizes
  cdelt1 = -1.*data->getdx_size() ; (arcsec pr pixel in solar-x)
  cdelt2 = 1.0 ; (arcsec pr pixel in solar-y)
;
  yw = exp_info.yw
  nraster = 1
  nhdr = n_elements(md_hdr)
  nexp = exp_info.nexp
  nexp_prp = exp_info.exp_prp
  if exp_info.fmir_step gt 0 then $
    nraster = nexp/nexp_prp ; nr of unique raster positions
  fovx = -1.*nraster*cdelt1
  fovy = yw*cdelt2
;
  xpos=(spcd->getcrval1()) + $
    (cal->getxmidmirrpos()-fmirr[0])*(cal->getfmirr_ss())*2. + $
    (exp_info.cmirr_pos-cal->getxmidcmirrpos())*(cal->getcmirr_ss()) + $
    (cal->getslit_pointing_offset(data->getslit_ind()))-fovx/2.
; 20100218 viggoh: old code below
;  xpos=(min(xpos)+max(xpos))/2.
;  xpos=median(xpos)
  ypos=(spcd->getcrval2()) + cdelt2*((yw+1)/2.-crpix2) - $
        (cal->getymidslitpos())+(data->getys())[0] + $
        (cal->getyoff_cmirr(data->date_obs2date(ot.start_ut_str)))
; 20100218 viggoh: old code below
;   -cal->getymidslitpos()+((data->getys())[0]+Indgen((data->getyw())[0]))
;  ypos=(min(ypos)+max(ypos))/2.
;  ypos=median(ypos)
; 17/09/2014 viggoh: The following is removed as these values are
; already calculated in eis_fits_coord and the below does not give the
; coorect xcen and ycen according to John M., while those done in
; eis_fits_coord *are* in agreement with the pointing.
;  fxaddpar, mhdr, 'xcen', xpos[0],  $
;                    'Center pointing (Solar X)'
;  fxaddpar, mhdr, 'ycen', ypos[0], $
;                    'Center pointing (Solar Y)'
;  fxaddpar, header, 'xcen', xpos[0],  $
;                    'Center pointing (Solar X)'
;  fxaddpar, header, 'ycen', ypos[0], $
;                    'Center pointing (Solar Y)'
; and write pointing information to bte table  
  fxbaddcol, col, header, float(xcen[0]), 'XCEN_TI1', $
                'Center pointing (Solar X(TI_1) )', $
                tunit = 'arcsec',$
                tdmin=min(xcen), $
                tdmax=max(xcen) 
  fxbaddcol, col, header, float(ycen[0]), 'YCEN_TI1', $
                'Center pointing (Solar Y(TI_1) )', $
                tunit = 'arcsec',$
                tdmin=min(ycen), $
                tdmax=max(ycen)              
;
; Add 2 columns for CCD temperatures 
;
  nhdr = nhdr + 2
;
; interpolate ccda_temp, ccdb_temp onto shutter open times
  time_sc =ulong(reform(spcd->gettime_sts1()))
  ccda_temp = double(spcd->getccda_temp())
  ccdb_temp = double(spcd->getccdb_temp()) 
;  print,ccda_temp
;  print,ccdb_temp
  if not spcd->getioerror() and n_elements(time_sc) ge 2 then begin
      ccda_temp = float(interpol(ccda_temp,time_sc,ulong(t1ccsds)))
      ccdb_temp = float(interpol(ccdb_temp,time_sc,ulong(t1ccsds)))
      ccda_temp = eis_convert_ccda_temperature(ccda_temp)
      ccdb_temp = eis_convert_ccdb_temperature(ccdb_temp)
  endif else begin
    if not spcd->getioerror() then begin
      ccda_temp = eis_convert_ccda_temperature(ccda_temp[0])+fltarr(nexp)
      ccdb_temp = eis_convert_ccdb_temperature(ccdb_temp[0])+fltarr(nexp)
    endif else begin
      ccda_temp = fltarr(nexp)
      ccdb_temp = fltarr(nexp)
    endelse
  endelse
; and write ccd temperature information  
  fxbaddcol, col, header, float(ccda_temp[0]), 'CCDAT_TI', $
                'CCD A temperature (CCDA_T(TI_1) )', $
                tunit = 'C',$
                tdmin=min(ccda_temp), $
                tdmax=max(ccda_temp) 
  fxbaddcol, col, header, float(ccdb_temp[0]), 'CCDBT_TI', $
                'CCD B temperature (CCDB_T(TI_1) )', $
                tunit = 'C',$
                tdmin=min(ccdb_temp), $
                tdmax=max(ccdb_temp)             
;
; Add 2 columns for MHC temperatures 
  if mhc_temp then begin
    nhdr = nhdr + 2
;
; average mhc_temp onto shutter open times, or interpolate onto shutter opening times
                
    s=spcd->getmhc_temp()
    t15=double(eis_convert_mhc_temperature(s.mhc_hz_t15,s.mhc_ref_ther_0,s.mhc_cal_ther_0))
;   ti5=smooth(t15,11<(size(t15))[1],/edge)
    t10=double(eis_convert_mhc_temperature(s.mhc_hz_t10,s.mhc_ref_ther_0,s.mhc_cal_ther_0))
;   ti0=smooth(t10,11<(size(t10))[1],/edge)
    if not spcd->getioerror() and n_elements(s.time_sc) ge 2 then begin
      exposures=t2ccsds-t1ccsds
      hkdtimes=shift(ulong(s.time_sc),-1)-ulong(s.time_sc)
      if (min(exposures) le max(hkdtimes)) then begin
        t10 = float(interpol(double(t10),ulong(s.time_sc),ulong(t1ccsds)))
        t15 = float(interpol(double(t15),ulong(s.time_sc),ulong(t1ccsds)))
      endif else begin
        t10ccsds=t1ccsds 
        t15ccsds=t1ccsds 
        for i=0,n_elements(t1ccsds)-1 do begin
          index=where(ulong(s.time_sc) ge t1ccsds[i] and ulong(s.time_sc) le t2ccsds[i])
          t10ccsds[i]=mean(t10[index])
          t15ccsds[i]=mean(t15[index])
        endfor
        t10 = float(t10ccsds)
        t15 = float(t15ccsds)
      endelse 
    endif else begin
      if not spcd->getioerror() then begin
        t10 = float(t15[0])+fltarr(nexp)
        t15 = float(t15[0])+fltarr(nexp)
      endif else begin
        t10 = fltarr(nexp)
        t15 = fltarr(nexp)
      endelse
    endelse
; and write mhc temperature information         
    fxbaddcol, col, header, float(t10[0]), 'MHC_HZ_T10', $
              'MHC HZ TEMP 10 (MHC_T10(TI) )', $
              tunit = 'C',$
              tdmin=min(t10), $
              tdmax=max(t10)
    fxbaddcol, col, header, float(t15[0]), 'MHC_HZ_T15', $
              'MHC HZ TEMP 15 (MHC_T15(TI) )', $
              tunit = 'C',$
              tdmin=min(t15), $
              tdmax=max(t15)
  endif
;
;
; Add 3 columns for Doppler velocities
  if doppler_v then begin
    nhdr = nhdr + 3
;
; average Doppler vel  onto shutter open times, or interpolate onto shutter opening times
    v_sat_ccsds = t1ccsds
    v_sun_ccsds = t1ccsds
    v_eth_ccsds = t1ccsds
    spcd->construct_veloc
    if not spcd->getioerror() then begin
      time_sc = ulong(reform(spcd->gettime_sot()))
      v_sat = spcd->getv_sat()
      v_sun = spcd->getv_sun()
      v_eth = spcd->getv_eth()
      v_sat=(v_sat*2L^16) / 2L^16
      v_sun=(v_sun*2L^16) / 2L^16
      v_eth=(v_eth*2L^16) / 2L^16
;
      if n_elements(time_sc) ge 2 then begin
        exposures=t2ccsds-t1ccsds
        hkdtimes=shift(time_sc,-1)-time_sc
        if (min(exposures) le max(hkdtimes)) then begin
          v_sat_ccsds = float(interpol(double(v_sat),ulong(time_sc),ulong(t1ccsds)))
          v_sun_ccsds = float(interpol(double(v_sun),ulong(time_sc),ulong(t1ccsds)))
          v_eth_ccsds = float(interpol(double(v_eth),ulong(time_sc),ulong(t1ccsds)))
        endif else begin
          for i=0,n_elements(t1ccsds)-1 do begin
            index=where(time_sc ge t1ccsds[i] and time_sc le t2ccsds[i])
            v_sat_ccsds[i]=float(mean(v_sat[index]))
            v_sun_ccsds[i]=float(mean(v_sun[index]))
            v_eth_ccsds[i]=float(mean(v_eth[index]))
          endfor
        endelse
      endif else begin 
        v_sat_ccsds = float(v_sat[0])+fltarr(nexp)
        v_sun_ccsds = float(v_sun[0])+fltarr(nexp)
        v_eth_ccsds = float(v_eth[0])+fltarr(nexp)
      endelse
    endif else begin
      v_sat_ccsds = fltarr(nexp)
      v_sun_ccsds = fltarr(nexp)
      v_eth_ccsds = fltarr(nexp)
    endelse
;  add Doppler vel. columns in the image if not already there; hdr is also updated
    fxbaddcol, col, header, float(v_sat_ccsds[0]), 'V_SAT', $
              'Satellite Doppler vel (V_SAT)', $
              tunit = 'm/s',$
              tdmin=min(v_sat_ccsds), $
              tdmax=max(v_sat_ccsds)
    fxbaddcol, col, header, float(v_sun_ccsds[0]), 'V_SUN', $
              'Sun Doppler vel (V_SUN)', $
              tunit = 'm/s',$
              tdmin=min(v_sun_ccsds), $
              tdmax=max(v_sun_ccsds)
    fxbaddcol, col, header, float(v_eth_ccsds[0]), 'V_ETH', $
              'Earth Doppler vel (V_ETH)', $
              tunit = 'm/s',$
              tdmin=min(v_eth_ccsds), $
              tdmax=max(v_eth_ccsds)
  endif
;  
;
  ncol = nwin + nhdr
  errmsg = ''
;
; update main hdr parameters (naxis* and tfields with new values
; Write the primary header to file
;  naxis = fxpar(header, 'NAXIS')  ; NAXIS
;  fxaddpar, mhdr, 'NAXIS', naxis
;  naxis = fxpar(header, 'NAXIS*') ; NAXIS1 and NAXIS2
;  fxaddpar, mhdr, 'NAXIS1', naxis[0]
;  fxaddpar, mhdr, 'NAXIS2', naxis[1]
;  tfields = fxpar(header, 'TFIELDS')
;  fxaddpar, mhdr, 'TFIELDS', tfields
  fxwrite, fitsfile, mhdr

  fxbcreate, lu, fitsfile, header, errmsg = errmsg

  if errmsg ne '' then begin
    ok = dialog_message(errmsg,/informational)
    return
  endif

  for icol = 0, nwin-1 do begin
    data ->getwin, icol, wd, pos
    for irow = 1, nexp do begin
      fxbwrite, lu, fix(wd[*,*,irow-1]), icol+1, irow
    endfor
  endfor

  icol=nwin
  iadd=0
  for irow = 1, nexp do begin
      fxbwrite, lu, double(t1[irow-1]), icol+1, irow
      fxbwrite, lu, double(t2[irow-1]), icol+2, irow
      fxbwrite, lu, double(durmhc[irow-1]), icol+3, irow
      fxbwrite, lu, double(dursec[irow-1]), icol+4, irow
      fxbwrite, lu, fmirr[irow-1], icol+5, irow
      fxbwrite, lu, hsl[irow-1], icol+6, irow
      fxbwrite, lu, xrt_flfl[irow-1], icol+7, irow
      fxbwrite, lu, xrt_fl_x[irow-1], icol+8, irow
      fxbwrite, lu, xrt_fl_y[irow-1], icol+9, irow
      fxbwrite, lu, aec_hepc[irow-1], icol+10, irow
      fxbwrite, lu, aec_lepc[irow-1], icol+11, irow
      fxbwrite, lu, mhcsg[irow-1], icol+12, irow
      fxbwrite, lu, float(xcen[irow-1]), icol+13, irow
      fxbwrite, lu, float(ycen[irow-1]), icol+14, irow
      fxbwrite, lu, float(ccda_temp[irow-1]), icol+15, irow
      fxbwrite, lu, float(ccdb_temp[irow-1]), icol+16, irow
      if mhc_temp then begin
        fxbwrite, lu, float(t10[irow-1]), icol+17, irow
        fxbwrite, lu, float(t15[irow-1]), icol+18, irow
        iadd=2
      endif
      if doppler_v then begin
        fxbwrite, lu, float(v_sat_ccsds[irow-1]), icol+17+iadd, irow
        fxbwrite, lu, float(v_sun_ccsds[irow-1]), icol+18+iadd, irow
        fxbwrite, lu, float(v_eth_ccsds[irow-1]), icol+19+iadd, irow
      endif
  endfor

; write EIS hdr data

; Close the binary table extension and destroy all objects
  fxbfinish, lu
  
  obj_destroy,cal
  obj_destroy,plan
  obj_destroy,spcd
;  obj_destroy,hk

; Call eis_add_fits_file to populate As-run database
;    ; /verbose until we are sure this works?
  if doasrun then begin
    ok=eis_add_fits_file(fitsfile, /verbose, err = err)
  endif

end

