;+
; NAME:
;     DLASOLVE
; PURPOSE:
;     Given the DELAY CENTER offsets for each baseline, solve for the best
;     values of DELAY CENTERs.
; CATEGORY:
;     OVRO APC CALIBRATION
; CALLING SEQUENCE:
;     dlasolve,d,ss,r
; INPUTS:
;     d       the delay centers for each antenna, as given in the CONFIG
;               segment, corresponding to the value in force at the time
;               of the observations.
;     ss      the delay shifts determined by DLAFIT routine.
; OPTIONAL (KEYWORD) INPUT PARAMETERS:
; ROUTINES CALLED:
;     openarc, getdata, lasthrec, tl_decode, decode, get_cycle, congrid
; OUTPUTS:
;     r       the updated delay values, which are to replace the current
;               values in D.
; COMMENTS:
;     This routine is very specific to the MUX sequence.  Currently two
;     MUX sequences are defined, one for 5-element and one for 6-element.
;     The channel assignments are:
;
;     5-element MUX sequence, 124, 125, 126, 456 yields:
;      abchan = [ 5,19]             ; Baselines 12 and 45
;      bcchan = [13,15,17,23]       ; Baselines 24, 25, 26, 56
;      cachan = [ 7, 9,11,21]       ; Baselines 14, 15, 16, 46
;
;     6-element MUX sequence, 457, 456, 124, 125, 167, 267 yields:
;      abchan = [ 6,12,20,24]       ; Baselines 12, 16, 26, 45
;      bcchan = [16,18,30,32,34]    ; Baselines 24, 25, 56, 57, 67
;      cachan = [ 8,10,14,22,26,28] ; Baselines 14, 15, 17, 27, 46, 47
;
; SIDE EFFECTS:
; RESTRICTIONS:
; MODIFICATION HISTORY:
;     Written 22-May-2000 by Dale Gary
;       Adapted from DLAFITSYS routine
;     10-Jan-2001  DG
;       Added A and B channel delays as d[6] and d[7], for 6-element data
;     10-Jul-2004  DG
;       Added a case for 7-element data.  This also needs to be able to handle
;       missing values.
;-
pro dlasolve, d,ss,r,new=new

  s = indgen(120)/2 - 30
  nant = n_elements(d)-2
;  if (nant gt 6) then nant = 6

  ; The following patterns apply.
  ;
  ;   The equations to be solved are:
  ;   For AB baselines
  ;         D_B - D_A + B_AB - A_AB = T_B - T_A
  ;    e.g. D_5 - D_4 + B_45 - A_45 = T_5 - T_4  for 45 baseline
  ;   For BC baselines
  ;         D_B - D_C + B_BC        = T_B - T_C
  ;    e.g. D_2 - D_4 + B_24        = T_2 - T_4  for 24 baseline
  ;   For CA baselines
  ;         D_B - D_C + A_AC        = T_A - T_C
  ;    e.g. D_1 - D_4 + A_14        = T_1 - T_4  for 14 baseline
  ;
  ; Here, the D's are the current delays from the CONFIG segment, the A's and B's are derived
  ; from the delay center shifts (SS) in a rather complicated way (see DELAY SCAN documentation),
  ; and the T's are the new delays to be solved for.

  ; The following code is very specific to the MUX sequence
  case nant of
   5: begin
     ; Set up column vector C and matrix M for 5-element data, representing the
     ; existing MUX sequence described in the header

     ; Derive the A's and B's from the delay center shifts
     a12 = ( s[ss[0] + 60.0])       ; AB baseline (12)
     b12 = (-s[ss[0] + 61.0])       ; AB baseline (12)
     a14 = ss[1]                    ; CA baseline (14)
     a15 = ss[2]                    ; CA baseline (15)
     a16 = ss[3]                    ; CA baseline (16)
     b24 = ss[4]                    ; BC baseline (24)
     b25 = ss[5]                    ; BC baseline (25)
     b26 = ss[6]                    ; BC baseline (26)
     a45 = ( s[ss[7] + 60.0])       ; AB baseline (45)
     b45 = (-s[ss[7] + 61.0])       ; AB baseline (45)
     a46 = ss[8]                    ; CA baseline (46)
     b56 = ss[9]                    ; BC baseline (56)

     ; Set up the column vector C, representing the left-hand-side of the above equations.
     ; The order is arbitrary, but MUST agree with order of matrix entries below.
     c = fltarr(10)
     c[0] = d[0] - d[2] + a14
     c[1] = d[0] - d[3] + a15
     c[2] = d[0] - d[4] + a16
     c[3] = d[1] - d[2] + b24
     c[4] = d[1] - d[3] + b25
     c[5] = d[1] - d[4] + b26
     c[6] = d[1] - d[0] + b12 - a12
     c[7] = d[2] - d[4] + a46
     c[8] = d[3] - d[4] + b56
     c[9] = d[3] - d[2] + b45 - a45

     ; Set up the matrix M, representing the right-hand-side of the above equations.
     ; These are simply the coefficients of the T's, either +/- 1.  This is an
     ; NANT x NBL matrix
     M = [[ 1, 0,-1, 0, 0], $
          [ 1, 0, 0,-1, 0], $
          [ 1, 0, 0, 0,-1], $
          [ 0, 1,-1, 0, 0], $
          [ 0, 1, 0,-1, 0], $
          [ 0, 1, 0, 0,-1], $
          [-1, 1, 0, 0, 0], $
          [ 0, 0, 1, 0,-1], $
          [ 0, 0, 0, 1,-1], $
          [ 0, 0,-1, 1, 0]]

   end
   6: begin
     if (new eq 0) then begin

     ;   The equations to be solved are:
     ;   For AB baselines
     ;         D_B - D_A + D_b - D_a + B_AB - A_AB = T_B - T_A + T_b - T_a
     ;    e.g. D_5 - D_4 + D_b - D_a + B_45 - A_45 = T_5 - T_4 + T_b - T_a for 45 baseline
     ;   For BC baselines
     ;         D_B - D_C + D_b       + B_BC        = T_B - T_C + T_b
     ;    e.g. D_2 - D_4 + D_b       + B_24        = T_2 - T_4 + T_b       for 24 baseline
     ;   For CA baselines
     ;         D_A - D_C       + D_a        + A_AC = T_A - T_C       + T_a
     ;    e.g. D_1 - D_4       + D_a        + A_14 = T_1 - T_4       + T_a for 14 baseline
     ;
     ; This is the same as above, except the original channel offsets D_a and D_b and the
     ; new channel offsets T_a and T_b have been included.

     ; Set up column vector C and matrix M for 6-element data, representing the
     ; existing MUX sequence described in the header

     ; Derive the A's and B's from the delay center shifts

     a12 = ( s[ss[0] + 60.0])       ; AB baseline (12)
     b12 = (-s[ss[0] + 61.0])       ; AB baseline (12)
     a14 = ss[1]                    ; CA baseline (14)
     a15 = ss[2]                    ; CA baseline (15)
     a16 = ( s[ss[3] + 60.0])       ; AB baseline (16)
     b16 = (-s[ss[3] + 61.0])       ; AB baseline (16)
     a17 = ss[4]                    ; CA baseline (17)
     b24 = ss[5]                    ; BC baseline (24)
     b25 = ss[6]                    ; BC baseline (25)
     a26 = ( s[ss[7] + 60.0])       ; AB baseline (26)
     b26 = (-s[ss[7] + 61.0])       ; AB baseline (26)
     a27 = ss[8]                    ; CA baseline (27)
     a45 = ( s[ss[9] + 60.0])       ; AB baseline (45)
     b45 = (-s[ss[9] + 61.0])       ; AB baseline (45)
     a46 = ss[10]                   ; CA baseline (46)
     a47 = ss[11]                   ; CA baseline (47)
     b56 = ss[12]                   ; BC baseline (56)
     b57 = ss[13]                   ; BC baseline (57)
     b67 = ss[14]                   ; BC baseline (67)

     ; Set up the column vector C, representing the left-hand-side of the above equations.
     ; The order is arbitrary, but MUST agree with order of matrix entries below.
     c = fltarr(15)
     c[0] = d[0] - d[2] + d[6] + a14
     c[1] = d[0] - d[3] + d[6] + a15
     c[2] = d[4] - d[0] + d[7] - d[6] + b16 - a16
     c[3] = d[1] - d[2] + d[7] + b24
     c[4] = d[1] - d[3] + d[7] + b25
     c[5] = d[4] - d[1] + d[7] - d[6] + b26 - a26
     c[6] = d[1] - d[0] + d[7] - d[6] + b12 - a12
     c[7] = d[2] - d[4] + d[6] + a46
     c[8] = d[3] - d[4] + d[7] + b56
     c[9] = d[3] - d[2] + d[7] - d[6] + b45 - a45
     c[10] = d[0] - d[5] + d[6] + a17
     c[11] = d[1] - d[5] + d[6] + a27
     c[12] = d[2] - d[5] + d[6] + a47
     c[13] = d[3] - d[5] + d[7] + b57
     c[14] = d[4] - d[5] + d[7] + b67

     ; Set up the matrix M, representing the right-hand-side of the above equations.
     ; These are simply the coefficients of the T's, either +/- 1.  This is an
     ; NANT x NBL matrix
     M = [[ 1, 0,-1, 0, 0, 0, 1, 0], $
          [ 1, 0, 0,-1, 0, 0, 1, 0], $
          [-1, 0, 0, 0, 1, 0,-1, 1], $
          [ 0, 1,-1, 0, 0, 0, 0, 1], $
          [ 0, 1, 0,-1, 0, 0, 0, 1], $
          [ 0,-1, 0, 0, 1, 0,-1, 1], $
          [-1, 1, 0, 0, 0, 0,-1, 1], $
          [ 0, 0, 1, 0,-1, 0, 1, 0], $
          [ 0, 0, 0, 1,-1, 0, 0, 1], $
          [ 0, 0,-1, 1, 0, 0,-1, 1], $
          [ 1, 0, 0, 0, 0,-1, 1, 0], $
          [ 0, 1, 0, 0, 0,-1, 1, 0], $
          [ 0, 0, 1, 0, 0,-1, 1, 0], $
          [ 0, 0, 0, 1, 0,-1, 0, 1], $
          [ 0, 0, 0, 0, 1,-1, 0, 1]]

     endif else begin

     ; Set up column vector C and matrix M for 6-element data, representing the
     ; existing MUX sequence described in the header

     ; Derive the A's and B's from the delay center shifts

     b12 = ss[0]                    ; BC baseline (12)
     a14 = ss[1]                    ; CA baseline (14)
     a15 = ( s[ss[2] + 60.0])       ; AB baseline (15)
     b15 = (-s[ss[2] + 61.0])       ; AB baseline (15)
     a16 = ss[3]                    ; CA baseline (16)
     a17 = ss[4]                    ; CA baseline (17)
     a24 = ( s[ss[5] + 60.0])       ; AB baseline (24)
     b24 = (-s[ss[5] + 61.0])       ; AB baseline (24)
     a25 = ( s[ss[6] + 60.0])       ; AB baseline (25)
     b25 = (-s[ss[6] + 61.0])       ; AB baseline (25)
     a26 = ss[7]                    ; CA baseline (26)
     a27 = ( s[ss[8] + 60.0])       ; AB baseline (27)
     b27 = (-s[ss[8] + 61.0])       ; AB baseline (27)
     b45 = ss[9]                    ; BC baseline (45)
     b46 = ss[10]                   ; BC baseline (46)
     a47 = ( s[ss[11] + 60.0])      ; AB baseline (47)
     b47 = (-s[ss[11] + 61.0])      ; AB baseline (47)
     b56 = ss[12]                   ; BC baseline (56)
     a57 = ss[13]                   ; CA baseline (57)
     a67 = ss[14]                   ; CA baseline (67)

     ; Set up the column vector C, representing the left-hand-side of the above equations.
     ; The order is arbitrary, but MUST agree with order of matrix entries below.
     c = fltarr(15)
     c[0] = d[1] - d[0] + d[7] + b12
     c[1] = d[2] - d[0] + d[6] + a14
     c[2] = d[3] - d[0] + d[7] - d[6] + b15 - a15
     c[3] = d[0] - d[4] + d[6] + a16
     c[4] = d[5] - d[0] + d[6] + a17
     c[5] = d[1] - d[2] + d[7] - d[6] + b24 - a24
     c[6] = d[3] - d[1] + d[7] - d[6] + b25 - a25
     c[7] = d[1] - d[4] + d[6] + a26
     c[8] = d[1] - d[5] + d[7] - d[6] + b27 - a27
     c[9] = d[2] - d[3] + d[7] + b45
     c[10] = d[2] - d[4] + d[7] + b46
     c[11] = d[2] - d[5] + d[7] - d[6] + b47 - a47
     c[12] = d[3] - d[4] + d[7] + b56
     c[13] = d[5] - d[3] + d[6] + a57
     c[14] = d[5] - d[4] + d[6] + a67

     ; Set up the matrix M, representing the right-hand-side of the above equations.
     ; These are simply the coefficients of the T's, either +/- 1.  This is an
     ; NANT x NBL matrix
     M = [[-1, 1, 0, 0, 0, 0, 0, 1], $
          [-1, 0, 1, 0, 0, 0, 1, 0], $
          [-1, 0, 0, 1, 0, 0,-1, 1], $
          [ 1, 0, 0, 0,-1, 0, 1, 0], $
          [-1, 0, 0, 0, 0, 1, 1, 0], $
          [ 0, 1,-1, 0, 0, 0,-1, 1], $
          [ 0,-1, 0, 1, 0, 0,-1, 1], $
          [ 0, 1, 0, 0,-1, 0, 1, 0], $
          [ 0, 1, 0, 0, 0,-1,-1, 1], $
          [ 0, 0, 1,-1, 0, 0, 0, 1], $
          [ 0, 0, 1, 0,-1, 0, 0, 1], $
          [ 0, 0, 1, 0, 0,-1,-1, 1], $
          [ 0, 0, 0, 1,-1, 0, 0, 1], $
          [ 0, 0, 0,-1, 0, 1, 1, 0], $
          [ 0, 0, 0, 0,-1, 1, 1, 0]]

     endelse
   end
   7: begin

     ; Set up column vector C and matrix M for 6-element data, representing the
     ; existing MUX sequence described in the header

     ; Derive the A's and B's from the delay center shifts

     b12 = ss[0]                    ; BC baseline (12)
     a14 = ( s[ss[1] + 60.0])       ; AB baseline (14)
     b14 = (-s[ss[1] + 61.0])       ; AB baseline (14)
     a15 = ( s[ss[2] + 60.0])       ; AB baseline (15)
     b15 = (-s[ss[2] + 61.0])       ; AB baseline (15)
     a16 = ss[3]                    ; CA baseline (16)
     a17 = ss[4]                    ; CA baseline (17)
     a18 = ss[5]				    ; CA baseline (18)
     a24 = ( s[ss[6] + 60.0])       ; AB baseline (24)
     b24 = (-s[ss[6] + 61.0])       ; AB baseline (24)
     a25 = ( s[ss[7] + 60.0])       ; AB baseline (25)
     b25 = (-s[ss[7] + 61.0])       ; AB baseline (25)
     a26 = ss[8]                    ; CA baseline (26)
     a27 = ( s[ss[9] + 60.0])       ; AB baseline (27)
     b27 = (-s[ss[9] + 61.0])       ; AB baseline (27)
     a28 = ss[10]					; CA baseline (28)
     b45 = ss[11]                   ; BC baseline (45)
     b46 = ss[12]                   ; BC baseline (46)
     a47 = ( s[ss[13] + 60.0])      ; AB baseline (47)
     b47 = (-s[ss[13] + 61.0])      ; AB baseline (47)
     b48 = ss[14]					; BC baseline (48)
     b56 = ss[15]                   ; BC baseline (56)
     a57 = ss[16]                   ; CA baseline (57)
     b58 = ss[17]					; BC baseline (58)
     a67 = ( s[ss[18] + 60.0])      ; AB baseline (67)
     b67 = (-s[ss[18] + 61.0])      ; AB baseline (67)
     b68 = ss[19]					; BC baseline (68)
     a78 = ss[20]					; CA baseline (78)

     ; Set up the column vector C, representing the left-hand-side of the above equations.
     ; The order is arbitrary, but MUST agree with order of matrix entries below.
     c = fltarr(21)
     c[0] = d[1] - d[0] + d[8] + b12
     c[1] = d[2] - d[0] + d[8] - d[7] + b14 - a14
     c[2] = d[3] - d[0] + d[8] - d[7] + b15 - a15
     c[3] = d[0] - d[4] + d[7] + a16
     c[4] = d[5] - d[0] + d[7] + a17
     c[5] = d[0] - d[6] + d[7] + a18
     c[6] = d[2] - d[1] + d[8] - d[7] + b24 - a24
     c[7] = d[3] - d[1] + d[8] - d[7] + b25 - a25
     c[8] = d[1] - d[4] + d[7] + a26
     c[9] = d[1] - d[5] + d[8] - d[7] + b27 - a27
     c[10] = d[1] - d[6] + d[7] + a28
     c[11] = d[2] - d[3] + d[8] + b45
     c[12] = d[2] - d[4] + d[8] + b46
     c[13] = d[2] - d[5] + d[8] - d[7] + b47 - a47
     c[14] = d[2] - d[6] + d[8] + b48
     c[15] = d[3] - d[4] + d[8] + b56
     c[16] = d[5] - d[3] + d[7] + a57
     c[17] = d[3] - d[6] + d[8] + b58
     c[18] = d[4] - d[5] + d[8] - d[7] + b67 - a67
     c[19] = d[4] - d[6] + d[8] + b68
     c[20] = d[5] - d[6] + d[7] + a78

     ; Set up the matrix M, representing the right-hand-side of the above equations.
     ; These are simply the coefficients of the T's, either +/- 1.  This is an
     ; NANT x NBL matrix
     M = [[-1, 1, 0, 0, 0, 0, 0, 0, 1], $
          [-1, 0, 1, 0, 0, 0, 0,-1, 1], $
          [-1, 0, 0, 1, 0, 0, 0,-1, 1], $
          [ 1, 0, 0, 0,-1, 0, 0, 1, 0], $
          [-1, 0, 0, 0, 0, 1, 0, 1, 0], $
          [ 1, 0, 0, 0, 0, 0,-1, 1, 0], $
          [ 0,-1, 1, 0, 0, 0, 0,-1, 1], $
          [ 0,-1, 0, 1, 0, 0, 0,-1, 1], $
          [ 0, 1, 0, 0,-1, 0, 0, 1, 0], $
          [ 0, 1, 0, 0, 0,-1, 0,-1, 1], $
          [ 0, 1, 0, 0, 0, 0,-1, 1, 0], $
          [ 0, 0, 1,-1, 0, 0, 0, 0, 1], $
          [ 0, 0, 1, 0,-1, 0, 0, 0, 1], $
          [ 0, 0, 1, 0, 0,-1, 0,-1, 1], $
          [ 0, 0, 1, 0, 0, 0,-1, 0, 1], $
          [ 0, 0, 0, 1,-1, 0, 0, 0, 1], $
          [ 0, 0, 0,-1, 0, 1, 0, 1, 0], $
          [ 0, 0, 0, 1, 0, 0,-1, 0, 1], $
          [ 0, 0, 0, 0, 1,-1, 0,-1, 1], $
          [ 0, 0, 0, 0, 1, 0,-1, 0, 1], $
          [ 0, 0, 0, 0, 0, 1,-1, 1, 0]]
     end
   else: begin
     print,'DLASOLVE: Unexpected number of antennas: ',n_elements(d)
     return
     end
  endcase

  ; Solve the equations by means of Singular-Value-Decomposition.
  svdc, m, w, u, v,/double
  n = n_elements(w)
  wp = fltarr(n,n)
  for k = 0, n-1 do $
     if abs(w(k)) ge 1.0e-5 then wp(k,k) = 1.0/w(k)

  ; This matrix equation actually provides the solution to the T's.  Note that
  ; only differences in the values of T are relevant, so the results will be
  ; shifted relative to the reference antenna 6, whose delay is always zero by
  ; definition.
  t = reform(v ## wp ## TRANSPOSE(U) ## C)

  ; Shift the results (except for the channel offsets) by the refant (Ant 6) delay (t[4])
  r = t
  r[0:nant-1] = t[0:nant-1] - t[4]

end
