
;+
; NAME:
;        IRUHXA2SXT
; PURPOSE:
;        Calculate suncenter positions (in SXT pixel coordinates) by
;        combining IRU and HXA data.
;        This program should be called with only one orbit worth of data
;        at a time.
; CATEGORY:
; CALLING SEQUENCE:
;        sunc = iruhxa2sxt(iru_i,iru_d,hxa_i,hir_d,hxa_d)
;        sunc = iruhxa2sxt(atr,atr.iru,atr,atr.iru,atr.hxa)
;        sunc = iruhxa2sxt(mk_timarr(ada_index,8,/struct), $
;                          reform(ada_data.iru,3,8*n_elements(ada_data)), $
;                          ada_index,gt_iru(ada_data.iru),gt_hxa(ada_data)
; INPUTS:
;        iru_i = index for iru_d. pnt, atr, or mk_timarr(ada_index,8,/struct)
;        iru_d = array(3,m). iru data, e.g., pnt.iru, reform(ada_data.iru,3,n8)
;        hxa_i = index for hxa_d and hir_d, e.g., pnt, atr, or ada_index
;        hir_d = array(3,n)iru data COTEMPORAL with hxa_d, e.g. pnt.iru
;        hxa_d = array(4,n). HXA data, e.g., pnt.hxa or gt_hxa(ada_data)
; KEYWORDS (INPUT):
; OUTPUTS:
;        sunc = suncenter coordinates in SXT full resolution pixels for
;               all times in iru_i.  sunc(0,*) = x, sunc(1,*) = y
; KEYWORDS (OUTPUT):
;        code = vector.  Indicates the reliability of each sun center position.
;               1: plain S/C commanded value used, no dejittering with IRU.
;               2: S/C commanded value dejittered with IRU.
;               4: HXA value dejittered with IRU.  Standard result, good.
;               Note: S/C commanded values can be several pixels off.
; COMMON BLOCKS:
;        None.
; SIDE EFFECTS:
; RESTRICTIONS:
;        This program should be called with only one orbit worth of data
;        at a time.
; PROCEDURE:
;        The HXA detectors provide absolute suncenter positions, but with a
;        relatively coarse resolution.  The gyros (IRU) have better resolution
;        but poor longterm stability.  The program fits the gyro data onto
;        the HXA data to obtain the absolute accuracy of the HXA, and the
;        high resolution of the gyros.  The gyros show a drift which can
;        assumed to be linear for time intervals of up to about 10 minutes.
;        If the covered time period is longer, the program splits the data
;        into shorter intervals and performs a linear fit for each interval.
; MODIFICATION HISTORY:
;        19-Jul-93 (JPW)  From get_suncenter.
;        27-Sep-93 (JPW)  Added call to iru_s2y to correct for iru switch.
;-

function iruhxa2sxt,iru_i,iru_d0,hxa_i,hir_d0,hxa_d,code=code

; various constants
tstep = 200        ; time step (in sec) used for recalc. linear IRU fit

; make copies of iru_d, hir_d.  Copies will be modified by program
iru_d = iru_d0
hir_d = hir_d0

; find the good iru values in hir_d : pointer wwp (wwp is always valid)
iru_filt,hxa_i,hir_d,w_good=wwp
; transform IRU-S to IRU-Y values (if necessary)
hir_d = iru_s2y(hxa_i,hir_d)

; fix the bad iru values in iru_d by interpolation.
iru_filt,iru_i,iru_d
; transform IRU-S to IRU-Y values (if necessary)
iru_d = iru_s2y(iru_i,iru_d)

; reconstruct the hxa hidden limbs and transform into sxt suncenter coord.

ctt = anytim2ints(hxa_i(wwp))
cir = hir_d(*,wwp)
cxy = hxa2hxaxy(ctt,hxa_d(*,wwp),code=hcod)
cxy = hxaxy2sxt(ctt,cxy)
wcp = where(hcod gt 1)

; get commanded suncenter positions to replace bad hxa data
wdp = where(hcod le 1)
if wdp(0) ge 0 then cxy(*,wdp) = sxt_cmd_pnt(ctt(wdp))  ; commanded suncenter

n_i = n_elements(iru_i)
out = fltarr(2,n_i)                     ; output variable
code = intarr(n_i)                      ; output data quality code

list = bytarr(n_i)+1          ; list to check off data points
wlis = where(list)

repeat begin  ; loop through short time intervals for which gyros are linear

   ; search for the earliest time in the list
   dummy = min(int2secarr(iru_i(wlis)),wlo)
   wlo = wlis(wlo)

   tilo = anytim2ints(iru_i(wlo))
   tihi = anytim2ints(iru_i(wlo),off=tstep)
   wwi = sel_timrange(iru_i(wlis),tilo,tihi)
   wwi = wlis(wwi)
   list(wwi) = 0B                   ; cross off selected elements in list

   tclo = anytim2ints(iru_i(wlo),off=-tstep)
   tchi = anytim2ints(iru_i(wlo),off=2*tstep)
   if wcp(0) ge 0 then $
      wwc = sel_timrange(ctt(wcp),tclo,tchi,/between) $
     else wwc = -1

   ; check if at least 2 hxa results over a large enough time interval
   ; else use commanded values

   if n_elements(wwc) ge 2 then begin      ; purely with HXA`
      wwc = wcp(wwc)
      tmin = min(int2secarr(ctt(wwc)),max=tmax)
      if (tmax-tmin) ge tstep/10 then $    ; time interval long enough?
         code(wwi) = 4 $                   ; code for IRU fitted HXA result
        else wwc = -1
   endif
   
   if n_elements(wwc) lt 2 then begin      ; include commanded values
      wwc = sel_timrange(ctt,tclo,tchi,/between)
      if n_elements(wwc) ge 2 then begin
         tmin = min(int2secarr(ctt(wwc)),max=tmax)
         if (tmax-tmin) ge tstep/10 then $ ; time interval long enough?
            code(wwi) = 2 $                ; code for IRU fitted S/C com. res.
           else wwc = -1                   ; force use of plain S/C com.
      endif
   endif

   ; do the fitting procedure

   if n_elements(wwc) ge 2 then begin
      out(*,wwi) = iruhxa_fit(iru_i(wwi),iru_d(*,wwi),ctt(wwc),cir(*,wwc), $
                              cxy(*,wwc),degree=2)
   endif else begin
      ; use plain S/C commanded value
      out(*,wwi) = sxt_cmd_pnt(iru_i(wwi))
      code(wwi) = 1
   endelse

   wlis = where(list)
endrep until wlis(0) lt 0                  ; loop until list empty

return,out
end

