;+
; NAME:
;     WAMPHIT
; PURPOSE:
;     Supervises display and processing of results from
;     AMPHIT amplitude and phase fitting.
; CATEGORY:
;     OVSA APC CALIBRATION ANALYSIS
; CALLING SEQUENCE:
;     wamphit,filename
; INPUTS:
;     filename   The name of the .SAV file containing the output
;                  from ANALYZE.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
; ROUTINES CALLED:
;     amphit
; OUTPUTS:
; COMMENTS:
; SIDE EFFECTS:
; RESTRICTIONS:
; MODIFICATION HISTORY:
;     Written 31-Mar-2000 by Dale E. Gary
;     06-Apr-2000  DG
;       Write polarization state to output file, obtained from input
;       filenames.  Also include new keyword NDFAC in final call to AMPHIT
;       on saving the results.
;     14-Apr-2000  DG
;       Get rid of C:\TEMP references (use !Defaults.workdir)
;     28-Jul-2000  DG
;       Now writes NF, NBL, and NFILES to first line of .AMF file on save.
;       Also makes use of HEADER structure newly saved in ANALYZE output,
;       to give which antennas are available.
;     17-Dec-2002  DG
;       Added new arguments to calls to AMPHIT.
;     29-Sep-2004  DG
;       Start on adding dual-polarization capability.  Reading and plotting
;       done, but still need to work on SAVE and probably some others.
;     07-Oct-2004  DG
;       Finished and tested routine.  On SAVE, a single AMF file is created
;       with both polarizations.
;     15-Oct-2006  DG
;       Fixed triad_list to indicate ant 8 instead of ant 3 (no idea why it
;       was indicating ant 3)
;     09-Feb-2014  DG
;       Added helpful suggestion of output filename, to allow standardization
;       of output filenames.
;     02-Mar=2014  DG
;       Handle mixed polarization case (between Oct. 2003-Jun. 2004) by issuing
;       a warning, but proceeding with only the first polarization in the file.
;-

pro wamphit_event, event

   ; Read the state structure from the child base
   base = event.handler
   stash = widget_info(base,/child)
   widget_control,stash,get_uvalue=state,/no_copy

   WIDGET_CONTROL,Event.Id,GET_UVALUE=Ev

   f = state.f
   nf = n_elements(f)
   ny = state.ny
   ncol = state.ncol
   avg = (*state.pavg)
   tavg = (*state.ptavg)
   bl_list = state.bl_list
   tri_bllist = state.tri_bllist
   nbl = n_elements(bl_list)
   f_buttons = state.f_buttons
   itriad = state.triad
   tableID = state.TableID
   frqID = state.frqID
   ifile = state.curfile
   header = state.header
   cfg = state.cfg

   CASE Ev OF
   'DRAW': BEGIN
         IF (Event.type eq 1) THEN BEGIN
            x = Event.X
            y = Event.Y
            nfp = total(f_buttons)
            nblp = 3   ; Always three baselines (one triad) selected)
            if (y gt 1000/3.) then begin
               i = fix(x/(500./nfp))
               iflist = where(f_buttons eq 1)
               frq = f[iflist[i]]
               state.fstd = frq
               state.pstd = state.outarr(3,iflist[i],0,ifile)
               widget_control,state.PCorID,sensitive=1
            endif else begin
               widget_control,state.PCorID,sensitive=0
            endelse
         ENDIF
      END
   'PCOR': BEGIN
         ; Correct the phases of the 12 baseline by flattening the phases at
         ; the selected frequency and applying the changes to other frequencies
         ; after scaling to the appropriate frequency.  All other baselines
         ; are adjusted to enforce phase closure
         pcorout = pcor12(f,avg,tavg,state.fstd,state.pstd)
         avg = pcorout
         goto,plot
      END
   'TRI': BEGIN
         WIDGET_CONTROL,Event.Id,GET_VALUE=itriad
         if(itriad eq state.triad) then goto,write_state
         state.triad = itriad
         ; Invalidate current table selection, if any
         state.select = -1
         widget_control,state.advID,sensitive=0
         widget_control,state.DecrID,sensitive=0
         goto,plot
      END
   'TAB_SEL': BEGIN
         if (Event.Type eq 4) then begin
            select = [Event.sel_left, Event.sel_top,$
                      Event.sel_right,Event.sel_bottom]
            IF (select[1] GE 0 AND select[1] EQ select[3]) THEN begin
               ; See if selection is consistent with TRIAD selected
               tribl = tri_bllist[*,itriad]  ; Get the list of baselines for this triad
               k = where(tribl eq bl_list[select[1]],ngood)
               if (ngood ne 0) then begin
                  state.select=select[1]
                  widget_control,state.advID,sensitive=1
                  widget_control,state.DecrID,sensitive=1
               endif else begin
                  state.select = -1
                  widget_control,state.advID,sensitive=0
                  widget_control,state.DecrID,sensitive=0
               endelse
            endif
         endif else begin
            state.select = -1
            widget_control,state.advID,sensitive=0
            widget_control,state.DecrID,sensitive=0
         endelse
      END
   'ADV': BEGIN
         if (state.select ne -1) then begin
            widget_control,state.tableID,get_value=slope
            slope[0,state.select] = slope[0,state.select] + 0.5
            ; Force phase closure of frequency drifts
            savdev = slope[1,state.select]   ; Save standard deviation of selection
            slope[1,state.select] = 0.001    ; Set low sdev for selection
            slope[0,*] = pclose(slope[0,*], slope[1,*]^2, 0)
            slope[1,state.select] = savdev   ; Reset sdev to original
            widget_control,state.tableID,set_value=slope
            state.slopes[*,*,ifile] = slope
         endif
      END
   'DECR': BEGIN
         if (state.select ne -1) then begin
            widget_control,state.tableID,get_value=slope
            slope[0,state.select] = slope[0,state.select] - 0.5
            ; Force phase closure of frequency drifts
            savdev = slope[1,state.select]   ; Save standard deviation of selection
            slope[1,state.select] = 0.001    ; Set low sdev for selection
            slope[0,*] = pclose(slope[0,*], slope[1,*]^2, 0)
            slope[1,state.select] = savdev   ; Reset sdev to original
            widget_control,state.tableID,set_value=slope
            state.slopes[*,*,ifile] = slope
         endif
      END
   'Poln': BEGIN
         WIDGET_CONTROL,Event.Id,GET_VALUE=ipoln
         if(ipoln eq state.poln) then goto,write_state
         state.poln = ipoln
         ; Invalidate current table selection, if any
         state.select = -1
         widget_control,state.advID,sensitive=0
         widget_control,state.DecrID,sensitive=0
         goto,plot
      END
   'FIT': BEGIN
         state.fit = 1 - state.fit
         goto,plot
      END
   'FILE': BEGIN
         WIDGET_CONTROL,state.FileId,GET_VALUE=ifile
         if (ifile eq state.curfile) then goto,write_state
file:
         ; Restore this file and check for compatibility with current settings
         restore,state.files[ifile]
         if (n_elements(avg[*,0,0,0]) ne n_elements((*state.pavg)[*,0,0,0])) then begin
            ans = dialog_message(['Number of channels in this file is not',$
               'compatible with current settings.'],/error)
            widget_control,Event.Id,set_value=state.curfile
            goto, write_state
         endif
         if (n_elements(f) ne n_elements(state.f)) then begin
            ans = dialog_message(['Number of frequencies in this file is not',$
               'compatible with current settings.'],/error)
            widget_control,Event.Id,set_value=state.curfile
            goto, write_state
         endif

         ; Things are consistent.
         ; See if we need to recreate the frequency buttons
         idxs = where(f ne state.f,ndif)  ; NDIF is non-zero if f ne state.f
         if (ndif ne 0) then begin
            ; Recreate frequency buttons for the new file
            for i = 0, ncol-1 do begin
               ; Find parent base for this column of buttons
               fbase = widget_info(frqid[i],/parent)
               ; Destroy existing buttons
               widget_control,frqid[i],/destroy
               ; Create a new set of buttons
               frqID[i] = cw_bgroup(fbase,string(f[0+ny*i:(ny*(i+1)-1)<(nf-1)],format='(F4.1)'),$
                     uvalue='FRQ'+string(i,format='(I1)'),/NONEX)
             endfor
             state.f_buttons = 1  ; Set all buttons
             for i = 0, ncol-1 do widget_control,frqID[i],set_value=f_buttons[0+ny*I:(ny*(I+1)-1)<(nf-1)]
          endif

         state.frqID = frqID
         state.f = f
         ptr_free,state.pavg
         ptr_free,state.ptavg
         state.pavg = ptr_new(avg)
         state.ptavg = ptr_new(tavg)
         state.prefcal = ptr_new(refcal)
         state.curfile = ifile

         widget_control,state.tableID,get_value=slope
         for j = 0, npol-1 do begin
            ; Loop over baselines
            for i = 0, nbl-1 do begin
               ; Determine basic solution, allowing for linear frequency drift w/ time
               amphit,f,avg[*,*,*,j],bl_list[i],tavg,header,cfg,out,/fit
               good = where(finite(reform(out[5,*])),ngood)
               if (ngood ne 0) then begin
                  ; Do weighted average over frequency to determine frequency drift
                  var = (out[2,good]/out[1,good])^2
                  slope[0,i] = total(reform(out[5,good])/var,1)/total(1./var)
                  slope[1,i] = (total(var)/ngood)^0.5
               endif else slope[*,i] = !values.f_nan
               ; Insert average frequency drift into "master" table
               state.outarr[*,*,i,ifile,j] = out
            endfor

            ; Force phase closure of frequency drifts
            slope[0,*] = pclose(slope[0,*], slope[1,*]^2, 0)

            widget_control,state.tableID,set_value=slope
            state.slopes[*,*,ifile,j] = slope
         endfor
         goto,plot
      END
   'PLOT': BEGIN
plot:
         nfp = total(f_buttons)
         nblp = 3   ; Always three baselines (one triad) selected)
         tribl = tri_bllist[*,itriad]  ; Get the list of baselines for this triad
         ipoln = state.poln
         psav = !p.multi
         xsav = !x.margin
         ysav = !y.margin
         !p.multi=[0,nfp,nblp,0,0]
         !x.margin=(!y.margin=[0,0])
         ipl = nfp*nblp  ; Plot number
         widget_control,state.tableID,get_value=slope
         for i = 0, nblp-1 do begin
            k = (where(bl_list eq tribl[i]))[0]
            for j = 0, nf-1 do begin
               if (f_buttons[j] eq 1) then begin
                  !p.multi[0] = ipl mod (nfp*nblp)
                  if (state.fit) then amphit,f,avg[*,*,*,ipoln],tribl[i],tavg,header,cfg,out,ifrq=j+1,/fit,debug=2,slope[0,k] $
                                 else amphit,f,avg[*,*,*,ipoln],tribl[i],tavg,header,cfg,out,ifrq=j+1,debug=2,slope[0,k]
                  state.outarr[*,j,k,state.curfile,ipoln] = out
                  ipl = ipl - 1
               endif
            endfor
         endfor
         !p.multi = psav
         !x.margin = xsav
         !y.margin = ysav
         if (n_elements(pcorout) ne 0) then begin
            ans = dialog_message('Do you wish to save this result?',/question)
            if (ans eq 'Yes') then begin
               fname = state.files[state.curfile]
               restore,fname
               avg = pcorout
               break_file,fname,disk,dir,file,ext
               state.files[state.curfile] = disk+dir+'a'+file+ext
               save,file=state.files[state.curfile],tavg,avg,sigma,f,header,refcal,calinfo,o_datfile,ndfac
               lbase = widget_info(state.fileID,/parent)
               widget_control,state.fileID,/destroy
               fileID = cw_bgroup(lbase,state.files,/return_index,/exclusive,uvalue='FILE')
               state.fileID = fileID
               widget_control,state.fileID,set_value=state.curfile
               ptr_free,state.pavg
               state.pavg = ptr_new(avg)
            endif
            ; In either case, force the file to be reread to update the plot
            blah = temporary(pcorout)   ; Force PCOROUT to be undefined
            widget_control,state.PCorID,sensitive=0
            goto, file
         endif
         widget_control,state.PCorID,sensitive=0
      END
   'SAVE': BEGIN
         ; Rerun AMPHIT on all files, all baselines, both polarizations, using the PSLOPE values
         ; saved in the SLOPES variable
         nfiles = n_elements(state.files)
         ; Write out info for reading AMF file, to beginning of the file
         dstr = header.tls.date
         triad_list = state.triad_list
         tlist = triad_list[0]
         nlist = n_elements(triad_list)
         if nlist gt 1 then for i = 1, nlist-1 do tlist = tlist+strmid(triad_list[i],2)
         outfile = !defaults.workdir+strmid(dstr,0,4)+strmid(dstr,5,2)+strmid(dstr,8,2)+'_'+tlist+'.amf'         
         filename = dialog_pickfile(path=!defaults.workdir,file=outfile,/write)
         ans = 'No'
         if (filename ne '') then ans = oktowrite(filename)
         if (ans eq 'No') then begin
            ans = dialog_message('No information has been saved.')
            return
         endif
         openw,/get_lun,lun,filename
         printf,lun,nf,nbl,nfiles

         ; Go through the files one at a time
         for j = 0, nfiles-1 do begin
            restore,state.files[j]

            if (header.tls.yrday lt 2004.231 and npol gt 1) then begin
               ans = dialog_message(['WAMPHIT:Error, WAMPHIT can only handle one polarization',$
                                       'for data prior to 2004.231.  Will use first poln.'],/error)
               npol = 1
            endif
             ; File contains 1 polarization if before 2004.231, or 2 if after.
             if (npol eq 1) then begin
                ; File contains only one polarization.
                ; Determine from the filename what polarization state is contained
                ; in the file (either R, L, or I, as last letter of stem of filename)
                break_file,state.files[j],disk,dir,file,ext
                CASE STRUPCASE(strmid(file,strlen(file)-1,1)) OF
                  'R': polstr = 'R'
                  'L': polstr = 'L'
                  ELSE: polstr = 'I'  ; If neither R nor L, assume I
                ENDCASE
                ; Loop over baselines
                for i = 0, nbl-1 do begin
                   pslope = state.slopes[0,i,j]
                   ; Determine basic solution, allowing for linear frequency drift w/ time
                   amphit,f,avg[*,*,*,0],bl_list[i],tavg,header,cfg,out,pslope,/save,lun=lun,pol=polstr,ndfac=ndfac
                   bad = where(finite(reform(out)) eq 0,nbad)
                   if (nbad ne 0) then out[bad] = -99
                endfor
             endif else begin
                ; File contains two polarizations.
                ; Loop over polarization
                for k = 0, 1 do begin
                   if (k eq 0) then polstr = 'R' else polstr = 'L'
                   ; Loop over baselines
                   for i = 0, nbl-1 do begin
                      pslope = state.slopes[0,i,j,k]
                      ; Determine basic solution, allowing for linear frequency drift w/ time
                      amphit,f,avg[*,*,*,k],bl_list[i],tavg,header,cfg,out,pslope,/save,lun=lun,pol=polstr,ndfac=ndfac
                      bad = where(finite(reform(out)) eq 0,nbad)
                      if (nbad ne 0) then out[bad] = -99
                   endfor
                endfor
             endelse
         endfor
         free_lun,lun
         if (npol eq 2) then begin
            ; Overwrite initial line of AMF file to give correct number of polarizations
            openu,lun,/get_lun,filename
            printf,lun,nf,nbl,nfiles*2
            free_lun,lun
         endif
         ptr_free,state.pavg
         ptr_free,state.ptavg
         widget_control,base,/destroy
         return
      END
   'QUIT': BEGIN
         ptr_free,state.pavg
         ptr_free,state.ptavg
         widget_control,base,/destroy
         return
      END
   'PCAL': BEGIN
         nchan  = n_elements(avg[*,0,0])
         ntimes = n_elements(avg[0,0,*])
         nant = sqrt(nchan)
         external = 0
         ans = dialog_message(['Would you like to use an external calibration file?',$
                               '(Answering NO will cause the internal REFCAL to be used.)'],$
                               /question)
         if (ans eq 'Yes') then begin
            calfile = dialog_pickfile(path=!defaults.workdir,filter='*.cal')
            if (calfile ne '') then begin
               external = 1
              ; Open and read the contents of the CALFILE
              ON_IOERROR,caldone
              openr,extlun,/get_lun,calfile
              in = {hed:strarr(3),data:fltarr(6,nf)}
              calin = fltarr(6,nf,nbl)
              bl = intarr(nbl)
              for i = 0, nbl-1 do begin
                 readf,extlun,in
                 bl[i] = fix(strmid(in.hed[0],0,2))
                 calin[*,*,i] = in.data
              endfor
      caldone:
              free_lun,extlun
              ON_IOERROR,NULL
              if (i lt nbl) then begin
                 calin = calin[*,*,0:i-1]
                 bl = bl[0:i-1]
                 nbl = i
              endif
              ; Check that the file was read in correctly, by comparing the first
              ; column with the frequencies list
              calfrq = calin[0,*,0]
              blah = where((calfrq - f) gt 0.1,ndiff)
              if (ndiff ne 0) then external = 0  ; If there are differences, disregard
            endif
         endif
;         p = fltarr(nf,nbl)
;         if (external eq 0) then for i = 0, nbl-1 do $
;                                 p[*,i] = reform((*(*state.prefcal).pphase)[2,i,*])*!dtor $
;                            else p = reform(calin[*,3,i])*!dtor
;         ptr_free,state.pphz
;         state.pphz = ptr_new(p)
         for i = 0, nbl-1 do begin
            y = reform(avg[i*2+nant,*,*])
            x = reform(avg[i*2+nant+1,*,*])
            if (external eq 0) then p = reform((*(*state.prefcal).pphase)[2,i,*])*!dtor $
                               else p = reform(calin[3,*,i])*!dtor
            for j = 0,ntimes-1 do begin
               avg[i*2+nant+1,*,j] = x[*,j]*cos(p) + y[*,j]*sin(p)
               avg[i*2+nant,*,j]   = y[*,j]*cos(p) - x[*,j]*sin(p)
            endfor
         endfor
         goto,plot
      END
   'CLEAR': BEGIN
         state.f_buttons = 0  ; Unset all buttons
         f_buttons = state.f_buttons
         for i = 0, ncol-1 do widget_control,frqID[i],set_value=f_buttons[0+ny*I:(ny*(I+1)-1)<(nf-1)]
      END
   'SET': BEGIN
         state.f_buttons = 1  ; Set all buttons
         f_buttons = state.f_buttons
         for i = 0, ncol-1 do widget_control,frqID[i],set_value=f_buttons[0+ny*I:(ny*(I+1)-1)<(nf-1)]
      END
   ELSE: BEGIN
         if (strmid(string(ev),0,3) eq 'FRQ') then begin
            n = strmid(string(ev),3,1)+1
            WIDGET_CONTROL,Event.Id,GET_VALUE=f_butn
            state.f_buttons[(n-1)*ny:(n*ny-1)<(nf-1)] = f_butn
         endif
      END
   ENDCASE

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

return
end


pro wamphit, files, group = Group

   IF N_ELEMENTS(Group) EQ 0 THEN GROUP=0

   ; If no filenames were specified, ask the user to select files.  If the
   ; user cancels, then exit.
   if (n_elements(files) eq 0) then begin
ask:
      files = dialog_pickfile(path=!defaults.workdir,filter='*.sav',/multi,$
                    title='Select file(s) containing ANALYZE processed data.')
      if (files[0] eq '') then return
      ; Sort file list
      files = files[sort(files)]
   endif

   ; Restore first file in the list
   nfiles = n_elements(files)
   ifile = 0
   restore,files[ifile]

   if (header.tls.yrday lt 2004.231 and npol gt 1) then begin
      ans = dialog_message(['WAMPHIT:Error, WAMPHIT can only handle one polarization',$
                                       'for data prior to 2004.231. Will use first poln.'],/error)
      npol=1
   endif

   nant = header.nant
   aatab = header.aatab(where(header.aatab ne 255))

   nf = n_elements(f)
   nbl = 2*nant-3 ; Number of baselines including at least one large antenna

   ; Create list of antenna triads, for buttons
   CASE nant OF
        3: triad_list = string(aatab,format='(3I1)')
        5: triad_list = ['124','125','126']
        6: triad_list = ['124','125','126','127']
        7: triad_list = ['124','125','126','127','128']
     else: BEGIN
           ans = dialog_message('Cannot determine antenna triads for this file.',/error)
           return
        END
   ENDCASE

   itriad = 0
   ntri = n_elements(triad_list)
   tri_bllist = intarr(3,ntri)   ; List of baselines in each triad
   for i = 0, ntri - 1 do begin
      bl1 = strmid(triad_list[i],0,2)
      bl2 = strmid(triad_list[i],0,1)+strmid(triad_list[i],2,1)
      bl3 = strmid(triad_list[i],1,2)
      tri_bllist[*,i] = [bl1,bl2,bl3]
      if (i eq 0) then bl_list = [bl1,bl2,bl3] $
                  else bl_list = [bl_list,bl1,bl2,bl3]
   endfor
   bl_list = bl_list[sort(bl_list)]
   bl_list = bl_list[uniq(bl_list)]

   slope = fltarr(2,nbl)
   outarr = fltarr(6,nf,nbl,nfiles,npol)

   f_buttons = replicate(1,nf)
   tri_buttons = intarr(ntri)

   for j = 0, npol-1 do begin
      ; Loop over baselines
      for i = 0, nbl-1 do begin
         ; Determine basic solution, allowing for linear frequency drift w/ time
         amphit,f,avg[*,*,*,j],bl_list[i],tavg,header,cfg,out,/fit
         good = where(finite(reform(out[5,*])),ngood)
         if (ngood ne 0) then begin
            ; Do weighted average over frequency to determine frequency drift
            var = (out[2,good]/out[1,good])^2
            slope[0,i] = total(reform(out[5,good])/var,1)/total(1./var)
            slope[1,i] = (total(var)/ngood)^0.5
         endif else slope[*,i] = !values.f_nan
         ; Insert average frequency drift into "master" table
         outarr[*,*,i,ifile,j] = out
      endfor

      ; Force phase closure of frequency drifts
      pin = reform(slope[0,*])
      wt = reform(slope[1,*]^2)
      slope[0,*] = pclose(pin, wt, 0)
      slopes = fltarr(2,nbl,nfiles,npol)
      slopes[*,*,ifile,j] = slope
   endfor

   ; Create a simple base widget and child base widget.  The
   ; child base carries the timer messages
   base = widget_base(TITLE='WAmphit',GROUP_LEADER=Group)
   base2 = widget_base(base,/ROW)
   lbase = widget_base(base2,/column)
   rbase = widget_base(base2,/column)
   gobase = widget_base(base2,/column)
   lbase1 = widget_base(lbase,/row)
   buttonbase = widget_base(lbase1,/column)
   tablebase = widget_base(lbase1,/column)
   label = widget_label(buttonbase,value='Antenna Triad')

   ; Baseline buttons
   triID = cw_bgroup(buttonbase,string(triad_list,format='(I3)'),/return_index,uvalue='TRI',/EXCL)

   ; Table of slopes
   fmt = strarr(2,nbl)
   for i = 0, nbl-1 do begin
      fmt[*,i] = ['(F6.1)','(F6.3)']
   endfor

   font = 'Lucida Console*18'

   TableId = WIDGET_TABLE(tablebase,VALUE=slope,COLUMN_WIDTHS=[40,40],$
       COLUMN_LABELS=['Slope','Dev'],ROW_LABELS=string(bl_list,format='(I2)'),$
       FORMAT=fmt,UVALUE='TAB_SEL',/ALL_EVENTS,/EDIT,$
       SCROLL=0)

   newbase = widget_base(lbase,/row)
   FitID = cw_bgroup(newbase,'Fit Slope',uvalue='FIT',/NONEX)
   PlotID = widget_button(newbase,Value='Refresh Plot',uvalue='PLOT')
   AdvID = widget_button(newbase,Value='Adv +0.5',uvalue='ADV',sensitive=0)
   DecrID = widget_button(newbase,Value='Adv -0.5',uvalue='DECR',sensitive=0)
   if (header.tls.yrday ge 2004.231 and npol gt 1) then begin
      RLBase = widget_base(newbase,/column)
      RLID = cw_bgroup(RLbase,['R','L'],/return_index,uvalue='Poln',/EXCL)
   endif else RLID = 0L

   lbase1 = widget_base(lbase,/row)
   label = widget_label(lbase1,value='Frequency [GHz]')
   ClrID = widget_button(lbase1,value='Clear All',uvalue='CLEAR')
   SetID = widget_button(lbase1,value='Set All',uvalue='SET')
   lbase2 = widget_base(lbase,/row)
   ny = ceil(sqrt(nf))
   ncol = (nf-1)/ny + 1
   frqID = lonarr(ncol)
   for i = 0, ncol-1 do begin
      fbase = widget_base(lbase2,/column)
      frqID[i] = cw_bgroup(fbase,string(f[0+ny*i:(ny*(i+1)-1)<(nf-1)],format='(F4.1)'),$
                     uvalue='FRQ'+string(i,format='(I1)'),/NONEX)
   endfor

   bottombase = widget_base(lbase,/row)
   PCorID = widget_button(bottombase,Value='Correct 12 Phase',uvalue='PCOR',sensitive=0)
   SaveID = widget_button(bottombase,Value='Save and Exit',uvalue='SAVE')
   QuitID = widget_button(bottombase,Value='Quit w/o save',uvalue='QUIT')
   label = widget_label(lbase,value='Files')
   fileID = cw_bgroup(lbase,files,/return_index,/exclusive,uvalue='FILE')
   calID = widget_button(lbase,value='Apply Phase Cal',uvalue='PCAL')

   drawID = widget_draw(rbase,xsiz=500,ysiz=500,/BUTTON_EVENTS,UVALUE='DRAW')

;   plotID = widget_button(gobase,value='Make Plot',uvalue='PLOT')

   ; Realize the heirarchy
   widget_control,base,/realize

   widget_control,tableID,set_value=slope
   for i = 0, ncol-1 do widget_control,frqID[i],set_value=f_buttons[0+ny*I:(ny*(I+1)-1)<(nf-1)]
   widget_control,triID,set_value=itriad
   if (header.tls.yrday ge 2004.231 and npol gt 1) then widget_control,RLID,set_value=0
   widget_control,fileID,set_value=ifile
   widget_control,FitID,set_value=1

   ; Save some information in a state structure to read in the
   ; event handler
   state = {files:files,f:f,pavg:ptr_new(avg),ptavg:ptr_new(tavg),prefcal:ptr_new(refcal),$
      calinfo:calinfo, header:header, cfg:cfg, $
      bl_list:bl_list, triad_list:triad_list, tri_bllist:tri_bllist, $
      f_buttons:f_buttons, triad:itriad, ncol:ncol, ny:ny, select:-1,$
      outarr:outarr, FrqID:FrqID, TableID:TableID, AdvID:AdvID, DecrID:DecrID, $
      fileID:fileID, calID:calID, fit:1, curfile:ifile, slopes:slopes, $
      RLID:RLID, Poln:0, PCorID:PCorID, fstd:0.0 , pstd:0.0}

   widget_control,widget_info(base,/child),set_uvalue=state, /no_copy

   ; Call XMANAGER to handle the event messages
   xmanager,'wamphit',base, /NO_BLOCK

   return
end
