;+
; NAME:
;     FINDLOCK
; PURPOSE:
;     Given a range of FCAL data around a nominal lock, finds the
;     nearest lock and returns the index of the center of it relative
;     to the nominal lock location.
; CATEGORY:
;     OVRO APC DIAGNOSTIC
; CALLING SEQUENCE:
;     tcmid = findlock(fcdata)
; INPUTS:
;     fcdata   FCAL data within +/- DIDH/2 about a nominal lock, as
;                given by the data in NOMTUNE.FTH, for a single antenna
;                and oscillator.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
; ROUTINES CALLED:
; OUTPUTS:
;     tcmid    The shift of the found lock nearest the nominal lock, or
;                NaN if no lock exists in the range.  TCMID is typically
;                a small integer value, but is returned as a float so
;                that NaN can be returned to flag a missing lock.
; COMMENTS:
; SIDE EFFECTS:
; RESTRICTIONS:
; MODIFICATION HISTORY:
;     Written 14-Mar-1999 by Dale E. Gary
;     17-Aug-1999  DG
;       Changed IDIR from +/- 1/2 to +2/3, -1/3, to bias the solution
;       to higher values of V/F.  For some reason, the locks are better
;       at higher V/F.
;     18-Aug-1999  DG
;       Changed back to +/- 1/2 for the high oscillator, since the locks
;       are too narrow to try offsetting
;-
function findlock,fcdata

   ; Number of points in FCDATA
   n = n_elements(fcdata)
   ; Index of middle point
   imiddle = (n-1)/2

   ; Flag indicating that this is for the High Oscillator (indicated by
   ; the width of FCDATA being less than 75).
   hiosc = 0
   if (n lt 75) then hiosc = 1

   ; Find the finite points in FCDATA
   finidx = where(finite(fcdata),nfin)

   ; Find the non-finite points in FCDATA
   nfinidx = where(finite(fcdata) eq 0)

   ; Bail out if there were NO finite values in FCDATA, so there is no lock
   if (nfin eq 0) then begin
      return, !values.f_nan
   endif

   ; Find the index IFIN, of the nearest finite point to the middle of FCDATA
   junk = min(abs(finidx-(n-1)/2),nmin)
   ifin = finidx(nmin)

   ; Find the index INFIN, of the nearest non-finite point to the middle of FCDATA
   junk = min(abs(nfinidx-(n-1)/2),nmin)
   infin = nfinidx(nmin)

   ; There are two possibilities.  Either the lock nearest the middle is at the
   ; middle, or it is not.
   if (ifin eq imiddle) then begin
      ; Lock in middle
      ; Two more possibilities, either the nearest non-finite point is to left or
      ; to right of middle
      if (infin lt imiddle) then begin
         ; Case of non-finite point to left
         istart = infin+1
         if (hiosc) then idir = -1/2. else idir = -1/3.
         snippet = fcdata(istart:(istart+50)<(n-1))
      endif else begin
         ; Case of non-finite point to right
         istart = infin-1
         if (hiosc) then idir = 1/2. else idir = +2/3.
         snippet = reverse(fcdata((istart-50)>0:istart))
      endelse
   endif else begin
      ; Lock not in middle
      ; Two more possibilities, either the nearest finite point is to left or
      ; to right of middle
      if (ifin lt imiddle) then begin
         ; Case of finite point to left
         istart = ifin
         if (hiosc) then idir = 1/2. else idir = +2/3.
         snippet = reverse(fcdata((istart-50)>0:istart))
      endif else begin
         ; Case of finite point to right
         istart = ifin
         if (hiosc) then idir = -1/2. else idir = -1/3.
         snippet = fcdata(istart:(istart+50)<(n-1))
      endelse
   endelse

   ; Snippet now starts with the first finite datum of the lock, and proceeds to
   ; the left.  Find the first non-finite datum to find the extent (width) of the
   ; lock
   infin = where(finite(snippet) eq 0,nnfin)
   if(nnfin eq 0) then begin
      ; There were no non-finite values, so use entire range as width
      nwid = n_elements(snippet)
   endif else begin
      ; The first non-finite value is what we want
      nwid = infin(0)
   endelse

   if (nwid lt n*0.05) then begin
      ; The lock is too narrow (less than 5% of range) so flag it bad
      tcmid = !values.f_nan
   endif else begin
      ; The width of the lock is NWID, and it starts at ISTART, but extends in the
      ; direction IDIR.  Find the middle.
      tcmid = float((istart - nwid*idir)-imiddle)
   endelse

;   print,fcdata(imiddle+tcmid)
return,tcmid
end