;+
; NAME:
;     WTPCAL
; PURPOSE:
; CATEGORY:
;     OVRO APC WIDGETS
; CALLING SEQUENCE:
;     updflag = wtpcal(f,solspec0,solrms0,refcal,solmed[,twometer=twometer][,auto=auto][,GROUP=Group])
; INPUTS:
;     f         Array of frequencies corresponding to the measurements [GHz], of
;                 size [NF]
;     solspec0  Array of values representing the uncalibrated solar total power
;                 spectrum, of size [NPOL,NANT,NF], where NPOL = 3 is the number
;                 of polarizations, NANT is the number of antennas, and NF is the
;                 number of frequencies (corresponding to array F).
;     solrms0   Array of values representing the total power residuals, of size
;                 same as SOLSPEC0.
;     refcal    A REFCAL structure as constructed by NEWSCAN() routine.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
;     twometer  A keyword specifying that the channels in SOLSPEC0 to be calibrated
;                 correspond to the 2 m antennas.  If omitted or zero, the 27 m
;                 channels are calibrated.
;     auto      A keyword specifying that automatic calibration to the RSTN flux for
;                 the day is to be done.  If the RSTN fluxes are not available on
;                 this day then no update is done.
;     group     The widget ID of the group leader.  If given and the group leader's
;                 widget is destroyed, this widget is destroyed also.
; ROUTINES CALLED:
; OUTPUTS:
;     updflag   An integer flag that specifies what kind of update the user selected.
;                 UPDFLAG = 0 => no update
;                 UPDFLAG = 1 => update secondary calibration (TPUPDATE)
;                 UPDFLAG = 2 => update primary calibration (TPCAL)
;     solmed    The array of actual solar flux units as a function of frequency,
;                 of size [NF].  The calibration factors are just those required
;                 to convert the data to this total power spectrum.
; COMMENTS:
; SIDE EFFECTS:
; RESTRICTIONS:
; MODIFICATION HISTORY:
;     Written 05-Dec-1999 by Dale E. Gary
;     30-Jan-2000  DG
;       Added Zoom button.
;     24-May-2000  DG
;       Changes to make it work with 5 or 6 antennas.  Additional small changes needed
;       when another antenna is added.
;     11-Nov-2000  DG
;       Changed to overplot the current expected RSTN flux, if any.
;     16-Jan-2002  DG
;       Added AUTO keyword, for automatic updating of secondary calibration
;       to match the RSTN fluxes for that day.
;     07-Nov-2003  DG
;       Several changes to reflect new dual-polarization feeds on 27-m dishes.  Added
;       AUTO calibration button.
;     24-Aug-2005  DG
;       Several changes to reflect dual-polarization on all dishes.
;     28-Aug-2005  DG
;       Cleaned up user interface (button handling).
;-

PRO WTPCal_Event, Event


  base = Event.handler

  if (Event.id eq event.top) then begin
     WIDGET_CONTROL,event.top,/DESTROY
     return
  endif

  stash = WIDGET_INFO(base, /CHILD)
  WIDGET_CONTROL,stash, GET_UVALUE = state, /NO_COPY
  if (Event.ID eq state.DrawID or Event.ID eq state.ExitID or Event.ID eq state.AutoID $
      or Event.ID eq state.AdjID or Event.ID eq state.ZoomID)THEN begin
     Ev = event.id
  endif else begin
     Ev = Event.Value
  endelse

  SaveID = state.SaveID
  DSID   = state.DSID
  LDSID  = state.LDSID
  DrawID = state.DrawID
  ShowID = state.ShowID
  CalID  = state.CalID
  ExitID = state.ExitID
  AdjID  = state.AdjID
  AutoID = state.AutoID
  ZoomID = state.ZoomID
  rstn   = state.rstn
  tls = state.tls
;  IF (n_elements(DSID) eq 3) THEN DSID = [DSID,-1]

  CASE ev OF

     SaveID[0]: *state.pPrimFlg  = 1 - *state.pPrimFlg
     SaveID[1]: *state.pSdaryFlg = 1 - *state.pSdaryFlg
     DSID[0]: BEGIN
           if (event.select) then state.ds[0] = 1 else state.ds[0] = 0
           goto, update
        END
     DSID[1]: BEGIN
           if (event.select) then state.ds[1] = 1 else state.ds[1] = 0
           goto, update
        END
     DSID[2]: BEGIN
           if (event.select) then state.ds[2] = 1 else state.ds[2] = 0
           goto, update
        END
     DSID[3]: BEGIN
           if (event.select) then state.ds[3] = 1 else state.ds[3] = 0
           goto, update
        END
     DSID[4]: BEGIN
           if (event.select) then state.ds[4] = 1 else state.ds[4] = 0
           goto, update
        END
     LDSID[0]: BEGIN
           if (event.select) then state.ds[5] = 1 else state.ds[5] = 0
           goto, update
        END
     LDSID[1]: BEGIN
           if (event.select) then state.ds[6] = 1 else state.ds[6] = 0
           goto, update
        END
     LDSID[2]: BEGIN
           if (event.select) then state.ds[7] = 1 else state.ds[7] = 0
           goto, update
        END
     LDSID[3]: BEGIN
           if (event.select) then state.ds[8] = 1 else state.ds[8] = 0
           goto, update
        END
     LDSID[4]: BEGIN
           if (event.select) then state.ds[9] = 1 else state.ds[9] = 0
           goto, update
        END
     AdjID: BEGIN
           if (state.AdjFlg) then WIDGET_CONTROL,AdjID,SET_VALUE='Adjust' $
                             else WIDGET_CONTROL,AdjID,SET_VALUE='End Adjust'
           state.xspl = state.f[indgen(8)*6]
           state.yspl = (*state.psolmed)[indgen(8)*6]
           state.AdjFlg = 1 - state.AdjFlg
           goto, update
       END
     AutoID: BEGIN
           ; Toggle flag for doing AUTO calibration to RSTN flux
           if (state.AutoFlg) then WIDGET_CONTROL,AutoID,SET_VALUE='Auto' $
                             else WIDGET_CONTROL,AutoID,SET_VALUE='Manual'
           state.AutoFlg = 1 - state.AutoFlg
           (*state.psolmed) = rstn/2.
           solmed = (*state.psolmed)
           goto, update
;           (*state.psdaryflg) = 1
;           WIDGET_CONTROL,event.top,/DESTROY
;           return
       END
     ShowID[0]: BEGIN
           ; Toggle flag for showing flux (SFU).
           ; If set, show flux density, if unset, show cal factors
           state.SfuFlg  = 1 - state.SfuFlg
           goto, update
        END
     CalID[0]: BEGIN
           ; Toggle flag for applying primary calibration
           if (event.select) then state.aprim = 1 else state.aprim = 0
           goto, update
        END
     CalID[1]: BEGIN
           ; Toggle flag for applying secondary calibration
           if (event.select) then state.apscnd = 1 else state.apscnd = 0
           goto, update
        END
     ZoomID: BEGIN
         if (state.Zoom EQ 0) then begin
            state.Zoom = 1
            WIDGET_CONTROL,state.DrawID,DRAW_XSIZE=600,DRAW_YSIZE=600
            WIDGET_CONTROL,state.ZoomID,SET_VALUE='Zoom Out'
         endif else begin
            state.Zoom = 0
            WIDGET_CONTROL,state.DrawID,DRAW_XSIZE=300,DRAW_YSIZE=300
            WIDGET_CONTROL,state.ZoomID,SET_VALUE='Zoom In'
         endelse
         goto, update
        END
     DrawID: BEGIN

         x = !x
         y = !y
         ; Get conversion for device coordinates to world coordinates
         xscl = (x.crange[1]-x.crange[0])/((x.window[1]-x.window[0])*!d.x_size)
         yscl = (y.crange[1]-y.crange[0])/((y.window[1]-y.window[0])*!d.y_size)
         xoff = x.window[0]*!d.x_size
         yoff = y.window[0]*!d.y_size
         ; Read device coordinates from event
         xpt = event.x
         ypt = event.y

         ; Apply conversion to get world coordinates under mouse
         wx = 10^((xpt - xoff)*xscl + x.crange[0])
         wy = 10^((ypt - yoff)*yscl + y.crange[0])

         if (event.press ne 0) then begin
            state.mousemove = 1 - state.mousemove
            if (state.mousemove) then begin
               widget_control,state.DrawID,DRAW_MOTION_EVENTS=1
               out = min(abs(state.xspl-wx),imin)
               state.ipt = imin
            endif else begin
               widget_control,state.DrawID,DRAW_MOTION_EVENTS=0
            endelse
         endif

         if (state.AdjFlg) then begin
            state.xspl(state.ipt) = wx
            state.yspl(state.ipt) = wy
         endif

         update:

         nant = n_elements(state.solspec0[0,*,0])
         if (state.SfuFlg) then begin
           solspec = state.solspec0
           solrms = state.solrms0
           refcal = state.refcal
           f = state.f
           if (state.aprim) then begin
              ; Apply primary calibration
              solspec = solspec/(*state.refcal.pfactors)[*,0:nant-1,*]
              solrms  = solrms/(*state.refcal.pfactors)[*,0:nant-1,*]
              if (state.apscnd) then begin
                 ; Apply secondary calibration
                 solspec = solspec/(*state.refcal.pfacupd)[*,0:nant-1,*]
                 solrms  = solrms/(*state.refcal.pfacupd)[*,0:nant-1,*]
              endif
           endif

           IF (state.twom) THEN BEGIN
              if (state.AutoFlg eq 0) then begin
                 ; Determine the median of the solar spectrum for the 2-m feeds
                 nf = n_elements(solspec[0,0,*])
                 solmed = fltarr(nf)
                 if (tls.yrday ge 2004.231) then begin
                    ; There are up to 10 feeds (5 ants x 2 poln)
                    for i = 0, nf-1 do begin
                       solarr = reform(solspec[0:1,2:nant-1,i],2*(nant-2))
                       good = where(finite(solarr),ngood)
                       case ngood of
                          0: solmed[i] = !values.f_nan
                          1: solmed[i] = solarr[good[0]]
                          2: solmed[i] = median(solarr[good],/even)
                          3: solmed[i] = median(solarr[good])
                          4: solmed[i] = median(solarr[good],/even)
                        else: solmed[i] = median(solarr[good])  ; For more than 4 values, do not worry about /even
                       endcase
                    endfor
                 endif else begin
                    for i = 0, nf-1 do begin
                       solarr = solspec[2,2:nant-1,i]
                       good = where(finite(solarr),ngood)
                       case ngood of
                          0: solmed[i] = !values.f_nan
                          1: solmed[i] = solarr[good[0]]
                          2: solmed[i] = median(solarr[good],/even)
                          3: solmed[i] = median(solarr[good])
                          4: solmed[i] = median(solarr[good],/even)
                       endcase
                    endfor
                 endelse
              endif

              ; Display the result
              plot_oo,f,solmed,xsty=1,yrange=[20,500],ystyle=1

              syms = [-1,-4,-5,-6,-2]
              if (tls.yrday ge 2004.231) then begin
                 ; 2-m ant feeds are now R, L
                 for i = 2, nant-1 do if (state.ds[(i-2)]) then oplot,f,solspec[0,i,*],psym=syms[i-2]
                 for i = 2, nant-1 do if (state.ds[(i-2)+5]) then oplot,f,solspec[1,i,*],psym=syms[i-2]
              endif else begin
                 for i = 2, nant-1 do if (state.ds[(i-2)]) then oplot,f,solspec[2,i,*],psym=syms[i-2]
              endelse
              oplot,f,solmed,color=255,thick=3
              if (n_elements(rstn) gt 1) then oplot,f,rstn/2,psym=2,color=100

              if (state.AdjFlg) then begin
                 oplot,state.xspl,state.yspl,color=200,psym=4,thick=2
                 state.fit = spline(state.xspl,state.yspl,f)
                 oplot,f,state.fit,color=220,thick=2
              endif
           ENDIF ELSE BEGIN
             if (state.AutoFlg eq 0) then begin
               ; Determine the median of the solar spectrum for the four 27-m feeds
               nf = n_elements(solspec[0,0,*])
               solmed = fltarr(nf)
               for i = 0, nf-1 do begin
                 if (tls.yrday ge 2003.266) then begin
                    ; 27-m ant feeds are now R, L
                    solarr = [solspec[0,0,i],solspec[1,0,i],solspec[0,1,i],solspec[1,1,i]]
                 endif else begin
                    solarr = [solspec[1,0,i],solspec[2,0,i],solspec[0,1,i],solspec[2,1,i]]
                 endelse
                 good = where(finite(solarr),ngood)
                 case ngood of
                    0: solmed[i] = !values.f_nan
                    1: solmed[i] = solarr[good[0]]
                    2: solmed[i] = median(solarr[good],/even)
                    3: solmed[i] = median(solarr[good])
                    4: solmed[i] = median(solarr[good],/even)
                 endcase
               endfor
             endif

              ; Display the result
              plot_oo,f,solmed,xsty=1,yrange=[1,100],ystyle=1
              if (tls.yrday ge 2003.266) then begin
                 ; 27-m ant feeds are now R, L
                 if (state.ds[0]) then oplot,f,solspec[0,0,*],psym=-1
                 if (state.ds[1]) then oplot,f,solspec[1,0,*],psym=-4
                 if (state.ds[2]) then oplot,f,solspec[0,1,*],psym=-5
                 if (state.ds[3]) then oplot,f,solspec[1,1,*],psym=-6
              endif else begin
                 if (state.ds[0]) then oplot,f,solspec[1,0,*],psym=-1
                 if (state.ds[1]) then oplot,f,solspec[2,0,*],psym=-4
                 if (state.ds[2]) then oplot,f,solspec[0,1,*],psym=-5
                 if (state.ds[3]) then oplot,f,solspec[2,1,*],psym=-6
              endelse
              oplot,f,solmed,color=255,thick=3
              if (n_elements(rstn) gt 1) then oplot,f,rstn/2,psym=2,color=100
              if (state.AdjFlg) then begin
                 oplot,state.xspl,state.yspl,color=200,psym=4,thick=2
                 state.fit = spline(state.xspl,state.yspl,f)
                 oplot,f,state.fit,color=220,thick=2
              endif
           ENDELSE
         endif else begin

           ; Plot the calibration factors themselves

           refcal = state.refcal
           f = state.f
           if (state.aprim) then begin
              ; Apply primary calibration
              solspec = (*state.refcal.pfactors)[*,0:nant-1,*]
              solrms  = (*state.refcal.prms)[*,0:nant-1,*]
              if (state.apscnd) then begin
                 ; Apply secondary calibration
                 solspec = solspec*(*state.refcal.pfacupd)[*,0:nant-1,*]
                 solrms  = sqrt(solrms^2+((*state.refcal.prmsupd)[*,0:nant-1,*])^2)
              endif
           endif else goto, WRITE_STATE


           IF (state.twom) THEN BEGIN
              if (state.AutoFlg eq 0) then begin

                 ; Determine the median of the solar spectrum for the 2-m feeds
                 nf = n_elements(solspec[0,0,*])
                 solmed = fltarr(nf)
                 if (tls.yrday ge 2004.231) then begin
                    ; There are up to 10 feeds (5 ants x 2 poln)
                    for i = 0, nf-1 do begin
                       solarr = reform(solspec[0:1,2:nant-1,i],2*(nant-2))
                       good = where(finite(solarr),ngood)
                       case ngood of
                          0: solmed[i] = !values.f_nan
                          1: solmed[i] = solarr[good[0]]
                          2: solmed[i] = median(solarr[good],/even)
                          3: solmed[i] = median(solarr[good])
                          4: solmed[i] = median(solarr[good],/even)
                        else: solmed[i] = median(solarr[good])  ; For more than 4 values, do not worry about /even
                       endcase
                    endfor
                 endif else begin
                    for i = 0, nf-1 do begin
                       solarr = solspec[2,2:nant-1,i]
                       good = where(finite(solarr),ngood)
                       case ngood of
                          0: solmed[i] = !values.f_nan
                          1: solmed[i] = solarr[good[0]]
                          2: solmed[i] = median(solarr[good],/even)
                          3: solmed[i] = median(solarr[good])
                          4: solmed[i] = median(solarr[good],/even)
                       endcase
                    endfor
                 endelse
              endif

              ; Display the result
              plot_oo,f,solmed,xsty=1,yrange=[0.1,10],ystyle=1

              if (tls.yrday ge 2004.231) then begin
                 ; 2-m ant feeds are now R, L
                 for i = 2, nant-1 do if (state.ds[(i-2)]) then oplot,f,solspec[0,i,*],psym=-1
                 for i = 2, nant-1 do if (state.ds[(i-2)+5]) then oplot,f,solspec[1,i,*],psym=-2
              endif else begin
                 for i = 2, nant-1 do oplot,f,solspec[2,i,*],psym=-1
              endelse
              oplot,f,solmed,color=255,thick=3
              if (n_elements(rstn) gt 1) then oplot,f,rstn/2,psym=2,color=100

           ENDIF ELSE BEGIN
              if (state.AutoFlg eq 0) then begin
                 ; Determine the median of the solar spectrum for the four 27-m feeds
                 nf = n_elements(solspec[0,0,*])
                 solmed = fltarr(nf)
              for i = 0, nf-1 do begin
                 if (tls.yrday ge 2003.266) then begin
                    ; 27-m ant feeds are now R, L
                    solarr = [solspec[0,0,i],solspec[1,0,i],solspec[0,1,i],solspec[1,1,i]]
                 endif else begin
                    solarr = [solspec[1,0,i],solspec[2,0,i],solspec[0,1,i],solspec[2,1,i]]
                 endelse
                 good = where(finite(solarr),ngood)
                 case ngood of
                    0: solmed[i] = !values.f_nan
                    1: solmed[i] = solarr[good[0]]
                    2: solmed[i] = median(solarr[good],/even)
                    3: solmed[i] = median(solarr[good])
                    4: solmed[i] = median(solarr[good],/even)
                 endcase
              endfor
              endif

              ; Display the result
              plot_oo,f,solmed,xsty=1
              if (tls.yrday ge 2003.266) then begin
                 ; 27-m ant feeds are now R, L
                 if (state.ds[0]) then oplot,f,solspec[0,0,*],psym=-1
                 if (state.ds[1]) then oplot,f,solspec[1,0,*],psym=-4
                 if (state.ds[2]) then oplot,f,solspec[0,1,*],psym=-5
                 if (state.ds[3]) then oplot,f,solspec[1,1,*],psym=-6
              endif else begin
                 if (state.ds[0]) then oplot,f,solspec[1,0,*],psym=-1
                 if (state.ds[1]) then oplot,f,solspec[2,0,*],psym=-4
                 if (state.ds[2]) then oplot,f,solspec[0,1,*],psym=-5
                 if (state.ds[3]) then oplot,f,solspec[2,1,*],psym=-6
              endelse
              oplot,f,solmed,color=255,thick=3
           ENDELSE
         endelse
         *state.psolmed = solmed
         END
     ExitID: BEGIN
          if (state.AutoFlg eq 0) then *state.psolmed = state.fit
          WIDGET_CONTROL,event.top,/DESTROY
          return
       END
 ELSE:
  ENDCASE


WRITE_STATE:
  WIDGET_CONTROL,stash, set_uvalue=state, /NO_COPY

END

FUNCTION wtpcal, f, solspec0, solrms0, refcal, solmed, tls, twometer=twometer, GROUP=Group, auto=auto

  nf = n_elements(f)
  nant = n_elements(solspec0[0,*,0])

  ; Read today's flux, assuming data are really for today
  read_rstn_flux,rstn_f,rstn_s,tls
  ; Convert to expected flux as measured by antenna
  if (keyword_set(twometer)) then rstn = rstn2ant(rstn_f,rstn_s,f,/twometer) $
                             else rstn = rstn2ant(rstn_f,rstn_s,f)

  if (keyword_set(auto)) then begin
     ; Keyword AUTO indicates that we are going to use the RSTN fluxes, if they
     ; exist, to set the secondary calibration.
     if (n_elements(rstn) gt 1) then begin
           ; The RSTN data exists for this date, so set the SOLMED output
           ; and return 1 to indicate that we are setting the secondary cal
           solmed = rstn/2.
           return,1
     endif
     ; If we get here, the RSTN data are not available for this date, so
     ; no update is possible.
     return,0
  endif

  device,decompose=0
  loadct,39

  IF N_ELEMENTS(Group) EQ 0 THEN GROUP=0

  TPCalMain = WIDGET_BASE(GROUP_LEADER=Group, $
      ROW=1, $
      MAP=1, $
      TITLE='WTPCal : OVRO Total Power Calibration (Widget Interface)', $
      UVALUE='TPCalMain')

  BASE2 = WIDGET_BASE(TPCalMain, $
      ROW=1, $
      MAP=1, $
      TITLE='ExtraBase', $
      UVALUE='BASE2')

  LeftBase = WIDGET_BASE(BASE2, $
      COLUMN=1, $
      MAP=1, $
      TITLE='LeftBase', $
      UVALUE='LeftBase')

  RightBase = WIDGET_BASE(BASE2, $
      COLUMN=1, $
      MAP=1, $
      TITLE='RightBase', $
      UVALUE='RightBase')

  DrawID = WIDGET_DRAW(LeftBase, $
      XSIZE=300, YSIZE=300,X_SCROLL_SIZE=300,Y_SCROLL_SIZE=300,/SCROLL,$
      /BUTTON_EVENTS,$
      UVALUE='DrawID')

  ExitID = WIDGET_BUTTON(LeftBase,VALUE='Save and Exit',/ALIGN_Left,/FRAME)
  SaveButtons = CW_BGroup(LeftBase,/ROW,/EXCLUSIVE,['Save as primary',$
      'Save as secondary','Do not save'],IDS=SaveID,/RETURN_ID)

  DSLabel = WIDGET_LABEL(RightBase,VALUE='Data Source',/ALIGN_Left,/FRAME)
  LDSID = -1L
  IF (keyword_set(twometer)) THEN BEGIN
     if (nant eq 5) then begin
       DSButtons = CW_BGROUP(RightBase,/COLUMN,/NONEXCLUSIVE,['Ant 4 Linear Feed',$
         'Ant 5 Linear Feed','Ant 6 Linear Feed'],$
         IDS = DSID,/RETURN_ID)
         ds = [1,1,1]
     endif else if (nant eq 6) then begin
       DSButtons = CW_BGROUP(RightBase,/COLUMN,/NONEXCLUSIVE,['Ant 4 Linear Feed',$
         'Ant 5 Linear Feed','Ant 6 Linear Feed','Ant 7 Linear Feed'],$
         IDS = DSID,/RETURN_ID)
         ds = replicate(1,4)
     endif else begin
       if (tls.yrday ge 2004.231) then begin
          NewBase = Widget_Base(RightBase,/ROW,UVALUE='NewBase')
          DSButtons = CW_BGROUP(NewBase,/COLUMN,/NONEXCLUSIVE,['Ant 4 RCP Feed',$
            'Ant 5 RCP Feed','Ant 6 RCP Feed','Ant 7 RCP Feed','Ant 8 RCP Feed'],$
            IDS = DSID,/RETURN_ID)
          LDSButtons = CW_BGROUP(NewBase,/COLUMN,/NONEXCLUSIVE,['Ant 4 LCP Feed',$
            'Ant 5 LCP Feed','Ant 6 LCP Feed','Ant 7 LCP Feed','Ant 8 LCP Feed'],$
            IDS = LDSID,/RETURN_ID)
          ds = replicate(1,10)
       endif else begin
          DSButtons = CW_BGROUP(RightBase,/COLUMN,/NONEXCLUSIVE,['Ant 4 Linear Feed',$
            'Ant 5 Linear Feed','Ant 6 Linear Feed','Ant 7 Linear Feed','Ant 8 Linear Feed'],$
            IDS = DSID,/RETURN_ID)
            LDSID = 0
          ds = replicate(1,5)
       endelse
     endelse
  ENDIF ELSE BEGIN
     if (tls.yrday ge 2003.266) then begin
        ; 27-m ant feeds are now R, L
        DSButtons = CW_BGROUP(RightBase,/COLUMN,/NONEXCLUSIVE,['Ant 1 RCP Feed',$
         'Ant 1 LCP Feed','Ant 2 RCP Feed','Ant 2 LCP Feed'],$
         IDS = DSID,/RETURN_ID)
     endif else begin
        DSButtons = CW_BGROUP(RightBase,/COLUMN,/NONEXCLUSIVE,['Ant 1 LCP Feed',$
         'Ant 1 Linear Feed','Ant 2 RCP Feed','Ant 2 Linear Feed'],$
         IDS = DSID,/RETURN_ID)
     endelse
     ds = replicate(1,4)
  ENDELSE

  CalLabel = WIDGET_LABEL(RightBase, VALUE='Apply Calibration',/ALIGN_Left,/FRAME)
  CalButtons = CW_BGROUP(RightBase,/COLUMN,/NONEXCLUSIVE,['Primary','Secondary'],$
      IDS = CalID,/RETURN_ID)

  ShowLabel = WIDGET_LABEL(RightBase, VALUE='Show',/ALIGN_Left,/FRAME)
  ShowButtons = CW_BGROUP(RightBase,/COLUMN,/EXCLUSIVE,['Flux Density','Cal Factors'],$
      IDS = ShowID,/RETURN_ID)

  ZoomID  = WIDGET_BUTTON(RightBase, VALUE='Zoom In')
  AdjID = WIDGET_BUTTON(RightBase, VALUE='Adjust')

  ; Offer AUTO calibration if RSTN data were read
  AutoID = 0L
  if (n_elements(rstn) gt 1) then begin
     AutoID = WIDGET_BUTTON(RightBase, VALUE='Auto')
  endif

  WIDGET_CONTROL, TPCalMain, /REALIZE

  WIDGET_CONTROL, SaveButtons, SET_VALUE=2
  nds = n_elements(ds)
  WIDGET_CONTROL, DSButtons, SET_VALUE=ds[0:4<(nds-1)]
  if (nds gt 5) then WIDGET_CONTROL, LDSButtons, SET_VALUE=ds[5:*]
  WIDGET_CONTROL, CalButtons, SET_VALUE=[1,0]
  WIDGET_CONTROL, ShowButtons, SET_VALUE=0

  WIDGET_CONTROL,DrawID,GET_VALUE=wid
  wset,wid

  ; Apply calibration
  ; Make copy of refcal
  ;refc = *refcal
  ;refcp = ptr_new(refc)
  if (tls.yrday ge 2004.231) then begin
     (*refcal.pfactors) = (*refcal.pfactors)[0:1,*,*]
     (*refcal.pfacupd) = (*refcal.pfacupd)[0:1,*,*]
  endif
  solspec = solspec0/(*refcal.pfactors)[*,0:nant-1,*]
  solrms  = solrms0/(*refcal.pfactors)[*,0:nant-1,*]

  ; Determine the median of the solar spectrum for the four 27-m feeds
  solmed = fltarr(nf)

  IF (keyword_set(twometer)) THEN BEGIN
     ; Determine a single trace that contains the median spectrum
     ; for all of the feeds
     if (tls.yrday ge 2004.231) then begin
        ; There are up to 10 feeds (5 ants x 2 poln)
        for i = 0, nf-1 do begin
           solarr = reform(solspec[0:1,2:nant-1,i],2*(nant-2))
           good = where(finite(solarr),ngood)
           case ngood of
              0: solmed[i] = !values.f_nan
              1: solmed[i] = solarr[good[0]]
              2: solmed[i] = median(solarr[good],/even)
              3: solmed[i] = median(solarr[good])
              4: solmed[i] = median(solarr[good],/even)
            else: solmed[i] = median(solarr[good])  ; For more than 4 values, do not worry about /even
           endcase
        endfor
     endif else begin
        ; There are up to 4 feeds (one per antenna)
        for i = 0, nf-1 do begin
           solarr = solspec[2,2:nant-1,i]
           good = where(finite(solarr),ngood)
           case ngood of
              0: solmed[i] = !values.f_nan
              1: solmed[i] = solarr[good[0]]
              2: solmed[i] = median(solarr[good],/even)
              3: solmed[i] = median(solarr[good])
              4: solmed[i] = median(solarr[good],/even)
           endcase
        endfor
     endelse

     ; Display the result
     plot_oo,f,solmed,xsty=1,yrange=[20,500],ystyle=1
     syms = [-1,-4,-5,-6,-2]
     if (tls.yrday ge 2004.231) then begin
        ; 2-m ant feeds are now R, L
        for i = 2, nant-1 do oplot,f,solspec[0,i,*],psym=syms[i-2]
        for i = 2, nant-1 do oplot,f,solspec[1,i,*],psym=syms[i-2]
     endif else begin
        for i = 2, nant-1 do oplot,f,solspec[2,i,*],psym=syms[i-2]
     endelse
     oplot,f,solmed,color=255,thick=3
     if (n_elements(rstn) gt 1) then oplot,f,rstn/2,psym=2,color=100
     twom = 1
  ENDIF ELSE BEGIN
     for i = 0, nf-1 do begin
        if (tls.yrday ge 2003.266) then begin
           ; 27-m ant feeds are now R, L
           solarr = [solspec[0,0,i],solspec[1,0,i],solspec[0,1,i],solspec[1,1,i]]
        endif else begin
           solarr = [solspec[1,0,i],solspec[2,0,i],solspec[0,1,i],solspec[2,1,i]]
        endelse
        good = where(finite(solarr),ngood)
        case ngood of
           0: solmed[i] = !values.f_nan
           1: solmed[i] = solarr[good[0]]
           2: solmed[i] = median(solarr[good],/even)
           3: solmed[i] = median(solarr[good])
           4: solmed[i] = median(solarr[good],/even)
        endcase
     endfor

     ; Display the result
     plot_oo,f,solmed,xsty=1,yrange=[1,100],ystyle=1
     if (tls.yrday ge 2003.266) then begin
        ; 27-m ant feeds are now R, L
        oplot,f,solspec[0,0,*],psym=-1
        oplot,f,solspec[1,0,*],psym=-4
        oplot,f,solspec[0,1,*],psym=-5
        oplot,f,solspec[1,1,*],psym=-6
     endif else begin
        oplot,f,solspec[1,0,*],psym=-1
        oplot,f,solspec[2,0,*],psym=-4
        oplot,f,solspec[0,1,*],psym=-5
        oplot,f,solspec[2,1,*],psym=-6
     endelse
     oplot,f,solmed,color=255,thick=3
     if (n_elements(rstn) gt 1) then oplot,f,rstn/2,psym=2,color=100
     twom = 0
  ENDELSE

  WIDGET_CONTROL,/HOURGLASS


  DSID = [DSID,replicate(-1,6-n_elements(DSID))]
  DSID = DSID[0:4]
  LDSID = [LDSID,replicate(-1,6-n_elements(LDSID))]
  LDSID = LDSID[0:4]
  pPrimFlg = ptr_new(0)
  pSdaryFlg = ptr_new(0)
  psolmed = ptr_new(solmed)
  state = {DrawID:DrawID, SaveID:SaveID, DSID:DSID, LDSID:LDSID, CalID:CalID, ShowID:ShowID, ExitID:ExitID,$
      AdjID:AdjID, ZoomID:ZoomID, AutoID:AutoID, pPrimFlg: pPrimFlg, pSdaryFlg: pSdaryFlg, wid:wid, solspec0:solspec0, solrms0:solrms0, $
      f:f, ds:ds, refcal:refcal, aprim:1, apscnd:0, sfuflg:1, mousemove:0, psolmed:psolmed,$
      xspl:fltarr(8), yspl:fltarr(8), AdjFlg:0, ipt: 0, fit: solmed*0, Zoom:0, twom:twom,$
      rstn:rstn,tls:tls, AutoFlg:0}

  device,decomp=0
  loadct,39

  ; Connect the STATE structure to the first child of the base widget
  WIDGET_CONTROL, BASE2, SET_UVALUE=state, /NO_COPY

  XMANAGER, 'WTPCal', TPCalMain

  ; Meaning of return values:
  ;   0 => no update is requested
  ;   1 => secondary update is requested
  ;   2 => primary update is requested

  solmed = *psolmed
  ptr_free,psolmed
  if (*pSdaryFlg) then return,1
  if (*pPrimFlg) then return,2

return,0
END

