;+
; NAME:
;       EIS_SPCD__DEFINE
;
; PURPOSE:
;       The eis_spcd object is the general superclass for spcd
;       class objects used by the Hansteen/Wikstøl QL/data analysis
;       SW. The spcd object contains data that is aqcuired from 
;       the space craft data telemetry stream on Solar-B. 
;       Some of these are used in the main FITS hdr of Solar-B fits files.
;
; CATEGORY:
;       Hansteen/Wikstol Data analysis SW
;
; CALLING SEQUENCE:
;	spcd_obj = obj_new('spcd', file = file)
;
; INPUTS:
;      None
;
; KEYWORD PARAMETERS:
;
;
; OUTPUTS:
;       Objects of class EIS_SPCD includes the following parameters:
;
; CALLS:
;
; COMMON BLOCKS:
;
;
; PROCEDURE:
;       Defines the structure of plan class objects. If no filename 
;       is given as input, the FITS keywords are set by 
;       the init-procedure. If filename is given (space craft data telemetry 
;       file), it is read from that file by eis_spcd__read.pro
;
; RESTRICTIONS:
;
;
; MODIFICATION HISTORY:
;       15-Nov-2005: Oivind Wikstol. First draft
;                    WARNING: saa, hlz, should come from ISACS-PLN files??
;       August 2006: Added xcen and ycen
;       14-Nov-2006: Viggo Hansteen - Added all variables needed for s/c pointing info
;                    WARNING: Still a bit unclear about difference between xcen,ycen
;                             and xhelio,yhelio
;                    saa, hlz will be moved to planning object
;       22-Nov-2006: Viggo Hansteen - Fixed pointing: xcen, ycen should now represent 
;                                     the solar x and y at the center of the image
;                                     Call to calibration object to get EIS offset
;                                     relative AOCS/SOT
;       23-Nov-2006: Viggo Hansteen - Moved saa and hlz to the planning object.
;       03-Dec-2006: Viggo Hansteen - Improved error handling in case "eis_aocs1" file is not
;                                     found. Also constrain search in "tomorrow's directory" to 
;                                     cases where date_end > max(ti1)
;       08-Dec-2006: Viggo Hansteen - Added alternate method for computing pointing
;                                     as given by Toshifumi Shimizu (/aocs to construct_xypos)
;       10-Dec-2006: Viggo Hansteen - Added CCD temperature keywords as well as keywords for 
;                                     time arrays for each individual time file 
;                                     i.e eis_aocs1, eis_hk2, eis_sts1, (with more to come)
;       10-Feb-2007: Viggo Hansteen - Added help methods.
;       09-Mar-2007: Viggo Hansteen - Now also reads velocity keywords v_sun, v_sat, v_eth.
;        4-Jul-2008: A. Gardini     - Added HELP and INIT_EIS_SPCD_METHODS.
;       30-Apr-2009: A. Gardini     - Set keyword to eis_cal.
;       18-Feb-2010  V. Hansteen     - Implemented John Mariska's 
;                                      "EIS pointing" ver 0.95 document.
;
;  $Id: eis_spcd__define.pro 4174 2014-09-17 15:31:36Z viggoh $
;-
function eis_spcd::init,date_obs_ut,date_end_ut,date_obs,date_end, dir_head=dir_head
  self->init_eis_spcd_methods ; initialization of the help method
  self.help=obj_new('hw_help')
  if n_elements(date_end) eq 0 then begin
    self->setdefaults
  endif else begin
    self->setdefaults
    self.date_obs_ut=date_obs_ut
    self.date_end_ut=date_end_ut
    self.date_obs=ulong(date_obs)
    self.date_end=ulong(date_end)
    self.inst_rot=0.0
 endelse
  if n_elements(dir_head) ne 0 then self.dir_head=dir_head
  return,1
end


function eis_spcd::getdir_head,init=init
  if n_elements(init) eq 1 then return, -1
  return,self.dir_head
end

pro eis_spcd::display_all,init=init
  if n_elements(init) eq 1 then return
  self.help->display_all
  return
end

pro eis_spcd::display_methods,init=init
  if n_elements(init) eq 1 then return
  self.help->display_methods
  return
end

pro eis_spcd::setdefaults,init=init
  if n_elements(init) eq 1 then return
    self.dir_head = getenv('HOME')
    self.tr_mode = 'NA'
    self.time_aocs1 = ptr_new([-1.0])
    self.time_hk2 = ptr_new([-1.0])
    self.time_sts1 = ptr_new([-1.0])
    self.time_sts3 = ptr_new([-1.0])
    self.time_pt = ptr_new([-1.0])
    self.xcen = ptr_new([-9999.0])
    self.ycen = ptr_new([-9999.0])
    self.ccda_temp = ptr_new([0.0])
    self.ccdb_temp = ptr_new([0.0])
    self.mhc_ref_ther_0 = ptr_new([0.0])
    self.mhc_cal_ther_0 = ptr_new([0.0])
    self.mhc_hz_t10 = ptr_new([0.0])
    self.mhc_hz_t15 = ptr_new([0.0])
    self.v_sat = ptr_new([0.0])
    self.v_sun = ptr_new([0.0])
    self.v_eth = ptr_new([0.0])
    self.v_rst = ptr_new([0.0])
    self.crval1 = ptr_new([-9999.0])
    self.crval2 = ptr_new([-9999.0])
    self.inst_rot = 0.0
    self.sat_rot = ptr_new(['-1.0'])
    self.crota1 = ptr_new([-1.0])
    self.crota2 = ptr_new([-1.0])
    self.ufsaxang=ptr_new([-1.0])
    self.ufsbxang=ptr_new([-1.0])
    self.ufsayang=ptr_new([-1.0])
    self.ufsbyang=ptr_new([-1.0])
    self.att_x=ptr_new([-9999.0])
    self.att_y=ptr_new([-9999.0])
    self.att_z=ptr_new([0.0])
    self.ioerror=1
end

pro eis_spcd::construct_pointing,aocs=aocs,init=init
  if n_elements(init) eq 1 then return
  self->construct,'TR_MODE'
  self->construct,'SAT_ROT'
  self->construct_xypos,aocs=aocs
;  self->construct_xypos 
end

pro eis_spcd::construct_ccdtemp,init=init
  if n_elements(init) eq 1 then return
  self->construct,'TIME_STS1'
  self->construct,'CCDA_TEMP'
  self->construct,'CCDB_TEMP'
end

pro eis_spcd::construct_mhctemp,init=init
  if n_elements(init) eq 1 then return
  self->construct,'TIME_STS3'
  self->construct,'MHC_REF_THER_0'
  self->construct,'MHC_CAL_THER_0'
  self->construct,'MHC_HZ_T10'
  self->construct,'MHC_HZ_T15'
end

pro eis_spcd::construct_veloc,init=init
  if n_elements(init) eq 1 then return
  self->construct,'TIME_SOT'
  self->construct,'MDP_DSC_V_SAT'
  self->construct,'MDP_DSC_V_SUN'
  self->construct,'MDP_DSC_V_ETH'
end

pro eis_spcd::construct,parameter,init=init
  if n_elements(init) eq 1 then return
  parameter=strupcase(parameter)
;  construct array of times and parameter(time) from date_obs to date end
;  find out which type of file the parameter is in
  case parameter of
  'TIME_AOCS1': begin
     filehead = 'eis_aocs1'
     bintable = 2
     read_all_files = 1
     parameter='TIME'
             end
  'TIME_HK2': begin
     filehead = 'eis_hk2'
     bintable = 2
     read_all_files = 1
     parameter='TIME'
             end
  'TIME_STS1': begin
     filehead = 'eis_sts1'
     bintable = 12
     read_all_files = 1
     parameter='TIME'
             end
  'TIME_STS3': begin
     filehead = 'eis_sts3'
     bintable = 11
     read_all_files = 1
     parameter='TIME'
             end
  'TIME_SOT': begin
     filehead = 'eis_sot'
     bintable = 2
     read_all_files = 1
     parameter='TIME'
             end
  'SAT_ROT': begin
     filehead = 'eis_aocs1'
     bintable = 1
     read_all_files = 1
             end
  'UFSAXANG': begin
     filehead = 'eis_aocs1'
     bintable = 1
     read_all_files = 1
             end
  'UFSAYANG': begin
     filehead = 'eis_aocs1'
     bintable = 1
     read_all_files = 1
             end
  'UFSBXANG': begin
     filehead = 'eis_aocs1'
     bintable = 1
     read_all_files = 1
             end
  'UFSBYANG': begin
     filehead = 'eis_aocs1'
     bintable = 1
     read_all_files = 1
             end
  'ERRANGZ': begin
     filehead = 'eis_aocs1'
     bintable = 1
     read_all_files = 1
             end
  'SC_ATT_X': begin
     filehead = 'eis_hk2'
     bintable = 1
     read_all_files = 1
             end
  'SC_ATT_Y': begin
     filehead = 'eis_hk2'
     bintable = 1
     read_all_files = 1
             end
  'SC_ATT_Z': begin
     filehead = 'eis_hk2'
     bintable = 1
     read_all_files = 1
             end
  'TR_MODE': begin
     filehead = 'eis_hk2'
     bintable = 1
     read_all_files = 0
             end
  'UFSAUSE': begin
     filehead = 'eis_hk2'
     bintable = 1
     read_all_files = 0
             end
  'UFSBUSE': begin
     filehead = 'eis_hk2'
     bintable = 1
     read_all_files = 0
             end
  'CCDA_TEMP': begin
     filehead = 'eis_sts1'
     bintable = 3
     read_all_files = 1
             end
  'CCDB_TEMP': begin
     filehead = 'eis_sts1'
     bintable = 3
     read_all_files = 1
             end
  'MHC_REF_THER_0': begin
     filehead = 'eis_sts3'
     bintable = 1
     read_all_files = 1
             end
  'MHC_CAL_THER_0': begin
     filehead = 'eis_sts3'
     bintable = 1
     read_all_files = 1
             end
  'MHC_HZ_T10': begin
     filehead = 'eis_sts3'
     bintable = 5
     read_all_files = 1
             end
  'MHC_HZ_T15': begin
     filehead = 'eis_sts3'
     bintable = 5
     read_all_files = 1
             end
  'MDP_DSC_V_SAT': begin
     filehead = 'eis_sot'
     bintable = 1
     read_all_files = 1
             end
  'MDP_DSC_V_SUN': begin
     filehead = 'eis_sot'
     bintable = 1
     read_all_files = 1
             end
  'MDP_DSC_V_ETH': begin
     filehead = 'eis_sot'
     bintable = 1
     read_all_files = 1
             end
  else: begin
    message,'no such parameter!!'
        end
  endcase
  start_ut=self->getdate_obs_ut()
  date=start_ut
  end_ut=self->getdate_end_ut()
  date_obs=self->getdate_obs()
  date_end=self->getdate_end()

  done=0
  yesterday=0
  self.ioerror=0
  on_ioerror,ioerror
  repeat begin
    eis_find_directory,date,dir,head=self->getdir_head()
    f=file_search(dir+filehead+'*fits*')
    if f[0] eq '' then begin
      message,'no spacecraft data for '+date+' available for parameter '+parameter,/info
      self.ioerror=1
      return
    end
;    ti0=lonarr(n_elements(f))
;    ti1=lonarr(n_elements(f))
;; find start and end times for all files in the directory
;    for i=0,n_elements(f)-1 do begin
;      dum=readfits(f[i],hdr,/silent)
;      hex2dec,fxpar(hdr,'TI0'),dum,/quiet
;      ti0[i]=dum
;      hex2dec,fxpar(hdr,'TI1'),dum,/quiet
;      ti1[i]=dum
;    endfor

    ti0=ulonarr(n_elements(f))
    ti1=ulonarr(n_elements(f))
; find start and end times for all files in the directory
    for i=0,n_elements(f)-1 do begin
      dum=readfits(f[i],hdr,/silent)
      hex2dec,fxpar(hdr,'TI0'),dum,/quiet
      ti0[i]=ulong(dum)
      hex2dec,fxpar(hdr,'TI1'),dum,/quiet
      ti1[i]=ulong(dum)
  endfor

; Check if we are in the vicinity of the 23rd december 2010 rollover
; or later...
if fix(self->year(start_ut)) gt 2006 then begin
;    print,'Greater than 2006'
    if date_obs lt '002A3000'xul or date_obs gt 'FFF5CFFF'xul then begin
;        print,'We made it...'
        date_obs = long(date_obs)
        ti0 = long(ti0)
        ti1 = long(ti1)
    endif
endif
;print, 'year, ti0 min, max date_obs:', self->year(start_ut), min(ti0), max(ti0), date_obs

; construct list of files starting at date_obs...
; check if observation starts before first spcd file of observation date 
; ....if so set search directory to yesterday

;  print, 'date_obs', date_obs, ' ti0[0]', ti0[0], ' yesterday', yesterday

    if date_obs lt ti0[0] and not yesterday then begin
      mjd=date2mjd(self->year(start_ut),self->month(start_ut),self->day(start_ut))
      mjd2date,mjd-1,yr,mon,day
      date=anytim2cal(string(yr)+'-'+string(mon)+'-'+string(day)+'T00:00:00Z',form=11,/date)
      yesterday=1
      goto,newsearch
    endif
; ok, we should now be able to start looking at the right files
    istart=(max(where(ti0 le date_obs)))>0
    iend=max(where(ti0 le date_end))
; check if all files in directory start after date_end, if so then done....
    if iend eq -1 then begin
      done=1
      goto,newsearch
    endif

;    print,'iend', iend, ' istart', istart

    sub=indgen(iend-istart+1)+istart
    f=f[sub]
    ti1=ti1[sub]
    ti0=ti0[sub]
; ...read files up until date_end
    if read_all_files then begin
      for i=0,n_elements(f)-1 do begin
        pdata_0=reform(eis_read_fits_data(f[i],parameter,bintable))
        case n_elements(pdata) of
          0: pdata=reform(pdata_0)
          else: pdata=[pdata,pdata_0]
        endcase
      endfor
      if self->day(date) ne self->day(end_ut) and date_end gt max(ti1) then begin
        mjd=date2mjd(self->year(date),self->month(date),self->day(date))
        mjd2date,mjd+1,yr,mon,day
        date=anytim2cal(string(yr)+'-'+string(mon)+'-'+string(day)+'T00:00:00Z',form=11,/date)
      endif else done=1
      
    endif else begin

      pdata=(eis_read_fits_data(f[0],parameter,bintable))[0]
      
      done=1
    endelse
newsearch:
    yesterday=1
  endrep until done
  case parameter of 
  'SAT_ROT': begin
     self.sat_rot = ptr_new(pdata*2.14577e-5) ; conversion factor is 180/2^23
     self.crota1 = ptr_new(*self.sat_rot+self.inst_rot)
     self.crota2 = ptr_new(*self.sat_rot+self.inst_rot)
             end
  'TIME': begin
     case filehead of
     'eis_aocs1': self.time_aocs1 = ptr_new(pdata)
     'eis_hk2'  : self.time_hk2 = ptr_new(pdata)
     'eis_sts1' : self.time_sts1 = ptr_new(pdata)
     'eis_sts3' : self.time_sts3 = ptr_new(pdata)
     'eis_sot'  : self.time_sot = ptr_new(pdata)
     endcase
             end
  'UFSAXANG': begin
     self.ufsaxang = ptr_new(pdata)
             end
  'UFSAYANG': begin
     self.ufsayang = ptr_new(pdata)
             end
  'UFSBXANG': begin
     self.ufsbxang = ptr_new(pdata)
             end
  'UFSBYANG': begin
     self.ufsbyang = ptr_new(pdata)
             end
  'ERRANGZ': begin
     self.errangz = ptr_new(pdata)
             end
  'SC_ATT_X': begin
     self.att_x = ptr_new(pdata)
             end
  'SC_ATT_Y': begin
     self.att_y = ptr_new(pdata)
             end
  'SC_ATT_Z': begin
     self.att_z = ptr_new(pdata)
             end
  'TR_MODE': begin
     if n_elements(pdata) eq 0 then pdata=-1
     case pdata of
     0: self.tr_mode='FIX'
     1: self.tr_mode='TR1'
     2: self.tr_mode='TR2'
     3: self.tr_mode='TR3'
     4: self.tr_mode='TR4'
     else: self.tr_mode='UNKNOWN'
     endcase
             end
  'UFSAUSE': begin
     self.ufsause = pdata
             end
  'UFSBUSE': begin
     self.ufsbuse = pdata
             end
  'CCDA_TEMP': begin
     self.ccda_temp = ptr_new(pdata)
             end
  'CCDB_TEMP': begin
     self.ccdb_temp = ptr_new(pdata)
             end
  'MHC_REF_THER_0': begin
     self.mhc_ref_ther_0 = ptr_new(pdata)
             end
  'MHC_CAL_THER_0': begin
     self.mhc_cal_ther_0 = ptr_new(pdata)
             end
  'MHC_HZ_T10': begin
     self.mhc_hz_t10 = ptr_new(pdata)
             end
  'MHC_HZ_T15': begin
     self.mhc_hz_t15 = ptr_new(pdata)
             end
  'MDP_DSC_V_SAT': begin
     self.v_sat = ptr_new(pdata)
             end
  'MDP_DSC_V_SUN': begin
     self.v_sun = ptr_new(pdata)
             end
  'MDP_DSC_V_ETH': begin
     self.v_eth = ptr_new(pdata)
             end
  endcase
  return  
  ioerror: message,'IO error while searching for/reading parameter '+parameter,/info
           self.ioerror=1
  return
end

pro eis_spcd::construct_xypos,aocs=aocs ,init=init
  if n_elements(init) eq 1 then return
if n_elements(aocs) eq 0 then aocs=0
self->setxyoffset 
date_obs=self->getdate_obs()
date_end=self->getdate_end()   
if aocs eq 0 then begin
;;;if aocs eq 1 then begin
  self->construct,'TIME_AOCS1'
  if self.ioerror then return
  self.time_pt=ptr_new(ulong(*self.time_aocs1))
  time_sub=where(*self.time_pt ge ulong(date_obs)-32ul and *self.time_pt le ulong(date_end)+32ul)
  if time_sub[0] eq -1 then begin
    time_sub=0
    message,'cannot find HK data around time of date_obs',/info
    message,'using parameters at time '+string((*self.time_pt)[time_sub])+', date_obs is '+string(date_obs),/info
  endif
  *self.time_pt=(*self.time_pt)[time_sub]
  scale=0.10986663
  origin=1800
  self->construct,'UFSAUSE'
  self->construct,'UFSBUSE'
; find which ultra fine sensor, a or b, is in use
  comp_xypos=0
  if self.ufsause then begin
    self->construct,'UFSAXANG'
    self->construct,'UFSAYANG'
    ufsxang=self->getufsaxang()
    ufsyang=self->getufsayang()
    if ufsxang[0] eq 0 or ufsyang[0] eq 0 then comp_xypos=0 else comp_xypos=1
  endif 
  if self.ufsbuse then begin
    self->construct,'UFSBXANG'
    self->construct,'UFSBYANG'
    ufsxang=self->getufsbxang()
    ufsyang=self->getufsbyang()
    if ufsxang[0] eq 0 or ufsyang[0] eq 0 then comp_xypos=0 else comp_xypos=1
  endif
  if not comp_xypos then begin
    message,'no ufss in use, no positioning computed',/info
    self.ioerror=1
    return
  endif
  xufss=ufsxang*scale-origin
  yufss=ufsyang*scale-origin
  self->construct,'ERRANGZ'
  thetaz=self->geterrangz()*0.0772476*!pi/180./60./60. ; 648000/2^23 in arcsec converted 
                                                       ; to radians
  xoffut=self->getxoffut()
  yoffut=self->getyoffut()
  xoffsu=self->getxoffsu()
  yoffsu=self->getyoffsu()
;
; offset angle of the telescope according to "Erratum of the list of Solar-B "Hinode"
; Mission-Wide keywords" Section: Note: Telemetry of AOCS data 2006/11/05 Masumi Shimojo
;
; xcen,ycen (coordinate of the center of the image) 
; 2006/11/14 viggoh: am assuming this is the same as xhelio, yhelio defined by Shimojo
; to find the position of a given pixel on EIS use 
; x = xcen+(npixx-nrefx)*pixszx*cos(inst_rot+thetaz)+(npixy-nrefy)*pixszy*sin(inst_rot+thetaz)
; y = ycen-(npixx-nrefx)*pixszx*sin(inst_rot+thetaz)+(npixy-nrefy)*pixszy*cos(inst_rot+thetaz)
; note that the crot keyword contains inst_rot+sat_rot equivalent to inst_rot+thetaz
;
  xcen=xoffsu+(xufss-xoffut)*cos(thetaz)+(yufss-yoffut)*sin(thetaz)
  ycen=yoffsu-(xufss-xoffut)*sin(thetaz)+(yufss-yoffut)*cos(thetaz)
  self.xcen=ptr_new(xcen[time_sub])
  self.ycen=ptr_new(ycen[time_sub])
endif else begin
  self->construct,'TIME_HK2'
  if self.ioerror then return
  self.time_pt=ptr_new(ulong(*self.time_hk2))
  time_sub=where(*self.time_pt ge ulong(date_obs)-32ul and *self.time_pt le ulong(date_end)+32ul)
  if time_sub[0] eq -1 then begin
    time_sub=0
    message,'cannot find HK data around time of date_obs',/info
    message,'using parameters at time '+string((*self.time_pt)[time_sub])+', date_obs is '+string(date_obs),/info
  endif
  *self.time_pt=(*self.time_pt)[time_sub]
  self->construct,'SC_ATT_X'
  self->construct,'SC_ATT_Y'
  self->construct,'SC_ATT_Z'
;
; Rather, for reformatter pointing keywords, which
; tells the heliocenteric coordinate of the observing region in order
; of 10 arcsec accuracy, the AOCS onboard determined attitude values
; available in HK2 packets may be more suitable. These values are
; the AOCS determined satellte attitude by using 2 UFSS sensors and
; Gyros with including instrument offset relative to the SOT pointing
; direction.
; [HK2_ATT_X]
;    Representing N-S direction (but sign is opposite)
;    APID 428  Word 275  Length 24bit
;    Conversion coefficients (Xarcsec= C1*X +C0; X telemetry)
;     C1: 180/2^23*60*60  for the conversion from telemetry to arcsec
;      C0: 0
; [HK2_ATT_Y]
;   Representing E-W direction (but sign is opposite)
;   APID 428  Word 278  Length 24bit
;   Conversion coefficients (Xarcsec= C1*X +C0; X telemetry)
;     C1: 180/2^23*60*60  for the conversion from telemetry to arcsec
;     C0: 0
; [HK2_ATT_Z]
;   Representing rotation around Z (sign is not yet confirmed)
;   APID 428  Word 281  Length 24bit
;   Conversion coefficients (Xarcsec= C1*X +C0; X telemetry)
;     C1: 180/2^23*60*60  for the conversion from telemetry to arcsec
;     C0: 0
; Shimizu-san e-mail of 04-Dec-2006...
;
  if not self.ioerror then begin
; First convert 24 bit to 32 bit long, change sign, and convert to arcsec
    xcen=-1.0*ishft(*self.att_y,8)/256.*180.*60.*60./2ul^23
    ycen=-1.0*ishft(*self.att_x,8)/256.*180.*60.*60./2ul^23
; Then add EIS specific offset
    xcen=xcen[time_sub]+self->getxoffut()
    ycen=ycen[time_sub]+self->getyoffut()
    self.xcen=ptr_new(xcen)
    self.ycen=ptr_new(ycen)
  endif
endelse
;
; crval (coordinate of the reference pixel in heliocentric coordinate)
; crpix (pixel coordinate of the reference pixel)
; 20061114 viggoh: don't know if crpix is defined, setting 
;                    crval eqal to xcen,ycen
; 20100217 viggoh: set crval1,crval2 to first presumed "good" pair of 
;                  xcen,ycen
;
limxy=self->getpointing_limits()
indx=where(xcen gt limxy.xmin and xcen lt limxy.xmax and $
           ycen gt limxy.ymin and ycen lt limxy.ymax,count)
if count eq 0 then begin
  message,'no good pointing found!',/info
endif else begin
  *self.crval1=xcen[min(indx)]
  *self.crval2=ycen[min(indx)]
endelse
return
end

pro eis_spcd::setxyoffset,init=init
  if n_elements(init) eq 1 then return
;
; EIS offset from z-axis of ultra fine sun sensor (UFSS) also called the ut offsets
; in the Shimojo FITS Keywords list "The List of Solar-B "Hinode" Mission-Wide FITS
; Keywords" 2006/11/14 ver. 1.1
; The following numbers are taken from "Alignment among Hinode Science Instruments
; (preliminary)" 2006/11/07 Hirohisa Hara 
; The middle of the eis field of view (cmir=892, fmir=1800) is 
; 13 XRT pixels South and 87 XRT pixels East of the AOCS (SOT) FOV 
; XRT pixel size is 1.025 arcsec
;
; The su offsets correspond to the inst_rot keyword and are the offsets between the
; origin of the UFSS coordinate and the Sun center
; 
  cal=obj_new('eis_cal',/quiet)
  self.xoffut = cal->getxoffsetut()
  self.yoffut = cal->getyoffsetut()
  self.xoffsu = cal->getxoffsetsu() ; so far undefined
  self.yoffsu = cal->getyoffsetsu() ; so far undefined
  obj_destroy,cal
  return
end

function eis_spcd::getxoffut,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.xoffut
end

function eis_spcd::getyoffut,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.yoffut
end

function eis_spcd::getxoffsu,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.xoffsu
end

function eis_spcd::getyoffsu,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.yoffsu
end

function eis_spcd::year,date,init=init
  if n_elements(init) eq 1 then return, -1
  return,fix(strmid(date,0,4))
end

function eis_spcd::month,date,init=init
  if n_elements(init) eq 1 then return, -1
  return,fix(strmid(date,5,2))
end

function eis_spcd::day,date,init=init
  if n_elements(init) eq 1 then return, -1
  return,fix(strmid(date,8,2))
end

function eis_spcd::gettr_mode,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.tr_mode
end

function eis_spcd::getdate_obs_ut,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.date_obs_ut
end

function eis_spcd::getdate_end_ut,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.date_end_ut
end

function eis_spcd::getdate_obs,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.date_obs
end

function eis_spcd::getdate_end,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.date_end
end

function eis_spcd::gettime_aocs1,init=init
  if n_elements(init) eq 1 then return, -1
  return, ulong(*self.time_aocs1)
end

function eis_spcd::gettime_hk2,init=init
  if n_elements(init) eq 1 then return, -1
  return, ulong(*self.time_hk2)
end

function eis_spcd::gettime_sts1,init=init
  if n_elements(init) eq 1 then return, -1
  return, ulong(*self.time_sts1)
end

function eis_spcd::gettime_sot,init=init
  if n_elements(init) eq 1 then return, -1
  return, ulong(*self.time_sot)
end

function eis_spcd::gettime_pt,init=init
  if n_elements(init) eq 1 then return, -1
  return, ulong(*self.time_pt)
end

function eis_spcd::getxcen,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.xcen
end

function eis_spcd::getycen,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.ycen
end

function eis_spcd::getmhc_temp,init=init
  if n_elements(init) eq 1 then return, -1
  return, {mhc_ref_ther_0:*self.mhc_ref_ther_0, $
           mhc_cal_ther_0:*self.mhc_cal_ther_0, $
           mhc_hz_t10:*self.mhc_hz_t10, $
           mhc_hz_t15:*self.mhc_hz_t15, $
           time_sc:*self.time_sts3}
end

function eis_spcd::getccda_temp,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.ccda_temp
end

function eis_spcd::getccdb_temp,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.ccdb_temp
end

function eis_spcd::getv_sun,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.v_sun
end

function eis_spcd::getv_sat,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.v_sat
end

function eis_spcd::getv_eth,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.v_eth
end

function eis_spcd::getufsaxang,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.ufsaxang
end

function eis_spcd::getufsayang,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.ufsayang
end

function eis_spcd::getufsbxang,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.ufsbxang
end

function eis_spcd::getufsbyang,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.ufsbyang
end

function eis_spcd::getufsause,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.ufsause
end

function eis_spcd::getufsbuse,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.ufsbuse
end


function eis_spcd::geterrangz,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.errangz
end

function eis_spcd::getpointing_limits,init=init
  if n_elements(init) eq 1 then return, -1
  return,{xmin:-1001.,xmax:1001.,ymin:-1001.,ymax:1001.}
end

function eis_spcd::getcrval1,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.crval1
end

function eis_spcd::getcrval2,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.crval2
end

function eis_spcd::getinst_rot,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.inst_rot
end

function eis_spcd::getsat_rot,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.sat_rot
end

function eis_spcd::getcrota1,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.crota1
end

function eis_spcd::getcrota2,init=init
  if n_elements(init) eq 1 then return, -1
  return, *self.crota2
end

function eis_spcd::getioerror,init=init
  if n_elements(init) eq 1 then return, -1
  return, self.ioerror
end

pro eis_spcd::help
  help,self,/obj
  return
end

pro eis_spcd::init_eis_spcd_methods

  a=self->getdir_head(/init)
  self->display_all,/init
  self->display_methods,/init
  self->setdefaults,/init
  self->construct_pointing,/init
  self->construct_ccdtemp,/init
  self->construct_mhctemp,/init
  self->construct_veloc,/init
  self->construct,/init
  self->construct_xypos,/init
  self->setxyoffset,/init
  a=self->getxoffut(/init)
  a=self->getyoffut(/init)
  a=self->getxoffsu(/init)
  a=self->getyoffsu(/init)
  a=self->year(/init)
  a=self->month(/init)
  a=self->day(/init)
  a=self->gettr_mode(/init)
  a=self->getdate_obs_ut(/init)
  a=self->getdate_end_ut(/init)
  a=self->getdate_obs(/init)
  a=self->getdate_end(/init)
  a=self->gettime_aocs1(/init)
  a=self->gettime_hk2(/init)
  a=self->gettime_sts1(/init)
  a=self->gettime_sot(/init)
  a=self->gettime_pt(/init)
  a=self->getxcen(/init)
  a=self->getycen(/init)
  a=self->getmhc_temp(/init)
  a=self->getccda_temp(/init)
  a=self->getccdb_temp(/init)
  a=self->getv_sun(/init)
  a=self->getv_sat(/init)
  a=self->getv_eth(/init)
  a=self->getufsaxang(/init)
  a=self->getufsayang(/init)
  a=self->getufsbxang(/init)
  a=self->getufsbyang(/init)
  a=self->getufsause(/init)
  a=self->getufsbuse(/init)
  a=self->geterrangz(/init)
  a=self->getcrval1(/init)
  a=self->getcrval2(/init)
  a=self->getinst_rot(/init)
  a=self->getsat_rot(/init)
  a=self->getcrota1(/init)
  a=self->getcrota2(/init)
  a=self->getioerror(/init)

  return
end

pro eis_spcd::cleanup
  ptr_free,self.time_aocs1
  ptr_free,self.time_hk2
  ptr_free,self.time_sot
  ptr_free,self.time_sts1
  ptr_free,self.time_sts3
  ptr_free,self.time_pt
  ptr_free,self.xcen
  ptr_free,self.ycen
  ptr_free,self.sat_rot
  ptr_free,self.ufsaxang
  ptr_free,self.ufsbxang
  ptr_free,self.ufsayang
  ptr_free,self.ufsbyang
  ptr_free,self.errangz
  ptr_free,self.ccda_temp
  ptr_free,self.ccdb_temp
  ptr_free,self.mhc_ref_ther_0
  ptr_free,self.mhc_cal_ther_0
  ptr_free,self.mhc_hz_t10
  ptr_free,self.mhc_hz_t15
  ptr_free,self.att_x
  ptr_free,self.att_y
  ptr_free,self.att_z
  ptr_free,self.v_sat
  ptr_free,self.v_sun
  ptr_free,self.v_eth
  ptr_free,self.crval1
  ptr_free,self.crval2
  ptr_free,self.crota1
  ptr_free,self.crota2
end

pro eis_spcd__define
  struct={eis_spcd, $
          help:obj_new(), $
          dir_head:'', $
          date_obs_ut:' ', $
          date_end_ut:' ', $
          date_obs:0ul, $
          date_end:0ul, $
          tr_mode:' ', $
          ufsause:' ', $
          ufsbuse:' ', $
          time_aocs1:ptr_new(), $
          time_hk2:ptr_new(), $
          time_sot:ptr_new(), $
          time_sts1:ptr_new(), $
          time_sts3:ptr_new(), $
          time_pt:ptr_new(), $
          xcen:ptr_new(), $
          ycen:ptr_new(), $
          xoffut: 0.0, $
          yoffut: 0.0, $
          xoffsu: 0.0, $
          yoffsu: 0.0, $
          sat_rot:ptr_new(), $
          inst_rot:0.0, $
          Ufsaxang:ptr_new(), $
          ufsbxang:ptr_new(), $
          ufsayang:ptr_new(), $
          ufsbyang:ptr_new(), $
          errangz:ptr_new(), $
          att_x:ptr_new(), $
          att_y:ptr_new(), $
          att_z:ptr_new(), $
          ccda_temp:ptr_new(), $
          ccdb_temp:ptr_new(), $
          mhc_ref_ther_0:ptr_new(), $
          mhc_cal_ther_0:ptr_new(), $
          mhc_hz_t10:ptr_new(), $
          mhc_hz_t15:ptr_new(), $
          v_sat:ptr_new(), $
          v_sun:ptr_new(), $
          v_eth:ptr_new(), $
          v_rst:ptr_new(), $
          crval1:ptr_new(), $
          crval2:ptr_new(), $
          crota1:ptr_new(), $
          crota2:ptr_new(), $
          ioerror:0}
end
