;+
; NAME:
;     GET_REFCAL_STRUCT
; PURPOSE:
;     Define structure used for holding all of the reference calibration
;     information gathered from TPCAL, AMPCAL, and PHZCAL segments, but
;     pared down to the minimum size necessary for the data within the
;     current scan.
; CATEGORY:
;     OVRO APC DATA ANALYSIS
; CALLING SEQUENCE:
;     refcal = get_refcal_struct()
; INPUTS:
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
; ROUTINES CALLED:
; OUTPUTS:
;     refcal    an empty reference calibration structure
; COMMENTS:
;     This structure requires the use of pointers to arrays,
;     because the array sizes are variable and structure definitions
;     must be static.  To use, always free the existing pointer and
;     then create a new one. For example, to add a new array, pFactors,
;     to the structure, do the following:
;
;       ptr_free,refcal.pFactors
;       refcal.pFactors = ptr_new(Factors)
;
;     This will ensure that the memory area pointed to by the
;     existing pointer is freed back to the memory pool.
;
;     To apply phase update to data, subtract from phase at baseline
;     i the phase
;       P_i = poff_i(t1) + [(t-t1)/(t2-t1)]*[poff_i(t2)-poff_i(t1)]
;          + {dpdf_i(t1) + [(t-t1)/(t2-t1)]*[dpdf_i(t2)-dpdf_i(t1)]}*f
;     where
;             poff_i(t1) = (*refcal.PhaseUpd[0].paref)[i]    [degrees]
;             dpdf_i(t1) = (*refcal.PhaseUpd[0].pdpdf)[i]    [degrees/GHz]
;                     t1 = refcal.PhaseUpd[0].tref           [msec]
;             poff_i(t2) = (*refcal.PhaseUpd[1].paref)[i]    [degrees]
;             dpdf_i(t2) = (*refcal.PhaseUpd[1].pdpdf)[i]    [degrees/GHz]
;                     t2 = refcal.PhaseUpd[1].tref           [msec]
;
; SIDE EFFECTS:
; RESTRICTIONS:
; MODIFICATION HISTORY:
;     Written 27-Jul-1999 by Dale E. Gary
;     20-Nov-1999  DG
;       Added an entry for OffSun RCVR level to structure
;     02-Dec-1999  DG
;       Added parallel pointers for update calibrations, so that they
;       can be optionally applied.
;     08-Jun-2000  DG
;       Changed structure for PhaseUpd entry to contain phase and time
;       dependent parameters.
;     16-Jul-2000  DG
;       A second change to PhaseUpd entry to reflect new approach.
;     07-Nov-2002  DG
;       Added BLDIR and CHANPHZ entries.
;     27-Nov-2002  DG
;       Removed name of structure, so that it becomes an anonymous
;       structure.  This solves the problem of saved calibration
;       data having an incompatible structure definition.
;     19-May-2014  DG
;       Added a key PUpdType to specify type of interpolation of two
;       PhaseUpd (DAILY) phase slopes, either '2-POINT', 'FIRST', or 'LAST'.
;-
function get_refcal_struct

   ; Define reference calibration structure
   refcal = {        pfrq:      ptr_new(0), $ ; Pointer to the frequency list
                     nant:               0, $ ; Number of antennas in REFCAL
                      nbl:               0, $ ; Number of baselines in REFCAL
                     npol:               0, $ ; Number of different poln in REFCAL
                   tls27m: get_tl_struct(), $ ; Time/Label structure for 27m meas.
                   tls02m: get_tl_struct(), $ ; Time/Label structure for  2m meas.
                     tlsi: get_tl_struct(), $ ; Time/Label structure for   I meas.
                    tlsrl: get_tl_struct(), $ ; Time/Label structure for R/L meas.
                 pFactors:      ptr_new(0), $ ; Ptr to the fluxcal factors for NPOL
                                              ;   polarizations, NANT+NBL channels,
                                              ;   and NFRQ = n_elements(*pfrq) freqs
                     pRMS:      ptr_new(0), $ ; Pointer to the RMS error corresp. to
                                              ;   factors.
                   pPhase:      ptr_new(0), $ ; Pointer to phases for NPOL polarizations,
                                              ;   NBL channels, and NFRQ frequencies
                  pFacUpd:      ptr_new(0), $ ; Ptr to the fluxcal update factors for NPOL
                                              ;   polarizations, NANT+NBL channels,
                                              ;   and NFRQ = n_elements(*pfrq) freqs
                  pRMSUpd:      ptr_new(0), $ ; Pointer to the RMS error corresp. to
                                              ;   update factors.
                 PUpdType:       '2-POINT', $ ; Type of update to do '2-POINT','FIRST' or 'LAST'
                 PhaseUpd: replicate({pupd, $ ; Array of 2 pupd structs, for two ref times
                       tref:            0L, $ ; Reference time for phase update
                      ppoff:    ptr_new(0), $ ; Ptr to phase offset at ref time
                                              ;   for NBL baselines
                      pdpdf:ptr_new(0)},2), $ ; Ptr to slope of phase vs freq
                                              ;   for NBL baselines.
                  pOffSun:      ptr_new(0), $ ; Pointer to off-Sun RCVR IF level,
                                              ;   for NFEED feeds and NFRQ frequencies
                   pBLDir:      ptr_new(0), $ ; Pointer to BL Direction (+1 or -1) (NBL)
                 pChanPhz:      ptr_new(0)}   ; Pointer to backend channel phase offsets (NBL)

return,refcal
end