;+
; NAME:
;     DLCALCHEK
; PURPOSE:
;     Main routine to analyze Delay Line Loss Calibration data.  Responds to
;     scans of type DLCAL (scan code 10) or TEST DATA (scan code 1).
; CATEGORY:
;     OVRO APC DATA ANALYSIS
; CALLING SEQUENCE:
;     dlcalchek[,filename][,hrec | ,after=after][,debug][,/cmdfile]
; INPUTS:
;     filename   the name of the file containing DLCAL data.  If
;                  omitted, the file DAILY.ARC in directory
;                  !DEFAULTS.WORKDIR is assumed.
;     hrec       the record number of the DLCAL scan header.  Data
;                  will be processed up to the next EOS segment.
;                  If this argument is given, then AFTER keyword
;                  is ignored.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
;     after      an optional time string of the standard form
;                  [yyyy.ddd ]hh:mm[:ss] after which to start
;                  looking for a valid DLCAL or TEST DATA scan.
;     cmdfile    a switch that indicates that the routine was called
;                  from a command file, so issue no modal messages, and
;                  print any error messages to <WORKDIR>\DLCAL.MSG.
;     debug      a switch that activates some debugging statements
;                  for getting an indication of intermediate steps.
;                  This switch is not compatible with /CMDFILE switch.
; ROUTINES CALLED:
;     openarc, getdata, lasthrec, newscan
; OUTPUTS:
; COMMENTS:
; SIDE EFFECTS:
; RESTRICTIONS:
; MODIFICATION HISTORY:
;     Written 04-Mar-1999 by Dale Gary
;     21-May-1999  DG
;       Change to write out results into file !DEFAULTS.DBDIR+'DELAY.DAT'
;     11-Jan-2000  DG
;       Eliminated hardwired directory locations.
;     16-Aug-2000  DG
;       Renamed PLOTERR (IDL version) to OVSA_PLOTERR, and copied to
;       OVSA tree, then changed PLOTERR calls to OVSA_PLOTERR, to avoid
;       conflict with SSW's PLOTERR.
;-
pro dlcalchek,filename,hrec,after=after,debug=debug,cmdfile=cmdfile

   ; If the /cmdfile switch is set, open a "new" DLCAL.MSG before doing
   ; anything.  If it exists it will be cleared.
   msglun = 0   ; Indicates DLCAL.MSG does not exist
   IF (keyword_set(cmdfile)) THEN $
                  openw,msglun,/get_lun,!defaults.workdir+'DLCAL.MSG'

   ; If no filename, assume standard DAILY.ARC file
   IF (n_elements(filename) EQ 0) THEN $
                  filename=!defaults.workdir+'DAILY.ARC'

   ; Open the file
   lun = openarc(filename,a,nrec)

   IF (n_elements(hrec) EQ 0) THEN BEGIN
      IF (keyword_set(after)) THEN hrec = lasthrec(a,nrec,tstr=after) $
                              ELSE hrec = lasthrec(a,nrec)
   ENDIF

   ; Read header info, etc.
   rec = newscan(a,nrec,hrec,header,obseq,cfg,traj,refcal,gparm)

   ; Verify that the specified record has either a DLCAL or TEST DATA
   ; scan code
   IF (header.tls.scancode NE !SCAN.TEST AND header.tls.scancode NE !SCAN.DLCAL) THEN BEGIN
      errstr = 'DLCALCHEK: Header found is of wrong type.'
      IF (keyword_set(cmdfile)) THEN printf,msglun,errstr,format='(a)' $
                                ELSE ans = widget_message(errstr,/ERROR)
      return
   ENDIF

   ; The DLCAL scan has NDLA settings of delay (4096, 2048, ..., 0).  Each
   ; is set and held for NCYC cycles to give NCYC independent measurements
   ; at each frequency of the observing cycle.
   ndla = 14
   ncyc = 5        ; Number of repeats of cycle (hardcoded for now)
   nfrq = n_elements(*obseq.phord)  ; Number of distinct frequencies (should be 6)
   nrpt = obseq.nx/nfrq     ; Number of times each freq is repeated (should be 10)
   koff = 2                       ; Number of samples before DOSEQ starts

   ; Length of observing sequence
   lseq = obseq.nx                ; Number of measurements in cycle (should be 60)

   nant = 2                 ; Use only the two 27-m antennas for DLCAL
   nndw = header.ndbw + header.nfgw + 1     ; Number of non-data words
   nws = header.nws                         ; Number of words per sample
   nsr = header.nsr                         ; Number of samples per record
   nsamp = ndla*ncyc*lseq                   ; Number of samples in entire sequence
   bigdata = fltarr(nant,nsamp)             ; Big enough to hold all of the data


   ; The number of records to expect should be nrecs=nsamp/header.nsr
   ; (14*5*60/33 = 127).  Note that there should be some samples in the 128th
   ; record, but CPC doesn't send it.
   nrecs = nsamp/header.nsr
;   rec = rec + 1
   datoff = header.rdoff+nndw
   ndat = nant

   ; Read data from the file into a single large array, BIGDATA, of
   ; size (2,14*5*60), which is just a long list of 2 total power channels
   ; Loop over the 127 records
   for i = 0,nrecs-1 do begin
      data = getdata(rec,a)                      ; Read a record
      ; Loop over the 33 samples in each record
      for j = 0, header.nsr-1 do begin
         soff = j*header.nws   ; Additional offset for each sample
         bigdata(*,i*header.nsr+j) = data(datoff+soff:datoff+soff+ndat-1)
      endfor
      rec = rec + 1                      ; Increment record number
   endfor

   free_lun,lun

   ; Eliminate the first two samples (which are not part of the observing
   ; sequence) by wrapping them to the end of the BIGDATA array using the
   ; SHIFT function
   bigdata = shift(bigdata,0,-2)

   ; The last part of the sequence is truncated because the CPC does not
   ; send partial records.  This code flags those entries with NaN
   nmissing = (nsamp-header.nsr*nrecs+2)
   bigdata(*,nsamp-nmissing:nsamp-1) = !values.f_nan

   ; The following statement is like an equivalence--or straight memory copy--
   ; allowing the data in BIGDATA to be referenced by the indexes of DLDAT
   dldat = reform(bigdata,nant,nrpt,nfrq,ndla,ncyc)

   ; We now want to average over the NRPT*NCYC equivalent measurements
   ; for each combination of NANT, NFRQ, and NDLA.  The first measurement
   ; of the 0th and 4th frequencies are bad.  Flag them with NaN
   dldat(*,0,[0,4],*,*) = !values.f_nan

   ; We have the data we want, but must now combine the information at
   ; different frequencies.  The procedure is to determine the mean value
   ; of the 50 measurements at each frequency, then normalize the different
   ; frequencies to remove the spectral dependence.  This gives 50*6=300
   ; normalized points, which are then averaged to give a final IF level
   ; for the antenna/delay setting combination.
   dlavg = fltarr(nant,ndla)
   dlrms = fltarr(nant,ndla)
   avg = fltarr(nfrq)
   rms = fltarr(nfrq)
   ; Loop over antenna
   !p.multi=[0,2,1,0,0]
   for i = 0, nant-1 do begin
      ; Loop over delay setting
      for k = 0, ndla-1 do begin
         ; Normalize frequencies for this antenna/delay combination
         for j = 0, nfrq-1 do begin
            ; Combine the NRPT*NCYC points into a single array
            pts = reform(dldat(i,*,j,k,*),nrpt*ncyc)
            ; Use the MOMENT() function to get the mean and std dev.
            out = moment(pts,/nan)
            avg[j] = out(0)
            rms[j] = sqrt(out(1))
         endfor
;         if (k eq 0) then ploterr,(*obseq.phord)*0.2,avg,rms,psym=-3 $
;                     else oploterr,(*obseq.phord)*0.2,avg,rms,psym=-3
         ; DLAVG now contains the average IF level as a function of freq.
         ; Determine the factor for each frequency that will normalize
         ; the averages to 5 GHz.
         dlfac = avg/avg[2]
         pts = fltarr(nrpt*ncyc,nfrq)
         ; Loop again over frequency to apply the normalization
         for j = 0, nfrq-1 do begin
            pts(*,j) = reform(dldat(i,*,j,k,*),nrpt*ncyc)
            pts(*,j) = pts(*,j)/dlfac(j)
         endfor
         ; Reform the array from fltarr(50,6) to fltarr(300), since the
         ; frequency dependence has now been normalized out.
         pts = reform(pts,nrpt*ncyc*nfrq)
         ; Determine the average and standard deviation for this antenna/delay comb.
         out = moment(pts,/nan)
         dlavg(i,k) = out(0)
         dlrms(i,k) = sqrt(out(1))
      endfor
   endfor

   avg1 = total(dlavg(0,*))/float(ndla)
   range = [avg1*0.8,avg1*1.2]
   ovsa_ploterr,reverse(indgen(ndla))-1,dlavg(0,*),dlrms(0,*),xran=[-2,13],xsty=1,yran=range,ysty=1,$
      title='DLCal: Ant 1',xtit='Delay Bit',ytit='IF Level',psym=10
   avg2 = total(dlavg(1,*))/float(ndla)
   range = [avg2*0.8,avg2*1.2]
   ovsa_ploterr,reverse(indgen(ndla))-1,dlavg(1,*),dlrms(1,*),xran=[-2,13],xsty=1,yran=range,ysty=1,$
      title='DLCal: Ant 2',xtit='Delay Bit',ytit='IF Level',psym=10

   openw,lun,/get_lun,!defaults.dbdir+'dlcal.dat'
   bit = 2^(reverse(indgen(ndla))-1)
   bit(ndla-1) = 0
   for i = 0, ndla-1 do printf,lun,bit(i),dlavg(0,i)/avg1,dlrms(0,i)/avg1,$
                                          dlavg(1,i)/avg2,dlrms(1,i)/avg2
   free_lun,lun

return
END