;+
; NAME:
;     MAKE_TPCAL2
; PURPOSE:
;     Generates the TPCAL segment records from REFTPCAL data.
; CATEGORY:
;     OVRO APC DATA CALIBRATION
; CALLING SEQUENCE:
;     newtp = make_tpcal2(tls,tpcal,tprms,ndavg,oldtp,nd_eff)
; INPUTS:
;     tls      A Time/Label structure from the header of the REFTPCAL 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.
;     oldtp    An instance of a TPCAL segment (two binary records) containing
;                the "current" total power calibration at the time of the
;                TPCAL observations.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
; ROUTINES CALLED:
;     get_nd_eff, tlsnow, get_tl_struct, tl_encode, dayofyr
; OUTPUTS:
;     newtp    The newly constructed TPCAL segment (two binary records), same
;                format as OLDTP, with 27m factors overwritten, but 2m factors
;                unchanged.
;     nd_eff   The 4-element array containing the effective noise diode
;                factors by which to divide TPCAL and TPRMS to give properly
;                normalized values.  This is returned so that it can be applied
;                before calling PLOT_TPCAL
; 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 12-Nov-2000 by Dale E. Gary   (based on MAKE_TPCAL)
;       Removed REFCAL argument, added OLDTP and NEWTP arguments.  The
;       routine no longer writes the !DEFAULTS.EPHEM+TPCAL.REC file.  Instead,
;       it returns NEWTP for further handling.  The routine has been changed
;       from a procedure to a function.
;     16-Nov-2000  DG
;       Added return of ND_EFF argument.
;-

function make_tpcal2,tls,tpcal,tprms,ndavg,oldtp,nd_eff

   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)

   ; Copy OLDTP to NEWTP, so that we can just overwrite those parts belonging
   ; to the 27 m antennas, and thus preserve the 2m calibration.
   newtp = oldtp

   ; Fill in record
   newtp[0:11,0] = tldata                  ; Time/Label field
   newtp[12:23,0] = 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)
   newtp[0:11,1] = 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
      newtp[wrdoff,0]    = reform(tpdat,4)
      newtp[wrdoff+10,0] = 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
         newtp[wrdoff,1]    = ['FFFF'x,'FFFF'x,'FFFF'x,'FFFF'x]
         newtp[wrdoff+10,1] = ['FFFF'x,'FFFF'x,'FFFF'x,'FFFF'x]
      endif else j = i

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

return,newtp
end