From bd8240184513b98bd3f24a10b6040d30adec56fb Mon Sep 17 00:00:00 2001 From: Yves Gouriou <yves.gouriou@ird.fr> Date: Mon, 10 Mar 2008 17:08:38 +0000 Subject: [PATCH] =?UTF-8?q?D=C3=A9veloppement=20de=20la=20focntion=20d'?= =?UTF-8?q?=C3=A9talonnage.=20Ajout=20de=20la=20bilbioth=C3=A8que=20CSIRO?= =?UTF-8?q?=20=C3=A0=20SVN=20(pas=20n=C3=A9cessaire)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- @tsg_nc/tsg_platform_info.mat | Bin 689 -> 689 bytes M_Csiro/Contents.m | 63 +++ M_Csiro/README | 7 + M_Csiro/bm_bvfrq.m | 95 +++++ M_Csiro/ctd.txt | 31 ++ M_Csiro/sw_CSIRO.zip | Bin 0 -> 63480 bytes M_Csiro/sw_adtg.m | 119 ++++++ M_Csiro/sw_alpha.m | 105 +++++ M_Csiro/sw_aonb.m | 130 ++++++ M_Csiro/sw_beta.m | 126 ++++++ M_Csiro/sw_bfrq.m | 164 ++++++++ M_Csiro/sw_bfrq_mean.m | 173 ++++++++ M_Csiro/sw_bfrq_old.m | 164 ++++++++ M_Csiro/sw_c3515.m | 39 ++ M_Csiro/sw_cndr.m | 145 +++++++ M_Csiro/sw_copy.m | 165 ++++++++ M_Csiro/sw_cp.m | 176 ++++++++ M_Csiro/sw_data.mat | Bin 0 -> 8077 bytes M_Csiro/sw_dens.m | 103 +++++ M_Csiro/sw_dens0.m | 91 ++++ M_Csiro/sw_dist.m | 112 +++++ M_Csiro/sw_dpth.m | 87 ++++ M_Csiro/sw_f.m | 57 +++ M_Csiro/sw_fp.m | 90 ++++ M_Csiro/sw_g.m | 70 ++++ M_Csiro/sw_gpan.m | 126 ++++++ M_Csiro/sw_gvel.m | 62 +++ M_Csiro/sw_info.m | 30 ++ M_Csiro/sw_new.m | 64 +++ M_Csiro/sw_pden.m | 57 +++ M_Csiro/sw_pres.m | 81 ++++ M_Csiro/sw_ptmp.m | 137 ++++++ M_Csiro/sw_salds.m | 74 ++++ M_Csiro/sw_salrp.m | 69 ++++ M_Csiro/sw_salrt.m | 49 +++ M_Csiro/sw_sals.m | 79 ++++ M_Csiro/sw_salt.m | 60 +++ M_Csiro/sw_satAr.m | 95 +++++ M_Csiro/sw_satN2.m | 95 +++++ M_Csiro/sw_satO2.m | 95 +++++ M_Csiro/sw_seck.m | 167 ++++++++ M_Csiro/sw_smow.m | 69 ++++ M_Csiro/sw_svan.m | 104 +++++ M_Csiro/sw_svel.m | 181 ++++++++ M_Csiro/sw_temp.m | 59 +++ M_Csiro/sw_test.m | 600 +++++++++++++++++++++++++++ tsg_io/readTsgDataLabview.m | 1 + tsg_util/calibration.m | 39 ++ tsg_util/corTsgLinear.m | 6 +- tsg_util/corTsgMedian.m | 6 +- tsg_util/plot_Calibration.m | 19 +- tsg_util/t90TOt68.m | 7 + tsg_util/updateAdjustedVariable.m | 59 +++ tsg_util/updateTsgStruct.m | 41 +- tsgcor_GUI.m | 665 ------------------------------ tsgqc_GUI.m | 294 +++++++------ 56 files changed, 5000 insertions(+), 802 deletions(-) create mode 100644 M_Csiro/Contents.m create mode 100644 M_Csiro/README create mode 100644 M_Csiro/bm_bvfrq.m create mode 100644 M_Csiro/ctd.txt create mode 100644 M_Csiro/sw_CSIRO.zip create mode 100644 M_Csiro/sw_adtg.m create mode 100644 M_Csiro/sw_alpha.m create mode 100644 M_Csiro/sw_aonb.m create mode 100644 M_Csiro/sw_beta.m create mode 100644 M_Csiro/sw_bfrq.m create mode 100644 M_Csiro/sw_bfrq_mean.m create mode 100644 M_Csiro/sw_bfrq_old.m create mode 100644 M_Csiro/sw_c3515.m create mode 100644 M_Csiro/sw_cndr.m create mode 100644 M_Csiro/sw_copy.m create mode 100644 M_Csiro/sw_cp.m create mode 100644 M_Csiro/sw_data.mat create mode 100644 M_Csiro/sw_dens.m create mode 100644 M_Csiro/sw_dens0.m create mode 100644 M_Csiro/sw_dist.m create mode 100644 M_Csiro/sw_dpth.m create mode 100644 M_Csiro/sw_f.m create mode 100644 M_Csiro/sw_fp.m create mode 100644 M_Csiro/sw_g.m create mode 100644 M_Csiro/sw_gpan.m create mode 100644 M_Csiro/sw_gvel.m create mode 100644 M_Csiro/sw_info.m create mode 100644 M_Csiro/sw_new.m create mode 100644 M_Csiro/sw_pden.m create mode 100644 M_Csiro/sw_pres.m create mode 100644 M_Csiro/sw_ptmp.m create mode 100644 M_Csiro/sw_salds.m create mode 100644 M_Csiro/sw_salrp.m create mode 100644 M_Csiro/sw_salrt.m create mode 100644 M_Csiro/sw_sals.m create mode 100644 M_Csiro/sw_salt.m create mode 100644 M_Csiro/sw_satAr.m create mode 100644 M_Csiro/sw_satN2.m create mode 100644 M_Csiro/sw_satO2.m create mode 100644 M_Csiro/sw_seck.m create mode 100644 M_Csiro/sw_smow.m create mode 100644 M_Csiro/sw_svan.m create mode 100644 M_Csiro/sw_svel.m create mode 100644 M_Csiro/sw_temp.m create mode 100644 M_Csiro/sw_test.m create mode 100644 tsg_util/calibration.m create mode 100644 tsg_util/t90TOt68.m create mode 100644 tsg_util/updateAdjustedVariable.m delete mode 100644 tsgcor_GUI.m diff --git a/@tsg_nc/tsg_platform_info.mat b/@tsg_nc/tsg_platform_info.mat index a424c2f3209f1634c1ea2f6ba88841a870eee1d8..5a747398c5b22dccf2faa18cc587c3c494b1849b 100644 GIT binary patch delta 41 wcmdnUx{-B)k%Vu4o`P>;k%FOtf}ydMshO3rk%EzdfyKl??THEO8*5CN0P~^?O#lD@ delta 41 wcmdnUx{-B)k%U`Orh;!`k%ED_f}xR>fr*u=k%EzdfyKl??THEO8*5CN0P>CtL;wH) diff --git a/M_Csiro/Contents.m b/M_Csiro/Contents.m new file mode 100644 index 0000000..8aa83ae --- /dev/null +++ b/M_Csiro/Contents.m @@ -0,0 +1,63 @@ +% SEAWATER Library +% Version 2.0.1 22-Apr-1998 +% +% ******************************* +% * SEAWATER Library * +% * * +% * Version 2.0.1 * +% * (for Matlab 5.x) * +% * * +% * * +% * Phillip P. Morgan * +% * CSIRO * +% * * +% * Phil.Morgan@marine.csiro.au * +% ******************************* +% +% LIST OF ROUTINES: +% +% SW_NEW What's new in this version of seawater. +% +% SW_ADTG Adiabatic temperature gradient +% SW_ALPHA Thermal expansion coefficient (alpha) +% SW_AONB Calculate alpha/beta (a on b) +% SW_BETA Saline contraction coefficient (beta) +% SW_BFRQ Brunt-Vaisala Frequency Squared (N^2) +% SW_COPY Copyright and Licence file +% SW_CP Heat Capacity (Cp) of Sea Water +% SW_DENS Density of sea water +% SW_DENS0 Denisty of sea water at atmospheric pressure +% SW_DIST Distance between two lat, lon coordinates +% SW_DPTH Depth from pressure +% SW_F Coriolis factor "f" +% SW_FP Freezing Point of sea water +% SW_G Gravitational acceleration +% SW_GPAN Geopotential anomaly +% SW_GVEL Geostrophic velocity +% SW_INFO Information on the SEAWATER library. +% SW_PDEN Potential Density +% SW_PRES Pressure from depth +% SW_PTMP Potential temperature +% SW_SALS Salinity of sea water +% SW_SALT Salinity from cndr, T, P +% SW_SATAr Solubility (saturation) of Ar in seawater +% SW_SATN2 Solubility (saturation) of N2 in seawater +% SW_SATO2 Solubility (saturation) of O2 in seawater +% SW_SVAN Specific volume anomaly +% SW_SVEL Sound velocity of sea water +% SW_SMOW Denisty of standard mean ocean water (pure water) +% SW_TEMP Temperature from potential temperature +% SW_TEST Run test suite on library +% SW_VER Version number of SEAWATER library +% +% LOW LEVEL ROUTINES CALLED BY ABOVE: (also available for you to use) +% +% SW_C3515 Conductivity at (35,15,0) +% SW_CNDR Conductivity ratio R = C(S,T,P)/C(35,15,0) +% SW_SALDS Differiential dS/d(sqrt(Rt)) at constant T. +% SW_SALRP Conductivity ratio Rp(S,T,P) = C(S,T,P)/C(S,T,0) +% SW_SALRT Conductivity ratio rt(T) = C(35,T,0)/C(35,15,0) +% SW_SECK Secant bulk modulus (K) of sea water +%======================================================================= + +% Contents.m $Revision: 1.6 $ $Date: 1998/04/22 02:12:17 $ diff --git a/M_Csiro/README b/M_Csiro/README new file mode 100644 index 0000000..a2881aa --- /dev/null +++ b/M_Csiro/README @@ -0,0 +1,7 @@ +% README file $Revision: 1.1 $ $Date: 1994/10/11 02:54:21 $ +% +% SEAWATER is a toolkit of MATLAB routines for calculating the +% properties of sea water. They are a self contained library and +% are extremely easy to use. +% +% See the file sw_info.m for info on installation and usage diff --git a/M_Csiro/bm_bvfrq.m b/M_Csiro/bm_bvfrq.m new file mode 100644 index 0000000..2de700e --- /dev/null +++ b/M_Csiro/bm_bvfrq.m @@ -0,0 +1,95 @@ +function [n2, e] = bm_bvfrq( S, T, P, LAT, DP) +%************************************************************* +% ***** brunt-vaisala freq ***** +% +% uses 1980 equation of state +% +% in : +% P pressure decibars +% T temperature deg celsius (ipts-68) +% S salinity psu (pss-78) +% LAT latitude +% DP intervalle de pression (db) sur lequel est calcule n2 +% +% out : +% n2 bouyancy freq cph +% e stability 1/m +% +% r. millard feb. 1991 +% +%************************************************************* +%------ +% BEGIN +%------ + +% change call list xlat to glat & pass gravity m/s^2 +% after formulation of n. p. fofonoff & breck owen's +% + +% Calcul de la gravité +% note that sw_g expects height as argument +Z = sw_dpth(P,LAT); +gp = sw_g(LAT,-Z); +g2 = gp .* gp; +g2 = g2 * 1.e-4; + +% compute least squares estimate of specific volume anamoly gradient + +[m,n] = size(P); +n2 = zeros(size(P)); + +% Calcul du nombre d'observation sur lequel est calcule n2 + +dp = P(2)-P(1); +nobs = DP / dp; + +% Debut du profil + +for i = 1:(nobs/2) + j = 1:i+nobs/2; + [n2(i), e(i)] = cal_bvfrq( S, T, P, g2(i), gp(i), nobs, j); +end + +% Fin du profil + +for i = m-(nobs/2):m + j = i-nobs/2:m; + [n2(i), e(i)] = cal_bvfrq( S, T, P, g2(i), gp(i), nobs, j); +end + +% Profil + +for i = (nobs/2+1):m-(nobs/2+1) + j = i-nobs/2:i+nobs/2; + [n2(i), e(i)] = cal_bvfrq( S, T, P, g2(i), gp(i), nobs, j); +end + +% Corps du calcul + +function [n2, e] = cal_bvfrq( S, T, P, g2, gp, nobs, j) + +% default gravity & rad/sec to cph conversion +% +radsec = 572.9578; + + pav = mean(P(j)); + data = sw_svan( S(j), sw_ptmp( S(j), T(j), P(j), pav), pav); + cxy = sum( data .* (P(j)-pav) ); + cy = sum( data ); + cxx = sum( (P(j)-pav).*(P(j)-pav) ); + + sigma = sw_pden(S(j), sw_ptmp( S(j), T(j), P(j), pav), P(j), pav); + + a0 = cxy/cxx; + + v350p = 1./sigma - data; + vbar = v350p(end) + cy/(nobs+1); + dvdp = a0; + + e = -g2*dvdp/(vbar)^2; + n2 = radsec*sqrt(abs(e))*sign(e); + + % define stability parameter units (1/m) + e = e/gp; + + return \ No newline at end of file diff --git a/M_Csiro/ctd.txt b/M_Csiro/ctd.txt new file mode 100644 index 0000000..3167e6f --- /dev/null +++ b/M_Csiro/ctd.txt @@ -0,0 +1,31 @@ + 0 25.698 35.221 + 10 26.673 36.106 + 20 26.678 36.106 + 30 26.676 36.107 + 50 24.528 36.561 + 75 22.753 36.614 + 100 21.427 36.637 + 125 20.633 36.627 + 150 19.522 36.558 + 200 18.798 36.555 + 250 18.431 36.537 + 300 18.189 36.526 + 400 17.726 36.477 + 500 17.165 36.381 + 600 15.592 36.105 + 700 13.458 35.766 + 800 11.109 35.437 + 900 8.798 35.178 +1000 6.292 35.044 +1100 5.249 35.004 +1200 4.813 34.995 +1300 4.554 34.986 +1400 4.357 34.977 +1500 4.245 34.975 +1750 4.028 34.973 +2000 3.852 34.975 +2500 3.424 34.968 +3000 2.963 34.946 +3500 2.462 34.920 +4000 2.259 34.904 +4327 2.221 34.896 \ No newline at end of file diff --git a/M_Csiro/sw_CSIRO.zip b/M_Csiro/sw_CSIRO.zip new file mode 100644 index 0000000000000000000000000000000000000000..70b24762db14d6795222e1fac3379bb8302ed29d GIT binary patch literal 63480 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�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 P)IhEPE5`Wb`Ir9(8l|cb literal 0 HcmV?d00001 diff --git a/M_Csiro/sw_adtg.m b/M_Csiro/sw_adtg.m new file mode 100644 index 0000000..9badeac --- /dev/null +++ b/M_Csiro/sw_adtg.m @@ -0,0 +1,119 @@ + +function ADTG = sw_adtg(S,T,P) + +% SW_ADTG Adiabatic temperature gradient +%=========================================================================== +% SW_ADTG $Revision: 1.4 $ $Date: 1994/10/10 04:16:37 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% adtg = sw_adtg(S,T,P) +% +% DESCRIPTION: +% Calculates adiabatic temperature gradient as per UNESCO 1983 routines. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% ADTG = adiabatic temperature gradient [degree_C/db] +% +% AUTHOR: Phil Morgan 92-04-03 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater. Unesco Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39 +% +% Bryden, H. 1973. +% "New Polynomials for thermal expansion, adiabatic temperature gradient +% and potential temperature of sea water." +% DEEP-SEA RES., 1973, Vol20,401-408. +%========================================================================= + +%------------- +% CHECK INPUTS +%------------- +if nargin ~= 3 + error('sw_adtg.m: Must pass 3 parameters ') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +%------------- +% BEGIN +%------------- +a0 = 3.5803E-5; +a1 = +8.5258E-6; +a2 = -6.836E-8; +a3 = 6.6228E-10; + +b0 = +1.8932E-6; +b1 = -4.2393E-8; + +c0 = +1.8741E-8; +c1 = -6.7795E-10; +c2 = +8.733E-12; +c3 = -5.4481E-14; + +d0 = -1.1351E-10; +d1 = 2.7759E-12; + +e0 = -4.6206E-13; +e1 = +1.8676E-14; +e2 = -2.1687E-16; + +ADTG = a0 + (a1 + (a2 + a3.*T).*T).*T ... + + (b0 + b1.*T).*(S-35) ... + + ( (c0 + (c1 + (c2 + c3.*T).*T).*T) + (d0 + d1.*T).*(S-35) ).*P ... + + ( e0 + (e1 + e2.*T).*T ).*P.*P; + +if Transpose + ADTG = ADTG'; +end %if + +return +%========================================================================== + diff --git a/M_Csiro/sw_alpha.m b/M_Csiro/sw_alpha.m new file mode 100644 index 0000000..828bf3b --- /dev/null +++ b/M_Csiro/sw_alpha.m @@ -0,0 +1,105 @@ + +function [ALPHA] = sw_alpha(S, T, P, keyword) + +% SW_ALPHA Thermal expansion coefficient (alpha) +%================================================================ +% SW_ALPHA $Revision: 1.6 $ $Date: 1998/04/21 05:42:10 $ +% Copyright (C) CSIRO, Nathan Bindoff 1993. +% +% USAGE: [ALPHA] = alpha(S, T, P, keyword) +% +% [ALPHA] = alpha(S, T, P, 'temp') %default +% [ALPHA] = alpha(S, PTMP, P, 'ptmp') +% +% DESCRIPTION: +% A function to calculate the thermal expansion coefficient. +% +% INPUT: +% S = salinity [psu (PSS-78) ] +% * PTMP = potential temperature [degree C (IPTS-68)] +% * T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% keyword = optional string to identify if temp or ptmp passed. +% = No argument defaults to 'temp' +% = 'temp' assumes (S,T,P) passed. Will execute slower +% as ptmp will be calculated internally. +% = 'ptmp' assumes (S,PTMP,P) passed. Will execute faster. +% +% OUTPUT: +% ALPHA = Thermal expansion coeff (alpha) [degree_C.^-1] +% +% AUTHOR: N.L. Bindoff 1993 +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCE: +% McDougall, T.J. 1987. "Neutral Surfaces" +% Journal of Physical Oceanography vol 17 pages 1950-1964, +% +% CHECK VALUE: +% See sw_beta.m amd sw_aonb.m +%================================================================ + +% Modifications +% 93-04-22. Phil Morgan, Help display modified to suit library +% 93-04-23. Phil Morgan, Input argument checking +% 94-10-15. Phil Morgan, Pass S,T,P and keyword for 'ptmp' + + +% CHECK INPUT ARGUMENTS +if ~(nargin==3 | nargin==4) + error('sw_alpha.m: requires 3 or 4 input arguments') +end %if +if nargin == 3 + keyword = 'temp'; +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +% BEGIN + +ALPHA = sw_aonb(S,T,P,keyword).*sw_beta(S,T,P,keyword); + +return +%------------------------------------------------------------------------ + diff --git a/M_Csiro/sw_aonb.m b/M_Csiro/sw_aonb.m new file mode 100644 index 0000000..e1f3370 --- /dev/null +++ b/M_Csiro/sw_aonb.m @@ -0,0 +1,130 @@ + +function [AONB]= aonb(S, T, P, keyword) + +% SW_AONB Calculate alpha/beta (a on b) +%================================================================ +% SW_AONB $Revision: 1.5 $ $Date: 1994/11/15 04:10:45 $ +% Copyright (C) CSIRO, Nathan Bindoff 1993 +% +% USAGE: [AONB] = aonb(S, T, P, {keyword} ) +% +% [AONB] = aonb(S, T, P, 'temp' ) %default +% [AONB] = aonb(S, PTMP, P, 'ptmp' ) +% +% DESCRIPTION +% Calculate alpha/beta. See sw_alpha.m and sw_beta.m +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% * PTMP = potential temperature [degree C (IPTS-68)] +% * T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% keyword = optional string to identify if temp or ptmp passed. +% = No argument defaults to 'temp' +% = 'temp' assumes (S,T,P) passed. Will execute slower +% as ptmp will be calculated internally. +% = 'ptmp' assumes (S,PTMP,P) passed. Will execute faster. +% +% OUTPUT +% AONB = alpha/beta [psu/degree_C] +% +% AUTHOR: N.L. Bindoff 1993 +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCE: +% McDougall, T.J. 1987. "Neutral Surfaces" +% Journal of Physical Oceanography vol 17 pages 1950-1964, +% +% CHECK VALUE: +% aonb=0.34763 psu C^-1 at S=40.0 psu, ptmp=10.0 C, p=4000 db +%================================================================ + +% Modifications +% 93-04-22. Phil Morgan, Help display modified to suit library +% 93-04-23. Phil Morgan, Input argument checking +% 94-10-15. Phil Morgan, Pass S,T,P and keyword for 'ptmp' + +% CHECK INPUT ARGUMENTS +if ~(nargin==3 | nargin==4) + error('sw_aonb.m: requires 3 input arguments') +end %if +if nargin == 3 + keyword = 'temp'; +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +% ENSURE WE USE PTMP IN CALCULATIONS +if strcmp(lower(keyword),'ptmp') + % already have ptmp +else + T = sw_ptmp(S,T,P,0); % now have ptmp +end %if + +% BEGIN + c1=fliplr([ 0.665157e-1, 0.170907e-1, ... + -0.203814e-3, 0.298357e-5, ... + -0.255019e-7]); + c2=fliplr([ 0.378110e-2, ... + -0.846960e-4]); + c2a=fliplr([0.0 -0.164759e-6, ... + -0.251520e-11]); + c3=[-0.678662e-5]; + c4=fliplr([+0.380374e-4, -0.933746e-6, ... + +0.791325e-8]); + c5=[0.512857e-12]; + c6=[-0.302285e-13]; +% +% Now calaculate the thermal expansion saline contraction ratio adb +% + [m,n] = size(S); + sm35 = S-35.0*ones(m,n); + AONB = polyval(c1,T) + sm35.*(polyval(c2,T)... + + polyval(c2a,P)) ... + + sm35.^2*c3 + P.*polyval(c4,T) ... + + c5*(P.^2).*(T.^2) + c6*P.^3; + +return +%---------------------------------------------------------------------- + diff --git a/M_Csiro/sw_beta.m b/M_Csiro/sw_beta.m new file mode 100644 index 0000000..3be9894 --- /dev/null +++ b/M_Csiro/sw_beta.m @@ -0,0 +1,126 @@ + +function [BETA] = sw_beta(S, T, P, keyword) + +% SW_BETA Saline contraction coefficient (beta) +%======================================================================== +% SW_BETA $Revision: 1.4 $ $Date: 1994/11/15 04:10:05 $ +% % Copyright (C) CSIRO, Nathan Bindoff 1993. +% +% USAGE: [BETA] = sw_beta(S, T, P, {keyword} ) +% +% [BETA] = sw_beta(S, T, P, 'temp') %default +% [BETA] = sw_beta(S, PTMP, P, 'ptmp') +% +% DESCRIPTION +% The saline contraction coefficient as defined by T.J. McDougall. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% * PTMP = potential temperature [degree C (IPTS-68)] +% * T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% keyword = optional string to identify if temp or ptmp passed. +% = No argument defaults to 'temp' +% = 'temp' assumes (S,T,P) passed. Will execute slower +% as ptmp will be calculated internally. +% = 'ptmp' assumes (S,PTMP,P) passed. Will execute faster. +% +% OUTPUT +% BETA = Saline Contraction Coefficient [psu.^-1] +% +% AUTHOR: N.L. Bindoff 1993 +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCE: +% McDougall, T.J. 1987. "Neutral Surfaces" +% Journal of Physical Oceanography vol 17 pages 1950-1964, +% +% CHECK VALUE: +% beta=0.72088e-3 psu.^-1 at S=40.0 psu, ptmp = 10.0 C, p=4000 db +%======================================================================== + +% Modifications +% 93-04-22. Phil Morgan, Help display modified to suit library +% 93-04-23. Phil Morgan, Input argument checking +% 94-10-15. Phil Morgan, Pass S,T,P and keyword for 'ptmp' + +% CHECK INPUT ARGUMENTS +if ~(nargin==3 | nargin==4) + error('sw_beta.m: requires 3 or 4 input arguments') +end %if +if nargin == 3 + keyword = 'temp'; +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +% ENSURE WE USE PTMP IN CALCULATIONS +if strcmp(lower(keyword),'ptmp') + % already have ptmp +else + T = sw_ptmp(S,T,P,0); % now have ptmp +end %if + +% BEGIN + + c1=fliplr([ 0.785567e-3, -0.301985e-5 ... + 0.555579e-7, -0.415613e-9]); + c2=fliplr([ -0.356603e-6, 0.788212e-8]); + c3=fliplr([0.0 0.408195e-10, -0.602281e-15]); + c4=[0.515032e-8]; + c5=fliplr([-0.121555e-7, 0.192867e-9, -0.213127e-11]); + c6=fliplr([0.176621e-12 -0.175379e-14]); + c7=[0.121551e-17]; +% +% Now calaculate the thermal expansion saline contraction ratio adb +% + [m,n] = size(S); + sm35 = S-35*ones(m,n); + BETA = polyval(c1,T) + sm35.*(polyval(c2,T) + ... + polyval(c3,P)) + c4*(sm35.^2) + ... + P.*polyval(c5,T) + (P.^2).*polyval(c6,T) ... + +c7*( P.^3); + +return +%------------------------------------------------------------------------ diff --git a/M_Csiro/sw_bfrq.m b/M_Csiro/sw_bfrq.m new file mode 100644 index 0000000..1c3d262 --- /dev/null +++ b/M_Csiro/sw_bfrq.m @@ -0,0 +1,164 @@ + +function [n2,q,p_ave] = sw_bfrq(S,T,P,LAT) + +% SW_BFRQ Brunt-Vaisala Frequency Squared (N^2) +%=========================================================================== +% SW_BFRQ $Revision: 1.12 $ $Date: 1994/11/15 04:13:34 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: [bfrq,vort,p_ave] = sw_bfrq(S,T,P,{LAT}) +% +% DESCRIPTION: +% Calculates Brunt-Vaisala Frequency squared (N^2) at the mid depths +% from the equation, +% +% -g d(pdens) +% N2 = ----- x -------- +% pdens d(z) +% +% Also returns Potential Vorticity from q = f*N2/g. +% +% INPUT: (all must have same dimensions MxN) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% +% OPTIONAL: +% LAT = Latitude in decimal degrees north [-90..+90] +% May have dimensions 1x1 or 1xn where S(mxn). +% (Will use sw_g instead of the default g=9.8 m^2/s) +% (Will also calc d(z) instead of d(p) in numerator) +% OUTPUT: +% bfrq = Brunt-Vaisala Frequency squared (M-1xN) [s^-2] +% vort = Planetary Potential Vorticity (M-1xN) [(ms)^-1] +% (if isempty(LAT) vort=NaN ) +% p_ave = Mid pressure between P grid (M-1xN) [db] +% +% AUTHOR: Phil Morgan 93-06-24 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% A.E. Gill 1982. p.54 eqn 3.7.15 +% "Atmosphere-Ocean Dynamics" +% Academic Press: New York. ISBN: 0-12-283522-0 +% +% Jackett, D.R. and McDougall, T.J. 1994. +% Minimal adjustment of hydrographic properties to achieve static +% stability. submitted J.Atmos.Ocean.Tech. +% +% Greg Johnson (gjohnson@pmel.noaa.gov) +% added potential vorticity calcuation +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_dens.m sw_pden.m + +%$Id: sw_bfrq.M,v 1.12 1994/11/15 04:13:34 morgan Exp $ + +%------------- +% CHECK INPUTS +%------------- +if ~(nargin==3 | nargin==4) + error('sw_bfrq.m: Must pass 3 or 4 parameters ') +end %if + +if nargin == 3 + LAT = []; +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +% IF LAT PASSED THEN VERIFY DIMENSIONS +if ~isempty(LAT) + [mL,nL] = size(LAT); + if mL==1 & nL==1 + LAT = LAT*ones(size(S)); + %end % Je commente le end et remplace le if suivant par elseif + + elseif (ms~=mL) | (ns~=nL) % S & LAT are not the same shape + if (ns==nL) & (mL==1) % copy LATS down each column + LAT = LAT( ones(1,ms), : ); % s.t. dim(S)==dim(LAT) + else + error('sw_bfrq.m: Inputs arguments have wrong dimensions') + end %if + end %if +end %if + + + +%------ +% BEGIN +%------ +if ~isempty(LAT) + % note that sw_g expects height as argument + Z = sw_dpth(P,LAT); + g = sw_g(LAT,-Z); + f = sw_f(LAT); +else + Z = P; + g = 9.8*ones(size(P)); + f = NaN*ones(size(P)); +end %if + +[m,n] = size(P); +iup = 1:m-1; +ilo = 2:m; +p_ave = (P(iup,:)+P(ilo,:) )/2; +pden_up = sw_pden(S(iup,:),T(iup,:),P(iup,:),p_ave); +pden_lo = sw_pden(S(ilo,:),T(ilo,:),P(ilo,:),p_ave); + +mid_pden = (pden_up + pden_lo )/2; +dif_pden = pden_up - pden_lo; +mid_g = (g(iup,:)+g(ilo,:))/2; +dif_z = diff(Z); +n2 = -mid_g .* dif_pden ./ (dif_z .* mid_pden); + +mid_f = f(iup,:); +q = mid_f .* dif_pden ./ (dif_z .* mid_pden); + +if Transpose + n2 = n2'; + q = q'; + p_ave = p_ave'; +end %if +return +%------------------------------------------------------------------- diff --git a/M_Csiro/sw_bfrq_mean.m b/M_Csiro/sw_bfrq_mean.m new file mode 100644 index 0000000..816a387 --- /dev/null +++ b/M_Csiro/sw_bfrq_mean.m @@ -0,0 +1,173 @@ + +function [n2,q,p_ave] = sw_bfrq_mean(S,T,P,LAT) + +% SW_BFRQ Brunt-Vaisala Frequency Squared (N^2) +%=========================================================================== +% SW_BFRQ $Revision: 1.12 $ $Date: 1994/11/15 04:13:34 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: [bfrq,vort,p_ave] = sw_bfrq(S,T,P,{LAT}) +% +% DESCRIPTION: +% Calculates Brunt-Vaisala Frequency squared (N^2) at the mid depths +% from the equation, +% +% -g d(pdens) +% N2 = ----- x -------- +% pdens d(z) +% +% Also returns Potential Vorticity from q = f*N2/g. +% +% INPUT: (all must have same dimensions MxN) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% +% OPTIONAL: +% LAT = Latitude in decimal degrees north [-90..+90] +% May have dimensions 1x1 or 1xn where S(mxn). +% (Will use sw_g instead of the default g=9.8 m^2/s) +% (Will also calc d(z) instead of d(p) in numerator) +% OUTPUT: +% bfrq = Brunt-Vaisala Frequency squared (M-1xN) [s^-2] +% vort = Planetary Potential Vorticity (M-1xN) [(ms)^-1] +% (if isempty(LAT) vort=NaN ) +% p_ave = Mid pressure between P grid (M-1xN) [db] +% +% AUTHOR: Phil Morgan 93-06-24 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% A.E. Gill 1982. p.54 eqn 3.7.15 +% "Atmosphere-Ocean Dynamics" +% Academic Press: New York. ISBN: 0-12-283522-0 +% +% Jackett, D.R. and McDougall, T.J. 1994. +% Minimal adjustment of hydrographic properties to achieve static +% stability. submitted J.Atmos.Ocean.Tech. +% +% Greg Johnson (gjohnson@pmel.noaa.gov) +% added potential vorticity calcuation +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_dens.m sw_pden.m + +%$Id: sw_bfrq.M,v 1.12 1994/11/15 04:13:34 morgan Exp $ + +%------------- +% CHECK INPUTS +%------------- +if ~(nargin==3 | nargin==4) + error('sw_bfrq.m: Must pass 3 or 4 parameters ') +end %if + +if nargin == 3 + LAT = []; +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +% IF LAT PASSED THEN VERIFY DIMENSIONS +if ~isempty(LAT) + [mL,nL] = size(LAT); + if mL==1 & nL==1 + LAT = LAT*ones(size(S)); + %end % Je commente le end et remplace le if suivant par elseif + + elseif (ms~=mL) | (ns~=nL) % S & LAT are not the same shape + if (ns==nL) & (mL==1) % copy LATS down each column + LAT = LAT( ones(1,ms), : ); % s.t. dim(S)==dim(LAT) + else + error('sw_bfrq.m: Inputs arguments have wrong dimensions') + end %if + end %if +end %if + + + +%------ +% BEGIN +%------ +if ~isempty(LAT) + % note that sw_g expects height as argument + Z = sw_dpth(P,LAT); + g = sw_g(LAT,-Z); + f = sw_f(LAT); +else + Z = P; + g = 9.8*ones(size(P)); + f = NaN*ones(size(P)); +end %if + +[m,n] = size(P); +iup = 1:m-1; +ilo = 2:m; +p_ave = (P(iup,:)+P(ilo,:) )/2; +pden_up = sw_pden(S(iup,:),T(iup,:),P(iup,:),p_ave); +pden_lo = sw_pden(S(ilo,:),T(ilo,:),P(ilo,:),p_ave); + +mid_pden = (pden_up + pden_lo )/2; +dif_pden = pden_up - pden_lo; +mid_g = (g(iup,:)+g(ilo,:))/2; +dif_z = diff(Z); + +% Calcul des moyennes +% ------------------- +Mmid_pden = mean(mid_pden,2); +Mdif_pden = mean(dif_pden,2); +Mmid_g = mid_g(:,1); +Mdif_z = dif_z(:,1); + +n2 = -Mmid_g .* Mdif_pden ./ (Mdif_z .* Mmid_pden); + +mid_f = f(iup,:); +Mmid_f = mid_f(:,1); +q = Mmid_f .* Mdif_pden ./ (Mdif_z .* Mmid_pden); + +if Transpose + n2 = n2'; + q = q'; + p_ave = p_ave'; +end %if +return +%------------------------------------------------------------------- diff --git a/M_Csiro/sw_bfrq_old.m b/M_Csiro/sw_bfrq_old.m new file mode 100644 index 0000000..72714c5 --- /dev/null +++ b/M_Csiro/sw_bfrq_old.m @@ -0,0 +1,164 @@ + +function [n2,q,p_ave] = sw_bfrq(S,T,P,LAT) + +% SW_BFRQ Brunt-Vaisala Frequency Squared (N^2) +%=========================================================================== +% SW_BFRQ $Revision: 1.12 $ $Date: 1994/11/15 04:13:34 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: [bfrq,vort,p_ave] = sw_bfrq(S,T,P,{LAT}) +% +% DESCRIPTION: +% Calculates Brunt-Vaisala Frequency squared (N^2) at the mid depths +% from the equation, +% +% -g d(pdens) +% N2 = ----- x -------- +% pdens d(z) +% +% Also returns Potential Vorticity from q = f*N2/g. +% +% INPUT: (all must have same dimensions MxN) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% +% OPTIONAL: +% LAT = Latitude in decimal degrees north [-90..+90] +% May have dimensions 1x1 or 1xn where S(mxn). +% (Will use sw_g instead of the default g=9.8 m^2/s) +% (Will also calc d(z) instead of d(p) in numerator) +% OUTPUT: +% bfrq = Brunt-Vaisala Frequency squared (M-1xN) [s^-2] +% vort = Planetary Potential Vorticity (M-1xN) [(ms)^-1] +% (if isempty(LAT) vort=NaN ) +% p_ave = Mid pressure between P grid (M-1xN) [db] +% +% AUTHOR: Phil Morgan 93-06-24 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% A.E. Gill 1982. p.54 eqn 3.7.15 +% "Atmosphere-Ocean Dynamics" +% Academic Press: New York. ISBN: 0-12-283522-0 +% +% Jackett, D.R. and McDougall, T.J. 1994. +% Minimal adjustment of hydrographic properties to achieve static +% stability. submitted J.Atmos.Ocean.Tech. +% +% Greg Johnson (gjohnson@pmel.noaa.gov) +% added potential vorticity calcuation +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_dens.m sw_pden.m + +%$Id: sw_bfrq.M,v 1.12 1994/11/15 04:13:34 morgan Exp $ + +%------------- +% CHECK INPUTS +%------------- +if ~(nargin==3 | nargin==4) + error('sw_bfrq.m: Must pass 3 or 4 parameters ') +end %if + +if nargin == 3 + LAT = []; +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +% IF LAT PASSED THEN VERIFY DIMENSIONS +if ~isempty(LAT) + [mL,nL] = size(LAT); + if mL==1 & nL==1 + LAT = LAT*ones(size(S)); + end %if + + if (ms~=mL) | (ns~=nL) % S & LAT are not the same shape + if (ns==nL) & (mL==1) % copy LATS down each column + LAT = LAT( ones(1,ms), : ); % s.t. dim(S)==dim(LAT) + else + error('sw_bfrq.m: Inputs arguments have wrong dimensions') + end %if + end %if +end %if + + + +%------ +% BEGIN +%------ +if ~isempty(LAT) + % note that sw_g expects height as argument + Z = sw_dpth(P,LAT); + g = sw_g(LAT,-Z); + f = sw_f(LAT); +else + Z = P; + g = 9.8*ones(size(P)); + f = NaN*ones(size(P)); +end %if + +[m,n] = size(P); +iup = 1:m-1; +ilo = 2:m; +p_ave = (P(iup,:)+P(ilo,:) )/2; +pden_up = sw_pden(S(iup,:),T(iup,:),P(iup,:),p_ave); +pden_lo = sw_pden(S(ilo,:),T(ilo,:),P(ilo,:),p_ave); + +mid_pden = (pden_up + pden_lo )/2; +dif_pden = pden_up - pden_lo; +mid_g = (g(iup,:)+g(ilo,:))/2; +dif_z = diff(Z); +n2 = -mid_g .* dif_pden ./ (dif_z .* mid_pden); + +mid_f = f(iup,:); +q = mid_f .* dif_pden ./ (dif_z .* mid_pden); + +if Transpose + n2 = n2'; + q = q'; + p_ave = p_ave'; +end %if +return +%------------------------------------------------------------------- diff --git a/M_Csiro/sw_c3515.m b/M_Csiro/sw_c3515.m new file mode 100644 index 0000000..0dd8a57 --- /dev/null +++ b/M_Csiro/sw_c3515.m @@ -0,0 +1,39 @@ + +function c3515 = sw_c3515() + +% SW_C3515 Conductivity at (35,15,0) +%========================================================================= +% SW_c3515 $Revision: 1.4 $ $Date: 1994/10/10 04:35:22 $ +% % Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: c3515 = sw_c3515 +% +% DESCRIPTION: +% Returns conductivity at S=35 psu , T=15 C [ITPS 68] and P=0 db). +% +% INPUT: (none) +% +% OUTPUT: +% c3515 = Conductivity [mmho/cm == mS/cm] +% +% AUTHOR: Phil Morgan 93-04-17 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% R.C. Millard and K. Yang 1992. +% "CTD Calibration and Processing Methods used by Woods Hole +% Oceanographic Institution" Draft April 14, 1992 +% (Personal communication) +%========================================================================= + +% CALLER: none +% CALLEE: none +% + +c3515 = 42.914; + +return +%------------------------------------------------------------------------- diff --git a/M_Csiro/sw_cndr.m b/M_Csiro/sw_cndr.m new file mode 100644 index 0000000..0060af8 --- /dev/null +++ b/M_Csiro/sw_cndr.m @@ -0,0 +1,145 @@ + +function R = sw_cndr(S,T,P) + +% SW_CNDR Conductivity ratio R = C(S,T,P)/C(35,15,0) +%========================================================================= +% SW_CNDR $Revision: 1.3 $ $Date: 1994/10/10 04:36:58 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: cndr = sw_cndr(S,T,P) +% +% DESCRIPTION: +% Calculates conductivity ratio from S,T,P. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% cndr = Conductivity ratio R = C(S,T,P)/C(35,15,0) [no units] +% +% AUTHOR: Phil Morgan 93-04-21 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_salds.m sw_sals.m sw_salrt.m + +%-------------- +% check inputs +%------------- +if nargin~=3 + error('sw_cndr.m: must have 3 input arguments') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +%------- +% BEGIN +%------- +del_T = T - 15; + +for i = 1:ms + for j = 1:ns + %--------------------------------------------------------------------- + % DO A NEWTON-RAPHSON ITERATION FOR INVERSE INTERPOLATION OF Rt FROM S. + %--------------------------------------------------------------------- + S_loop = S(i,j); % S in the loop + T_loop = T(i,j); % T in the loop + Rx_loop = sqrt(S_loop/35.0); % first guess at Rx = sqrt(Rt) + SInc = sw_sals(Rx_loop.*Rx_loop,T_loop); % S INCrement (guess) from Rx + iloop = 0; + end_loop = 0; + while ~end_loop + Rx_loop = Rx_loop + (S_loop - SInc)./sw_salds(Rx_loop,del_T(i,j)); + SInc = sw_sals(Rx_loop.*Rx_loop,T_loop); + iloop = iloop + 1; + dels = abs(SInc-S_loop); + if (dels>1.0e-4 & iloop<10) + end_loop = 0; + else + end_loop = 1; + end %if + end %while + + Rx(i,j) = Rx_loop; + + end %for j +end %for i + +%------------------------------------------------------ +% ONCE Rt FOUND, CORRESPONDING TO EACH (S,T) EVALUATE R +%------------------------------------------------------ +% eqn(4) p.8 Unesco 1983 + +d1 = 3.426e-2; +d2 = 4.464e-4; +d3 = 4.215e-1; +d4 = -3.107e-3; + +e1 = 2.070e-5; +e2 = -6.370e-10; +e3 = 3.989e-15; + +A = (d3 + d4.*T); +B = 1 + d1.*T + d2.*T.^2; +C = P.*(e1 + e2.*P + e3.*P.^2); + +% eqn(6) p.9 UNESCO 1983. +Rt = Rx.*Rx; +rt = sw_salrt(T); +Rtrt = rt.*Rt; +D = B - A.*rt.*Rt; +E = rt.*Rt.*A.*(B+C); +R = sqrt(abs(D.^2+4*E)) - D; +R = 0.5*R./A; + +return +%----------------------------------------------------------------------- + diff --git a/M_Csiro/sw_copy.m b/M_Csiro/sw_copy.m new file mode 100644 index 0000000..69a0229 --- /dev/null +++ b/M_Csiro/sw_copy.m @@ -0,0 +1,165 @@ +% SW_COPY Copyright and licence information on SEAWATER library. +% ================================================================= +% SW_COPY $Revision: 1.6 $ $Date: 1994/12/06 03:05:54 $ +% Copyright (C) Phil Morgan 1993 +% +% SOFTWARE LICENCE AGREEMENT +% +% 1.0 Grant of Licence +% +% 1.1 The CSIRO Division of Oceanography (herein referred to as +% "CSIRO") hereby grants you (hereinafter referred to as +% the "Licencee"), subject to the Licencee agreeing to +% comply with the terms and conditions of this Agreement, a +% non-transferable, non-exclusive licence to use the +% computer programs described in this document (hereinafter +% referred to as the "Software") for the purpose of +% the Licencee's computing activity. +% +% 1.2 CSIRO hereby grants the Licencee the right to make copies +% of the Software for the purpose of the Licencee's +% computing activity only. +% +% 1.3 The benefit of the rights granted to the Licencee by the +% Licence and this Agreement generally shall be personal to +% the Licencee and the Licencee shall not mortgage, charge, +% assign, rent, lease, sell or otherwise dispose of or +% transfer the same or any part to any third party. +% +% 1.4 Unless otherwise agreed in writing or provided for in +% this Agreement, CSIRO shall be under no obligation or +% responsibility to provide the Licencee with any training, +% maintenance services, enhancements or updates of the +% Software or any services whatsoever. +% +% 2.0 Acknowledgment by the Licencee +% +% 2.1 The Licencee acknowledges and agrees that it shall not: +% +% (i) sell, let for hire or by way of trade, offer or +% exhibit or expose for sale or hire or otherwise +% distribute the Software for the purposes of trade or +% any other purpose; +% +% (ii) authorise or assist any third person to do any +% of the acts set out in (i) above; +% +% (iii) modify the Software source code without advising +% CSIRO. +% +% 2.2 The Licencee agrees that: +% +% (a) CSIRO is the owner of all copyright and other +% Intellectual Property Rights subsisting in the +% Software; +% +% (b) this document must be properly cited in any +% publication reporting results derived from this +% document or obtained from application and use of this +% software. Any of the Licencee's documentation +% describing results generated by the Licencee's +% use of the Software will contain an acknowledgement +% of CSIRO's ownership of the Software; +% +% (c) CSIRO reserves all rights in the Software other than +% the rights granted to the Licencee by this +% Agreement; +% +% (d) each item of the Software will display a banner +% summarising the terms of this Agreement and +% acknowledging the source of the Software, and the +% contents of a banner will not be modified and its +% display will not be inactivated by the Licencee +% without the approval of CSIRO. +% +% 3.0 Indemnity +% +% 3.1 To the full extent permitted by law, CSIRO excludes any +% and all liability in respect of any loss or damage, +% whether personal (includes death or illness) or of +% property and whether direct, consequential or special +% (including consequential financial loss or damage) of +% the Licencee, its officers, agents and employees or any +% third party howsoever caused, which may be suffered or +% incurred or which may arise directly or indirectly in +% respect of or arising out of the Licencee's use or +% inability to use the Software or the failure or omission +% on the part of CSIRO to comply with the conditions and +% warranties under this Licence Agreement. Insofar as +% liability for loss or damages under or pursuant to such +% legislation cannot be excluded, CSIRO's liability for +% loss or damages shall be limited to the amount of One +% Dollar ($1.00). +% +% 3.2 CSIRO make no warranties, expressed or implied, and +% excludes all other warranties representations, terms or +% conditions, whether express or implied, oral or written, +% statutory or otherwise, relating in any way to the +% Software, or to this Agreement, including any implied +% warranty of merchantability or of fitness for particular +% purpose. To the full extent permitted by the law of the +% Commonwealth of Australia or the laws of any State or +% Territory of Australia, any conditions or warranties +% imposed by such legislation are hereby excluded. In so +% far as liability under or pursuant to such legislation +% may not be excluded, CSIRO's liability to the Licencee +% pursuant to this Agreement shall be limited as set out in +% clause 3.1 hereof. +% +% 3.3 The Licencee acknowledges and agrees that the Software +% was developed for CSIRO research purposes and may have +% inherent defects, errors or deficiencies, and that it is +% the responsibility of the Licencee to make its own +% assessment of the suitability of the Software for the +% purpose of the Licencee's computing activity. The +% Licencee will use the Software, and advice, opinions or +% information supplied by CSIRO, its officers, employees or +% agents concerning the Software at the Licencee's own +% risk. +% +% 3.4 The Licencee hereby releases and indemnifies and shall +% continue to release and indemnify CSIRO, its officers, +% employees and agents from and against all actions, +% claims, proceedings or demands (including those brought +% by third parties) which may be bought against it or them, +% whether on their own or jointly with the Licencee and +% whether at common law, in equity or pursuant to statute or +% otherwise, in respect of any loss, death, injury, illness +% or damage (whether personal or property, and whether +% direct or consequential, including consequential +% financial loss) and any infringement of copyright, +% patents, trade marks, designs or other Intellectual +% Property Rights, howsoever arising out of the Licencee's +% exercise of its rights under this Agreement and from and +% against all damages, costs and expenses incurred in +% defending or settling any such claim, proceeding or +% demand. +% +% 3.5 The Licencee's obligation to indemnify CSIRO and its +% officers, employees and agents set out in clause 3.4 +% hereof is a continuing obligation separate from +% and independent of the Licencee's other obligations under +% this Agreement, and shall survive all expiration or +% termination of this Agreement. +% +% 4.0 Termination +% +% 4.1 The Licence shall terminate immediately upon the Licencee +% breaching any term or condition of this Agreement whether +% or not CSIRO is aware of the occurrence of the breach at +% the time that it happens. +% +% 4.2 CSIRO may terminate the Licence on reasonable grounds by +% notice in writing to the Licencee, and such notice of +% termination shall be effective immediately upon receipt +% by the Licencee. +% +%========================================================================= + +%$Id: sw_copy.M,v 1.6 1994/12/06 03:05:54 morgan Exp $ + +more on +help sw_copy +more off +return +%-------------------------------------------------------------------- diff --git a/M_Csiro/sw_cp.m b/M_Csiro/sw_cp.m new file mode 100644 index 0000000..8094e06 --- /dev/null +++ b/M_Csiro/sw_cp.m @@ -0,0 +1,176 @@ + +function cp = sw_cp(S,T,P) + +% SW_CP Heat Capacity (Cp) of sea water +%========================================================================= +% SW_CP $Revision: 1.3 $ $Date: 1994/10/10 04:38:05 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: cp = sw_cp(S,T,P) +% +% DESCRIPTION: +% Heat Capacity of Sea Water using UNESCO 1983 polynomial. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% cp = Specific Heat Capacity [J kg^-1 C^-1] +% +% AUTHOR: Phil Morgan 93-04-20 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: general purpose +% CALLEE: none + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=3 + error('sw_cp.m: Must pass 3 parameters') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +%------ +% BEGIN +%------ +P = P/10; % to convert db to Bar as used in Unesco routines + +%------------ +% eqn 26 p.32 +%------------ +c0 = 4217.4; +c1 = -3.720283; +c2 = 0.1412855; +c3 = -2.654387e-3; +c4 = 2.093236e-5; + +a0 = -7.64357; +a1 = 0.1072763; +a2 = -1.38385e-3; + +b0 = 0.1770383; +b1 = -4.07718e-3; +b2 = 5.148e-5; + +Cpst0 = c0 + c1.*T + c2.*T.^2 + c3.*T.^3 + c4.*T.^4 + ... + (a0 + a1.*T + a2.*T.^2).*S + ... + (b0 + b1.*T + b2.*T.^2).*S.*sqrt(S); + +%------------ +% eqn 28 p.33 +%------------ +a0 = -4.9592e-1; +a1 = 1.45747e-2; +a2 = -3.13885e-4; +a3 = 2.0357e-6; +a4 = 1.7168e-8; + +b0 = 2.4931e-4; +b1 = -1.08645e-5; +b2 = 2.87533e-7; +b3 = -4.0027e-9; +b4 = 2.2956e-11; + +c0 = -5.422e-8; +c1 = 2.6380e-9; +c2 = -6.5637e-11; +c3 = 6.136e-13; + +del_Cp0t0 = (a0 + a1.*T + a2.*T.^2 + a3.*T.^3 + a4.*T.^4).*P + ... + (b0 + b1.*T + b2.*T.^2 + b3.*T.^3 + b4.*T.^4).*P.^2 + ... + (c0 + c1.*T + c2.*T.^2 + c3.*T.^3).*P.^3; + +%------------ +% eqn 29 p.34 +%------------ +d0 = 4.9247e-3; +d1 = -1.28315e-4; +d2 = 9.802e-7; +d3 = 2.5941e-8; +d4 = -2.9179e-10; + +e0 = -1.2331e-4; +e1 = -1.517e-6; +e2 = 3.122e-8; + +f0 = -2.9558e-6; +f1 = 1.17054e-7; +f2 = -2.3905e-9; +f3 = 1.8448e-11; + +g0 = 9.971e-8; + +h0 = 5.540e-10; +h1 = -1.7682e-11; +h2 = 3.513e-13; + +j1 = -1.4300e-12; +S3_2 = S.*sqrt(S); + +del_Cpstp = [(d0 + d1.*T + d2.*T.^2 + d3.*T.^3 + d4.*T.^4).*S + ... + (e0 + e1.*T + e2.*T.^2).*S3_2].*P + ... + [(f0 + f1.*T + f2.*T.^2 + f3.*T.^3).*S + ... + g0.*S3_2].*P.^2 + ... + [(h0 + h1.*T + h2.*T.^2).*S + ... + j1.*T.*S3_2].*P.^3; + + +cp = Cpst0 + del_Cp0t0 + del_Cpstp; + +if Transpose + cp = cp'; +end %if + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_data.mat b/M_Csiro/sw_data.mat new file mode 100644 index 0000000000000000000000000000000000000000..c12ce2d917c580ea3790aed4f2ae55421b45fc31 GIT binary patch literal 8077 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 SxbE>H9Q*73`y+6^1^yQ)T@e`o literal 0 HcmV?d00001 diff --git a/M_Csiro/sw_dens.m b/M_Csiro/sw_dens.m new file mode 100644 index 0000000..a1613d5 --- /dev/null +++ b/M_Csiro/sw_dens.m @@ -0,0 +1,103 @@ + +function dens = sw_dens(S,T,P) + +% SW_DENS Density of sea water +%========================================================================= +% SW_DENS $Revision: 1.3 $ $Date: 1994/10/10 04:39:16 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: dens = sw_dens(S,T,P) +% +% DESCRIPTION: +% Density of Sea Water using UNESCO 1983 (EOS 80) polynomial. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% dens = density [kg/m^3] +% +% AUTHOR: Phil Morgan 92-11-05 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +% +% Millero, F.J., Chen, C.T., Bradshaw, A., and Schleicher, K. +% " A new high pressure equation of state for seawater" +% Deap-Sea Research., 1980, Vol27A, pp255-264. +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_dens0.m sw_seck.m + +% UNESCO 1983. eqn.7 p.15 + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=3 + error('sw_dens.m: Must pass 3 parameters') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +%------ +% BEGIN +%------ +densP0 = sw_dens0(S,T); +K = sw_seck(S,T,P); +P = P/10; % convert from db to atm pressure units +dens = densP0./(1-P./K); + +if Transpose + dens = dens'; +end %if + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_dens0.m b/M_Csiro/sw_dens0.m new file mode 100644 index 0000000..0d63ca8 --- /dev/null +++ b/M_Csiro/sw_dens0.m @@ -0,0 +1,91 @@ + +function dens = sw_dens0(S,T) + +% SW_DENS0 Denisty of sea water at atmospheric pressure +%========================================================================= +% SW_DENS0 $Revision: 1.3 $ $Date: 1994/10/10 04:54:09 $ +% Copyright (C) CSIRO, Phil Morgan 1992 +% +% USAGE: dens0 = sw_dens0(S,T) +% +% DESCRIPTION: +% Density of Sea Water at atmospheric pressure using +% UNESCO 1983 (EOS 1980) polynomial. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% T = temperature [degree C (IPTS-68)] +% +% OUTPUT: +% dens0 = density [kg/m^3] of salt water with properties S,T, +% P=0 (0 db gauge pressure) +% +% AUTHOR: Phil Morgan 92-11-05 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +% +% Millero, F.J. and Poisson, A. +% International one-atmosphere equation of state of seawater. +% Deep-Sea Res. 1981. Vol28A(6) pp625-629. +%========================================================================= + +% CALLER: general purpose, sw_dens.m +% CALLEE: sw_smow.m + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=2 + error('sw_dens0.m: Must pass 2 parameters') +end %if + +[mS,nS] = size(S); +[mT,nT] = size(T); + +if (mS~=mT) | (nS~=nT) + error('sw_dens0.m: S,T inputs must have the same dimensions') +end %if + +Transpose = 0; +if mS == 1 % a row vector + S = S(:); + T = T(:); + Transpose = 1; +end %if + +%---------------------- +% DEFINE CONSTANTS +%---------------------- +% UNESCO 1983 eqn(13) p17. + +b0 = 8.24493e-1; +b1 = -4.0899e-3; +b2 = 7.6438e-5; +b3 = -8.2467e-7; +b4 = 5.3875e-9; + +c0 = -5.72466e-3; +c1 = +1.0227e-4; +c2 = -1.6546e-6; + +d0 = 4.8314e-4; + +%$$$ dens = sw_smow(T) + (b0 + b1*T + b2*T.^2 + b3*T.^3 + b4*T.^4).*S ... +%$$$ + (c0 + c1*T + c2*T.^2).*S.*sqrt(S) + d0*S.^2; + +dens = sw_smow(T) + (b0 + (b1 + (b2 + (b3 + b4*T).*T).*T).*T).*S ... + + (c0 + (c1 + c2*T).*T).*S.*sqrt(S) + d0*S.^2; + +if Transpose + dens = dens'; +end %if + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_dist.m b/M_Csiro/sw_dist.m new file mode 100644 index 0000000..329ca19 --- /dev/null +++ b/M_Csiro/sw_dist.m @@ -0,0 +1,112 @@ + +function [dist,phaseangle] = distance(lat,lon,units) + +% SW_DIST Distance between two lat,lon coordinates +%=================================================================== +% SW_DIST $Revision: 1.4 $ $Date: 1994/10/10 04:55:23 $ +% Copyright (C) CSIRO, Phil Morgan & Steve Rintoul 1992. +% +% USAGE: [dist,phaseangle] = distance(lat,lon {,units} ) +% +% DESCRIPTION: +% Calculate distance between two positions on glode using the "Plane +% Sailing" method. Also uses simple geometry to calculate the bearing of +% the path between position pairs. +% +% INPUT: +% lat = decimal degrees (+ve N, -ve S) [- 90.. +90] +% lon = decimal degrees (+ve E, -ve W) [-180..+180] +% units = optional string specifing units of distance +% 'nm' = nautical miles (default) +% 'km' = kilometres +% +% OUTPUT: +% dist = distance between positions in units +% phaseangle = angle of line between stations with x axis (East). +% Range of values are -180..+180. (E=0, N=90, S=-90) +% +% AUTHOR: Phil Morgan and Steve Rintoul 92-02-10 +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCE: +% The PLANE SAILING method as descriibed in "CELESTIAL NAVIGATION" 1989 by +% Dr. P. Gormley. The Australian Antartic Division. +%================================================================== + +% CALLER: general purpose +% CALLEE: none + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin > 3 + error('sw_dist.m: No more than 3 arguments allowed') +elseif nargin==3 + if ~isstr(units) + error('sw_dist.m: units argument must be string') + end %if +elseif nargin==2 + units = 'nm'; % default units +else + error('sw_dist.m: wrong number of arguments') +end%if + +[mlat,nlat] = size(lat); +if mlat~=1 & nlat~=1 + error('sw_dist.m: lat, lon must be vectors. No matrices allowed') +else + if mlat == 1 + Transpose = 1; % row vector passed in + else + Transpose = 0; % accept column vector + end%if +end%if +lat = lat(:); %force to column vectors +lon = lon(:); +if length(lat)~=length(lon) + error('sw_dist.m: lat and lon must have same number of elements') +end%if + +%----------------- +% DEFINE CONSTANTS +%----------------- +DEG2RAD = (2*pi/360); +RAD2DEG = 1/DEG2RAD; +DEG2MIN = 60; +DEG2NM = 60; +NM2KM = 1.8520; % Defined in Pond & Pickard p303. + +% BEGIN +npositions = length(lat); +ind=1:npositions-1; % index to first of position pairs + +dlon = diff(lon); +if any(abs(dlon)>180) + flag = find(abs(dlon)>180); + for ii=1:length(flag) + dlon(flag(ii))= -sign(dlon(flag(ii))) * (360 - abs(dlon(flag(ii))) ); + end %for +end %if +latrad = abs(lat*DEG2RAD); +dep = cos( (latrad(ind+1)+latrad(ind))./2 ) .* dlon; +dlat = diff(lat); +dist = DEG2NM*sqrt(dlat.^2 + dep.^2); % in n.miles + +if strcmp(units,'km') % defaults to n.miles + dist = dist * NM2KM; +end %if + +% CALCUALTE ANGLE TO X AXIS +phaseangle = angle(dep+dlat*sqrt(-1))*RAD2DEG; + +if Transpose + dist = dist'; + phaseangle = phaseangle'; +end %if + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_dpth.m b/M_Csiro/sw_dpth.m new file mode 100644 index 0000000..91f3ab2 --- /dev/null +++ b/M_Csiro/sw_dpth.m @@ -0,0 +1,87 @@ + +function DEPTHM = sw_dpth(P,LAT) + +% SW_DPTH Depth from pressure +%=========================================================================== +% SW_DPTH $Revision: 1.3 $ $Date: 1994/10/10 04:56:32 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: dpth = sw_dpth(P,LAT) +% +% DESCRIPTION: +% Calculates depth in metres from pressure in dbars. +% +% INPUT: (all must have same dimensions) +% P = Pressure [db] +% LAT = Latitude in decimal degress north [-90..+90] +% (lat may have dimensions 1x1 or 1xn where P(mxn). +% +% OUTPUT: +% dpth = depth [metres] +% +% AUTHOR: Phil Morgan 92-04-06 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: general purpose +% CALLEE: none + +%------------- +% CHECK INPUTS +%------------- +[mP,nP] = size(P); +[mL,nL] = size(LAT); +if mL==1 & nL==1 + LAT = LAT*ones(size(P)); + [mL,nL] = size(LAT); +end %if + +if (mP~=mL) | (nP~=nL) % P & LAT are not the same shape + if (nP==nL) & (mL==1) % LAT for each column of P + LAT = LAT( ones(1,mP), : ); % copy LATS down each column + % s.t. dim(P)==dim(LAT) + else + error('sw_depth.m: Inputs arguments have wrong dimensions') + end %if +end %if + +Transpose = 0; +if mP == 1 % row vector + P = P(:); + LAT = LAT(:); + Transpose = 1; +end %if + +%------------- +% BEGIN +%------------- +% Eqn 25, p26. Unesco 1983. + +DEG2RAD = pi/180; +c1 = +9.72659; +c2 = -2.2512E-5; +c3 = +2.279E-10; +c4 = -1.82E-15; +gam_dash = 2.184e-6; + +LAT = abs(LAT); +X = sin(LAT*DEG2RAD); % convert to radians +X = X.*X; +bot_line = 9.780318*(1.0+(5.2788E-3+2.36E-5*X).*X) + gam_dash*0.5*P; +top_line = (((c4*P+c3).*P+c2).*P+c1).*P; +DEPTHM = top_line./bot_line; + +if Transpose + DEPTHM = DEPTHM'; +end %if + +return +%=========================================================================== +% diff --git a/M_Csiro/sw_f.m b/M_Csiro/sw_f.m new file mode 100644 index 0000000..caa36eb --- /dev/null +++ b/M_Csiro/sw_f.m @@ -0,0 +1,57 @@ + +function f = sw_f(lat) + +% SW_F Coriolis factor "f" +%=========================================================================== +% SW_F $Revision: 1.3 $ $Date: 1994/10/10 04:57:08 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: f = sw_f(lat) +% +% DESCRIPTION: +% Calculates the Coriolis factor "f" defined by +% f = 2*Omega*Sin(lat) where Omega = 7.292e-5 radians/sec +% +% INPUT: +% lat = Latitude in decimal degress north [-90..+90] +% +% OUTPUT: +% f = Coriolis Factor "f" [s-1] +% +% AUTHOR: Phil Morgan 93-04-20 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCE: +% S. Pond & G.Pickard 2nd Edition 1986 +% Introductory Dynamical Oceanogrpahy +% Pergamon Press Sydney. ISBN 0-08-028728-X +% +% A.E. Gill 1982. p.597 +% "Atmosphere-Ocean Dynamics" +% Academic Press: New York. ISBN: 0-12-283522-0 +%========================================================================= + +% CALLER: general purpose +% CALLEE: none + +%------------- +% CHECK INPUTS +%------------- +if nargin ~= 1 + error('sw_f.m: Requires one input argument') +end %if + +%------------- +% BEGIN +%------------- +% Eqn p27. Unesco 1983. +DEG2RAD = pi/180; +OMEGA = 7.292e-5; %s-1 A.E.Gill p.597 +f = 2*OMEGA*sin(lat*DEG2RAD); + +return +%=========================================================================== + diff --git a/M_Csiro/sw_fp.m b/M_Csiro/sw_fp.m new file mode 100644 index 0000000..acd959c --- /dev/null +++ b/M_Csiro/sw_fp.m @@ -0,0 +1,90 @@ + +function fp = sw_fp(S,P) + +% SW_FP Freezing point of sea water +%========================================================================= +% SW_FP % $Revision: 1.3 $ $Date: 1994/10/10 04:57:50 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: fp = sw_fp(S,P) +% +% DESCRIPTION: +% Heat Capacity of Sea Water using UNESCO 1983 polynomial. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% fp = Freezing Point temperature [degree C (IPTS-68)] +% +% AUTHOR: Phil Morgan 93-04-20 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: general purpose +% CALLEE: none + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=2 + error('sw_fp.m: Must pass 3 parameters') +end %if + +[ms,ns] = size(S); +[mp,np] = size(P); + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('sw_fp.m: P has wrong dimensions') +end %if +[mp,np] = size(P); + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + S = S(:); + Transpose = 1; +end %if + +%------ +% BEGIN +%------ +%P = P/10; % to convert db to Bar as used in Unesco routines + +%------------ +% eqn p.29 +%------------ +a0 = -0.0575; +a1 = 1.710523e-3; +a2 = -2.154996e-4; +b = -7.53e-4; + +fp = a0.*S + a1.*S.*sqrt(S) + a2.*S.^2 + b.*P; + +if Transpose + fp = fp'; +end %if + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_g.m b/M_Csiro/sw_g.m new file mode 100644 index 0000000..c2a3c90 --- /dev/null +++ b/M_Csiro/sw_g.m @@ -0,0 +1,70 @@ + +function g = sw_g(LAT,z) + +% SW_G Gravitational acceleration +%=========================================================================== +% SW_G $Revision: 1.4 $ $Date: 1994/10/11 00:00:54 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: g = sw_g(lat,z) +% +% DESCRIPTION: +% Calculates acceleration due to gravity as function of latitude. +% +% INPUT: (all must have same dimensions) +% lat = Latitude in decimal degress north [-90..+90] +% z = height in metres (+ve above sea surface, -ve below) +% +% OUTPUT: +% g = gravity [m/s^2] +% +% AUTHOR: Phil Morgan 93-04-20 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +% +% A.E. Gill 1982. p.597 +% "Atmosphere-Ocean Dynamics" +% Academic Press: New York. ISBN: 0-12-283522-0 +%========================================================================= + +% CALLER: general purpose +% CALLEE: none + +%------------- +% CHECK INPUTS +%------------- +if ~(nargin==1 | nargin==2) + error('sw_g.m: Requires one or two input arguments') +end %if +if nargin == 1 + z = zeros(size(LAT)); +end %if + +[mL,nL] = size(LAT); +[mz,nz] = size(z); +if ~(mL==mz | nL==nz) + error('sw_g.m: Input arguments should have same dimensions') +end %if + +%------------- +% BEGIN +%------------- +% Eqn p27. Unesco 1983. +a = 6371000; % mean radius of earth A.E.Gill +DEG2RAD = pi/180; +LAT = abs(LAT); +X = sin(LAT*DEG2RAD); % convert to radians +sin2 = X.*X; +g = 9.780318*(1.0+(5.2788E-3+2.36E-5*sin2).*sin2); +if any(any(z)) + g = g./((1+z/a).^2); % from A.E.Gill p.597 +end %if +return +%=========================================================================== + diff --git a/M_Csiro/sw_gpan.m b/M_Csiro/sw_gpan.m new file mode 100644 index 0000000..2f5c1ad --- /dev/null +++ b/M_Csiro/sw_gpan.m @@ -0,0 +1,126 @@ + +function [ga, pe] = sw_gpan(S,T,P,LAT) + +% SW_GPAN Geopotential anomaly +%========================================================================= +% SW_GPAN $Revision: 1.3 $ $Date: 1994/10/10 05:01:00 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: [gpan, pe]= sw_gpan(S,T,P,LAT) +% +% DESCRIPTION: +% Geopotential Anomaly calculated as the integral of svan from the +% the sea surface to the bottom. Thus RELATIVE TO SEA SURFACE. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% T = temperature [degree C (ITP-68)] +% P = Pressure [db] +% LAT = latitude +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% gpan = Geopotential Anomaly [m^3 kg^-1 Pa == m^2 s^-2 == J kg^-1] +% pe = anomalie d'energie potentielle en kg/s^2 * 10 +% +% AUTHOR: Phil Morgan 92-11-05 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCE: S. Pond & G.Pickard 2nd Edition 1986 +% Introductory Dynamical Oceanogrpahy +% Pergamon Press Sydney. ISBN 0-08-028728-X +% +% Note that older literature may use units of "dynamic decimeter' for above. +% +% Adapted method from Pond and Pickard (p76) to calc gpan rel to sea +% surface whereas P&P calculated relative to the deepest common depth. +%========================================================================= + +% +% CALLER: general purpose +% CALLEE: sw_svan.m + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~= 4 + error('sw_gpan.m: Must pass 4 parameters') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +%------ +% BEGIN +%------ +db2Pascal = 1e4; +[m,n] = size(P); +svan = sw_svan(S,T,P); +mean_svan = 0.5*(svan(2:m,:) + svan(1:m-1,:) ); + +if n==1 + top = svan(1,1).*P(1,1)*db2Pascal; +else + top = svan(1,:).*P(1,:)*db2Pascal; +end %if + +%press_diff = diff(P); + +delta_ga = (mean_svan.*diff(P))*db2Pascal; +ga = cumsum([ top; delta_ga]); + +% Rajoute par Y. Gouriou en se basant sur la routine de Millard +% pe[ref] = hdy[ref] * (ctd[ref].pres + ctd[ind].pres)*0.5F / +% (float)grav( (double)ctd[ref].pres,lat ); */ +% pe[ref] = (float) ( fabs( (double)( pres[ref] - pres[ind]) ) +% * (anvs[ref]*pres[ref] + anvs[ind]*pres[ind]) +% * 0.5e-5 / (float)grav( (double)pres[ref],lat )); +mean_P = 0.5*( P(2:m,:) + P(1:m-1,:) ); +delta_pe = delta_ga .* mean_P ./ sw_g( LAT, -sw_dpth(P(2:end),LAT)); +pe = cumsum([ top/sw_g( LAT, 0); delta_pe]); + +if Transpose + ga = ga'; + pe = pe'; +end %if + +return +%-------------------------------------------------------------------- diff --git a/M_Csiro/sw_gvel.m b/M_Csiro/sw_gvel.m new file mode 100644 index 0000000..31ae07d --- /dev/null +++ b/M_Csiro/sw_gvel.m @@ -0,0 +1,62 @@ + +function vel = sw_gvel(ga,lat,lon) + +% SW_GVEL Geostrophic velocity +%=================================================================== +% GEOVEL $Revision: 1.5 $ $Date: 1994/11/15 04:00:36 $ +% Copyright (C) CSIRO, Phil Morgan 1992 +% +% USAGE: vel = sw_gvel(ga,lat,lon) +% +% DESCRIPTION: +% Calculates geostrophic velocity given the geopotential anomaly +% and position of each station. +% +% INPUT: +% ga = geopotential anomoly relative to the sea surface. +% dim(mxnstations) +% lat = latitude of each station (+ve = N, -ve = S) [ -90.. +90] +% lon = longitude of each station (+ve = E, -ve = W) [-180..+180] +% +% OUTPUT: +% vel = geostrophic velocity RELATIVE to the sea surface. +% dim(m,nstations-1) +% +% AUTHOR: Phil Morgan 1992/03/26 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCE: S. Pond & G.Pickard 2nd Edition 1986 +% Introductory Dynamical Oceanogrpahy +% Pergamon Press Sydney. ISBN 0-08-028728-X +% Equation 8.9A p73 Pond & Pickard +% +% NOTE: This calls sw_dist.m. You can replace the call to this +% routine if you have a more appropraite distance routine. +%================================================================== + +% CALLER: general purpose +% CALLEE: sw_dist.m +% + + +DEG2RAD = pi/180; +RAD2DEG = 180/pi; +OMEGA = 7.292e-5; % Angular velocity of Earth [radians/sec] + +% You may replace the call to sw_dist if you have +% a more appropriate distance routine. +distm = 1000*sw_dist(lat,lon,'km'); +[m,n] = size(ga); +f = 2*OMEGA*sin( (lat(1:n-1)+lat(2:n))*DEG2RAD/2 ); +lf = f.*distm; + +LF = lf(ones(m,1),:); + +vel = -( ga(:,2:n)-ga(:,1:n-1) ) ./ LF; + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_info.m b/M_Csiro/sw_info.m new file mode 100644 index 0000000..21e57fc --- /dev/null +++ b/M_Csiro/sw_info.m @@ -0,0 +1,30 @@ + +% SW_INFO Computational routines for the properties of sea water +% +% SEAWATER - devloped by Phil Morgan, CSIRO +% +% DESCRIPTION: +% SEAWATER is a toolkit of MATLAB routines for calculating the +% properties of sea water. They are a self contained library and +% are extremely easy to use and will run on all computers that +% support MATLAB. +% +% MATLAB: +% For information on MATLAB contact info@mathworks.com +% +% DISCLAIMER +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% MORE INFORMATION: +% http://www.marine.csiro.au/~morgan/seawater +% +% $Revision: 1.10 $ $Date: 1998/04/21 05:50:33 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +%========================================================================= + +more on +help sw_info +more off +return +%-------------------------------------------------------------------- diff --git a/M_Csiro/sw_new.m b/M_Csiro/sw_new.m new file mode 100644 index 0000000..0034026 --- /dev/null +++ b/M_Csiro/sw_new.m @@ -0,0 +1,64 @@ + +% SW_NEW What's new in this version of seawater. +% +% 22 April 1998 release 2.0.1 (For version 5.x of Matlab) +% ******************************************************** +% This version is not optimised but will run under Matlab 5.x +% sw_satAr New routine. Solubility of Ar in seawater +% sw_satN2 New routine. Solubility of Ar in seawater +% sw_satO2 New routine. Solubility of Ar in seawater +% sw_test Updated to include tests for above +% +% April 1998 release 1.2e (For version 4.x of Matlab) +% ************************ +% sw_alpha Fixed bug where temp used in calculations regardless of +% whether 'temp' or 'pmpt' was passed as keyword. +% +% sw_info Shorter version. Refer users to web pages +% http://www.marine.csiro.au +% +% sw_ver New routine. Returns version number of SEAWATER +% +% sw_test New Routine. Run a test on the SEAWATER routines +% and compare results with literature values +% +% 94/11/15 release 1.2d +% ********************** +% sw_bfrq.m Now also returns potential vorticity. +% Thanks to Greg Johnson (gjohnson@pmel.noaa.gov) +% +% sw_gvel.m OMEGA=7.29e-5 changed to OMEGA=7.292e-5 to be +% consistent with sw_f.m +% +% IMPORTANT CHANGE: The usage of the following +% routines has changed! +% +% sw_alpha.m | All these routines expect (S,T,P) to +% sw_beta.m |-- be passed instead of (S,PTMP,P) as in +% sw_aonb.m | previous releases of seawater. +% Fast execution can still be obtained by passing +% ptmp with a string flag 'ptmp' see help. +% +% 94/10/19 release 1.2c +% ********************** +% Added routine sw_new.m to inform of updates and new features. +% sw_bfrq.m Fixed bug where LAT = [] was needed as argument when +% no latitude values are being passed. +% Now pass PRESSURE instead of DEPTH -> more consistent +% though only a negligible change is answers. +% +% sw_info.m Updated to include a registration section. +% Noted that software is FREE. +% Noted best email address is seawater@ml.csiro.au +% Requests for Report also via email to library@ml.csiro.au +% +% 94/10/12 release 1.2b +% ******************** +% First official release and announcement on the networks. +% + +more on +help sw_new +more off + +%------------- diff --git a/M_Csiro/sw_pden.m b/M_Csiro/sw_pden.m new file mode 100644 index 0000000..9f47a8b --- /dev/null +++ b/M_Csiro/sw_pden.m @@ -0,0 +1,57 @@ + +function pden = sw_pden(S,T,P,PR) + +% SW_PDEN Potential density +%=========================================================================== +% SW_PDEN $Revision: 1.3 $ $Date: 1994/10/10 05:05:21 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: pden = sw_pden(S,T,P,PR) +% +% DESCRIPTION: +% Calculates potential density of water mass relative to the specified +% reference pressure by pden = sw_dens(S,ptmp,PR). +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% PR = Reference pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% pden = Potential denisty relative to the ref. pressure [kg/m^3] +% +% AUTHOR: Phil Morgan 1992/04/06 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% A.E. Gill 1982. p.54 +% "Atmosphere-Ocean Dynamics" +% Academic Press: New York. ISBN: 0-12-283522-0 +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_ptmp.m sw_dens.m + +%------------- +% CHECK INPUTS +%------------- +if nargin ~= 4 + error('sw_pden.m: Must pass 4 parameters ') +end %if + +% LET sw_ptmp.m DO DIMENSION CHECKING + +%------ +% BEGIN +%------ +ptmp = sw_ptmp(S,T,P,PR); +pden = sw_dens(S,ptmp,PR); + +return +%========================================================================= + diff --git a/M_Csiro/sw_pres.m b/M_Csiro/sw_pres.m new file mode 100644 index 0000000..1d2d7ac --- /dev/null +++ b/M_Csiro/sw_pres.m @@ -0,0 +1,81 @@ + +function pres = sw_pres(DEPTH,LAT) + +% SW_PRES Pressure from depth +%=========================================================================== +% SW_PRES $Revision: 1.5 $ $Date: 1994/10/11 01:23:32 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: pres = sw_pres(depth,lat) +% +% DESCRIPTION: +% Calculates pressure in dbars from depth in meters. +% +% INPUT: (all must have same dimensions) +% depth = depth [metres] +% lat = Latitude in decimal degress north [-90..+90] +% (LAT may have dimensions 1x1 or 1xn where depth(mxn) ) +% +% OUTPUT: +% pres = Pressure [db] +% +% AUTHOR: Phil Morgan 93-06-25 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Saunders, P.M. 1981 +% "Practical conversion of Pressure to Depth" +% Journal of Physical Oceanography, 11, 573-574 +% +% CHECK VALUE: +% P=7500.00 db for LAT=30 deg, depth=7321.45 meters +%========================================================================= + +% CALLER: general purpose +% CALLEE: none + +%------------- +% CHECK INPUTS +%------------- + +[mD,nD] = size(DEPTH); +[mL,nL] = size(LAT); +if mL==1 & nL==1 + LAT = LAT*ones(size(DEPTH)); + [mL,nL] = size(LAT); +end %if + +if (mD~=mL) | (nD~=nL) % DEPTH & LAT are not the same shape + if (nD==nL) & (mL==1) % LAT for each column of DEPTH + LAT = LAT( ones(1,mD), : ); % copy LATS down each column + % s.t. dim(DEPTH)==dim(LAT) + else + error('sw_pres.m: Inputs arguments have wrong dimensions') + end %if +end %if + +Transpose = 0; +if mD == 1 % row vector + DEPTH = DEPTH(:); + LAT = LAT(:); + Transpose = 1; +end %if + +%------------- +% BEGIN +%------------- + +DEG2RAD = pi/180; +X = sin(abs(LAT)*DEG2RAD); % convert to radians +C1 = 5.92E-3+X.^2*5.25E-3; +pres = ((1-C1)-sqrt(((1-C1).^2)-(8.84E-6*DEPTH)))/4.42E-6; + +if Transpose + pres = pres'; +end %if + +return +%=========================================================================== diff --git a/M_Csiro/sw_ptmp.m b/M_Csiro/sw_ptmp.m new file mode 100644 index 0000000..b0c37eb --- /dev/null +++ b/M_Csiro/sw_ptmp.m @@ -0,0 +1,137 @@ + +function PT = sw_ptmp(S,T,P,PR) + +% SW_PTMP Potential temperature +%=========================================================================== +% SW_PTMP $Revision: 1.3 $ $Date: 1994/10/10 05:45:13 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: ptmp = sw_ptmp(S,T,P,PR) +% +% DESCRIPTION: +% Calculates potential temperature as per UNESCO 1983 report. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% PR = Reference pressure [db] +% (P & PR may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% ptmp = Potential temperature relative to PR [degree C (IPTS-68)] +% +% AUTHOR: Phil Morgan 92-04-06 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +% Eqn.(31) p.39 +% +% Bryden, H. 1973. +% "New Polynomials for thermal expansion, adiabatic temperature gradient +% and potential temperature of sea water." +% DEEP-SEA RES., 1973, Vol20,401-408. +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_adtg.m + +%------------- +% CHECK INPUTS +%------------- +if nargin ~= 4 + error('sw_ptmp.m: Must pass 4 parameters ') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + +[mpr,npr] = size(PR); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + +% CHECK OPTIONAL SHAPES FOR PR +if mpr==1 & npr==1 % PR is a scalar. Fill to size of S + PR = PR(1)*ones(ms,ns); +elseif npr==ns & mpr==1 % PR is row vector with same cols as S + PR = PR( ones(1,ms), : ); % Copy down each column. +elseif mpr==ms & npr==1 % P is column vector + PR = PR( :, ones(1,ns) ); % Copy across each row +elseif mpr==ms & npr==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: PR has wrong dimensions') +end %if +[mpr,npr] = size(PR); + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + PR = PR(:); + + Transpose = 1; +end %if +%***check_stp + +%------ +% BEGIN +%------ + +% theta1 +del_P = PR - P; +del_th = del_P.*sw_adtg(S,T,P); +th = T + 0.5*del_th; +q = del_th; + +% theta2 +del_th = del_P.*sw_adtg(S,th,P+0.5*del_P); +th = th + (1 - 1/sqrt(2))*(del_th - q); +q = (2-sqrt(2))*del_th + (-2+3/sqrt(2))*q; + +% theta3 +del_th = del_P.*sw_adtg(S,th,P+0.5*del_P); +th = th + (1 + 1/sqrt(2))*(del_th - q); +q = (2 + sqrt(2))*del_th + (-2-3/sqrt(2))*q; + +% theta4 +del_th = del_P.*sw_adtg(S,th,P+del_P); +PT = th + (del_th - 2*q)/6; + +if Transpose + PT = PT'; +end %if + +return +%========================================================================= diff --git a/M_Csiro/sw_salds.m b/M_Csiro/sw_salds.m new file mode 100644 index 0000000..134e970 --- /dev/null +++ b/M_Csiro/sw_salds.m @@ -0,0 +1,74 @@ + +function dS = sw_salds(Rtx,delT) + +% SW_SALDS Differiential dS/d(sqrt(Rt)) at constant T. +%========================================================================= +% SW_SALDS $Revision: 1.3 $ $Date: 1994/10/10 05:46:08 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: dS = sw_salds(Rtx,delT) +% +% DESCRIPTION: +% Calculates Salinity differential dS/d(sqrt(Rt)) at constant T. +% UNESCO 1983 polynomial. +% +% INPUT: (all must have same dimensions) +% Rtx = sqrt(Rt) where Rt defined in sw_salt.m +% delT = T-15 [degree C (IPTS-68)] +% +% OUTPUT: +% dS = S differential dS/d(sqrt(Rt)) at constant T. +% +% AUTHOR: Phil Morgan 93-04-21 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: sw_cndr.m +% CALLEE: none + +%------------- +% CHECK INPUTS +%------------- +if nargin~=2 + error('sw_salds.m: must have 2 input arguments') +end %if + +[m1,n1] = size(Rtx); +[m2,n2] = size(delT); +if ~(m1==m2 | n1==n2) + error('sw_salds.m: Rtx and delT must have the same shape') +end %if + +%------- +% BEGIN +%------- +a0 = 0.0080; +a1 = -0.1692; +a2 = 25.3851; +a3 = 14.0941; +a4 = -7.0261; +a5 = 2.7081; + +b0 = 0.0005; +b1 = -0.0056; +b2 = -0.0066; +b3 = -0.0375; +b4 = 0.0636; +b5 = -0.0144; + +k = 0.0162; + +dS = a1 + (2*a2 + (3*a3 + (4*a4 + 5*a5.*Rtx).*Rtx).*Rtx).*Rtx + ... + (delT./(1+k*delT))* ... + (b1 + (2*b2 + (3*b3 + (4*b4 + 5*b5.*Rtx).*Rtx).*Rtx).*Rtx); + +return +%----------------------------------------------------------------------- diff --git a/M_Csiro/sw_salrp.m b/M_Csiro/sw_salrp.m new file mode 100644 index 0000000..c795f22 --- /dev/null +++ b/M_Csiro/sw_salrp.m @@ -0,0 +1,69 @@ + +function Rp = sw_salrp(R,T,P) + +% SW_SALRP Conductivity ratio Rp(S,T,P) = C(S,T,P)/C(S,T,0) +%========================================================================= +% SW_SALRP $Revision: 1.3 $ $Date: 1994/10/10 05:47:27 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: Rp = sw_salrp(R,T,P) +% +% DESCRIPTION: +% Equation Rp(S,T,P) = C(S,T,P)/C(S,T,0) used in calculating salinity. +% UNESCO 1983 polynomial. +% +% INPUT: (All must have same shape) +% R = Conductivity ratio R = C(S,T,P)/C(35,15,0) [no units] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% +% OUTPUT: +% Rp = conductivity ratio Rp(S,T,P) = C(S,T,P)/C(S,T,0) [no units] +% +% AUTHOR: Phil Morgan 93-04-17 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: sw_salt +% CALLEE: none + +%------------------- +% CHECK INPUTS +%------------------- +if nargin~=3 + error('sw_salrp.m: requires 3 input arguments') +end %if + +[mr,nr] = size(R); +[mp,np] = size(P); +[mt,nt] = size(T); +if ~(mr==mp | mr==mt | nr==np | nr==nt) + error('sw_salrp.m: R,T,P must all have the same shape') +end %if + +%------------------- +% eqn (4) p.8 unesco. +%------------------- +d1 = 3.426e-2; +d2 = 4.464e-4; +d3 = 4.215e-1; +d4 = -3.107e-3; + +e1 = 2.070e-5; +e2 = -6.370e-10; +e3 = 3.989e-15; + +Rp = 1 + ( P.*(e1 + e2.*P + e3.*P.^2) ) ... + ./ (1 + d1.*T + d2.*T.^2 +(d3 + d4.*T).*R); + +return +%----------------------------------------------------------------------- + diff --git a/M_Csiro/sw_salrt.m b/M_Csiro/sw_salrt.m new file mode 100644 index 0000000..db985e5 --- /dev/null +++ b/M_Csiro/sw_salrt.m @@ -0,0 +1,49 @@ + +function rt = sw_salrt(T) + +% SW_SALRT Conductivity ratio rt(T) = C(35,T,0)/C(35,15,0) +%========================================================================= +% SW_SALRT $Revision: 1.3 $ $Date: 1994/10/10 05:48:34 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: rt = sw_salrt(T) +% +% DESCRIPTION: +% Equation rt(T) = C(35,T,0)/C(35,15,0) used in calculating salinity. +% UNESCO 1983 polynomial. +% +% INPUT: +% T = temperature [degree C (IPTS-68)] +% +% OUTPUT: +% rt = conductivity ratio [no units] +% +% AUTHOR: Phil Morgan 93-04-17 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: sw_salt +% CALLEE: none + +% rt = rt(T) = C(35,T,0)/C(35,15,0) +% Eqn (3) p.7 Unesco. + +c0 = 0.6766097; +c1 = 2.00564e-2; +c2 = 1.104259e-4; +c3 = -6.9698e-7; +% c4 = 1.0031e-9; +c4 = 1.e-9; + +rt = c0 + (c1 + (c2 + (c3 + c4.*T).*T).*T).*T; + +return +%-------------------------------------------------------------------- diff --git a/M_Csiro/sw_sals.m b/M_Csiro/sw_sals.m new file mode 100644 index 0000000..fb7bdbd --- /dev/null +++ b/M_Csiro/sw_sals.m @@ -0,0 +1,79 @@ + +function S = sw_sals(Rt,T) + +% SW_SALS Salinity of sea water +%========================================================================= +% SW_SALS $Revision: 1.3 $ $Date: 1994/10/10 05:49:13 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: S = sw_sals(Rt,T) +% +% DESCRIPTION: +% Salinity of sea water as a function of Rt and T. +% UNESCO 1983 polynomial. +% +% INPUT: +% Rt = Rt(S,T) = C(S,T,0)/C(35,T,0) +% T = temperature [degree C (IPTS-68)] +% +% OUTPUT: +% S = salinity [psu (PSS-78)] +% +% AUTHOR: Phil Morgan 93-04-17 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: sw_salt +% CALLEE: none + +%-------------------------- +% CHECK INPUTS +%-------------------------- +if nargin~=2 + error('sw_sals.m: requires 2 input arguments') +end %if + +[mrt,nrt] = size(Rt); +[mT,nT] = size(T); +if ~(mrt==mT | nrt==nT) + error('sw_sals.m: Rt and T must have the same shape') +end %if + +%-------------------------- +% eqn (1) & (2) p6,7 unesco +%-------------------------- +a0 = 0.0080; +a1 = -0.1692; +a2 = 25.3851; +a3 = 14.0941; +a4 = -7.0261; +a5 = 2.7081; + +b0 = 0.0005; +b1 = -0.0056; +b2 = -0.0066; +b3 = -0.0375; +b4 = 0.0636; +b5 = -0.0144; + +k = 0.0162; + +Rtx = sqrt(Rt); +del_T = T - 15; +del_S = (del_T ./ (1+k*del_T) ) .* ... + ( b0 + (b1 + (b2+ (b3 + (b4 + b5.*Rtx).*Rtx).*Rtx).*Rtx).*Rtx); + +S = a0 + (a1 + (a2 + (a3 + (a4 + a5.*Rtx).*Rtx).*Rtx).*Rtx).*Rtx; + +S = S + del_S; + +return +%---------------------------------------------------------------------- diff --git a/M_Csiro/sw_salt.m b/M_Csiro/sw_salt.m new file mode 100644 index 0000000..d0102b8 --- /dev/null +++ b/M_Csiro/sw_salt.m @@ -0,0 +1,60 @@ + +function S = sw_salt(cndr,T,P) + +% SW_SALT Salinity from cndr, T, P +%========================================================================= +% SW_SALT $Revision: 1.3 $ $Date: 1994/10/10 05:49:53 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: S = sw_salt(cndr,T,P) +% +% DESCRIPTION: +% Calculates Salinity from conductivity ratio. UNESCO 1983 polynomial. +% +% INPUT: +% cndr = Conductivity ratio R = C(S,T,P)/C(35,15,0) [no units] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% +% OUTPUT: +% S = salinity [psu (PSS-78)] +% +% AUTHOR: Phil Morgan 93-04-17 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_sals.m sw_salrt.m sw_salrp.m + + +%---------------------------------- +% CHECK INPUTS ARE SAME DIMENSIONS +%---------------------------------- +[mc,nc] = size(cndr); +[mt,nt] = size(T); +[mp,np] = size(P); + +if ~(mc==mt | mc==mp | nc==nt | nc==np) + error('sw_salt.m: cndr,T,P must all have the same dimensions') +end %if + +%------- +% BEGIN +%------- +R = cndr; +rt = sw_salrt(T); +Rp = sw_salrp(R,T,P); +Rt = R./(Rp.*rt); +S = sw_sals(Rt,T); + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_satAr.m b/M_Csiro/sw_satAr.m new file mode 100644 index 0000000..481271b --- /dev/null +++ b/M_Csiro/sw_satAr.m @@ -0,0 +1,95 @@ +%$$$ +%$$$ #undef __PR +%$$$ #include "VARIANT.h" + +function c = sw_satAr(S,T) + +% SW_SATAr Satuaration of Ar in sea water +%========================================================================= +% sw_satAr $Revision: 1.1 $ $Date: 1998/04/22 02:15:56 $ +% Copyright (C) CSIRO, Phil Morgan 1998. +% +% USAGE: satAr = sw_satAr(S,T,P) +% +% DESCRIPTION: +% Solubility (satuaration) of Argon (Ar) in sea water +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% T = temperature [degree C (IPTS-68)] +% +% OUTPUT: +% satAr = solubility of Ar [ml/l] +% +% AUTHOR: Phil Morgan 97-11-05 (morgan@ml.csiro.au) +% +%$$$ #include "disclaimer_in_code.inc" +% +% REFERENCES: +% Weiss, R. F. 1970 +% "The solubility of nitrogen, oxygen and argon in water and seawater." +% Deap-Sea Research., 1970, Vol 17, pp721-735. +%========================================================================= + +% CALLER: general purpose +% CALLEE: + +%$$$ #ifdef VARIANT_PRIVATE +%$$$ %*********************************************************** +%$$$ %$Id: sw_satAr.M,v 1.1 1998/04/22 02:15:56 morgan Exp $ +%$$$ % +%$$$ %$Log: sw_satAr.M,v $ + +%$$$ % +%$$$ %*********************************************************** +%$$$ #endif + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=2 + error('sw_satAr.m: Must pass 2 parameters') +end %if + +% CHECK S,T dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('sw_satAr: S & T must have same dimensions') +end %if + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if ms == 1 % row vector + T = T(:); + S = S(:); + Transpose = 1; +end %if + +%------ +% BEGIN +%------ + +% convert T to Kelvin +T = 273.15 + T; + +% constants for Eqn (4) of Weiss 1970 +a1 = -173.5146; +a2 = 245.4510; +a3 = 141.8222; +a4 = -21.8020; +b1 = -0.034474; +b2 = 0.014934; +b3 = -0.0017729; + +% Eqn (4) of Weiss 1970 +lnC = a1 + a2.*(100./T) + a3.*log(T./100) + a4.*(T./100) + ... + S.*( b1 + b2.*(T./100) + b3.*((T./100).^2) ); + +c = exp(lnC); + +return + diff --git a/M_Csiro/sw_satN2.m b/M_Csiro/sw_satN2.m new file mode 100644 index 0000000..f1a0ca8 --- /dev/null +++ b/M_Csiro/sw_satN2.m @@ -0,0 +1,95 @@ +%$$$ +%$$$ #undef __PR +%$$$ #include "VARIANT.h" + +function c = sw_satN2(S,T) + +% SW_SATN2 Satuaration of N2 in sea water +%========================================================================= +% sw_satN2 $Revision: 1.1 $ $Date: 1998/04/22 02:15:56 $ +% Copyright (C) CSIRO, Phil Morgan 1998. +% +% USAGE: satN2 = sw_satN2(S,T,P) +% +% DESCRIPTION: +% Solubility (satuaration) of Nitrogen (N2) in sea water +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% T = temperature [degree C (IPTS-68)] +% +% OUTPUT: +% satN2 = solubility of N2 [ml/l] +% +% AUTHOR: Phil Morgan 97-11-05 (morgan@ml.csiro.au) +% +%$$$ #include "disclaimer_in_code.inc" +% +% REFERENCES: +% Weiss, R. F. 1970 +% "The solubility of nitrogen, oxygen and argon in water and seawater." +% Deap-Sea Research., 1970, Vol 17, pp721-735. +%========================================================================= + +% CALLER: general purpose +% CALLEE: + +%$$$ #ifdef VARIANT_PRIVATE +%$$$ %*********************************************************** +%$$$ %$Id: sw_satN2.M,v 1.1 1998/04/22 02:15:56 morgan Exp $ +%$$$ % +%$$$ %$Log: sw_satN2.M,v $ + +%$$$ % +%$$$ %*********************************************************** +%$$$ #endif + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=2 + error('sw_satN2.m: Must pass 2 parameters') +end %if + +% CHECK S,T dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('sw_satN2: S & T must have same dimensions') +end %if + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if ms == 1 % row vector + T = T(:); + S = S(:); + Transpose = 1; +end %if + +%------ +% BEGIN +%------ + +% convert T to Kelvin +T = 273.15 + T; + +% constants for Eqn (4) of Weiss 1970 +a1 = -172.4965; +a2 = 248.4262; +a3 = 143.0738; +a4 = -21.7120; +b1 = -0.049781; +b2 = 0.025018; +b3 = -0.0034861; + +% Eqn (4) of Weiss 1970 +lnC = a1 + a2.*(100./T) + a3.*log(T./100) + a4.*(T./100) + ... + S.*( b1 + b2.*(T./100) + b3.*((T./100).^2) ); + +c = exp(lnC); + +return + diff --git a/M_Csiro/sw_satO2.m b/M_Csiro/sw_satO2.m new file mode 100644 index 0000000..ea1b5c7 --- /dev/null +++ b/M_Csiro/sw_satO2.m @@ -0,0 +1,95 @@ +%$$$ +%$$$ #undef __PR +%$$$ #include "VARIANT.h" + +function c = sw_satO2(S,T) + +% SW_SATO2 Satuaration of O2 in sea water +%========================================================================= +% sw_satO2 $Revision: 1.1 $ $Date: 1998/04/22 02:15:56 $ +% Copyright (C) CSIRO, Phil Morgan 1998. +% +% USAGE: satO2 = sw_satO2(S,T,P) +% +% DESCRIPTION: +% Solubility (satuaration) of Oxygen (O2) in sea water +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% T = temperature [degree C (IPTS-68)] +% +% OUTPUT: +% satO2 = solubility of O2 [ml/l] +% +% AUTHOR: Phil Morgan 97-11-05 (morgan@ml.csiro.au) +% +%$$$ #include "disclaimer_in_code.inc" +% +% REFERENCES: +% Weiss, R. F. 1970 +% "The solubility of nitrogen, oxygen and argon in water and seawater." +% Deap-Sea Research., 1970, Vol 17, pp721-735. +%========================================================================= + +% CALLER: general purpose +% CALLEE: + +%$$$ #ifdef VARIANT_PRIVATE +%$$$ %*********************************************************** +%$$$ %$Id: sw_satO2.M,v 1.1 1998/04/22 02:15:56 morgan Exp $ +%$$$ % +%$$$ %$Log: sw_satO2.M,v $ + +%$$$ % +%$$$ %*********************************************************** +%$$$ #endif + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=2 + error('sw_satO2.m: Must pass 2 parameters') +end %if + +% CHECK S,T dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('sw_satO2: S & T must have same dimensions') +end %if + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if ms == 1 % row vector + T = T(:); + S = S(:); + Transpose = 1; +end %if + +%------ +% BEGIN +%------ + +% convert T to Kelvin +T = 273.15 + T; + +% constants for Eqn (4) of Weiss 1970 +a1 = -173.4292; +a2 = 249.6339; +a3 = 143.3483; +a4 = -21.8492; +b1 = -0.033096; +b2 = 0.014259; +b3 = -0.0017000; + +% Eqn (4) of Weiss 1970 +lnC = a1 + a2.*(100./T) + a3.*log(T./100) + a4.*(T./100) + ... + S.*( b1 + b2.*(T./100) + b3.*((T./100).^2) ); + +c = exp(lnC); + +return + diff --git a/M_Csiro/sw_seck.m b/M_Csiro/sw_seck.m new file mode 100644 index 0000000..ae1dc17 --- /dev/null +++ b/M_Csiro/sw_seck.m @@ -0,0 +1,167 @@ + +function K = sw_seck(S,T,P) + +% SW_SECK Secant bulk modulus (K) of sea water +%========================================================================= +% SW_SECK $Revision: 1.3 $ $Date: 1994/10/10 05:50:45 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: dens = sw_seck(S,T,P) +% +% DESCRIPTION: +% Secant Bulk Modulus (K) of Sea Water using Equation of state 1980. +% UNESCO polynomial implementation. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (alternatively, may have dimensions 1*1 or 1*n where n is columns in S) +% +% OUTPUT: +% K = Secant Bulk Modulus [bars] +% +% AUTHOR: Phil Morgan 92-11-05 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +% Eqn.(15) p.18 +% +% Millero, F.J. and Poisson, A. +% International one-atmosphere equation of state of seawater. +% Deep-Sea Res. 1981. Vol28A(6) pp625-629. +%========================================================================= + +% CALLER: sw_dens.m +% CALLEE: none + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=3 + error('sw_seck.m: Must pass 3 parameters') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +%-------------------------------------------------------------------- +% COMPUTE COMPRESSION TERMS +%-------------------------------------------------------------------- +P = P/10; %convert from db to atmospheric pressure units + +% Pure water terms of the secant bulk modulus at atmos pressure. +% UNESCO eqn 19 p 18 + +h3 = -5.77905E-7; +h2 = +1.16092E-4; +h1 = +1.43713E-3; +h0 = +3.239908; %[-0.1194975]; + +%AW = h0 + h1*T + h2*T.^2 + h3*T.^3; +AW = h0 + (h1 + (h2 + h3.*T).*T).*T; + +k2 = 5.2787E-8; +k1 = -6.12293E-6; +k0 = +8.50935E-5; %[+3.47718E-5]; + +BW = k0 + (k1 + k2*T).*T; +%BW = k0 + k1*T + k2*T.^2; + +e4 = -5.155288E-5; +e3 = +1.360477E-2; +e2 = -2.327105; +e1 = +148.4206; +e0 = 19652.21; %[-1930.06]; + +KW = e0 + (e1 + (e2 + (e3 + e4*T).*T).*T).*T; % eqn 19 +%KW = e0 + e1*T + e2*T.^2 + e3*T.^3 + e4*T.^4; + +%-------------------------------------------------------------------- +% SEA WATER TERMS OF SECANT BULK MODULUS AT ATMOS PRESSURE. +%-------------------------------------------------------------------- +j0 = 1.91075E-4; + +i2 = -1.6078E-6; +i1 = -1.0981E-5; +i0 = 2.2838E-3; + +SR = sqrt(S); + +A = AW + (i0 + (i1 + i2*T).*T + j0*SR).*S; +%A = AW + (i0 + i1*T + i2*T.^2 + j0*SR).*S; % eqn 17 + + +m2 = 9.1697E-10; +m1 = +2.0816E-8; +m0 = -9.9348E-7; + +B = BW + (m0 + (m1 + m2*T).*T).*S; % eqn 18 +%B = BW + (m0 + m1*T + m2*T.^2).*S; % eqn 18 + + +f3 = -6.1670E-5; +f2 = +1.09987E-2; +f1 = -0.603459; +f0 = +54.6746; + +g2 = -5.3009E-4; +g1 = +1.6483E-2; +g0 = +7.944E-2; + +K0 = KW + ( f0 + (f1 + (f2 + f3*T).*T).*T ... + + (g0 + (g1 + g2*T).*T).*SR ).*S; % eqn 16 + +%K0 = KW + (f0 + f1*T + f2*T.^2 + f3*T.^3).*S ... +% + (g0 + g1*T + g2*T.^2).*SR.*S; % eqn 16 + +K = K0 + (A + B.*P).*P; % eqn 15 + +if Transpose + K = K'; +end %if + +return +%---------------------------------------------------------------------------- + diff --git a/M_Csiro/sw_smow.m b/M_Csiro/sw_smow.m new file mode 100644 index 0000000..725e5e2 --- /dev/null +++ b/M_Csiro/sw_smow.m @@ -0,0 +1,69 @@ + +function dens = sw_smow(T) + +% SW_SMOW Denisty of standard mean ocean water (pure water) +%========================================================================= +% SW_SMOW $Revision: 1.3 $ $Date: 1994/10/10 05:51:46 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: dens = sw_smow(T) +% +% DESCRIPTION: +% Denisty of Standard Mean Ocean Water (Pure Water) using EOS 1980. +% +% INPUT: +% T = temperature [degree C (IPTS-68)] +% +% OUTPUT: +% dens = density [kg/m^3] +% +% AUTHOR: Phil Morgan 92-11-05 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +% UNESCO 1983 p17 Eqn(14) +% +% Millero, F.J & Poisson, A. +% INternational one-atmosphere equation of state for seawater. +% Deep-Sea Research Vol28A No.6. 1981 625-629. Eqn (6) +%========================================================================= + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +% TEST INPUTS +if nargin ~= 1 + error('sw_smow.m: Only one input argument allowed') +end %if + +Transpose = 0; +[mT,nT] = size(T); +if mT == 1 % a row vector + T = T(:); + Tranpose = 1; +end %if + +%---------------------- +% DEFINE CONSTANTS +%---------------------- +a0 = 999.842594; +a1 = 6.793952e-2; +a2 = -9.095290e-3; +a3 = 1.001685e-4; +a4 = -1.120083e-6; +a5 = 6.536332e-9; + +dens = a0 + (a1 + (a2 + (a3 + (a4 + a5*T).*T).*T).*T).*T; + +if Transpose + dens = dens'; +end %if + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_svan.m b/M_Csiro/sw_svan.m new file mode 100644 index 0000000..c714431 --- /dev/null +++ b/M_Csiro/sw_svan.m @@ -0,0 +1,104 @@ + +function svan = sw_svan(S,T,P) + +% SW_SVAN Specific volume anomaly +%========================================================================= +% SW_SVAN $Revision: 1.3 $ $Date: 1994/10/10 05:52:20 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: svan = sw_svan(S,T,P) +% +% DESCRIPTION: +% Specific Volume Anomaly calculated as +% svan = 1/sw_dens(s,t,p) - 1/sw_dens(35,0,p) +% Note that it is often quoted in literature as 1e8*units +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% T = temperature [degree C (IPTS-68)] +% P = Pressure [db] +% (alternatively, may have dimensions 1*1 or 1*n where n is columns in S) +% +% OUTPUT: +% svan = Specific Volume Anomaly [m^3 kg^-1] +% +% AUTHOR: Phil Morgan 92-11-05 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCE: +% Fofonoff, N.P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +% Eqn (9) p.15. +% +% S. Pond & G.Pickard 2nd Edition 1986 +% Introductory Dynamical Oceanogrpahy +% Pergamon Press Sydney. ISBN 0-08-028728-X +%========================================================================= + +% +% CALLER: general purpose +% CALLEE: sw_dens.m + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=3 + error('sw_svan.m: Must pass 3 parameters') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + + +% ----- +% BEGIN +% ----- +svan = ( ones(size(S)) ./ sw_dens(S,T,P)) - ... + (ones(size(S)) ./ sw_dens(35*ones(size(S)),zeros(size(S)),P) ); + +if Transpose + svan = svan'; +end %if + +return +%-------------------------------------------------------------------- + diff --git a/M_Csiro/sw_svel.m b/M_Csiro/sw_svel.m new file mode 100644 index 0000000..f3dff2f --- /dev/null +++ b/M_Csiro/sw_svel.m @@ -0,0 +1,181 @@ + +function svel = sw_svel(S,T,P) + +% SW_SVEL Sound velocity of sea water +%========================================================================= +% SW_SVEL $Revision: 1.3 $ $Date: 1994/10/10 05:53:00 $ +% Copyright (C) CSIRO, Phil Morgan 1993. +% +% USAGE: svel = sw_svel(S,T,P) +% +% DESCRIPTION: +% Sound Velocity in sea water using UNESCO 1983 polynomial. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78)] +% T = temperature [degree C (IPTS-68)] +% P = pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% svel = sound velocity [m/s] +% +% AUTHOR: Phil Morgan 93-04-20 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +%========================================================================= + +% CALLER: general purpose +% CALLEE: none + +% UNESCO 1983. eqn.33 p.46 + +%---------------------- +% CHECK INPUT ARGUMENTS +%---------------------- +if nargin ~=3 + error('sw_svel.m: Must pass 3 parameters') +end %if + +% CHECK S,T,P dimensions and verify consistent +[ms,ns] = size(S); +[mt,nt] = size(T); +[mp,np] = size(P); + + +% CHECK THAT S & T HAVE SAME SHAPE +if (ms~=mt) | (ns~=nt) + error('check_stp: S & T must have same dimensions') +end %if + +% CHECK OPTIONAL SHAPES FOR P +if mp==1 & np==1 % P is a scalar. Fill to size of S + P = P(1)*ones(ms,ns); +elseif np==ns & mp==1 % P is row vector with same cols as S + P = P( ones(1,ms), : ); % Copy down each column. +elseif mp==ms & np==1 % P is column vector + P = P( :, ones(1,ns) ); % Copy across each row +elseif mp==ms & np==ns % PR is a matrix size(S) + % shape ok +else + error('check_stp: P has wrong dimensions') +end %if +[mp,np] = size(P); + + + +% IF ALL ROW VECTORS ARE PASSED THEN LET US PRESERVE SHAPE ON RETURN. +Transpose = 0; +if mp == 1 % row vector + P = P(:); + T = T(:); + S = S(:); + + Transpose = 1; +end %if +%***check_stp + +%--------- +% BEGIN +%-------- + +P = P/10; % convert db to bars as used in UNESCO routines + +%------------ +% eqn 34 p.46 +%------------ +c00 = 1402.388; +c01 = 5.03711; +c02 = -5.80852e-2; +c03 = 3.3420e-4; +c04 = -1.47800e-6; +c05 = 3.1464e-9; + +c10 = 0.153563; +c11 = 6.8982e-4; +c12 = -8.1788e-6; +c13 = 1.3621e-7; +c14 = -6.1185e-10; + +c20 = 3.1260e-5; +c21 = -1.7107e-6; +c22 = 2.5974e-8; +c23 = -2.5335e-10; +c24 = 1.0405e-12; + +c30 = -9.7729e-9; +c31 = 3.8504e-10; +c32 = -2.3643e-12; + +Cw = c00 + c01.*T + c02.*T.^2 + c03.*T.^3 + c04.*T.^4 + c05.*T.^5 ... + + (c10 + c11.*T + c12.*T.^2 + c13.*T.^3 + c14.*T.^4).*P ... + + (c20 + c21.*T + c22.*T.^2 + c23.*T.^3 + c24.*T.^4).*P.^2 ... + + (c30 + c31.*T + c32.*T.^2).*P.^3; + +%------------- +% eqn 35. p.47 +%------------- +a00 = 1.389; +a01 = -1.262e-2; +a02 = 7.164e-5; +a03 = 2.006e-6; +a04 = -3.21e-8; + +a10 = 9.4742e-5; +a11 = -1.2580e-5; +a12 = -6.4885e-8; +a13 = 1.0507e-8; +a14 = -2.0122e-10; + +a20 = -3.9064e-7; +a21 = 9.1041e-9; +a22 = -1.6002e-10; +a23 = 7.988e-12; + +a30 = 1.100e-10; +a31 = 6.649e-12; +a32 = -3.389e-13; + +A = a00 + a01.*T + a02.*T.^2 + a03.*T.^3 + a04.*T.^4 ... + + (a10 + a11.*T + a12.*T.^2 + a13.*T.^3 + a14.*T.^4).*P ... + + (a20 + a21.*T + a22.*T.^2 + a23.*T.^3).*P.^2 ... + + (a30 + a31.*T + a32.*T.^2).*P.^3; + + +%------------ +% eqn 36 p.47 +%------------ +b00 = -1.922e-2; +b01 = -4.42e-5; +b10 = 7.3637e-5; +b11 = 1.7945e-7; + +B = b00 + b01.*T + (b10 + b11.*T).*P; + +%------------ +% eqn 37 p.47 +%------------ +d00 = 1.727e-3; +d10 = -7.9836e-6; + +D = d00 + d10.*P; + +%------------ +% eqn 33 p.46 +%------------ +svel = Cw + A.*S + B.*S.*sqrt(S) + D.*S.^2; + +if Transpose + svel = svel'; +end %if + +return +%-------------------------------------------------------------------------- + diff --git a/M_Csiro/sw_temp.m b/M_Csiro/sw_temp.m new file mode 100644 index 0000000..c62e569 --- /dev/null +++ b/M_Csiro/sw_temp.m @@ -0,0 +1,59 @@ + +function PT = sw_temp(S,T,P,PR) + +% SW_TEMP Temperature from potential temperature +%=========================================================================== +% TEMP $Revision: 1.3 $ $Date: 1994/10/10 05:53:39 $ +% Copyright (C) CSIRO, Phil Morgan 1992. +% +% USAGE: temp = sw_temp(S,PTMP,P,PR) +% +% DESCRIPTION: +% Calculates temperature from potential temperature at the reference +% pressure PR and in-situ pressure P. +% +% INPUT: (all must have same dimensions) +% S = salinity [psu (PSS-78) ] +% PTMP = potential temperature [degree C (IPTS-68)] +% P = pressure [db] +% PR = Reference pressure [db] +% (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) ) +% +% OUTPUT: +% temp = temperature [degree C (IPTS-68)] +% +% AUTHOR: Phil Morgan 92-04-06 (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +% REFERENCES: +% Fofonoff, P. and Millard, R.C. Jr +% Unesco 1983. Algorithms for computation of fundamental properties of +% seawater, 1983. _Unesco Tech. Pap. in Mar. Sci._, No. 44, 53 pp. +% Eqn.(31) p.39 +% +% Bryden, H. 1973. +% "New Polynomials for thermal expansion, adiabatic temperature gradient +% and potential temperature of sea water." +% DEEP-SEA RES., 1973, Vol20,401-408. +%========================================================================= + +% CALLER: general purpose +% CALLEE: sw_ptmp.m + +%------------- +% CHECK INPUTS +%------------- +if nargin ~= 4 + error('sw_temp.m: Must pass 4 parameters ') +end %if +% LET sw_ptmp.m DO DIMENSION CHECKING + +% CARRY OUT INVERSE CALCULATION BY SWAPPING P0 & PR. +PT = sw_ptmp(S,T,PR,P); + +return +%========================================================================= + diff --git a/M_Csiro/sw_test.m b/M_Csiro/sw_test.m new file mode 100644 index 0000000..26f2350 --- /dev/null +++ b/M_Csiro/sw_test.m @@ -0,0 +1,600 @@ + +function [] = sw_test() + +% SW_TEST Test SEAWATER Library Routines +%========================================================================= +% SW_TEST $Revision: 1.4 $ $Date: 1998/04/22 02:08:04 $ +% Copyright (C) CSIRO, Phil Morgan 1994 +% +% sw_test +% +% DESCRIPTION: +% Execute test routines to test and verify SEAWATER Library routines +% for your platform. Prints output to screen and to file sw_test.txt +% +% Use the "more" command to scroll results to screen +% +% OUTPUT: +% file sw_test.txt +% +% AUTHOR: Phil Morgan (morgan@ml.csiro.au) +% +% DISCLAIMER: +% This software is provided "as is" without warranty of any kind. +% See the file sw_copy.m for conditions of use and licence. +% +%========================================================================= + +delete sw_test.txt +disp('OUTPUT FROM THIS TEST WILL ALSO BE SAVED IN FILE sw_test.txt') +disp(' <enter> to continue...') +pause +reply = input('Full listing of help for each routine (y/n) ? ','s'); +display_help = strcmp(reply,'y') | strcmp(reply,'Y'); + +format compact +echo off +diary sw_test.txt + +disp( '***********************') +disp( ' TEST REPORT ') +disp( ' ') +disp( ' SEA WATER LIBRARY ') +disp( ' ') +sw_ver +disp( ' ') +disp(['Matlab Version ' version ]) +disp( ' ') +disp([' ' date '']) +disp( '***********************') + +disp(' ') + +%-------------------------------- +% TEST MAIN MODULE sw_ptmp.m +% SUB-MODULES sw_atg.m +%-------------------------------- +module = 'sw_ptmp'; +submodules = 'sw_adtg.m'; +disp('*************************************') +disp(['** TESTING MODULE: ' module]) +disp(['** and SUB-MODULE: ' submodules]) +disp('*************************************') +if display_help + eval(['help ' module]) + eval(['help ' submodules]) +end %if + +% TEST 1 - data from Unesco 1983 p45 + +T = [ 0 0 0 0 0 0; + 10 10 10 10 10 10; + 20 20 20 20 20 20; + 30 30 30 30 30 30; + 40 40 40 40 40 40 ]; + +S = [25 25 25 35 35 35; + 25 25 25 35 35 35; + 25 25 25 35 35 35 ; + 25 25 25 35 35 35; + 25 25 25 35 35 35 ]; + +P = [0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000 ; + 0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000 ]; + +Pr = [0 0 0 0 0 0]; + +UN_ptmp = [ 0 -0.3061 -0.9667 0 -0.3856 -1.0974; + 10 9.3531 8.4684 10 9.2906 8.3643; + 20 19.0438 17.9426 20 18.9985 17.8654; + 30 28.7512 27.4353 30 28.7231 27.3851; + 40 38.4607 36.9254 40 38.4498 36.9023]; + +ptmp = sw_ptmp(S,T,P,Pr); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from UNESCO 1983 ') +disp (' (Unesco Tech. Paper in Marine Sci. No. 44, p45)') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') + +for icol = 1:length(S(1,:)) +disp(' ') +disp (' Sal Temp Press PTMP sw_ptmp') +disp (' (psu) (C) (db) (C) (C)') + fprintf(1,' %4.0f %4.0f %5.0f %8.4f %11.5f\n', ... + [S(:,icol) T(:,icol) P(:,icol) UN_ptmp(:,icol) ptmp(:,icol)]'); +end %for + +%------------------------------------------------------------------------------- +% TEST MAIN MODULE sw_svan.m +% SUB-MODULES sw_dens.m sw_dens0.m sw_smow.m sw_seck.m sw_pden.m sw_ptmp.m +%------------------------------------------------------------------------------ +module = 'sw_svan.m'; +submodules = 'sw_dens.m sw_dens0.m sw_smow.m sw_seck.m sw_pden.m sw_ptmp.m'; +disp(' ') +disp('************************************************************************') +disp(['** TESTING MODULE: ' module]) +disp(['** and SUB-MODULE: ' submodules]) +disp('************************************************************************') +if display_help + eval(['help ' module]) + eval(['help ' submodules]) +end %if + +% TEST DATA FROM +% Unesco Tech. Paper in Marine Sci. No. 44, p22 + +s = [0 0 0 0 35 35 35 35]'; +p = [0 10000 0 10000 0 10000 0 10000]'; +t = [0 0 30 30 0 0 30 30]'; + +UN_svan = [2749.54 2288.61 3170.58 3147.85 ... + 0.0 0.00 607.14 916.34]'; + +svan = sw_svan(s,t,p); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from UNESCO 1983') +disp (' (Unesco Tech. Paper in Marine Sci. No. 44, p22)') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') +disp(' ') +disp (' Sal Temp Press SVAN sw_svan') +disp (' (psu) (C) (db) (1e-8*m3/kg) (1e-8*m3/kg)') +fprintf(1,' %4.0f %4.0f %5.0f %11.2f %11.3f\n',[s t p UN_svan 1e+8*svan]'); + +%------------------------------------------------------------------------------- +% TEST MAIN MODULE +% SUB-MODULES +%------------------------------------------------------------------------------ +module = 'sw_salt.m'; +submodules = 'sw_salrt.m sw_salrp.m sw_sals.m'; +disp(' ') +disp('************************************************************************') +disp(['** TESTING MODULE: ' module]) +disp(['** and SUB-MODULE: ' submodules]) +disp('************************************************************************') +if display_help + eval(['help ' module]) + eval(['help ' submodules]) +end %if + +% TEST 1 - data from Unesco 1983 p9 +%*************************************************************************** + +R = [1 1.2 0.65]'; % cndr = R +T = [15 20 5]'; +P = [0 2000 1500]'; + +Rt = [1 1.0568875 0.81705885]'; +UN_S = [35 37.245628 27.995347]'; +S = sw_salt(R,T,P); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from UNESCO 1983 ') +disp (' (Unesco Tech. Paper in Marine Sci. No. 44, p9)') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') +disp(' ') +disp (' Temp Press R S sw_salt') +disp (' (C) (db) (no units) (psu) (psu) ') +table = [T P R UN_S S]'; +fprintf(1,' %4.0f %4.0f %8.2f %11.6f %14.7f\n', table); + +%------------------------------------------------------------------------------- +% TEST MAIN MODULE +% SUB-MODULES +%------------------------------------------------------------------------------ +module = 'sw_cndr.m'; +submodules = 'sw_salds.m'; +disp(' ') +disp('************************************************************************') +disp(['** TESTING MODULE: ' module]) +disp(['** and SUB-MODULE: ' submodules]) +disp('************************************************************************') +if display_help + eval(['help ' module]) + eval(['help ' submodules]) +end %if + +% TEST 1 - data from Unesco 1983 p9 + +T = [0 10 0 10 10 30]'; +P = [0 0 1000 1000 0 0]'; +S = [25 25 25 25 40 40]'; +UN_R = [ 0.498088 0.654990 0.506244 0.662975 1.000073 1.529967]'; +R = sw_cndr(S,T,P); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from UNESCO 1983 ') +disp (' (Unesco Tech. Paper in Marine Sci. No. 44, p14)') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') +disp(' ') +disp (' Temp Press S cndr sw_cndr') +disp (' (C) (db) (psu) (no units) (no units) ') +table = [T P S UN_R R]'; +fprintf(1,' %4.0f %4.0f %8.6f %11.6f %14.8f\n', table); + +%------------------------------------------------------------------------------- +% TEST MAIN MODULE +% SUB-MODULES +%------------------------------------------------------------------------------ +module = 'sw_dpth.m'; +disp(' ') +disp('************************************************************************') +disp(['** TESTING MODULE: ' module]) +disp('************************************************************************') +if display_help + eval(['help ' module]) +end %if + +% TEST DATA - matrix "pressure", vector "lat" Unesco 1983 data p30. + +lat = [0 30 45 90]; +P = [ 500 500 500 500; + 5000 5000 5000 5000; + 10000 10000 10000 10000]; + +UN_dpth = [ 496.65 496.00 495.34 494.03; + 4915.04 4908.56 4902.08 4889.13; + 9725.47 9712.65 9699.84 9674.23]; + +dpth = sw_dpth(P,lat); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from Unesco 1983 ') +disp (' (Unesco Tech. Paper in Marine Sci. No. 44, p28)') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') + +for irow = 1:3 + disp(' ') + disp (' Lat Press DPTH sw_dpth') + disp (' (degree) (db) (meter) (meter)') + table = [lat' P(irow,:)' UN_dpth(irow,:)' dpth(irow,:)']; + fprintf(1,' %6.3f %6.0f %8.2f %8.3f\n', table') +end %for + +%------------------------------------------------------------------------------- +% TEST MAIN MODULE +% SUB-MODULES +%------------------------------------------------------------------------------ +module = 'sw_fp.m'; +disp(' ') +disp('************************************************************************') +disp(['** TESTING MODULE: ' module]) +disp('************************************************************************') +if display_help + eval(['help ' module]) +end %if + +% TEST 1 - +% UNESCO DATA p.30 +%*************************************************************************** +S = [ 5 10 15 20 25 30 35 40; + 5 10 15 20 25 30 35 40]; + +P = [ 0 0 0 0 0 0 0 0; + 500 500 500 500 500 500 500 500]; + + +UN_fp = [-0.274 -0.542 -0.812 -1.083 -1.358 -1.638 -1.922 -2.212; + -0.650 -0.919 -1.188 -1.460 -1.735 -2.014 -2.299 -2.589]; + +fp = sw_fp(S,P); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from UNESCO 1983 ') +disp (' (Unesco Tech. Paper in Marine Sci. No. 44, p30)') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') + +for irow = 1:2 + disp(' ') + disp (' Sal Press fp sw_fp') + disp (' (psu) (db) (C) (C)') + table = [S(irow,:); P(irow,:); UN_fp(irow,:); fp(irow,:)]; + fprintf(1,' %4.0f %5.0f %8.3f %11.4f\n', table) +end %for + +%------------------------------------------------------------------------------- +% TEST MAIN MODULE +% SUB-MODULES +%------------------------------------------------------------------------------ +module = 'sw_cp.m'; +disp(' ') +disp('************************************************************************') +disp(['** TESTING MODULE: ' module]) +disp('************************************************************************') +if display_help + eval(['help ' module]) +end %if + +% TEST 1 - +% DATA FROM POND AND PICKARD INTRO. DYNAMICAL OCEANOGRAPHY 2ND ED. 1986 +%*************************************************************************** + +T = [ 0 0 0 0 0 0; + 10 10 10 10 10 10; + 20 20 20 20 20 20; + 30 30 30 30 30 30; + 40 40 40 40 40 40 ]; + +S = [25 25 25 35 35 35; + 25 25 25 35 35 35; + 25 25 25 35 35 35 ; + 25 25 25 35 35 35; + 25 25 25 35 35 35 ]; + +P = [0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000 ; + 0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000 ]; + +UN_cp = [ 4048.4 3896.3 3807.7 3986.5 3849.3 3769.1; + 4041.8 3919.6 3842.3 3986.3 3874.7 3804.4; + 4044.8 3938.6 3866.7 3993.9 3895.0 3828.3; + 4049.1 3952.0 3883.0 4000.7 3909.2 3844.3; + 4051.2 3966.1 3905.9 4003.5 3923.9 3868.3 ]; + +cp = sw_cp(S,T,P); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from UNESCO 1983 ') +disp (' (Unesco Tech. Paper in Marine Sci. No. 44, p37)') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') + +for icol = 1:length(S(1,:)) + disp(' ') + disp (' Sal Temp Press Cp sw_cp') + disp (' (psu) (C) (db) (J/kg.C) (J/kg.C)') + fprintf(1,' %4.0f %4.0f %5.0f %8.1f %11.2f\n', ... + [S(:,icol) T(:,icol) P(:,icol) UN_cp(:,icol) cp(:,icol)]'); +end %for + +%------------------------------------------------------------------------------- +% TEST MAIN MODULE +% SUB-MODULES +%------------------------------------------------------------------------------ +module = 'sw_svel.m'; +disp(' ') +disp('************************************************************************') +disp(['** TESTING MODULE: ' module]) +disp('************************************************************************') +if display_help + eval(['help ' module]) +end %if + +% TEST 1 - +% DATA FROM POND AND PICKARD INTRO. DYNAMICAL OCEANOGRAPHY 2ND ED. 1986 +%*************************************************************************** + +T = [ 0 0 0 0 0 0; + 10 10 10 10 10 10; + 20 20 20 20 20 20; + 30 30 30 30 30 30; + 40 40 40 40 40 40 ]; + +S = [25 25 25 35 35 35; + 25 25 25 35 35 35; + 25 25 25 35 35 35 ; + 25 25 25 35 35 35; + 25 25 25 35 35 35 ]; + +P = [0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000 ; + 0 5000 10000 0 5000 10000; + 0 5000 10000 0 5000 10000 ]; + +UN_svel = [1435.8 1520.4 1610.4 1449.1 1534.0 1623.2; + 1477.7 1561.3 1647.4 1489.8 1573.4 1659.0; + 1510.3 1593.6 1676.8 1521.5 1604.5 1687.2; + 1535.2 1619.0 1700.6 1545.6 1629.0 1710.1; + 1553.4 1638.0 1719.2 1563.2 1647.3 1727.8 ]; + +svel = sw_svel(S,T,P); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from UNESCO 1983 ') +disp (' (Unesco Tech. Paper in Marine Sci. No. 44, p50)') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') + +for icol = 1:length(S(1,:)) + disp(' ') + disp (' Sal Temp Press SVEL sw_svel') + disp (' (psu) (C) (db) (m/s) (m/s)') + fprintf(1,' %4.0f %4.0f %5.0f %8.1f %11.3f\n', ... + [S(:,icol) T(:,icol) P(:,icol) UN_svel(:,icol) svel(:,icol)]'); +end %for + +%---------------------------------------------------------------------------- +% TEST MAIN MODULE +% SUB-MODULES +%--------------------------------------------------------------------------- +submodules = 'sw_alpha.m sw_beta.m sw_aonb.m'; +disp(' ') +disp('**********************************************************************') +disp(['** TESTING MODULE: ' submodules]) +disp('**********************************************************************') +if display_help + eval(['help ' submodules]) +end %if + +% DATA FROM MCDOUOGALL 1987 +s = 40; +ptmp = 10; +p = 4000; +beta_lit = 0.72088e-03; +aonb_lit = 0.34763; +alpha_lit = aonb_lit*beta_lit; + +%$$$ % TEST ARGUMENT PASSING +%$$$ beta = sw_beta(s,ptmp,p,'ptmp') +%$$$ beta = sw_beta(s,ptmp,p,'temp') +%$$$ beta = sw_beta(s,ptmp,p) +%$$$ +%$$$ alpha = sw_alpha(s,ptmp,p,'ptmp') +%$$$ alpha = sw_alpha(s,ptmp,p,'temp') +%$$$ alpha = sw_alpha(s,ptmp,p) +%$$$ +%$$$ aonb = sw_aonb( s,ptmp,p,'ptmp') +%$$$ aonb = sw_aonb( s,ptmp,p,'temp') +%$$$ aonb = sw_aonb( s,ptmp,p) +%$$$ +beta = sw_beta( s,ptmp,p,'ptmp'); +alpha = sw_alpha(s,ptmp,p,'ptmp'); +aonb = sw_aonb( s,ptmp,p,'ptmp'); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from MCDOUGALL 1987 ') +disp (['with computed results on ' computer ' computer']) +disp ('********************************************************') + + disp(' ') + disp (' Sal Temp Press BETA sw_beta') + disp (' (psu) (C) (db) (psu^-1) (psu^-1)') + fprintf(1,' %4.0f %4.0f %5.0f %11.4e %11.5e\n', ... + [s ptmp p beta_lit beta]'); + + disp(' ') + disp (' Sal Temp Press AONB sw_aonb') + disp (' (psu) (C) (db) (psu C^-1) (psu C^-1)') + fprintf(1,' %4.0f %4.0f %5.0f %8.5f %11.6f\n', ... + [s ptmp p aonb_lit aonb]'); + + disp(' ') + disp (' Sal Temp Press ALPHA sw_alpha') + disp (' (psu) (C) (db) (psu^-1) (psu^-1)') + fprintf(1,' %4.0f %4.0f %5.0f %11.4e %11.4e\n', ... + [s ptmp p alpha_lit alpha]'); + +%-------------------------------- +% TEST MAIN MODULE sw_satO2.m +% SUB-MODULES +%-------------------------------- +module = 'sw_satO2 sw_satN2 sw_satAr'; +disp(' ') +disp('*************************************') +disp(['** TESTING MODULE: ' module]) +disp(['** and SUB-MODULE: ' submodules]) +disp('*************************************') +if display_help + eval(['help ' module]) +end %if + +% Data from Weiss 1970 + +T = [-1 -1; + 10 10; + 20 20 ; + 40 40 ]; + +S = [20 40; + 20 40; + 20 40 ; + 20 40]; + +lit_O2= [ 9.162 7.984; + 6.950 6.121; + 5.644 5.015; + 4.050 3.656]; + +lit_N2= [16.28 14.01; + 12.64 11.01; + 10.47 9.21; + 7.78 6.95]; + +lit_Ar= [ 0.4456 0.3877; + 0.3397 0.2989; + 0.2766 0.2457; + 0.1986 0.1794]; + + +satO2 = sw_satO2(S,T); +satN2 = sw_satN2(S,T); +satAr = sw_satAr(S,T); + +%---------------- +% DISPLAY RESULTS +%---------------- +disp(' ') +disp ('********************************************************') +disp ('Comparison of accepted values from Weiss, R.F. 1979 ') +disp ('"The solubility of nitrogen, oxygen and argon in water and seawater."') +disp (' Deap-Sea Research., 1970, Vol 17, pp721-735.') +disp (['with computed results from ' module ' on ' computer ' computer']) +disp ('********************************************************') + +for icol = 1:length(S(1,:)) +disp(' ') +disp (' Sal Temp O2 sw_satO2') +disp (' (psu) (C) (ml/l) (ml/l)') + fprintf(1,' %4.0f %4.0f %8.2f %9.3f\n', ... + [S(:,icol) T(:,icol) lit_O2(:,icol) satO2(:,icol)]'); +end %for + +for icol = 1:length(S(1,:)) +disp(' ') +disp (' Sal Temp N2 sw_satN2') +disp (' (psu) (C) (ml/l) (ml/l)') + fprintf(1,' %4.0f %4.0f %8.2f %9.3f\n', ... + [S(:,icol) T(:,icol) lit_N2(:,icol) satN2(:,icol)]'); +end %for + +for icol = 1:length(S(1,:)) +disp(' ') +disp (' Sal Temp Ar sw_satAr') +disp (' (psu) (C) (ml/l) (ml/l)') + fprintf(1,' %4.0f %4.0f %8.4f %9.4f\n', ... + [S(:,icol) T(:,icol) lit_Ar(:,icol) satAr(:,icol)]'); +end %for + +diary off +return + +%-------------------------------------------------------------------- diff --git a/tsg_io/readTsgDataLabview.m b/tsg_io/readTsgDataLabview.m index 4778fef..7a44159 100644 --- a/tsg_io/readTsgDataLabview.m +++ b/tsg_io/readTsgDataLabview.m @@ -165,6 +165,7 @@ if fid ~= -1 % -------------------------------------------- %tsg.SSPS_QC = tsg.qc.active.Code * ones(length(noNaN),1); tsg.SSPS_QC = castByteQC( tsg.qc.active.Code, noNaN ); + tsg.SSJT_QC = castByteQC( tsg.qc.active.Code, noNaN ); % populate tsg.file structure % --------------------------- diff --git a/tsg_util/calibration.m b/tsg_util/calibration.m new file mode 100644 index 0000000..8ff5810 --- /dev/null +++ b/tsg_util/calibration.m @@ -0,0 +1,39 @@ +function calibration( hMainFig ) +% +% Compute salinity from calibrated conductivity and jacket temperature +% + +% Get tsg application data +% ------------------------ +tsg = getappdata( hMainFig, 'tsg_data' ); + +if ~isempty( tsg.CNDC ) + cndcCal = tsg.CNDC_LINCOEF(1) * tsg.CNDC + tsg.CNDC_LINCOEF(2); +else + msgbox( 'Conductivity not loaded',... + 'Function ''Calibration''',... + 'warn', 'modal'); +end + +if ~isempty( tsg.SSJT ) + ssjtCal = tsg.SSJT_LINCOEF(1) * tsg.SSJT + tsg.SSJT_LINCOEF(2); +else + msgbox( 'Jacket temperature not loaded',... + 'Function ''Calibration''',... + 'warn', 'modal'); +end + +% Compute salinity - Use CSIRO functions +% -------------------------------------- +tsg.SSPS_CAL = sw_salt( ... + cndcCal/sw_c3515(), t90TOt68(ssjtCal), zeros(size(cndcCal))); + +% Keep SSJT calibrated +% -------------------- +tsg.SSJT_CAL = ssjtCal; + +% Save tsg application data +% -------------------------- +setappdata( hMainFig, 'tsg_data', tsg ); + +end diff --git a/tsg_util/corTsgLinear.m b/tsg_util/corTsgLinear.m index b5ce9e0..f466796 100644 --- a/tsg_util/corTsgLinear.m +++ b/tsg_util/corTsgLinear.m @@ -26,9 +26,9 @@ if dateMax > dateMin % intialisation % ------------- if isempty( tsg.SSPS_ADJUSTED ) - tsg.SSPS_ADJUSTED = tsg.SSPS; - tsg.SSPS_ADJUSTED_ERROR = NaN * ones( size( tsg.SSPS ) ); - tsg.SSPS_ADJUSTED_QC = tsg.SSPS_QC; + msgbox( 'Variable SSPS_ADJUSTED should be initialise in updateTsgStruct',... + 'Function ''corTsgLinear''',... + 'warn', 'modal'); end % Find samples within TIME_WINDOWS with Good and probably Good QC diff --git a/tsg_util/corTsgMedian.m b/tsg_util/corTsgMedian.m index 8245a21..316feb0 100644 --- a/tsg_util/corTsgMedian.m +++ b/tsg_util/corTsgMedian.m @@ -43,9 +43,9 @@ if dateMax > dateMin % intialisation % ------------- if isempty( tsg.SSPS_ADJUSTED ) - tsg.SSPS_ADJUSTED = tsg.SSPS; - tsg.SSPS_ADJUSTED_ERROR = NaN * ones( size( tsg.SSPS ) ); - tsg.SSPS_ADJUSTED_QC = tsg.SSPS_QC; + msgbox( 'Variable SSPS_ADJUSTED should be initialise in updateTsgStruct',... + 'Function ''corTsgMedian''',... + 'warn', 'modal'); end % Find the indices of samples within the time limits. diff --git a/tsg_util/plot_Calibration.m b/tsg_util/plot_Calibration.m index 2638031..9305746 100644 --- a/tsg_util/plot_Calibration.m +++ b/tsg_util/plot_Calibration.m @@ -7,7 +7,7 @@ tsg = getappdata( hMainFig, 'tsg_data'); switch nPlot % --------------------------------------------------------------------- - % Plot SSPS and SSPS_CAL + % Plot SSPS in black and SSPS_CAL in red case 1 erase_Line( hPlotAxes, 1 ); @@ -18,23 +18,22 @@ switch nPlot if ~isempty( tsg.SSPS_CAL ) plot_Tsg( hMainFig, hPlotAxes, 1, tsg.DAYD, tsg.SSPS_CAL, [],... - 'SSPS_CAL','r','none','*',2); + 'SSPS_CAL','r','none','o',2); end % --------------------------------------------------------------------- - % Plot SSPS in Black and SSPS with no position value in Red + % Plot SSJT in black and SSJT_CAL in red case 2 erase_Line( hPlotAxes, 2 ); - if ~isempty( tsg.SSPS ) - plot_Tsg( hMainFig, hPlotAxes, 2, tsg.DAYD, tsg.SSPS,[],... - 'SSPS','k','none','*',2); + if ~isempty( tsg.SSJT ) + plot_Tsg( hMainFig, hPlotAxes, 2, tsg.DAYD, tsg.SSJT,[],... + 'SSJT','k','none','*',2); end - ind = find( isnan(tsg.LATX) == 1 ); - if ~isempty( ind ) - plot_Tsg( hMainFig, hPlotAxes, 2, tsg.DAYD(ind), tsg.SSPS(ind),[],... - 'SSPS_NaN','r','none','*',2); + if ~isempty( tsg.SSJT_CAL ) + plot_Tsg( hMainFig, hPlotAxes, 2, tsg.DAYD, tsg.SSJT_CAL,[],... + 'SSJT_CAL','r','none','*',2); end diff --git a/tsg_util/t90TOt68.m b/tsg_util/t90TOt68.m new file mode 100644 index 0000000..15ade3f --- /dev/null +++ b/tsg_util/t90TOt68.m @@ -0,0 +1,7 @@ +function [t68] = t90TOt68( t90 ) + +if ~isempty( t90 ) + t68 = 1.00024 * t90; +end + +end diff --git a/tsg_util/updateAdjustedVariable.m b/tsg_util/updateAdjustedVariable.m new file mode 100644 index 0000000..63c1a7b --- /dev/null +++ b/tsg_util/updateAdjustedVariable.m @@ -0,0 +1,59 @@ +function updateAdjustedVariable( hMainFig ) +% +% Update adjusted SSPS and SSJT arrays once calibration has been +% applied to these variable. +% +% The TRICK : +% Test ADJUSTED_ERROR - Only records corrected compared to water sample +% get error values +% + +% Get tsg application data +% ------------------------ +tsg = getappdata( hMainFig, 'tsg_data' ); + +% Get VALUE_CHANGED +% ------------------------------------------------------- +VALUE_CHANGED = get(tsg.qc.hash, 'VALUE_CHANGED', 'code'); + +% SSPS +% Get Adjusted records that were not corrected using Water samples +% Only records corrected get error values +% ---------------------------------------------------------------- +ind = find( isnan(tsg.SSPS_ADJUSTED_ERROR ) == 1); + +if ~isempty(tsg.SSPS_CAL) + tsg.SSPS_ADJUSTED(ind) = tsg.SSPS_CAL(ind); + tsg.SSPS_ADJUSTED_QC(ind) = VALUE_CHANGED; +else + + % If the calibration has been canceled the ADJUSTED value is equal to + % the raw value + % ------------------------------------------------------------------- + tsg.SSPS_ADJUSTED(ind) = tsg.SSPS(ind); + tsg.SSPS_ADJUSTED_QC(ind) = tsg.SSPS_QC(ind); +end + +% SSJT +% Get Adjusted records that were not corrected using Water samples +% Only records corrected get error values +% ---------------------------------------------------------------- +ind = find( isnan(tsg.SSJT_ADJUSTED_ERROR ) == 1); + +if ~isempty(tsg.SSJT_CAL) + tsg.SSJT_ADJUSTED(ind) = tsg.SSJT_CAL(ind); + tsg.SSJT_ADJUSTED_QC(ind) = VALUE_CHANGED; +else + + % If the calibration has been canceled the ADJUSTED value is equal to + % the raw value + % ------------------------------------------------------------------- + tsg.SSJT_ADJUSTED(ind) = tsg.SSJT(ind); + tsg.SSJT_ADJUSTED_QC(ind) = tsg.SSJT_QC(ind); +end + +% Save tsg application data +% -------------------------- +setappdata( hMainFig, 'tsg_data', tsg ); + +end \ No newline at end of file diff --git a/tsg_util/updateTsgStruct.m b/tsg_util/updateTsgStruct.m index af236b0..5a67ab5 100644 --- a/tsg_util/updateTsgStruct.m +++ b/tsg_util/updateTsgStruct.m @@ -22,23 +22,56 @@ tsg.EAST_LONX = max(tsg.LONX); % get date start and end value and set to globals attributes % ----------------------------------------------------------------- -date = datestr(min(tsg.DAYD),30); +date = datestr(min(tsg.DAYD),30); tsg.DATE_START = [date(1:8) date(10:15)]; -date = datestr(max(tsg.DAYD),30); +date = datestr(max(tsg.DAYD),30); tsg.DATE_END = [date(1:8) date(10:15)]; % Compute ship velocity from positions if sog not available % --------------------------------------------------------- if isempty(tsg.SPDC) - range = m_lldist(tsg.LONX,tsg.LATX); - ind = size(tsg.DAYD); + range = m_lldist(tsg.LONX,tsg.LATX); + ind = size(tsg.DAYD); tsg.SPDC = zeros(size(ind)); + for i=1:length(tsg.DAYD)-1 tsg.SPDC(i) = range(i) / ((tsg.DAYD(i+1)-tsg.DAYD(i)) * 24 * 1.854); end tsg.SPDC = [tsg.SPDC';0]; end +% Initialise ADJUSTED variables if empty +% -------------------------------------- +if isempty( tsg.SSPS_ADJUSTED ) && ~isempty( tsg.SSPS ) + tsg.SSPS_ADJUSTED = tsg.SSPS; + tsg.SSPS_ADJUSTED_QC = tsg.SSPS_QC; + tsg.SSPS_ADJUSTED_ERROR = NaN * ones( size( tsg.SSPS )); + +elseif isempty( tsg.SSPS ) + + msgbox('You must initialise the tsg.SSPS variable',... + 'function ''updateTsgStruct''', .... + 'warn', 'modal'); +end + +if isempty( tsg.SSJT_ADJUSTED ) && ~isempty( tsg.SSJT ) + tsg.SSJT_ADJUSTED = tsg.SSJT; + tsg.SSJT_ADJUSTED_QC = tsg.SSJT_QC; + tsg.SSJT_ADJUSTED_ERROR = NaN * ones( size( tsg.SSJT )); + +elseif isempty( tsg.SSJT ) + + msgbox('You must initialise the tsg.SSJT variable',... + 'function ''updateTsgStruct''', .... + 'warn', 'modal'); +end + +if isempty( tsg.SSPS_ADJUSTED ) && ~isempty( tsg.SSPS ) + tsg.SSPT_ADJUSTED = tsg.SSPT; + tsg.SSPT_ADJUSTED_QC = tsg.SSPT_QC; + tsg.SSPT_ADJUSTED_ERROR = NaN * ones( size( tsg.SSPS )); +end + % Save tsg structure % ------------------ setappdata( hTsgGUI, 'tsg_data', tsg); diff --git a/tsgcor_GUI.m b/tsgcor_GUI.m deleted file mode 100644 index 6220fb1..0000000 --- a/tsgcor_GUI.m +++ /dev/null @@ -1,665 +0,0 @@ -function tsgcor_GUI( hTsgGUI ) -% tsgcor_GUI -% -% GUI for correction of TSG data by comparison to samples -% this GUI is a children of tsgqc_GUI -% -% - -%% COPYRIGHT & LICENSE -% Copyright 2007 - IRD US191, all rights reserved. -% -% This file is part of tsgqc_GUI. -% -% Datagui is free software; you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation; either version 2 of the License, or -% (at your option) any later version. -% -% tsgqc_GUI is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with Datagui; if not, write to the Free Software -% Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -%% Initialization tasks -% ******************** -clc - -% Screen limits for the GUI -% ------------------------- -set(0,'Units','normalized'); -guiLimits = get(0,'ScreenSize'); -guiLimits(1) = guiLimits(1) + 0.05; -guiLimits(2) = guiLimits(2) + 0.05; -guiLimits(3) = guiLimits(3) - 0.1; -guiLimits(4) = guiLimits(4) - 0.2; - -% Create and then hide the GUI as it is being constructed. -% -------------------------------------------------------- -hTsgCorGUI = figure(... - 'Name', 'TSG Correction', ... - 'NumberTitle', 'off', ... - 'Resize', 'on', ... - 'Menubar','none', ... - 'Toolbar', 'none', ... - 'Tag', 'ButtonMotionOff', ... - 'WindowButtonMotionFcn', @MouseMotion, ... - 'CloseRequestFcn', @QuitProgram,... - 'HandleVisibility','callback',... - 'Visible','on',... - 'Units', 'normalized',... - 'Position',guiLimits); - -% Get the CONSTANTS -% ----------------- -cst = getappdata( hTsgGUI, 'constante'); - -% Construct the Menu -% ----------------- -hFileMenu = uimenu(... - 'Parent', hTsgCorGUI,... - 'HandleVisibility','callback',... - 'Label', 'File'); - -hQuitMenu = uimenu(... - 'Parent',hFileMenu,... - 'Label','Quit',... - 'Separator','on',... - 'Accelerator','Q',... - 'HandleVisibility','callback',... - 'Callback',@QuitMenuCallback); - -%% Construct the Toolbar -% -------------------- -hToolbar = uitoolbar(... % Toolbar for Open and Print buttons - 'Parent',hTsgCorGUI, ... - 'HandleVisibility','callback'); -hZoomToggletool = uitoggletool(... % Open Zoom toolbar button - 'Parent',hToolbar,... - 'Separator', 'on', ... - 'TooltipString','Zoom',... - 'CData', iconRead(fullfile(matlabroot, ... - '/toolbox/matlab/icons/zoom.mat')),... - 'HandleVisibility','callback', ... - 'Tag','PUSHTOOL_ZOOM',... - 'Enable', 'off',... - 'OffCallback', @Zoom_OffMenuCallback,... - 'ONCallback', @Zoom_OnMenuCallback); -hPanToggletool = uitoggletool(... % Open Pan toolbar button - 'Parent',hToolbar,... - 'TooltipString','Pan',... - 'CData',iconRead(fullfile(matlabroot, ... - '/toolbox/matlab/icons/pan.mat')),... - 'HandleVisibility','callback', ... - 'Tag','PUSHTOOL_PAN',... - 'Enable', 'off',... - 'OffCallback', @Pan_OffMenuCallback,... - 'ONCallback', @Pan_OnMenuCallback); - %'ClickedCallback', @PanMenuCallback); - -hBottlePushtool = uipushtool(... % Open toolbar button - 'Parent',hToolbar,... - 'TooltipString','Plot the Samples',... - 'Separator', 'on', ... - 'Tag', 'off', ... - 'CData',iconRead(... - [DEFAULT_PATH_FILE 'tsg_icon' filesep 'bottleicon.mat']),... - 'HandleVisibility','callback', ... - 'ClickedCallback', @BottleMenuCallback); -hStartlimitPushtool = uipushtool(... % Open toolbar button - 'Parent',hToolbar,... - 'TooltipString','Start time',... - 'Separator', 'on', ... - 'Tag', 'off', ... - 'CData',iconRead(... - [DEFAULT_PATH_FILE 'tsg_icon' filesep 'startlimit.mat']),... - 'HandleVisibility','callback', ... - 'ClickedCallback', @TimeLimitCallback); -hEndlimitPushtool = uipushtool(... % Open toolbar button - 'Parent',hToolbar,... - 'TooltipString','End time',... - 'Tag', 'off', ... - 'CData',iconRead(... - [DEFAULT_PATH_FILE 'tsg_icon' filesep 'endlimit.mat']),... - 'HandleVisibility','callback', ... - 'ClickedCallback', @TimeLimitCallback); - -% Static text that displays the position, salinity and temperature -% ---------------------------------------------------------------- -hInfoText = uicontrol(... - 'Parent', hTsgCorGUI, ... - 'Style', 'text', ... - 'Fontsize', 12, ... - 'Fontweight', 'bold', ... - 'Visible','on',... - 'Units', 'normalized',... - 'String', 'Information sur la position du curseur', ... - 'Position', [.05, .95, .9, .03]); - -% Construct the plot axes -% ----------------------- -hPlotAxes(1) = axes(... % the axes for plotting Salinity - 'Parent', hTsgCorGUI, ... - 'Units', 'normalized', ... - 'Visible', 'off', ... - 'HandleVisibility','callback', ... - 'Position',[.25, .6, .7, .32]); -hPlotAxes(2) = axes(... % the axes for plotting sample - 'Parent', hTsgCorGUI, ... - 'Units', 'normalized', ... - 'Visible', 'off', ... - 'HandleVisibility','callback', ... - 'Position',[.25, .3, .7, .25]); -hPlotAxes(3) = axes(... % the axes for plotting ship velocity - 'Parent', hTsgCorGUI, ... - 'Units', 'normalized', ... - 'Visible', 'off', ... - 'HandleVisibility','callback', ... - 'Position',[.25, .05, .7, .2]); - - % Choose the date limits for the correction - % -------------------------------------------------- - % Create the uipanel - hpDateLimit = uipanel( ... - 'Parent', hTsgCorGUI, ... - 'Title', 'Date Limits', ... - 'Units', 'normalized', ... - 'FontSize', 11, ... - 'Fontweight', 'bold', ... - 'BackgroundColor', 'white',... - 'Position',[.01 .75 .2 .19]); - - htDateMin = uicontrol( ... - 'Parent', hpDateLimit, ... - 'Style', 'Text', ... - 'String', 'Minimum (yyyy-mm-dd hh:mm:ss)', ... - 'HorizontalAlignment', 'left', ... - 'Units', 'normalized', ... - 'backgroundcolor', 'white', ... - 'FontSize', 10, ... - 'Position',[.05 .8 .9 .15]); - - hetDateMin = uicontrol( ... - 'Parent', hpDateLimit, ... - 'Style', 'edit', ... - 'Units', 'normalized', ... - 'FontSize', 10, ... - 'Position',[.05 .6 .9 .18]); - - htDateMax = uicontrol( ... - 'Parent', hpDateLimit, ... - 'Style', 'Text', ... - 'String', 'Maximum (yyyy-mm-dd hh:mm:ss)', ... - 'HorizontalAlignment', 'left', ... - 'Units', 'normalized', ... - 'backgroundcolor', 'white', ... - 'FontSize', 10, ... - 'Position',[.05 .3 .9 .15]); - - hetDateMax = uicontrol( ... - 'Parent', hpDateLimit, ... - 'Style', 'edit', ... - 'Units', 'normalized', ... - 'FontSize', 10, ... - 'Position',[.05 .1 .9 .18]); - - - % Choose the correction method - % -------------------------------------------------- - % Create the button group - hbgMethod = uibuttongroup( ... - 'Parent',hTsgCorGUI, ... - 'Title','Correction Method', ... - 'Units', 'normalized', ... - 'FontSize',11, ... - 'Fontweight', 'bold', ... - 'BackgroundColor','white',... - 'Position',[.01 .6 .2 .14]); - - % Create 2 radio buttons in the button group - hrbLinear = uicontrol( ... - 'Style','pushbutton', ... - 'Parent',hbgMethod, ... - 'Units', 'normalized', ... - 'String','Linear adjustment',... - 'pos',[.05 .55 .9 .4], ... - 'HandleVisibility','callback', ... - 'Callback', @CorLinearCallback); - - hrbMedian = uicontrol( ... - 'Style','pushbutton', ... - 'Parent',hbgMethod, ... - 'Units', 'normalized', ... - 'String','Running median filter',... - 'pos',[.05 .05 .9 .4],... - 'HandleVisibility','callback', ... - 'Callback', @CorMedianCallback); - - - % Initialize some button group properties - set(hbgMethod,'SelectionChangeFcn',@selcbk); - set(hbgMethod,'SelectedObject',[]); % No selection - set(hbgMethod,'Visible','on'); - - % Construct the context menu to delete samples - % -------------------------------------------- - hSampleCmenu = uicontextmenu(... - 'Parent', hTsgCorGUI, ... - 'HandleVisibility','callback' ); - hQcSampleNocontrol = uimenu(... - 'Parent', hSampleCmenu,... - 'HandleVisibility','off', ... - 'Label', 'No control',... - 'ForegroundColor', 'k',... - 'Callback', @Qc); - hQcSampleGood = uimenu(... - 'Parent', hSampleCmenu,... - 'HandleVisibility','off', ... - 'Label', 'Good',... - 'ForegroundColor', 'b',... - 'Callback', @Qc); - hQcSampleBad = uimenu(... - 'Parent', hSampleCmenu,... - 'HandleVisibility','off', ... - 'Label', 'Bad',... - 'ForegroundColor', 'r',... - 'Callback', @Qc); - - - - -% Pointer set to watch during reading and plotting -% ------------------------------------------------ -set( hTsgCorGUI, 'Pointer', 'watch' ); - -% Get the data useful to the correction GUI -% ----------------------------------------- -tsg = getappdata( hTsgGUI, 'tsg_data' ); - -% Merge bucket and external samples -% --------------------------------- -tsg_mergesample( hTsgGUI ); - - - -dateMin = datestr(tsg.TIME(1), 31); -dateMax = datestr(tsg.TIME(end), 31); -set( hetDateMin, 'String', dateMin); -set( hetDateMax, 'String', dateMax); - -% dt between 2 tsg measurements -TSG_SAMPLING_TIME = tsg.TIME(2) - tsg.TIME(1); - -% Running average of TSG time series over TSG_DT_SMOOTH hour. -[psal_smooth, nval] = ... - dev_moveaverage(tsg.TIME, tsg.PSAL, cst.TSG_DT_SMOOTH, cst.TSG_STDMAX); - -% Compute the sample-TSG differences -sample = dev_diffTsgSample(tsg, psal_smooth, sample, TSG_SAMPLING_TIME); - -% Tracé -% ----- -tsg_plot_SalTsgSample( hTsgGUI, hPlotAxes ); - -% Pointer reset to arrow -% ---------------------- -set( hTsgCorGUI, 'Pointer', 'arrow' ); - -% The callback to detect the mouse motion can be set to on -% -------------------------------------------------------- -set( hTsgCorGUI, 'Tag', 'ButtonMotionOn'); - -% Callbacks for tsgcqc_GUI -% ************************ - - %---------------------------------------------------------------------- - function ZoomMenuCallback(hObject, eventdata) - % Callback function run when the ... - - % Returns a zoom mode object for the figure handle - % ------------------------------------------------ - hZoom = zoom(hTsgCorGUI); - - % Specifies whether this mode is currently enabled on the figure - % -------------------------------------------------------------- - zoomOnOff = get(hZoom, 'Enable' ); - switch zoomOnOff - case 'on' - zoom off - zoomAdaptiveDateTicks('off'); - case 'off' - pan off - set(hTsgCorGUI,'Pointer','arrow'); - set(hEndlimitPushtool, 'Tag', 'off' ); - set(hStartlimitPushtool, 'Tag', 'off' ); - - zoom on - zoomAdaptiveDateTicks('on'); - end - end - - %---------------------------------------------------------------------- - function PanMenuCallback(hObject, eventdata) - % Callback function run when the .... - - % Returns a pan mode object for the figure handle - % ----------------------------------------------- - hPan = pan(hTsgCorGUI); - - % Specifies whether this mode is currently enabled on the figure - % -------------------------------------------------------------- - panOnOff = get(hPan, 'Enable' ); - switch panOnOff - case 'on' - pan off - panAdaptiveDateTicks('off'); - case 'off' - zoom off - set(hTsgCorGUI,'Pointer','arrow'); - set(hEndlimitPushtool, 'Tag', 'off' ); - set(hStartlimitPushtool, 'Tag', 'off' ); - - pan on - panAdaptiveDateTicks('on'); - end - end - - %---------------------------------------------------------------------- - function TimeLimitCallback(hObject, eventdata) - % Callback function run when the .... - - % Desactivate the Zoom and Pan functions. - % --------------------------------------- - zoom off; pan off - panAdaptiveDateTicks('off');zoomAdaptiveDateTicks('off'); - - % Retrieve named application data - % ------------------------------- - tsg = getappdata( hTsgGUI, 'tsg_data'); - - % Toggle the tag of the Qc pushbutton to 'on' or 'off' - % ---------------------------------------------------- - switch get(hObject, 'Tag'); - case 'off' - set(hObject, 'Tag', 'on' ); - set( hTsgCorGUI, 'Pointer', 'crosshair'); - case 'on' - set(hObject, 'Tag', 'off' ); - set(hTsgCorGUI,'Pointer','arrow'); - end - - % Wait for key press - % ------------------ - [x, y] = ginput(1); - - % Write the date in the Editable uicontrol - % ---------------------------------------- - if hObject == hEndlimitPushtool - set( hetDateMax, 'String', datestr(x, 31)); - else - set( hetDateMin, 'String', datestr(x, 31)); - end - - set(hTsgCorGUI,'Pointer','arrow'); - - end - -%---------------------------------------------------------------------- - function BottleMenuCallback(gcbo, eventdata,handles) - % Callback function run when the QC pushbutton is selected - - % Desactivate the Zoom and Pan functions. - % --------------------------------------- - zoom off; pan off - panAdaptiveDateTicks('off');zoomAdaptiveDateTicks('off'); - - % Toggle the tag of the Qc pushbutton to 'on' or 'off' - % ---------------------------------------------------- - switch get(hBottlePushtool, 'Tag'); - case 'off' - set(hBottlePushtool, 'Tag', 'on' ); - set(hPlotAxes(2),'UIContextMenu', hSampleCmenu); - set(hTsgCorGUI, 'Pointer', 'crosshair'); - case 'on' - set(hBottlePushtool, 'Tag', 'off' ); - set(hPlotAxes(2),'UIContextMenu', []); - set(hTsgCorGUI,'Pointer','arrow'); - end - - qualityCode = -1; - ind = []; - while strcmp( get(hBottlePushtool, 'Tag'),'on') - - k = waitforbuttonpress; - - % If the QC pushbutton is pressed we quit the callback - % ---------------------------------------------------- - if strcmp( get(hBottlePushtool, 'Tag'),'off') - - % Desactivate the context menu use to choose the Quality Codes - % ---------------------------------------------- - set(hSampleCmenu, 'Visible', 'off'); - break - end - - % Test if the right mouse button is clicked - % ----------------------------------------- - if strcmp(get(hTsgCorGUI, 'SelectionType'), 'alt') && ~isempty(ind) - - % Wait for a QC Context Menu choice : The user choose the - % quality code - % ------------------------------------------------------- - uiwait - qualityCode = 1; - - else - - % Mouse motion callback desactivated when a selection is made. - % Otherwise there is a conflict with the map if it is activated - % ------------------------------------------------------- - set( hTsgCorGUI, 'Tag', 'ButtonMotionOff'); - - % Selection of the data within the figure - % --------------------------------------- - point1 = get(gca,'CurrentPoint'); % button down detected - finalRect = rbbox; % return figure units - point2 = get(gca,'CurrentPoint'); % button up detected - - point1 = point1(1,1:2); % extract x and y - point2 = point2(1,1:2); - - p1 = min(point1,point2); - p2 = max(point1,point2); % calculate locations - - % Retrieve named application data - % ------------------------------- - sample = getappdata( hTsgGUI, 'sample'); - - ind = find(sample.DAYD > p1(1,1) & sample.DAYD < p2(1,1) & ... - sample.SSPS_DIF > p1(1,2) & sample.SSPS_DIF < p2(1,2)); - - % Selection made : Mouse motion callback re-activated - % --------------------------------------------------- - set( hTsgCorGUI, 'Tag', 'ButtonMotionOn'); - - end - - % Plot the data with the color of the chosen quality Code. - % Is it the right place for this source code ???? - % -------------------------------------------------------- - if qualityCode ~= -1 - - tsg = getappdata( hTsgGUI, 'tsg_data'); - - sample.SSPS_QC(ind) = tsg.qc.Code.ACTIVE; - - % Save the modifications - % ---------------------- - setappdata( hTsgGUI, 'sample', sample); - - axes(hPlotAxes(2)); - hold on - color = ['o' tsg.qc.Color.ACTIVE]; - plot(sample.DAYD(ind), sample.SSPS_DIF(ind), color ); - hold off - end - end - end - -%--------------------------------------------------------------------- -function Qc(hObject, eventdata) - % Callback function run when the QC context menu is selected - - % Retrieve Default Quality Code and Color - % --------------------------------------- - tsg = getappdata( hTsgGUI, 'qcColor'); - - switch hObject - case hQcSampleNocontrol - tsg.qc.Code.ACTIVE = tsg.qc.Code.NO_CONTROL; - tsg.qc.Color.ACTIVE = tsg.qc.Color.NO_CONTROL; - case hQcSampleGood - tsg.qc.Code.ACTIVE = tsg.qc.Code.GOOD; - tsg.qc.Color.ACTIVE = tsg.qc.Color.GOOD; - case hQcSampleBad - tsg.qc.Code.ACTIVE = tsg.qc.Code.PROBABLY_BAD; - tsg.qc.Color.ACTIVE = tsg.qc.Color.PROBABLY_BAD; - end - - setappdata( hMainFig, 'tsg_data', tsg ); - - % uiwait in the QCMenuCallback function - % ------------------------------------- - uiresume -end - - %--------------------------------------------------------------------- - function MouseMotion(hObject, eventdata) - - % Test if the callback can be activated - % ------------------------------------- - if strcmp( get( hTsgCorGUI, 'Tag'), 'ButtonMotionOn') - - % Retrieve named application data - % ------------------------------- - tsg = getappdata( hTsgGUI, 'tsg_data'); - - % Get the mouse position - % ---------------------- - point = get(gcf,'CurrentPoint'); - - if point(1) > .05 && point(2) > .6 && point(1) < .95 && point(2) < .92 - - % Get current position of cusor and return its coordinates in - % axes with handle h_axes - % ----------------------------------------------------------- - [x, y] = gpos(hPlotAxes(1)); - - if x > tsg.TIME(1) && x < tsg.TIME(end) - - indCursor = find( tsg.TIME > x); - % use sprintf with format instead strcat & num2str but flag - % - don't work with 0, eg %+07.4f - set( hInfoText, 'String',... - sprintf(['%s - Latitude = %s - Longitude = %s '... - ' - Salinity = %07.4f - Temperature = %07.4f'],... - datestr(tsg.TIME(indCursor(1)),'dd/mm/yyyy HH:MM'),... - dd2dm(tsg.LATITUDE(indCursor(1)),0), ... - dd2dm(tsg.LONGITUDE(indCursor(1)),1), ... - tsg.PSAL(indCursor(1)), ... - tsg.TEMP_TSG(indCursor(1))... - )); - - end - end - end - end - - % ----------------------------------------------------------------- - function SaveMenuCallback(hObject, eventdata) - % Callback function run when the Save menu item is selected - -% [fileName, pathName, filterIndex] = uiputfile('*.txt', ... -% 'Save file name'); - -% fileName = [pathName fileName]; -% error = tsg_writeTsgData( hTsgGUI, fileName ); -% if ~error - % -% end - end - - % ----------------------------------------------------------------- - function CorLinearCallback(hObject, eventdata) - % Callback function run when - - msgbox('Method not yet implemented', 'modal' ); - - end - - % ----------------------------------------------------------------- - function CorMedianCallback(hObject, eventdata) - % Callback function run when - - msgbox('Method not yet implemented', 'modal' ); - - % Get the time limits for the correction A TESTER - % -------------------------------------- - %dateMin = get( hetDateMin, 'String'); - %dateMax = get( hetDateMax, 'String'); - - % Correction - % ---------- - % tsg = dev_corMethod1(tsg, sample, dateMin, dateMax, cst.COR_TIME_WINDOWS); - - % Update application data 'tsg' - % ---------------------------- - %tsg = getappdata( hTsgGUI, 'tsg_data' ); - - end - - - % ----------------------------------------------------------------- - function QuitMenuCallback(hObject, eventdata) - % Callback function run when the Quit menu item is selected - - % If the data have been modified and not save, the program - % propose to save the data - % -------------------------------------------------------- - if strcmp( get( hSaveMenu, 'Tag' ), 'on') - selection = ... - questdlg('The file has been modified. Do you want to save it ?',... - 'Save before Quit?',... - 'Yes', 'No', 'Yes'); - if strcmp(selection, 'Yes') - return; - else - QuitProgram; - end - else - selection = ... - questdlg(['Quit ' get(hTsgCorGUI, 'Name') '?'],... - ['Quit ' get(hTsgCorGUI, 'Name') '?'],... - 'Yes', 'No', 'Yes'); - if strcmp(selection, 'No') - return; - else - QuitProgram; - end - end - - end - - % ---------------------------------------------------------------- - function QuitProgram(hObject, eventdata) - - delete(hTsgCorGUI); - - end - -end diff --git a/tsgqc_GUI.m b/tsgqc_GUI.m index ff48a8e..ed4e03a 100644 --- a/tsgqc_GUI.m +++ b/tsgqc_GUI.m @@ -753,94 +753,87 @@ hetDateMax = uicontrol( ... hpCalCoef = uipanel( ... 'Parent', hMainFig, ... 'Title', 'Calibration', ... - 'Units', 'normalized', ... 'FontSize', tsg.fontSize-1, 'Fontweight', 'bold', ... 'Visible', 'off', ... - 'Position', [.0, .68, .15, .28]); + 'Units', 'normalized','Position', [.0, .64, .15, .32]); htCalCNDC1 = uicontrol( ... 'Parent', hpCalCoef, ... - 'Style', 'Text', 'String', 'Conductivity : C = A*C +B', ... - 'Units', 'normalized', ... + 'Style', 'Text', 'String', 'Conductivity : C = A*C + B', ... 'HorizontalAlignment', 'left', 'FontSize', tsg.fontSize-1, ... - 'Position',[.01 .85 .95 .1]); + 'Units', 'normalized', 'Position',[.01 .89 .95 .1]); htCalCNDC2 = uicontrol( ... 'Parent', hpCalCoef, ... 'Style', 'Text', 'String', 'A', ... - 'Units', 'normalized', ... 'HorizontalAlignment', 'left', 'FontSize', tsg.fontSize-1, ... - 'Position',[.01 .75 .08 .1]); + 'Units', 'normalized', 'Position',[.01 .8 .08 .1]); hetCalCNDCSlope = uicontrol( ... 'Parent', hpCalCoef, ... 'Style', 'edit', ... - 'Units', 'normalized', ... - 'BackgroundColor', 'white',... - 'FontSize', tsg.fontSize, ... + 'FontSize', tsg.fontSize, 'BackgroundColor', 'white',... 'Tag', 'CORRECT_CAL_CNDC_A',... 'HandleVisibility','on', ... - 'Position',[.1 .75 .85 .10]); + 'Units', 'normalized', 'Position',[.1 .8 .85 .10]); htCalCNDC3 = uicontrol( ... 'Parent', hpCalCoef, ... 'Style', 'Text', 'String', 'B', ... - 'Units', 'normalized', ... 'HorizontalAlignment', 'left', 'FontSize', tsg.fontSize-1, ... - 'Position',[.01 .6 .08 .1]); + 'Units', 'normalized', 'Position',[.01 .68 .08 .1]); hetCalCNDCOffset = uicontrol( ... 'Parent', hpCalCoef, ... 'Style', 'edit', ... - 'Units', 'normalized', ... - 'BackgroundColor', 'white',... - 'FontSize', tsg.fontSize, ... + 'FontSize', tsg.fontSize, 'BackgroundColor', 'white',... 'HandleVisibility','on', ... 'Tag', 'CORRECT_CAL_CNDC_B',... - 'Position',[.1 .6 .85 .10]); + 'Units', 'normalized', 'Position',[.1 .68 .85 .10]); htCalSSJT1 = uicontrol( ... 'Parent', hpCalCoef, ... - 'Style', 'Text', 'String', 'SSJT : T = A*T +B', ... - 'Units', 'normalized', ... + 'Style', 'Text', 'String', 'SSJT : T = A*T + B', ... 'HorizontalAlignment', 'left', 'FontSize', tsg.fontSize-1, ... - 'Position',[.01 .45 .95 .1]); + 'Units', 'normalized', 'Position',[.01 .55 .95 .1]); htCalSSJT2 = uicontrol( ... 'Parent', hpCalCoef, ... 'Style', 'Text', 'String', 'A', ... - 'Units', 'normalized', ... 'HorizontalAlignment', 'left', 'FontSize', tsg.fontSize-1, ... - 'Position',[.01 .35 .08 .1]); + 'Units', 'normalized', 'Position',[.01 .45 .08 .1]); hetCalSSJTSlope = uicontrol( ... 'Parent', hpCalCoef, ... 'Style', 'edit', ... - 'Units', 'normalized', ... 'BackgroundColor', 'white',... 'FontSize', tsg.fontSize, ... 'HandleVisibility','on', ... 'Tag', 'CORRECT_CAL_SSJT_A',... - 'Position',[.1 .35 .85 .10]); + 'Units', 'normalized', 'Position',[.1 .45 .85 .10]); htCalSSJT3 = uicontrol( ... 'Parent', hpCalCoef, ... 'Style', 'Text', 'String', 'B', ... - 'Units', 'normalized', ... 'HorizontalAlignment', 'left', 'FontSize', tsg.fontSize-1, ... - 'Position',[.01 .2 .08 .1]); + 'Units', 'normalized', 'Position',[.01 .32 .08 .1]); hetCalSSJTOffset = uicontrol( ... 'Parent', hpCalCoef, ... 'Style', 'edit', ... - 'Units', 'normalized', ... 'FontSize', tsg.fontSize, 'BackgroundColor', 'white',... 'HandleVisibility','on', ... 'Tag', 'CORRECT_CAL_SSJT_B',... - 'Position',[.1 .2 .85 .10]); + 'Units', 'normalized', 'Position',[.1 .32 .85 .10]); hrbCal = uicontrol( ... - 'Style','pushbutton', ... - 'Parent',hpCalCoef, ... - 'Units', 'normalized', ... + 'Style','pushbutton', 'Parent',hpCalCoef, ... 'String','Calibrate',... 'FontSize',tsg.fontSize-1,... 'Tag', 'CORRECT_CAL_PUSH', ... - 'pos',[.05 .04 .9 .13], ... + 'Units', 'normalized','pos',[.05 .17 .9 .1], ... 'HandleVisibility','callback', ... 'Callback', @CalibrateCallback); + hrbCancelCal = uicontrol( ... + 'Style','pushbutton', 'Parent',hpCalCoef, ... + 'String','Cancel calibration',... + 'FontSize',tsg.fontSize-1,... + 'Tag', 'CORRECT_CAL_PUSH', ... + 'Units', 'normalized','pos',[.05 .04 .9 .1], ... + 'HandleVisibility','callback', ... + 'Callback', @CancelCalibrationCallback); @@ -1151,6 +1144,73 @@ end end +%% CalibrateCallback .......................................... Calibration + function CalibrateCallback(hObject, eventdata) + % Callback function run when + + % Get tsg application data + % ------------------------ + tsg = getappdata( hMainFig, 'tsg_data' ); + + % Get the calibration coefficients + % -------------------------------- + tsg.CNDC_LINCOEF(1) = str2num(get( hetCalCNDCSlope, 'String')); + tsg.CNDC_LINCOEF(2) = str2num(get( hetCalCNDCOffset, 'String')); + tsg.SSJT_LINCOEF(1) = str2num(get( hetCalSSJTSlope, 'String')); + tsg.SSJT_LINCOEF(2) = str2num(get( hetCalSSJTOffset, 'String')); + + % Save tsg application data + % -------------------------- + setappdata( hMainFig, 'tsg_data', tsg ); + + % Calibrate the sensors + % --------------------- + calibration( hMainFig ); + + % Update the Adjusted variables (SSPS - SSJT) with calibrated records + % ------------------------------------------------------------------- + updateAdjustedVariable( hMainFig ); + + % Refresh plot #1 + % --------------- + plot_Calibration( hMainFig, hPlotAxes, 1 ); + plot_Calibration( hMainFig, hPlotAxes, 2 ); + + % As soon as a modification took place the data should be saved + % ------------------------------------------------------------- + set( hSaveMenu, 'UserData', 'on' ); + + end + +%% CancelCalibrationCallback .................................. Calibration + function CancelCalibrationCallback(hObject, eventdata) + % Callback function run when + + % Get tsg application data + % ------------------------ + tsg = getappdata( hMainFig, 'tsg_data' ); + + tsg.SSPS_CAL = []; + tsg.SSJT_CAL = []; + + % Update the Adjusted variables (SSPS - SSJT) with calibrated records + % ------------------------------------------------------------------- + updateAdjustedVariable( hMainFig ); + + % Save tsg application data + % -------------------------- + setappdata( hMainFig, 'tsg_data', tsg ); + + % Refresh plot #1 + % --------------- + plot_Calibration( hMainFig, hPlotAxes, 1 ); + plot_Calibration( hMainFig, hPlotAxes, 2 ); + + % As soon as a modification took place the data should be saved + % ------------------------------------------------------------- + set( hSaveMenu, 'UserData', 'on' ); + + end %% Zoom_OffMenuCallback %---------------------------------------------------------------------- @@ -1801,91 +1861,6 @@ end end -%% SelectTime_OnMenuCallback ............................ Correction module -%---------------------------------------------------------------------- - function SelectTime_OnMenuCallback(hObject, eventdata) - % Callback function run when the .... - - % Desactivate Zoom and Pan functions. - % ---------------------------------- - set( hZoomToggletool, 'state', 'off' ); - set( hQCToggletool, 'state', 'off' ); - set( hPanToggletool, 'state', 'off' ); - - % Create a pointer to select the time limits - % ------------------------------------------ - selTimePointer = ones(16)+1; - selTimePointer(1,:) = 1; selTimePointer(16,:) = 1; - selTimePointer(:,1) = 1; selTimePointer(:,16) = 1; - selTimePointer(1:4,8:9) = 1; selTimePointer(13:16,8:9) = 1; - selTimePointer(8:9,1:4) = 1; selTimePointer(8:9,13:16) = 1; - selTimePointer(5:12,5:12) = NaN; % Create a transparent region in the center - - % Activate clic mouse menu on second axes (salinity) for next rbbox - % ---------------------------------------------------------------- - set(hMainFig,'WindowButtonDownFcn', @Time_SelectCallback); - - % change cursor - % --------------- - set( hMainFig, 'Pointer', 'custom',... - 'PointerShapeCData', selTimePointer, 'PointerShapeHotSpot',[9 9]); - - % ---------------------------------------------------------------------- - % nested function on mouse clic when Select Time toggle tool is selected - % ---------------------------------------------------------------------- - function Time_SelectCallback(gcbo, eventdata) - - % disable ButtonMotion on main fig during select - % prevent drawing to map - % ---------------------------------------------- - set( hMainFig, 'WindowButtonMotionFcn', []); - - % Retrieve named application data - % ------------------------------- - tsg = getappdata( hMainFig, 'tsg_data'); - - % Selection of the data within the figure - % --------------------------------------- - point1 = get(gca,'CurrentPoint'); % button down detected - finalRect = rbbox; % return figure units - point2 = get(gca,'CurrentPoint'); % button up detected - - point1 = point1(1,1:2); % extract x and y - point2 = point2(1,1:2); - - p1 = min(point1,point2); - p2 = max(point1,point2); % calculate locations - - % get index on selected zone - Only on X axes (time) - % -------------------------------------------------- - ind = find(tsg.DAYD >= p1(1,1) & tsg.DAYD <= p2(1,1)); - - % Write the date in the Editable uicontrol - % ---------------------------------------- - set( hetDateMin, 'String', datestr(tsg.DAYD(ind(1)), 31)); - set( hetDateMax, 'String', datestr(tsg.DAYD(ind(end)), 31)); - - % enable ButtonMotion on main fig after select QC area - % ---------------------------------------------------- - set( hMainFig, 'WindowButtonMotionFcn', @MouseMotion); - end - end - -%% SelectTime_OffMenuCallback ........................... Correction module -%-------------------------------------------------------------------------- - function SelectTime_OffMenuCallback(hObject, eventdata) - % Callback function run when the .... - - % Desactivate time limit buttons - % ------------------------------ - set( hTimelimitToggletool, 'state', 'off'); - - set( hMainFig,'WindowButtonDownFcn', []); - - set(hMainFig,'Pointer','arrow'); - - end - %% CorCancelCallback .................................... Correction Module function CorCancelCallback(hObject, eventdata) % Callback function run when ... @@ -1989,6 +1964,91 @@ end end +%% SelectTime_OnMenuCallback +%--------------------------- + function SelectTime_OnMenuCallback(hObject, eventdata) + % Callback function run when the .... + + % Desactivate Zoom and Pan functions. + % ---------------------------------- + set( hZoomToggletool, 'state', 'off' ); + set( hQCToggletool, 'state', 'off' ); + set( hPanToggletool, 'state', 'off' ); + + % Create a pointer to select the time limits + % ------------------------------------------ + selTimePointer = ones(16)+1; + selTimePointer(1,:) = 1; selTimePointer(16,:) = 1; + selTimePointer(:,1) = 1; selTimePointer(:,16) = 1; + selTimePointer(1:4,8:9) = 1; selTimePointer(13:16,8:9) = 1; + selTimePointer(8:9,1:4) = 1; selTimePointer(8:9,13:16) = 1; + selTimePointer(5:12,5:12) = NaN; % Create a transparent region in the center + + % Activate clic mouse menu on second axes (salinity) for next rbbox + % ---------------------------------------------------------------- + set(hMainFig,'WindowButtonDownFcn', @Time_SelectCallback); + + % change cursor + % --------------- + set( hMainFig, 'Pointer', 'custom',... + 'PointerShapeCData', selTimePointer, 'PointerShapeHotSpot',[9 9]); + + % ---------------------------------------------------------------------- + % nested function on mouse clic when Select Time toggle tool is selected + % ---------------------------------------------------------------------- + function Time_SelectCallback(gcbo, eventdata) + + % disable ButtonMotion on main fig during select + % prevent drawing to map + % ---------------------------------------------- + set( hMainFig, 'WindowButtonMotionFcn', []); + + % Retrieve named application data + % ------------------------------- + tsg = getappdata( hMainFig, 'tsg_data'); + + % Selection of the data within the figure + % --------------------------------------- + point1 = get(gca,'CurrentPoint'); % button down detected + finalRect = rbbox; % return figure units + point2 = get(gca,'CurrentPoint'); % button up detected + + point1 = point1(1,1:2); % extract x and y + point2 = point2(1,1:2); + + p1 = min(point1,point2); + p2 = max(point1,point2); % calculate locations + + % get index on selected zone - Only on X axes (time) + % -------------------------------------------------- + ind = find(tsg.DAYD >= p1(1,1) & tsg.DAYD <= p2(1,1)); + + % Write the date in the Editable uicontrol + % ---------------------------------------- + set( hetDateMin, 'String', datestr(tsg.DAYD(ind(1)), 31)); + set( hetDateMax, 'String', datestr(tsg.DAYD(ind(end)), 31)); + + % enable ButtonMotion on main fig after select QC area + % ---------------------------------------------------- + set( hMainFig, 'WindowButtonMotionFcn', @MouseMotion); + end + end + +%% SelectTime_OffMenuCallback +%---------------------------- + function SelectTime_OffMenuCallback(hObject, eventdata) + % Callback function run when the .... + + % Desactivate time limit buttons + % ------------------------------ + set( hTimelimitToggletool, 'state', 'off'); + + set( hMainFig, 'WindowButtonDownFcn', []); + + set( hMainFig, 'Pointer', 'arrow'); + + end + %% Clim_OffMenuCallback %------------------------------------------------------------------------ % Callback function run when the Levitus climatology toolbar is unselected -- GitLab