;+
; NAME:
;     MAKE_TPCAL
; PURPOSE:
;     Interim routine to generate the TPCAL segment record from TPCAL data,
;     for writing into each scan by ARCHIVE.
; CATEGORY:
;     OVRO APC DATA CALIBRATION
; CALLING SEQUENCE:
;     make_tpcal,tls,tpcal,tprms,ndavg,refcal
; INPUTS:
;     tls      A Time/Label structure from the header of the REF-TPCAL scan
;                that took the data.
;     tpcal    An array containing the 27-m total power calibration factors,
;                of size (2,2,85), where the first index is the feed (0 = RH
;                position, 1 = LH position), the second is the antenna
;                (0 = Ant 1, 1 = Ant 2) and the third is the frequencies
;                (all harmonics except H89).  The calibration factors
;                (unnormalized to the noise diode) are in units/SFU.
;     tprms    An identical array to TPCAL, giving the corresponding RMS
;                deviations derived from multiple measurements, in the same
;                units as for TPCAL.
;     ndavg    An identical array to TPCAL, giving the corrsponding noise
;                diode increment, in raw units.  The final TPCAL factors
;                will be scaled by a factor derived from these.
;     refcal   The REFCAL structure from the data (.ARC) file containing
;                the TPCAL observations.  This will have the previously
;                active TPCAL calibration.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
; ROUTINES CALLED:
;     get_nd_eff, tlsnow, get_tl_struct, tl_encode, dayofyr
; OUTPUTS:
; COMMENTS:
;     The values written to the file are in scaled, 2-byte integer form.  To convert
;     the 2-byte values back to units/SFU, read the integer value, multiply by 0.1,
;     and apply to TP data by dividing by the factors.
; SIDE EFFECTS:
;     Data are written to the file !DEFAULTS.EPHEMDIR+'TPCAL.REC'.
; RESTRICTIONS:
;     Provision is made for 2-m calibration factors, but the actual 2-m
;     calibration is not yet set, so this routine just leaves the space
;     for these values blank (or uses values from an earlier determination).
; MODIFICATION HISTORY:
;     Written 23-Jul-1999 by Dale E. Gary
;     11-Sep-1999  DG
;       Changed entire scheme to use 2-byte rather than byte values, so that
;       digitization is not a problem for the 2-m dish data.
;     14-Sep-1999  DG
;       Had to scale the 27 m TPCALs by 10 rather than 100, to prevent overflow
;       of 2-byte word.
;     12-Nov-1999  DG
;       Read existing disk file (to preserve 2m information) rather than
;       create a new one from scratch.
;     11-Jan-2000  DG
;       Eliminated hardwired directory locations.
;     23-Jul-2000  DG
;       Changed to use the function TLSNOW (no functional change).
;     03-Sep-2000  DG
;       Added REFCAL to argument list.
;-

pro make_tpcal,tls,tpcal,tprms,ndavg,oldtp

   nf = n_elements(tpcal[0,0,*])
   ikey = [7,9,14,25,41,53]-5  ; Key harmonics for calculation of ND_eff value
   nd_eff = fltarr(4)      ; Array to hold effective noise diode value (4 feeds)
   ; Calculate the effective noise diode value relative to 500
   for iant = 0,1 do $
      for ifeed = 0,1 do $
         nd_eff[ifeed+iant*2] = get_nd_eff(ikey,ndavg[ifeed,iant,*])

   ; Create an appropriate TIME/LABEL structure containing the current
   ; system date/time
   tl_struct = tlsnow(!SEGM.TPCAL)

   ; Convert tl_struct to binary data
   tldata = tl_encode(tl_struct)
   tls27m = tl_encode(tls)

   ; Reformat the TPCAL records directly from the .ARC file, as contained
   ; in the REFCAL structure.  For older data, where there is no REFCAL
   ; structure, REFCAL will not be a structure, in which case we create a
   ; new file.
   if (n_elements(oldtp) eq 0) then begin
      ; Declare storage for entire record
      data = intarr(1024)
      data2 = intarr(1024)
      ; Empty 2-m TLS structure, for now, since no 2-m calibration yet
      tls02m = tl_encode(get_tl_struct())
      data[24:35] = tls02m                 ; Time/Label field of  2-m data epoch
   endif else begin
      ; OLDTP exists, so use it, but overwrite 27-m factors with newly
      ; determined factors (this will preserve 2m info)
      data  = reform(oldtp[*,0])
      data2 = reform(oldtp[*,1])
   endelse

   ; Fill in record
   data[0:11] = tldata                  ; Time/Label field
   data[12:23] = tls27m                 ; Time/Label field of 27-m data epoch

   ; For the second record, update the NRS field
   tl_struct.nrs = 2
   tldata = tl_encode(tl_struct)
   data2[0:11] = tldata

   ; Loop over frequency, scaling the TP and RMS data to the ND_eff value and
   ; converting to units of 1/10 of a unit/SFU.  Replace all bad (-99) data
   ; with 'FFFF'x
   for i = 0, 48 do begin
      bad = where(tpcal[*,*,i] eq -99,nbad)
      tpdat = uint(reform(tpcal[*,*,i])*10./nd_eff)
      if (nbad ne 0) then tpdat[bad] = 'FFFF'x
      bad = where(tprms[*,*,i] eq -99,nbad)
      tprmsdat = uint(reform(tprms[*,*,i])*10./nd_eff)
      if (nbad ne 0) then tprmsdat[bad] = 'FFFF'x
      ; TPDAT now contains the 4 scaled calibration factors for feeds 1I, 1L, 2R, and 2I.
      ; TPRMSDAT now contains the 4 scaled rms values corresponding to these feeds.
      ; To get back the actual calibration factors in units/SFU, read the 2-byte data,
      ; and multiply by 0.1.  To apply it, multiply it into the data.

      wrdoff = 36 + i*20
      data[wrdoff]    = reform(tpdat,4)
      data[wrdoff+10] = reform(tprmsdat,4)
   endfor
   for i = 49, nf-1 do begin
      bad = where(tpcal[*,*,i] eq -99,nbad)
      tpdat = uint(reform(tpcal[*,*,i])*10./nd_eff)
      if (nbad ne 0) then tpdat[bad] = 'FFFF'x
      bad = where(tprms[*,*,i] eq -99,nbad)
      tprmsdat = uint(reform(tprms[*,*,i])*10./nd_eff)
      if (nbad ne 0) then tprmsdat[bad] = 'FFFF'x
      ; TPDAT now contains the 4 scaled calibration factors for feeds 1I, 1L, 2R, and 2I.
      ; TPRMSDAT now contains the 4 scaled rms values corresponding to these feeds.
      ; To get back the actual calibration factors in units/SFU, read the 2-byte data,
      ; and multiply by 0.1.  To apply it, multiply it into the data.

      ; This next line is because harmonic 89 is not measured, so have to skip the
      ; next to last frequency.
      if (i eq nf-1) then begin
         j = nf
         wrdoff = 12 + (i-49)*20
         data2[wrdoff]    = ['FFFF'x,'FFFF'x,'FFFF'x,'FFFF'x]
         data2[wrdoff+10] = ['FFFF'x,'FFFF'x,'FFFF'x,'FFFF'x]
      endif else j = i

      wrdoff = 12 + (j-49)*20
      data2[wrdoff]    = reform(tpdat,4)
      data2[wrdoff+10] = reform(tprmsdat,4)
   endfor

   cd,!defaults.ephemdir,current=cwd

   ; Open the output file to write the record.  This will overwrite any
   ; existing file, or create a new one if none exists.
   openw,lun,/get_lun,'tpcal.rec',bufsiz=2048
   ; Create an associated variable for the file
   b = assoc(lun,intarr(1024))
   ; Write the data
   b(0) = data
   b(1) = data2
   ; Close the file and free the unit number
   free_lun,lun

   cd,cwd

return
end