function [ssh, HT, HS]=steric(So,To,S,T,D,FL,TH,L);
% STERIC density driven sea surface height perturbation (cm)
%
%        [ssh HT HS] = steric (So, To, S, T, D, FL, TH, L)
%
%        ssh   sea surface height perturbation in cm
%        HT    conversion matrix from perturbation T to ssh
%        HS    conversion matrix from perturbation S to ssh
%
%        So    vector or matrix reference salinity (ppt)
%        To    vector or matrix reference temperature (deg C)
%        S     scalar, vector or matrix perturbation salinity (ppt)
%        T     scalar, vector or matrix perturbation temperature (deg C)
%        D     vector depth (m)
%        FL    flag: if FL==1, S=S-So; T=T-To;
%        TH    vector layer thickness (m)
%        L     scalar or vector latitude (deg N)
%
%        D. Menemenlis (MIT 23 jul 97)

% check input arguments

if nargin < 5, error('need at least 5 arguments'), end
if nargin < 8, L=30; end
D=D(:);
if nargin < 7 | (nargin >=7 & isempty(TH))     % find layer thicknesses
  TH=zeros(size(D));
  for i=1:length(D), TH(i)=2*(D(i)-sum(TH(1:(i-1)))); end
end
if nargin < 6, FL=0; end

if length(T(:))>=length(S(:))
  [m n]=size(T);
  switch length(D);
    case m, T=T;
    case n, T=T'; [m n]=size(T);
    otherwise error('mismatch between T and D')
  end
  [mm nn]=size(S);
  switch mm
    case 1, switch nn
      case 1, S=S*ones(m,n);
      case m, S=S';
      otherwise error('mismatch between T and S')
    end
    case m, switch nn
      case 1, S=S*ones(1,n);
      case n, S=S;
      otherwise error('mismatch between T and S')
    end
    case n, switch nn
      case m, S=S';
      otherwise error('mismatch between T and S')
    end
  end
else
  [m n]=size(S);
  switch length(D);
    case m, S=S;
    case n, S=S'; [m n]=size(S); 
    otherwise error('mismatch between S and D')
  end
  [mm nn]=size(T);
  switch mm
    case 1, switch nn
      case 1, T=T*ones(m,n);
      case m, T=T';
      otherwise error('mismatch between T and S')
    end
    case m, switch nn
      case 1, T=T*ones(1,n);
      case n, T=T;
      otherwise error('mismatch between T and S')
    end
    case n, switch nn
      case m, T=T';
      otherwise error('mismatch between T and S')
    end
  end
end

TH=TH(:);
if length(TH)~=m, error('mismatch between T and D'), end
D=D*ones(1,n);
TH=TH*ones(1,n);

L=L(:);
switch length(L)
  case 1, L=L*ones(m,n);
  case n, L=ones(m,1)*L';
  otherwise error('mismatch between T and L')
end

[mm nn]=size(So);
switch mm
  case 1, switch nn
    case 1, So=So*ones(m,n);
    case m, So=So'*ones(1,n);
    otherwise error('mismatch between T and So')
  end
  case m, switch nn
    case 1, So=So*ones(1,n);
    case n, So=So;
    otherwise error('mismatch between T and So')
  end
  case n, switch nn
    case m, So=So';
    otherwise error('mismatch between T and So')
  end
end

[mm nn]=size(To);
switch mm
  case 1, switch nn
    case 1, error('To must be vertical profile')
    case m, To=To';
    otherwise error('mismatch between T and To')
  end
  case m, switch nn
    case 1, To=To*ones(1,n);
    case n, To=To;
    otherwise error('mismatch between T and To')
  end
  case n, switch nn
    case m, To=To';
    otherwise error('mismatch between T and To')
  end
end

if FL, S=S-So; T=T-To; end

% compute reference density
P=pressure(D,L);
Ro=rho(So,To,P);

% compute perturbation density
R=rho(S+So,T+To,P)-Ro;

% depth-integrate, divide by surface reference density, convert to cm
ssh=-100*sum(R.*TH)./Ro(1,:);

if nargout>1
  P=P(:,1); Ro=Ro(:,1); So=So(:,1); To=To(:,1); TH=TH(:,1);
  HT=0*P'; S=0*P;
  for i=1:length(P)
    T=0*P; T(i)=.01;
    R=rho(S+So,T+To,P)-Ro;
    HT(i)=-10000*sum(R.*TH)./Ro(1,:);
  end
end

if nargout>2
  HS=0*P'; T=0*P;
  for i=1:length(P)
    S=0*P; S(i)=.01;
    R=rho(S+So,T+To,P)-Ro;
    HS(i)=-10000*sum(R.*TH)./Ro(1,:);
  end
end
