[gsw] 01/02: Imported Upstream version 3.0.3

Alastair McKinstry mckinstry at moszumanska.debian.org
Thu Jul 9 13:21:26 UTC 2015


This is an automated email from the git hooks/post-receive script.

mckinstry pushed a commit to branch debian/master
in repository gsw.

commit e6caa7cbd60bc59ff093c7b27b7eedf503df8f54
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Thu Jul 9 14:13:07 2015 +0100

    Imported Upstream version 3.0.3
---
 CHANGES.txt                               |    6 +
 LICENSE.txt                               |   19 +
 MANIFEST.in                               |   11 +
 PKG-INFO                                  |  154 +++
 README.txt                                |  106 ++
 docs/Makefile                             |   89 ++
 docs/conf.py                              |  195 ++++
 docs/index.rst                            |   45 +
 gsw.egg-info/PKG-INFO                     |  154 +++
 gsw.egg-info/SOURCES.txt                  |   47 +
 gsw.egg-info/dependency_links.txt         |    1 +
 gsw.egg-info/requires.txt                 |    2 +
 gsw.egg-info/top_level.txt                |    4 +
 gsw/__init__.py                           |   12 +
 gsw/gibbs/__init__.py                     |   19 +
 gsw/gibbs/constants.py                    |  144 +++
 gsw/gibbs/conversions.py                  | 1724 ++++++++++++++++++++++++++++
 gsw/gibbs/density_enthalpy_48.py          | 1459 ++++++++++++++++++++++++
 gsw/gibbs/density_enthalpy_48_ct.py       |  106 ++
 gsw/gibbs/density_enthalpy_ct_exact.py    |  716 ++++++++++++
 gsw/gibbs/derivatives.py                  |  677 +++++++++++
 gsw/gibbs/earth.py                        |  219 ++++
 gsw/gibbs/freezing.py                     |  569 ++++++++++
 gsw/gibbs/geostrophic.py                  |   16 +
 gsw/gibbs/geostrophic_48.py               |   41 +
 gsw/gibbs/isobaric.py                     |   72 ++
 gsw/gibbs/library.py                      | 1646 +++++++++++++++++++++++++++
 gsw/gibbs/neutral_nonlinear_48.py         |   35 +
 gsw/gibbs/practical_salinity.py           |  754 +++++++++++++
 gsw/gibbs/steric.py                       |  131 +++
 gsw/gibbs/thermodynamics_from_t.py        | 1750 +++++++++++++++++++++++++++++
 gsw/gibbs/water_column_48.py              |  344 ++++++
 gsw/test/__init__.py                      |    1 +
 gsw/test/check_functions.py               |  194 ++++
 gsw/test/signatures.py                    |  178 +++
 gsw/test/test_check_values.py             |   66 ++
 gsw/test/test_octave.py                   |  208 ++++
 gsw/test/test_profiles.py                 |  339 ++++++
 gsw/test/test_tuples.py                   |   99 ++
 gsw/utilities/__init__.py                 |    3 +
 gsw/utilities/data/gsw_cf.npz             |  Bin 0 -> 266964 bytes
 gsw/utilities/data/gsw_cv_v3_0.npz        |  Bin 0 -> 285644 bytes
 gsw/utilities/data/gsw_data_v3_0.npz      |  Bin 0 -> 4492826 bytes
 gsw/utilities/data/gsw_demo_data_v3_0.npz |  Bin 0 -> 4456 bytes
 gsw/utilities/list_npz.py                 |   26 +
 gsw/utilities/mat2npz.py                  |   50 +
 gsw/utilities/utilities.py                |  333 ++++++
 setup.cfg                                 |    5 +
 setup.py                                  |   69 ++
 49 files changed, 12838 insertions(+)

diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644
index 0000000..81f6484
--- /dev/null
+++ b/CHANGES.txt
@@ -0,0 +1,6 @@
+version 3.0.3
+=============
+
+version 3.0
+===========
+* New repository with TEOS10 code (version 3 only).
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..eb056c7
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright Notice and Statement for the gsw project:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..8de1cd7
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,11 @@
+include README.txt
+include LICENSE.txt
+include CHANGES.txt
+include docs/conf.py
+include docs/index.rst
+include docs/Makefile
+include gsw/*.py
+include gsw/gibbs/*.py
+include gsw/test/*.py
+include gsw/utilities/*.py
+include gsw/utilities/data/*.npz
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..f2e2952
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,154 @@
+Metadata-Version: 1.1
+Name: gsw
+Version: 3.0.3
+Summary: Gibbs SeaWater Oceanographic Package of TEOS-10
+Home-page: http://pypi.python.org/pypi/seawater/
+Author: Filipe Fernandes
+Author-email: ocefpaf at gmail.com
+License: Copyright Notice and Statement for the gsw project:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Download-URL: https://pypi.python.org/pypi/gsw/
+Description: This python module is incomplete and should be used with caution.
+        =================================================================
+        
+        python gsw
+        ==========
+        
+        | |Build|
+        | |Build|
+        | |Downloads|
+        
+        Python implementation of the Thermodynamic Equation Of Seawater - 2010 (TEOS-10)[http://www.teos-10.org/\ ]
+        -----------------------------------------------------------------------------------------------------------
+        
+        gsw vs. csiro
+        -------------
+        
+        This table shows some function names in the gibbs library and the
+        corresponding function names in the csiro library.
+        
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | **Variable**                                              | **SeaWater (EOS 80)**                              | **Gibbs SeaWater (GSW TEOS 10)**                             |
+        +===========================================================+====================================================+==============================================================+
+        | Absolute Salinity                                         | NA                                                 | gsw.SA\_from\_SP(SP,p,long,lat)                              |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | Conservative Temperature                                  | NA                                                 | gsw.CT\_from\_t(SA,t,p)                                      |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | density (i.e. in situ density)                            | sw.dens(SP,t,p)                                    | gsw.rho\_CT(SA,CT,p), or gsw.rho(SA,t,p)                     |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | potential density                                         | sw.pden(SP,t,p,pr)                                 | gsw.rho\_CT(SA,CT,pr)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | potential temperature                                     | sw.ptmp(SP,t,p,pr)                                 | gsw.pt\_from\_t(SA,t,p,pr)                                   |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | $\\sigma\_0$, using $\\theta\_o$ = sw.ptmp(SP,t,p,0)      | sw.dens(SP, $\\theta\_o$, 0) -1000 kg m$^{-3}$     | gsw.sigma0\_CT(SA,CT)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | $\\sigma\_2$, using $\\theta\_2$ = sw.ptmp(SP,t,p,2000)   | sw.dens(SP,$\\theta\_2$, 2000) -1000 kg m$^{-3}$   | gsw.sigma2\_CT(SA,CT)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | $\\sigma\_4$, using $\\theta\_4$ = sw.ptmp(SP,t,p,2000)   | sw.dens(SP,$\\theta\_4$, 4000) -1000 kg m$^{-3}$   | gsw.sigma2\_CT(SA,CT)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | specific volume anomaly                                   | sw.svan(SP,t,p)                                    | gsw.specvol\_anom\_CT(SA,CT,p)                               |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | dynamic height anomaly                                    | -sw.gpan(SP,t,p)                                   | gsw.geo\_strf\_dyn\_height(SA,CT,p,delta\_p,interp\_style)   |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | geostrophic velocity                                      | sw.gvel(ga,lat,long)                               | gsw.geostrophic\_velocity(geo\_str,long,lat,p)               |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | N$^2$                                                     | sw.bfrq(SP,t,p,lat)                                | gsw.Nsquared(SA,CT,p,lat)                                    |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | pressure from height (SW uses depth, not height)          | sw.pres(-z,lat)                                    | gsw.p\_from\_z(z,lat)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | height from pressure (SW outputs depth, not height)       | z = -sw.dpth(p,lat)                                | gsw.z\_from\_p(p,lat)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | in situ temperature from pt                               | sw.temp(SP,pt,p,pr)                                | gsw.pt\_from\_t(SA,pt,pr,p)                                  |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | sound speed                                               | sw.svel(SP,t,p)                                    | gsw.sound\_speed(SA,t,p)                                     |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | isobaric heat capacity                                    | sw.cp(SP,t,p)                                      | gsw.cp(SA,t,p)                                               |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | adiabatic lapse rate\*                                    | sw.adtg(SP,t,p)                                    | gsw.adiabatic\_lapse\_rate(SA,t,p)                           |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | SP from cndr, (PSS 78)                                    | sw.salt(cndr,t,p)                                  | gsw.SP\_from\_cndr(cndr,t,p)                                 |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | cndr from SP, (PSS 78)                                    | sw.cndr(SP,t,p)                                    | gsw.cndr\_from\_SP(SP,t,p)                                   |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | distance                                                  | sw.dist(lat,long,units)                            | gsw.distance(long,lat,p)                                     |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | gravitational acceleration                                | sw.g(lat,z)                                        | gsw.grav(lat,p)                                              |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | Coriolis parameter                                        | sw.f(lat)                                          | gsw.f(lat)                                                   |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        
+        | Note that the SW and GSW functions output the adiabatic lapse rate in
+        different units, being K (dbar)$^{-1}$ and K Pa$^{-1}$
+        | respectively.
+        
+        Authors
+        -------
+        
+        -  Bjørn Ådlandsvik
+        -  Eric Firing
+        -  Filipe Fernandes
+        
+        Thanks
+        ------
+        
+        -  Bjørn Ådlandsvik - Testing unit and several bug fixes.
+        -  Eric Firing - Support for masked arrays, re-write of *delta*\ SA.
+        -  Trevor J. McDougall (and all of SCOR/IAPSO WG127) for making
+           available the Matlab version of this software.
+        
+        Acknowledgments
+        ---------------
+        
+        -  SCOR/IAPSO WG127.
+        
+        Caveats
+        -------
+        
+        -  This python module is incomplete and should be used with caution.
+        -  The database used in ``_delta_SA`` comes from the MatlabTM gsw
+           version.
+        
+        .. |Build| image:: https://badge.fury.io/py/gsw.png
+           :target: http://badge.fury.io/py/gsw
+        .. |Build| image:: https://api.travis-ci.org/ocefpaf/python-gsw.png?branch=master
+           :target: https://travis-ci.org/ocefpaf/python-gsw
+        .. |Downloads| image:: https://pypip.in/d/gsw/badge.png
+           :target: https://crate.io/packages/gsw/
+        
+        version 3.0.3
+        =============
+        
+        version 3.0
+        ===========
+        * New repository with TEOS10 code (version 3 only).
+        
+Keywords: oceanography,seawater,TEOS-10,gibbs
+Platform: any
+Classifier: Development Status :: 4 - Beta
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Science/Research
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Education
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Education
+Classifier: Topic :: Scientific/Engineering
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..b986cfc
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,106 @@
+This python module is incomplete and should be used with caution.
+=================================================================
+
+python gsw
+==========
+
+| |Build|
+| |Build|
+| |Downloads|
+
+Python implementation of the Thermodynamic Equation Of Seawater - 2010 (TEOS-10)[http://www.teos-10.org/\ ]
+-----------------------------------------------------------------------------------------------------------
+
+gsw vs. csiro
+-------------
+
+This table shows some function names in the gibbs library and the
+corresponding function names in the csiro library.
+
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| **Variable**                                              | **SeaWater (EOS 80)**                              | **Gibbs SeaWater (GSW TEOS 10)**                             |
++===========================================================+====================================================+==============================================================+
+| Absolute Salinity                                         | NA                                                 | gsw.SA\_from\_SP(SP,p,long,lat)                              |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| Conservative Temperature                                  | NA                                                 | gsw.CT\_from\_t(SA,t,p)                                      |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| density (i.e. in situ density)                            | sw.dens(SP,t,p)                                    | gsw.rho\_CT(SA,CT,p), or gsw.rho(SA,t,p)                     |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| potential density                                         | sw.pden(SP,t,p,pr)                                 | gsw.rho\_CT(SA,CT,pr)                                        |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| potential temperature                                     | sw.ptmp(SP,t,p,pr)                                 | gsw.pt\_from\_t(SA,t,p,pr)                                   |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| $\\sigma\_0$, using $\\theta\_o$ = sw.ptmp(SP,t,p,0)      | sw.dens(SP, $\\theta\_o$, 0) -1000 kg m$^{-3}$     | gsw.sigma0\_CT(SA,CT)                                        |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| $\\sigma\_2$, using $\\theta\_2$ = sw.ptmp(SP,t,p,2000)   | sw.dens(SP,$\\theta\_2$, 2000) -1000 kg m$^{-3}$   | gsw.sigma2\_CT(SA,CT)                                        |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| $\\sigma\_4$, using $\\theta\_4$ = sw.ptmp(SP,t,p,2000)   | sw.dens(SP,$\\theta\_4$, 4000) -1000 kg m$^{-3}$   | gsw.sigma2\_CT(SA,CT)                                        |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| specific volume anomaly                                   | sw.svan(SP,t,p)                                    | gsw.specvol\_anom\_CT(SA,CT,p)                               |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| dynamic height anomaly                                    | -sw.gpan(SP,t,p)                                   | gsw.geo\_strf\_dyn\_height(SA,CT,p,delta\_p,interp\_style)   |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| geostrophic velocity                                      | sw.gvel(ga,lat,long)                               | gsw.geostrophic\_velocity(geo\_str,long,lat,p)               |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| N$^2$                                                     | sw.bfrq(SP,t,p,lat)                                | gsw.Nsquared(SA,CT,p,lat)                                    |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| pressure from height (SW uses depth, not height)          | sw.pres(-z,lat)                                    | gsw.p\_from\_z(z,lat)                                        |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| height from pressure (SW outputs depth, not height)       | z = -sw.dpth(p,lat)                                | gsw.z\_from\_p(p,lat)                                        |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| in situ temperature from pt                               | sw.temp(SP,pt,p,pr)                                | gsw.pt\_from\_t(SA,pt,pr,p)                                  |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| sound speed                                               | sw.svel(SP,t,p)                                    | gsw.sound\_speed(SA,t,p)                                     |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| isobaric heat capacity                                    | sw.cp(SP,t,p)                                      | gsw.cp(SA,t,p)                                               |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| adiabatic lapse rate\*                                    | sw.adtg(SP,t,p)                                    | gsw.adiabatic\_lapse\_rate(SA,t,p)                           |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| SP from cndr, (PSS 78)                                    | sw.salt(cndr,t,p)                                  | gsw.SP\_from\_cndr(cndr,t,p)                                 |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| cndr from SP, (PSS 78)                                    | sw.cndr(SP,t,p)                                    | gsw.cndr\_from\_SP(SP,t,p)                                   |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| distance                                                  | sw.dist(lat,long,units)                            | gsw.distance(long,lat,p)                                     |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| gravitational acceleration                                | sw.g(lat,z)                                        | gsw.grav(lat,p)                                              |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+| Coriolis parameter                                        | sw.f(lat)                                          | gsw.f(lat)                                                   |
++-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+
+| Note that the SW and GSW functions output the adiabatic lapse rate in
+different units, being K (dbar)$^{-1}$ and K Pa$^{-1}$
+| respectively.
+
+Authors
+-------
+
+-  Bjørn Ådlandsvik
+-  Eric Firing
+-  Filipe Fernandes
+
+Thanks
+------
+
+-  Bjørn Ådlandsvik - Testing unit and several bug fixes.
+-  Eric Firing - Support for masked arrays, re-write of *delta*\ SA.
+-  Trevor J. McDougall (and all of SCOR/IAPSO WG127) for making
+   available the Matlab version of this software.
+
+Acknowledgments
+---------------
+
+-  SCOR/IAPSO WG127.
+
+Caveats
+-------
+
+-  This python module is incomplete and should be used with caution.
+-  The database used in ``_delta_SA`` comes from the MatlabTM gsw
+   version.
+
+.. |Build| image:: https://badge.fury.io/py/gsw.png
+   :target: http://badge.fury.io/py/gsw
+.. |Build| image:: https://api.travis-ci.org/ocefpaf/python-gsw.png?branch=master
+   :target: https://travis-ci.org/ocefpaf/python-gsw
+.. |Downloads| image:: https://pypip.in/d/gsw/badge.png
+   :target: https://crate.io/packages/gsw/
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..fd6fd6e
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,89 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  dirhtml   to make HTML files named index.html in directories"
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  qthelp    to make HTML files and a qthelp project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/seawater.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/seawater.qhc"
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..97ad07b
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-
+#
+# seawater documentation build configuration file, created by
+# sphinx-quickstart on Tue Aug 10 16:47:25 2010.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.pngmath', 'numpydoc',
+              'numpydoc.plot_directive']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'seawater'
+copyright = u'2010, Filipe Fernandes'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '3.0'
+# The full version, including alpha/beta/rc tags.
+release = '3.0.1'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'gswdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'gsw.tex', u'GSW Documentation',
+   u'Filipe Fernandes', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..805ad3d
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,45 @@
+.. seawater documentation master file, created by
+   sphinx-quickstart on Tue Aug 10 16:47:25 2010.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to gsw's documentation!
+====================================
+
+python gsw
+==========
+
+Introduction:
+-------------
+Python implementation of the Thermodynamic Equation Of Seawater - 2010
+(TEOS-10)
+
+For more information go to:
+    http://www.teos-10.org/
+
+Modules:
+--------
+
+.. toctree::
+   :maxdepth: 4
+
+
+gibbs Seawater Documentation
+============================
+
+This page contains the gsw Module documentation.
+
+The :mod:`gibbs` module
+-----------------------
+
+.. automodule:: seawater.gibbs
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/gsw.egg-info/PKG-INFO b/gsw.egg-info/PKG-INFO
new file mode 100644
index 0000000..f2e2952
--- /dev/null
+++ b/gsw.egg-info/PKG-INFO
@@ -0,0 +1,154 @@
+Metadata-Version: 1.1
+Name: gsw
+Version: 3.0.3
+Summary: Gibbs SeaWater Oceanographic Package of TEOS-10
+Home-page: http://pypi.python.org/pypi/seawater/
+Author: Filipe Fernandes
+Author-email: ocefpaf at gmail.com
+License: Copyright Notice and Statement for the gsw project:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Download-URL: https://pypi.python.org/pypi/gsw/
+Description: This python module is incomplete and should be used with caution.
+        =================================================================
+        
+        python gsw
+        ==========
+        
+        | |Build|
+        | |Build|
+        | |Downloads|
+        
+        Python implementation of the Thermodynamic Equation Of Seawater - 2010 (TEOS-10)[http://www.teos-10.org/\ ]
+        -----------------------------------------------------------------------------------------------------------
+        
+        gsw vs. csiro
+        -------------
+        
+        This table shows some function names in the gibbs library and the
+        corresponding function names in the csiro library.
+        
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | **Variable**                                              | **SeaWater (EOS 80)**                              | **Gibbs SeaWater (GSW TEOS 10)**                             |
+        +===========================================================+====================================================+==============================================================+
+        | Absolute Salinity                                         | NA                                                 | gsw.SA\_from\_SP(SP,p,long,lat)                              |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | Conservative Temperature                                  | NA                                                 | gsw.CT\_from\_t(SA,t,p)                                      |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | density (i.e. in situ density)                            | sw.dens(SP,t,p)                                    | gsw.rho\_CT(SA,CT,p), or gsw.rho(SA,t,p)                     |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | potential density                                         | sw.pden(SP,t,p,pr)                                 | gsw.rho\_CT(SA,CT,pr)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | potential temperature                                     | sw.ptmp(SP,t,p,pr)                                 | gsw.pt\_from\_t(SA,t,p,pr)                                   |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | $\\sigma\_0$, using $\\theta\_o$ = sw.ptmp(SP,t,p,0)      | sw.dens(SP, $\\theta\_o$, 0) -1000 kg m$^{-3}$     | gsw.sigma0\_CT(SA,CT)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | $\\sigma\_2$, using $\\theta\_2$ = sw.ptmp(SP,t,p,2000)   | sw.dens(SP,$\\theta\_2$, 2000) -1000 kg m$^{-3}$   | gsw.sigma2\_CT(SA,CT)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | $\\sigma\_4$, using $\\theta\_4$ = sw.ptmp(SP,t,p,2000)   | sw.dens(SP,$\\theta\_4$, 4000) -1000 kg m$^{-3}$   | gsw.sigma2\_CT(SA,CT)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | specific volume anomaly                                   | sw.svan(SP,t,p)                                    | gsw.specvol\_anom\_CT(SA,CT,p)                               |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | dynamic height anomaly                                    | -sw.gpan(SP,t,p)                                   | gsw.geo\_strf\_dyn\_height(SA,CT,p,delta\_p,interp\_style)   |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | geostrophic velocity                                      | sw.gvel(ga,lat,long)                               | gsw.geostrophic\_velocity(geo\_str,long,lat,p)               |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | N$^2$                                                     | sw.bfrq(SP,t,p,lat)                                | gsw.Nsquared(SA,CT,p,lat)                                    |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | pressure from height (SW uses depth, not height)          | sw.pres(-z,lat)                                    | gsw.p\_from\_z(z,lat)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | height from pressure (SW outputs depth, not height)       | z = -sw.dpth(p,lat)                                | gsw.z\_from\_p(p,lat)                                        |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | in situ temperature from pt                               | sw.temp(SP,pt,p,pr)                                | gsw.pt\_from\_t(SA,pt,pr,p)                                  |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | sound speed                                               | sw.svel(SP,t,p)                                    | gsw.sound\_speed(SA,t,p)                                     |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | isobaric heat capacity                                    | sw.cp(SP,t,p)                                      | gsw.cp(SA,t,p)                                               |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | adiabatic lapse rate\*                                    | sw.adtg(SP,t,p)                                    | gsw.adiabatic\_lapse\_rate(SA,t,p)                           |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | SP from cndr, (PSS 78)                                    | sw.salt(cndr,t,p)                                  | gsw.SP\_from\_cndr(cndr,t,p)                                 |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | cndr from SP, (PSS 78)                                    | sw.cndr(SP,t,p)                                    | gsw.cndr\_from\_SP(SP,t,p)                                   |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | distance                                                  | sw.dist(lat,long,units)                            | gsw.distance(long,lat,p)                                     |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | gravitational acceleration                                | sw.g(lat,z)                                        | gsw.grav(lat,p)                                              |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        | Coriolis parameter                                        | sw.f(lat)                                          | gsw.f(lat)                                                   |
+        +-----------------------------------------------------------+----------------------------------------------------+--------------------------------------------------------------+
+        
+        | Note that the SW and GSW functions output the adiabatic lapse rate in
+        different units, being K (dbar)$^{-1}$ and K Pa$^{-1}$
+        | respectively.
+        
+        Authors
+        -------
+        
+        -  Bjørn Ådlandsvik
+        -  Eric Firing
+        -  Filipe Fernandes
+        
+        Thanks
+        ------
+        
+        -  Bjørn Ådlandsvik - Testing unit and several bug fixes.
+        -  Eric Firing - Support for masked arrays, re-write of *delta*\ SA.
+        -  Trevor J. McDougall (and all of SCOR/IAPSO WG127) for making
+           available the Matlab version of this software.
+        
+        Acknowledgments
+        ---------------
+        
+        -  SCOR/IAPSO WG127.
+        
+        Caveats
+        -------
+        
+        -  This python module is incomplete and should be used with caution.
+        -  The database used in ``_delta_SA`` comes from the MatlabTM gsw
+           version.
+        
+        .. |Build| image:: https://badge.fury.io/py/gsw.png
+           :target: http://badge.fury.io/py/gsw
+        .. |Build| image:: https://api.travis-ci.org/ocefpaf/python-gsw.png?branch=master
+           :target: https://travis-ci.org/ocefpaf/python-gsw
+        .. |Downloads| image:: https://pypip.in/d/gsw/badge.png
+           :target: https://crate.io/packages/gsw/
+        
+        version 3.0.3
+        =============
+        
+        version 3.0
+        ===========
+        * New repository with TEOS10 code (version 3 only).
+        
+Keywords: oceanography,seawater,TEOS-10,gibbs
+Platform: any
+Classifier: Development Status :: 4 - Beta
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Science/Research
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Education
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Topic :: Education
+Classifier: Topic :: Scientific/Engineering
diff --git a/gsw.egg-info/SOURCES.txt b/gsw.egg-info/SOURCES.txt
new file mode 100644
index 0000000..c5f117c
--- /dev/null
+++ b/gsw.egg-info/SOURCES.txt
@@ -0,0 +1,47 @@
+CHANGES.txt
+LICENSE.txt
+MANIFEST.in
+README.txt
+setup.py
+docs/Makefile
+docs/conf.py
+docs/index.rst
+gsw/__init__.py
+gsw.egg-info/PKG-INFO
+gsw.egg-info/SOURCES.txt
+gsw.egg-info/dependency_links.txt
+gsw.egg-info/requires.txt
+gsw.egg-info/top_level.txt
+gsw/gibbs/__init__.py
+gsw/gibbs/constants.py
+gsw/gibbs/conversions.py
+gsw/gibbs/density_enthalpy_48.py
+gsw/gibbs/density_enthalpy_48_ct.py
+gsw/gibbs/density_enthalpy_ct_exact.py
+gsw/gibbs/derivatives.py
+gsw/gibbs/earth.py
+gsw/gibbs/freezing.py
+gsw/gibbs/geostrophic.py
+gsw/gibbs/geostrophic_48.py
+gsw/gibbs/isobaric.py
+gsw/gibbs/library.py
+gsw/gibbs/neutral_nonlinear_48.py
+gsw/gibbs/practical_salinity.py
+gsw/gibbs/steric.py
+gsw/gibbs/thermodynamics_from_t.py
+gsw/gibbs/water_column_48.py
+gsw/test/__init__.py
+gsw/test/check_functions.py
+gsw/test/signatures.py
+gsw/test/test_check_values.py
+gsw/test/test_octave.py
+gsw/test/test_profiles.py
+gsw/test/test_tuples.py
+gsw/utilities/__init__.py
+gsw/utilities/list_npz.py
+gsw/utilities/mat2npz.py
+gsw/utilities/utilities.py
+gsw/utilities/data/gsw_cf.npz
+gsw/utilities/data/gsw_cv_v3_0.npz
+gsw/utilities/data/gsw_data_v3_0.npz
+gsw/utilities/data/gsw_demo_data_v3_0.npz
\ No newline at end of file
diff --git a/gsw.egg-info/dependency_links.txt b/gsw.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/gsw.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/gsw.egg-info/requires.txt b/gsw.egg-info/requires.txt
new file mode 100644
index 0000000..9b65aaf
--- /dev/null
+++ b/gsw.egg-info/requires.txt
@@ -0,0 +1,2 @@
+numpy
+nose
\ No newline at end of file
diff --git a/gsw.egg-info/top_level.txt b/gsw.egg-info/top_level.txt
new file mode 100644
index 0000000..d9a3fb5
--- /dev/null
+++ b/gsw.egg-info/top_level.txt
@@ -0,0 +1,4 @@
+gsw/utilities
+gsw/gibbs
+gsw/test
+gsw
diff --git a/gsw/__init__.py b/gsw/__init__.py
new file mode 100644
index 0000000..c8ea799
--- /dev/null
+++ b/gsw/__init__.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+
+from .gibbs import *
+from .utilities import (Bunch, match_args_return, read_data, strip_mask,
+                        loadmatbunch)
+
+data = read_data("gsw_data_v3_0.npz")
+
+__version__ = "3.0.3"
+__all__ = ['gibbs', 'utilities']
+__data_date__ = str(data['version_date'])
+__data_version__ = str(data['version_number'])
diff --git a/gsw/gibbs/__init__.py b/gsw/gibbs/__init__.py
new file mode 100644
index 0000000..f236509
--- /dev/null
+++ b/gsw/gibbs/__init__.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+
+from .earth import *
+from .steric import *
+from .library import *
+from .freezing import *
+from .isobaric import *
+from .constants import *
+from .derivatives import *
+from .conversions import *
+from .geostrophic import *
+from .geostrophic_48 import *
+from .water_column_48 import *
+from .practical_salinity import *
+from .density_enthalpy_48 import *
+from .neutral_nonlinear_48 import *
+from .thermodynamics_from_t import *
+from .density_enthalpy_48_ct import *
+from .density_enthalpy_ct_exact import *
diff --git a/gsw/gibbs/constants.py b/gsw/gibbs/constants.py
new file mode 100644
index 0000000..4939be7
--- /dev/null
+++ b/gsw/gibbs/constants.py
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+
+"""Constants"""
+
+from __future__ import division
+
+C3515 = 42.9140
+r"""Conductivity of 42.914 [mmho cm :sup:`-1` == mS cm :sup:`-1`] at Salinity
+35 psu, Temperature 15 :math:`^\\circ` C [ITPS 68] and Pressure 0 db.
+
+References
+----------
+.. [1] Culkin and Smith, 1980:  Determination of the Concentration of Potassium
+Chloride Solution Having the Same Electrical Conductivity, at 15C and Infinite
+Frequency, as Standard Seawater of Salinity 35.0000 (Chlorinity 19.37394),
+IEEE J. Oceanic Eng, 5, 22-23.
+
+.. [2] Unesco, 1983: Algorithms for computation of fundamental properties of
+seawater. Unesco Technical Papers in Marine Science, 44, 53 pp."""
+
+earth_radius = 6371000.
+r"""Mean radius of earth  A.E. Gill."""
+
+OMEGA = 7.292115e-5
+r""":math:`\\Omega = \\frac{2\\pi}{\\textrm{sidereal day}}` =
+                                                 7.292e-5.radians sec :sup:`-1`
+
+1 sidereal day = 23.9344696 hours
+
+Changed to a more precise value at Groten 2004
+
+References
+----------
+.. [1] A.E. Gill 1982. p.54  eqn 3.7.15 "Atmosphere-Ocean Dynamics" Academic
+Press: New York. ISBN: 0-12-283522-0. page: 597
+.. [2] Groten, E., 2004: Fundamental Parameters and Current (2004) Best
+Estimates of the Parameters of Common Relevance to Astronomy, Geodesy, and
+Geodynamics. Journal of Geodesy, 77, pp. 724-797."""
+
+gdef = 9.8
+r"""Acceleration of gravity [m s :sup:`2`] used by sw.swvel and bfrq without
+lat info."""
+
+T0 = Kelvin = 273.15
+r"""The Celsius zero point; 273.15 K.  That is T = t + T0 where T is the
+Absolute Temperature (in degrees K) and t is temperature in degrees C."""
+
+db2Pascal = 1e4
+r"""Decibar to pascal."""
+
+gamma = 2.26e-7
+r"""Gamma (A.E. Gill)."""
+
+M_S = 0.0314038218
+r"""Mole-weighted average atomic weight of the elements of
+Reference-Composition sea salt, in units of kg mol :sup:`-1`. Strictly
+speaking, the formula below applies only to seawater of Reference Composition.
+If molality is required to an accuracy of better than 0.1% we suggest you
+contact the authors for further guidance."""
+
+cp0 = 3991.86795711963
+r"""The "specific heat" for use with Conservative Temperature. cp0 is the ratio
+of potential enthalpy to Conservative Temperature.
+See Eqn. (3.3.3) and Table D.5 from IOC et al. (2010)."""
+
+SSO = 35.16504
+r"""SSO is the Standard Ocean Reference Salinity (35.16504 g/kg.)
+
+SSO is the best estimate of the Absolute Salinity of Standard Seawater
+when the seawater sample has a Practical Salinity, SP, of 35
+(Millero et al., 2008), and this number is a fundamental part of the
+TEOS-10 definition of seawater.
+
+References:
+-----------
+.. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
+seawater - 2010: Calculation and use of thermodynamic properties.
+Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+UNESCO (English), 196 pp. See appendices A.3, A.5 and Table D.4.
+
+.. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008:
+The composition of Standard Seawater and the definition of the
+Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72.
+See Table 4 and section 5."""
+
+sfac = 0.0248826675584615
+r"""sfac = 1 / (40. * (SSO / 35.))"""
+
+R = 8.314472
+r"""The molar gas constant = 8.314472 m :sup:`2` kg s:sup:`-21 K :sup:`-1`
+mol :sup:`-1`."""
+
+r1 = 0.35
+""" TODO """
+
+uPS = SSO / 35.0
+r"""The unit conversion factor for salinities (35.16504/35) g/kg (Millero et
+al., 2008). Reference Salinity SR is uPS times Practical Salinity SP.
+
+Ratio, unit conversion factor for salinities [g kg :sup:`-1`]
+
+References
+----------
+Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008: The
+composition of Standard Seawater and the definition of the
+Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. See
+section 6, Eqn.(6.1)."""
+
+
+P0 = 101325
+r"""Absolute Pressure of one standard atmosphere in Pa, 101325 Pa."""
+
+SonCl = 1.80655
+r"""The ratio of Practical Salinity, SP, to Chlorinity, 1.80655 kg/g for
+Reference Seawater (Millero et al., 2008). This is the ratio that was used by
+the JPOTS committee in their construction of the 1978 Practical Salinity Scale
+(PSS-78) to convert between the laboratory measurements of seawater samples
+(which were measured in Chlorinity) to Practical Salinity.
+
+References:
+-----------
+.. [1] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008:
+The composition of Standard Seawater and the definition of the
+Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72. See section
+5 below Eqn. (5.5)."""
+
+valence_factor = 1.2452898
+r"""This function returns the valence factor of sea salt of Reference
+Composition, 1.2452898.  This valence factor is exact, and follows from
+the definition of the Reference-Composition Salinity Scale 2008 of
+Millero et al. (2008).  The valence factor is the mole-weighted square
+of the charges, Z, of the ions comprising Reference Composition sea salt.
+
+References:
+-----------
+.. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
+seawater - 2010: Calculation and use of thermodynamic properties.
+Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+UNESCO (English), 196 pp. See Table D.4 of this TEOS-10 Manual.
+
+.. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008:
+The composition of Standard Seawater and the definition of the
+Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72.
+See Eqn. (5.9)."""
diff --git a/gsw/gibbs/conversions.py b/gsw/gibbs/conversions.py
new file mode 100644
index 0000000..9b66eee
--- /dev/null
+++ b/gsw/gibbs/conversions.py
@@ -0,0 +1,1724 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from ..utilities import match_args_return, strip_mask
+from .constants import SSO, cp0, r1, Kelvin, sfac, uPS
+from .constants import db2Pascal, gamma, P0, M_S, valence_factor
+from .library import (entropy_part, entropy_part_zerop, gibbs, gibbs_pt0_pt0,
+                      enthalpy_SSO_0_p, specvol_SSO_0_p)
+
+from .library import SA_from_SP_Baltic, SP_from_SA_Baltic, SAAR
+
+# This first set is moved over from absolute_salinity_sstar_ct,
+# which is being absorbed into this module.
+__all__ = ['CT_from_t',
+           'SA_from_SP',
+           'Sstar_from_SP',
+           'Abs_Pressure_from_p',
+           'CT_from_entropy',
+           'CT_from_pt',
+           'SA_Sstar_from_SP',
+           'SA_from_Sstar',
+           'SP_from_SA',
+           'SP_from_SR',
+           'SP_from_Sstar',  # TODO
+           'SR_from_SP',
+           'Sstar_from_SA',
+           'deltaSA_from_SP',  # TODO
+           'depth_from_z',
+           'entropy_from_CT',
+           'entropy_from_pt',
+           'entropy_from_t',
+           'ionic_strength_from_SA',
+           'molality_from_SA',
+           'p_from_Abs_Pressure',
+           'p_from_z',
+           'pot_enthalpy_from_pt',
+           'pt0_from_t',
+           'pt_from_CT',
+           'pt_from_entropy',
+           'pt_from_t',
+           't90_from_t48',
+           't90_from_t68',
+           't_from_CT',
+           't_from_entropy',
+           'z_from_depth',
+           'z_from_p']  # TODO: Test with geo_strf_dyn_height != None
+
+DEG2RAD = np.pi / 180.0
+n0, n1, n2 = 0, 1, 2  # constants used as arguments to gibbs()
+
+
+def check_input(SP, p, lon, lat):
+    r"""Check for out of range values."""
+    # Helper for the "from_SP" functions.
+    lon, lat, p, SP = np.broadcast_arrays(lon, lat, p, SP)
+
+    cond1 = ((p < 100) & (SP > 120))
+    cond2 = ((p >= 100) & (SP > 42))
+    if cond1.any() or cond2.any():  # don't modify input array
+        mask = np.ma.filled(cond1, False) | np.ma.filled(cond2, False)
+        SP = np.ma.array(SP, mask=mask)
+
+    lon = lon % 360
+
+    # FIXME: If we do keep the checks below, they need to
+    # be reformulated with ValueError('pressure out of range') etc.
+    # The original also checks for 9999s--a fossil from old-time
+    # Fortran days.
+
+    # I don't think we need these here; if any such checking is
+    # needed, it should not just be for the "from_SP" functions.
+    if False:
+        if ((p < -1.5) | (p > 12000)).any():
+            raise(Exception, 'Sstar_from_SP: pressure is out of range')
+        if ((lon < 0) | (lon > 360)).any():
+            raise(Exception, 'Sstar_from_SP: longitude is out of range')
+        if (np.abs(lat) > 90).any():
+            raise(Exception, 'Sstar_from_SP: latitude is out of range')
+
+    SP = np.maximum(SP, 0)  # Works on masked array also.
+
+    return SP, p, lon, lat
+
+
+ at match_args_return
+def Abs_Pressure_from_p(p):
+    r"""Calculates Absolute Pressure from sea pressure.  Note that Absolute
+    Pressure is in Pa NOT dbar.
+
+    Parameters
+    ---------
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    Absolute_Pressure : array_like
+        Absolute Pressure [Pa]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.2.1).
+
+        Modifications:
+    2011-03-29. Trevor McDougall & Paul Barker
+    """
+
+    return p * db2Pascal + P0
+
+
+ at match_args_return
+def CT_from_entropy(SA, entropy):
+    r"""Calculates Conservative Temperature with entropy as an input variable.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    entropy : array_like
+              specific entropy [J kg :sup:`-1` K :sup:`-1`]
+
+    Returns
+    -------
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> entropy = [400.3892, 395.4378, 319.8668, 146.7910, 98.6471, 62.7919]
+    >>> gsw.CT_from_entropy(SA, entropy)
+    array([ 28.80990279,  28.43919923,  22.78619927,  10.22619767,
+             6.82719674,   4.32360295])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix  A.10.
+
+    Modifications:
+    2011-03-03. Trevor McDougall and Paul Barker.
+    """
+
+    SA = np.maximum(SA, 0)
+    pt = pt_from_entropy(SA, entropy)
+    return CT_from_pt(SA, pt)
+
+
+ at match_args_return
+def CT_from_pt(SA, pt):
+    r"""Calculates Conservative Temperature of seawater from potential
+    temperature (whose reference sea pressure is zero dbar).
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    pt : array_like
+         potential temperature referenced to a sea pressure of zero dbar
+         [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> pt = [28.7832, 28.4209, 22.7850, 10.2305, 6.8292, 4.3245]
+    >>> gsw.CT_from_pt(SA, pt)
+    array([ 28.80992302,  28.43914426,  22.78624661,  10.22616561,
+             6.82718342,   4.32356518])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.3.
+
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker.
+    """
+
+    SA, pt, mask = strip_mask(SA, pt)
+
+    pot_enthalpy = pot_enthalpy_from_pt(SA, pt)
+
+    CT = pot_enthalpy / cp0
+
+    return np.ma.array(CT, mask=mask, copy=False)
+
+
+ at match_args_return
+def SA_Sstar_from_SP(SP, p, lon, lat):
+    """
+    TODO: docstring
+    """
+    # Note: with match_args_return, the variables inside
+    # this function are masked arrays, so the outputs of
+    # other functions called here are also masked arrays.
+
+    SP, p, lon, lat = check_input(SP, p, lon, lat)
+
+    saar, in_ocean = SAAR(p, lon, lat)
+    SA = uPS * SP * (1 + saar)
+    Sstar = uPS * SP * (1 - r1 * saar)
+
+    SA_baltic = SA_from_SP_Baltic(SP, lon, lat)
+    bmask = SA_baltic.mask
+    if bmask is not np.ma.nomask and not bmask.all():
+        inbaltic = ~bmask
+        SA[inbaltic] = SA_baltic[inbaltic]
+        Sstar[inbaltic] = SA_baltic[inbaltic]
+
+    return SA, Sstar
+
+
+ at match_args_return
+def SA_from_Sstar(Sstar, p, lon, lat):
+    """
+    TODO: docstring
+    """
+    # maybe add some input checking...
+
+    saar, in_ocean = SAAR(p, lon, lat)
+    SA = Sstar * (1 + saar) / (1.0 - r1 * saar)
+
+    # % In the Baltic Sea, SA = Sstar, and note that gsw_delta_SA returns zero
+    # % for dSA in the Baltic.
+
+    return SA, in_ocean
+
+
+ at match_args_return
+def SP_from_SA(SA, p, lon, lat):
+    """
+    TODO: docstring
+    """
+    # maybe add input checking...
+
+    saar, in_ocean = SAAR(p, lon, lat)
+    SP = (35 / 35.16504) * SA / (1.0 + saar)
+
+    SP_baltic = SP_from_SA_Baltic(SA, lon, lat)
+    bmask = SP_baltic.mask
+    if bmask is not np.ma.nomask and not bmask.all():
+        inbaltic = ~bmask
+        SP[inbaltic] = SP_baltic[inbaltic]
+
+    return SP, in_ocean
+
+
+ at match_args_return
+def SP_from_SR(SR):
+    r"""Calculates Practical Salinity from Reference Salinity.
+
+    Parameters
+    ---------
+    SR : array_like
+        Reference Salinity [g kg :sup:`-1`]
+
+    Returns
+    -------
+    SP : array_like
+        Practical Salinity (PSS-78) [unitless]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+
+    Modifications:
+    2011-03-27. Trevor McDougall & Paul Barker
+    """
+
+    return 1. / uPS * SR
+
+
+def SP_from_Sstar():
+    pass
+
+
+ at match_args_return
+def SR_from_SP(SP):
+    r"""Calculates Reference Salinity from Practical Salinity.
+
+    Parameters
+    ---------
+    SP : array_like
+        Practical Salinity (PSS-78) [unitless]
+
+    Returns
+    -------
+    SR : array_like
+        Reference Salinity [g kg :sup:`-1`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+
+    Modifications:
+    2011-03-27. Trevor McDougall & Paul Barker
+    """
+
+    return uPS * SP
+
+
+ at match_args_return
+def Sstar_from_SA(SA, p, lon, lat):
+    """
+    TODO: docstring
+    """
+    saar, in_ocean = SAAR(p, lon, lat)
+    Sstar = SA * (1 - r1 * saar) / (1 + saar)
+    # dSA is zero in Baltic
+    return Sstar, in_ocean
+
+
+ at match_args_return
+def CT_from_t(SA, t, p):
+    r"""Calculates Conservative Temperature of seawater from in situ
+    temperature.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+
+    Returns
+    -------
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.3.
+
+    Modifications:
+    2011-03-27. David Jackett, Trevor McDougall and Paul Barker
+    """
+    # Find values that are out of range, set them to NaN.
+    invalid = np.logical_and(p < 100, np.logical_or(t > 80, t < -12))
+    t[invalid] = np.ma.masked
+
+    invalid = np.logical_and(p >= 100, np.logical_or(t > 40, t < -12))
+    t[invalid] = np.ma.masked
+
+    pt0 = pt0_from_t(SA, t, p)
+    CT = CT_from_pt(SA, pt0)
+
+    return CT
+
+
+ at match_args_return
+def SA_from_SP(SP, p, lon, lat):
+    r"""Calculates Absolute Salinity from Practical Salinity.
+
+    Parameters
+    ----------
+    SP : array_like
+         salinity (PSS-78) [unitless]
+    p : array_like
+        pressure [dbar]
+    lon : array_like
+          decimal degrees east [0..+360] or [-180..+180]
+    lat : array_like
+          decimal degrees (+ve N, -ve S) [-90..+90]
+
+    Returns
+    -------
+    SA : masked array
+         Absolute salinity [g kg :sup:`-1`]
+
+    See Also
+    --------
+    FIXME
+    _delta_SA, _SA_from_SP_Baltic
+
+    Notes
+    -----
+    The mask is only set when the observation is well and truly on dry
+    land; often the warning flag is not set until one is several hundred
+    kilometers inland from the coast.
+
+    Since SP is non-negative by definition, this function changes any negative
+    input values of SP to be zero.
+
+    Examples
+    --------
+    >>> import seawater.gibbs as gsw
+    >>> SP = [34.5487, 34.7275, 34.8605, 34.6810, 34.5680, 34.5600]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> lon, lat = 188, 4
+    >>> gsw.SA_from_SP(SP, p, lon, lat)
+    array([ 34.71177971,  34.89152372,  35.02554774,  34.84723008,
+            34.7366296 ,  34.73236186])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.5 and appendices A.4 and A.5.
+
+    .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm
+    for estimating Absolute Salinity in the global ocean. Submitted to Ocean
+    Science. A preliminary version is available at Ocean Sci. Discuss.,
+    6, 215-242.
+    http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf
+
+    Modifications:
+    2011-05-31. David Jackett, Trevor McDougall & Paul Barker.
+    """
+
+    SP, p, lon, lat = check_input(SP, p, lon, lat)
+
+    SA = (SSO / 35) * SP * (1 + SAAR(p, lon, lat)[0])
+    SA_baltic = SA_from_SP_Baltic(SP, lon, lat)
+
+    # The following function (SAAR) finds SAAR in the non-Baltic parts of
+    # the world ocean.  (Actually, this SAAR look-up table returns values
+    # of zero in the Baltic Sea since SAAR in the Baltic is a function of SP,
+    # not space.
+    if SA_baltic is not None:
+        SA[~SA_baltic.mask] = SA_baltic[~SA_baltic.mask]
+
+    return SA
+
+
+ at match_args_return
+def Sstar_from_SP(SP, p, lon, lat):
+    r"""Calculates Preformed Salinity from Absolute Salinity.
+
+    Parameters
+    ----------
+    SP : array_like
+         salinity (PSS-78) [unitless]
+    p : array_like
+        pressure [dbar]
+    lon : array_like
+          decimal degrees east [0..+360] or [-180..+180]
+    lat : array_like
+          decimal degrees (+ve N, -ve S) [-90..+90]
+
+    Returns
+    -------
+    Sstar : masked array
+            Preformed Salinity [g kg :sup:`-1`]
+
+    See Also
+    --------
+    FIXME
+    _delta_SA, _SA_from_SP_Baltic
+
+    Notes
+    -----
+    The mask is only set when the observation is well and truly on dry
+    land; often the warning flag is not set until one is several hundred
+    kilometers inland from the coast.
+
+    Since SP is non-negative by definition, this function changes any negative
+    input values of SP to be zero.
+
+    Examples
+    --------
+    >>> import seawater.gibbs as gsw
+    >>> SP = [34.5487, 34.7275, 34.8605, 34.6810, 34.5680, 34.5600]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> lon, lat =  188, 4
+    >>> gsw.Sstar_from_SP(SP, p, lon, lat)
+    array([ 34.7115532 ,  34.89116101,  35.02464926,  34.84359277,
+            34.7290336 ,  34.71967638])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.5 and appendices A.4 and A.5.
+
+    .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm
+    for estimating Absolute Salinity in the global ocean. Submitted to Ocean
+    Science. A preliminary version is available at Ocean Sci. Discuss.,
+    6, 215-242.
+
+    Modifications:
+    2011-03-27. David Jackett, Trevor McDougall and Paul Barker.
+    """
+
+    SP, p, lon, lat = check_input(SP, p, lon, lat)
+
+    Sstar = (SSO / 35.0) * SP * (1.0 - r1 * SAAR(p, lon, lat)[0])
+
+    # In the Baltic Sea, Sstar==SA.
+    Sstar_baltic = SA_from_SP_Baltic(SP, lon, lat)
+
+    # TODO: Create Baltic and non-Baltic test cases.
+    if Sstar_baltic is not None:
+        Sstar[~Sstar_baltic.mask] = Sstar_baltic[~Sstar_baltic.mask]
+
+    return Sstar
+
+
+ at match_args_return
+def deltaSA_from_SP(SP, p, lon, lat):
+    """
+     gsw_deltaSA_from_SP                             Absolute Salinity Anomaly
+                                                       from Practical Salinity
+    ==========================================================================
+
+     USAGE:
+      deltaSA = gsw_deltaSA_from_SP(SP,p,long,lat)
+
+     DESCRIPTION:
+      Calculates Absolute Salinity Anomaly from Practical Salinity.  Since SP
+      is non-negative by definition, this function changes any negative input
+      values of SP to be zero.
+
+     INPUT:
+      SP   =  Practical Salinity  (PSS-78)                        [ unitless ]
+      p    =  sea pressure                                            [ dbar ]
+             ( i.e. absolute pressure - 10.1325 dbar )
+      long =  longitude in decimal degrees                      [ 0 ... +360 ]
+                                                         or  [ -180 ... +180 ]
+      lat  =  latitude in decimal degrees north                [ -90 ... +90 ]
+
+      p, lat & long may have dimensions 1x1 or Mx1 or 1xN or MxN,
+      where SP is MxN.
+
+     OUTPUT:
+      deltaSA  =  Absolute Salinity Anomaly                           [ g/kg ]
+
+     AUTHOR:
+      Trevor McDougall & Paul Barker                      [ help at teos-10.org ]
+
+     VERSION NUMBER: 3.03 (29th April, 2013)
+
+     REFERENCES:
+      IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
+       seawater - 2010: Calculation and use of thermodynamic properties.
+       Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+       UNESCO (English), 196 pp.  Available from http://www.TEOS-10.org
+        See section 2.5 and appendices A.4 and A.5 of this TEOS-10 Manual.
+
+      McDougall, T.J., D.R. Jackett, F.J. Millero, R. Pawlowicz and
+       P.M. Barker, 2012: A global algorithm for estimating Absolute Salinity.
+       Ocean Science, 8, 1117-1128.
+       http://www.ocean-sci.net/8/1117/2012/os-8-1117-2012.pdf
+
+    """
+    return SA_from_SP(SP, p, lon, lat) - SR_from_SP(SP)
+
+
+def depth_from_z(z):
+    r"""Calculates depth from height, z.  Note that in general height is
+    negative in the ocean.
+
+    Parameters
+    ---------
+    z : array_like
+        height [m]
+
+    Returns
+    -------
+    depth : array_like
+        depth [m]
+
+    Modifications:
+    2011-03-26. Winston.
+    """
+
+    return -z
+
+
+ at match_args_return
+def entropy_from_CT(SA, CT):
+    r"""Calculates specific entropy of seawater.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    entropy : array_like
+              specific entropy [J kg :sup:`-1` K :sup:`-1`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236]
+    >>> gsw.entropy_from_CT(SA, CT)
+    array([ 400.38916315,  395.43781023,  319.86680989,  146.79103279,
+             98.64714648,   62.79185763])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix A.10.
+
+    Modifications:
+    2011-04-04. Trevor McDougall & Paul Barker
+    """
+
+    SA = np.maximum(SA, 0)
+    pt0 = pt_from_CT(SA, CT)
+    return -gibbs(n0, n1, n0, SA, pt0, 0)
+
+
+ at match_args_return
+def entropy_from_pt(SA, pt):
+    r"""Calculates specific entropy of seawater.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    pt : array_like
+         potential temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    entropy : array_like
+              specific entropy [J kg :sup:`-1` K :sup:`-1`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> pt = [28.7832, 28.4210, 22.7850, 10.2305, 6.8292, 4.3245]
+    >>> gsw.entropy_from_pt(SA, pt)
+    array([ 400.38946744,  395.43839949,  319.86743859,  146.79054828,
+             98.64691006,   62.79135672])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix A.10.
+
+    Modifications:
+    2011-04-03. Trevor McDougall & Paul Barker
+    """
+
+    SA = np.maximum(SA, 0)
+    return -gibbs(n0, n1, n0, SA, pt, 0)
+
+
+ at match_args_return
+def entropy_from_t(SA, t, p):
+    """
+     gsw_entropy_from_t                          specific entropy of seawater
+    ==========================================================================
+
+     USAGE:
+      entropy  =  gsw_entropy_from_t(SA,t,p)
+
+     DESCRIPTION:
+      Calculates specific entropy of seawater.
+
+     INPUT:
+      SA  =  Absolute Salinity                                        [ g/kg ]
+      t   =  in-situ temperature (ITS-90)                            [ deg C ]
+      p   =  sea pressure                                             [ dbar ]
+             ( i.e. absolute pressure - 10.1325 dbar )
+
+      SA & t need to have the same dimensions.
+      p may have dimensions 1x1 or Mx1 or 1xN or MxN, where SA & t are MxN.
+
+     OUTPUT:
+      entropy  =  specific entropy                                [ J/(kg*K) ]
+
+     AUTHOR:
+      David Jackett, Trevor McDougall and Paul Barker     [ help at teos-10.org ]
+
+     VERSION NUMBER: 3.03 (29th April, 2013)
+
+     REFERENCES:
+      IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
+       seawater - 2010: Calculation and use of thermodynamic properties.
+       Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+       UNESCO (English), 196 pp.  Available from http://www.TEOS-10.org
+
+    """
+
+    return -gibbs(n0, n1, n0, SA, t, p)
+
+
+ at match_args_return
+def ionic_strength_from_SA(SA):
+    r"""Calculates the ionic strength of seawater from Absolute Salinity.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+
+    Returns
+    -------
+    ionic_strength : array_like
+                     ionic strength of seawater [mol kg :sup:`-1`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> gsw.ionic_strength_from_SA(SA)
+    array([ 0.71298118,  0.71680567,  0.71966059,  0.71586272,  0.71350891,
+            0.71341953])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Table L.1.
+
+    .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008:
+    The composition of Standard Seawater and the definition of the
+    Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72.
+    See Eqns. 5.9 and 5.12.
+
+    Modifications:
+    2011-03-29. Trevor McDougall and Paul Barker
+    """
+
+    # Molality of seawater in mol kg :sup:`-1`
+    molality = molality_from_SA(SA)
+
+    return 0.5 * valence_factor * molality
+
+
+ at match_args_return
+def molality_from_SA(SA):
+    r"""Calculates the molality of seawater from Absolute Salinity.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+
+    Returns
+    -------
+    molality : array_like
+            seawater molality [mol kg :sup:`-1`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> gsw.molality(SA)
+    array([ 1.14508476,  1.15122708,  1.15581223,  1.14971265,  1.14593231,
+            1.14578877])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+
+    Modifications:
+    2011-03-29. Trevor McDougall & Paul Barker
+    """
+
+    # Molality of seawater in mol kg :sup:`-1`.
+    SA = np.maximum(SA, 0)
+    molality = SA / (M_S * (1000 - SA))
+
+    return molality
+
+
+ at match_args_return
+def p_from_Abs_Pressure(Absolute_Pressure):
+    r"""Calculates sea pressure from Absolute Pressure. Note that Absolute
+    Pressure is in Pa NOT dbar.
+
+    Parameters
+    ---------
+    Absolute_Pressure : array_like
+                        Absolute Pressure [Pa]
+
+    Returns
+    -------
+    p : array_like
+        sea pressure [dbar]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.2.1).
+
+    Modifications:
+    2011-03-29. Trevor McDougall & Paul Barker
+    """
+
+    return (Absolute_Pressure - P0) * 1. / db2Pascal
+
+
+ at match_args_return
+def p_from_z(z, lat, geo_strf_dyn_height=0):
+    r"""Calculates sea pressure from height using computationally-efficient
+    48-term expression for density, in terms of SA, CT and p (McDougall et al.,
+    2011).  Dynamic height anomaly, geo_strf_dyn_height, if provided, must be
+    computed with its pr=0 (the surface.)
+
+    Parameters
+    ----------
+    z : array_like
+        height [m]
+    lat : array_like
+          latitude in decimal degrees north [-90..+90]
+    geo_strf_dyn_height : float, optional
+                          dynamic height anomaly [ m :sup:`2` s :sup:`-2` ]
+                          The reference pressure (p_ref) of geo_strf_dyn_height
+                          must be zero (0) dbar.
+
+    Returns
+    -------
+    p : array_like
+        pressure [dbar]
+
+    See Also
+    --------
+    #FIXME: specvol_SSO_0_CT25, enthalpy_SSO_0_CT25, changed!
+
+    Examples
+    --------
+    >>> import gsw
+    >>> z = [-10., -50., -125., -250., -600., -1000.]
+    >>> lat = 4.
+    >>> gsw.p_from_z(z, lat)
+    array([  10.05521794,   50.2711751,  125.6548857,  251.23284504,
+            602.44050752, 1003.07609807])
+    >>> z = [9.94460074, 49.71817465, 124.2728275, 248.47044828, 595.82618014,
+    ...      992.0931748]
+    >>> gsw.p_from_z(z, lat)
+    array([   10.,    50.,   125.,   250.,   600.,  1000.])
+
+    Notes
+    -----
+    Height (z) is NEGATIVE in the ocean. Depth is -z. Depth is not used in the
+    gibbs library.
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A
+    computationally efficient 48-term expression for the density of seawater
+    in terms of Conservative Temperature, and related properties of seawater.
+
+    .. [3] Moritz (2000) Goedetic reference system 1980. J. Geodesy, 74,
+    128-133.
+
+    .. [4] Saunders, P. M., 1981: Practical conversion of pressure to depth.
+    Journal of Physical Oceanography, 11, 573-574.
+
+    Modifications:
+    2010-08-26. Trevor McDougall, Claire Roberts-Thomson and Paul Barker.
+    2011-03-26. Trevor McDougall, Claire Roberts-Thomson and Paul Barker
+    """
+
+    X = np.sin(lat * DEG2RAD)
+    sin2 = X ** 2
+    gs = 9.780327 * (1.0 + (5.2792e-3 + (2.32e-5 * sin2)) * sin2)
+
+    # get the first estimate of p from Saunders (1981)
+    c1 = 5.25e-3 * sin2 + 5.92e-3
+    p = -2 * z / ((1 - c1) + np.sqrt((1 - c1) * (1 - c1) + 8.84e-6 * z))
+
+    df_dp = db2Pascal * specvol_SSO_0_p(p)  # Initial value for f derivative.
+
+    f = (enthalpy_SSO_0_p(p) + gs *
+         (z - 0.5 * gamma * (z ** 2)) - geo_strf_dyn_height)
+
+    p_old = p
+    p = p_old - f / df_dp
+    p_mid = 0.5 * (p + p_old)
+    df_dp = db2Pascal * specvol_SSO_0_p(p_mid)
+    p = p_old - f / df_dp
+
+    # After this one iteration through this modified Newton-Raphson iterative
+    # procedure, the remaining error in p is at computer machine precision,
+    # being no more than 1.6e-10 dbar.
+
+    return p
+
+
+ at match_args_return
+def pot_enthalpy_from_pt(SA, pt):
+    r"""Calculates the potential enthalpy of seawater from potential
+    temperature (whose reference sea pressure is zero dbar).
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    pt : array_like
+         potential temperature referenced to a sea pressure of zero dbar
+         [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    pot_enthalpy : array_like
+                   potential enthalpy [J kg :sup:`-1`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> pt = [28.7832, 28.4209, 22.7850, 10.2305, 6.8292, 4.3245]
+    >>> gsw.pot_enthalpy_from_pt(SA, pt)
+    array([ 115005.40853458,  113525.30870246,   90959.68769935,
+             40821.50280454,   27253.21472227,   17259.10131183])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.2.
+
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker
+    """
+
+    SA, pt, mask = strip_mask(SA, pt)
+
+    SA = np.maximum(SA, 0)
+
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y = pt * 0.025  # Normalize for F03 and F08
+
+    pot_enthalpy = (61.01362420681071 + y * (168776.46138048015 +
+    y * (-2735.2785605119625 + y * (2574.2164453821433 +
+    y * (-1536.6644434977543 + y * (545.7340497931629 +
+    (-50.91091728474331 - 18.30489878927802 * y) * y))))) +
+    x2 * (268.5520265845071 + y * (-12019.028203559312 +
+    y * (3734.858026725145 + y * (-2046.7671145057618 +
+    y * (465.28655623826234 + (-0.6370820302376359 -
+    10.650848542359153 * y) * y)))) +
+    x * (937.2099110620707 + y * (588.1802812170108 +
+    y * (248.39476522971285 + (-3.871557904936333 -
+    2.6268019854268356 * y) * y)) +
+    x * (-1687.914374187449 + x * (246.9598888781377 +
+    x * (123.59576582457964 - 48.5891069025409 * x)) +
+    y * (936.3206544460336 +
+    y * (-942.7827304544439 + y * (369.4389437509002 +
+    (-33.83664947895248 - 9.987880382780322 * y) * y)))))))
+
+    """The above polynomial for pot_enthalpy is the full expression for
+    potential enthalpy in terms of SA and pt, obtained from the Gibbs function
+    as below.  It has simply collected like powers of x and y so that it is
+    computationally faster than calling the Gibbs function twice as is done in
+    the commented code below. When this code below is run, the results are
+    identical to calculating pot_enthalpy as above, to machine precision.
+
+    g000 = gibbs(n0, n0, n0, SA, pt, 0)
+    g010 = gibbs(n0, n1, n0, SA, pt, 0)
+    pot_enthalpy = g000 - (Kelvin + pt) * g010
+
+    This is the end of the alternative code
+    %timeit gsw.CT_from_pt(SA, pt)
+    1000 loops, best of 3: 1.34 ms per loop <- calling gibbs
+    1000 loops, best of 3: 254 us per loop <- standard
+    """
+
+    return np.ma.array(pot_enthalpy, mask=mask, copy=False)
+
+
+ at match_args_return
+def pt0_from_t(SA, t, p):
+    r"""Calculates potential temperature with reference pressure, pr = 0 dbar.
+    The present routine is computationally faster than the more general
+    function "pt_from_t(SA, t, p, pr)" which can be used for any reference
+    pressure value.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+
+    Returns
+    -------
+    pt0 : array_like
+          potential temperature relative to 0 dbar [:math:`^\circ` C (ITS-90)]
+
+    See Also
+    --------
+    entropy_part, gibbs_pt0_pt0, entropy_part_zerop
+
+    Notes
+    -----
+    pt_from_t  has the same result (only slower)
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.pt0_from_t(SA, t, p)
+    array([ 28.78319682,  28.42098334,  22.7849304 ,  10.23052366,
+             6.82923022,   4.32451057])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.1.
+
+    .. [2] McDougall T. J., D. R. Jackett, P. M. Barker, C. Roberts-Thomson,
+    R. Feistel and R. W. Hallberg, 2010:  A computationally efficient 25-term
+    expression for the density of seawater in terms of Conservative
+    Temperature, and related properties of seawater.
+
+    Modifications:
+    2011-03-29. Trevor McDougall, David Jackett, Claire Roberts-Thomson and
+    Paul Barker.
+    """
+
+    SA = np.maximum(SA, 0)
+
+    s1 = SA * (35. / SSO)
+
+    pt0 = t + p * (8.65483913395442e-6 -
+             s1 * 1.41636299744881e-6 -
+              p * 7.38286467135737e-9 +
+              t * (-8.38241357039698e-6 +
+             s1 * 2.83933368585534e-8 +
+              t * 1.77803965218656e-8 +
+              p * 1.71155619208233e-10))
+
+    dentropy_dt = cp0 / ((Kelvin + pt0) * (1 - 0.05 * (1 - SA / SSO)))
+
+    true_entropy_part = entropy_part(SA, t, p)
+
+    for Number_of_iterations in range(0, 2, 1):
+        pt0_old = pt0
+        dentropy = entropy_part_zerop(SA, pt0_old) - true_entropy_part
+        # Half way the mod. method (McDougall and Wotherspoon, 2012).
+        pt0 = pt0_old - dentropy / dentropy_dt
+        pt0m = 0.5 * (pt0 + pt0_old)
+        dentropy_dt = -gibbs_pt0_pt0(SA, pt0m)
+        pt0 = pt0_old - dentropy / dentropy_dt
+
+    """maximum error of 6.3x10^-9 degrees C for one iteration. maximum error is
+    1.8x10^-14 degrees C for two iterations (two iterations is the default,
+    "for Number_of_iterations = 1:2").  These errors are over the full
+    "oceanographic funnel" of McDougall et al. (2010), which reaches down to
+    p = 8000 dbar."""
+
+    return pt0
+
+
+ at match_args_return
+def pt_from_CT(SA, CT):
+    r"""Calculates potential temperature (with a reference sea pressure of zero
+    dbar) from Conservative Temperature.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    pt : array_like
+         potential temperature referenced to a sea pressure of zero dbar
+         [:math:`^\circ` C (ITS-90)]
+
+    See Also
+    --------
+    specvol_anom
+
+    Notes
+    -----
+    This function uses 1.5 iterations through a modified Newton-Raphson (N-R)
+    iterative solution procedure, starting from a rational-function-based
+    initial condition for both pt and dCT_dpt.
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236]
+    >>> gsw.pt_from_CT(SA, CT)
+    array([ 28.78317705,  28.4209556 ,  22.78495347,  10.23053439,
+             6.82921659,   4.32453484])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See sections 3.1 and 3.3.
+
+    .. [2] McDougall T. J., D. R. Jackett, P. M. Barker, C. Roberts-Thomson,
+    R. Feistel and R. W. Hallberg, 2010:  A computationally efficient 25-term
+    expression for the density of seawater in terms of Conservative
+    Temperature, and related properties of seawater.
+
+    Modifications:
+    2011-03-29. Trevor McDougall, David Jackett, Claire Roberts-Thomson and
+    Paul Barker.
+    """
+
+    SA, CT, mask = strip_mask(SA, CT)
+    SA = np.maximum(SA, 0)
+
+    s1 = SA * 35. / SSO
+
+    a0 = -1.446013646344788e-2
+    a1 = -3.305308995852924e-3
+    a2 = 1.062415929128982e-4
+    a3 = 9.477566673794488e-1
+    a4 = 2.166591947736613e-3
+    a5 = 3.828842955039902e-3
+
+    b0 = 1.000000000000000e+0
+    b1 = 6.506097115635800e-4
+    b2 = 3.830289486850898e-3
+    b3 = 1.247811760368034e-6
+
+    a5CT = a5 * CT
+    b3CT = b3 * CT
+    CT_factor = (a3 + a4 * s1 + a5CT)
+    pt_num = a0 + s1 * (a1 + a2 * s1) + CT * CT_factor
+    pt_den = b0 + b1 * s1 + CT * (b2 + b3CT)
+    pt = pt_num / pt_den
+
+    dCT_dpt = pt_den / (CT_factor + a5CT - (b2 + b3CT + b3CT) * pt)
+
+    # 1.5 iterations through the modified Newton-Rapshon iterative method
+    CT_diff = CT_from_pt(SA, pt) - CT
+    pt_old = pt
+    pt = pt_old - CT_diff / dCT_dpt  # 1/2-way through the 1st modified N-R.
+    ptm = 0.5 * (pt + pt_old)
+
+    # This routine calls gibbs_pt0_pt0(SA, pt0) to get the second derivative of
+    # the Gibbs function with respect to temperature at zero sea pressure.
+
+    dCT_dpt = -(ptm + Kelvin) * gibbs_pt0_pt0(SA, ptm) / cp0
+    pt = pt_old - CT_diff / dCT_dpt  # End of 1st full modified N-R iteration.
+    CT_diff = CT_from_pt(SA, pt) - CT
+    pt_old = pt
+    pt = pt_old - CT_diff / dCT_dpt  # 1.5 iterations of the modified N-R.
+    # Abs max error of result is 1.42e-14 deg C.
+    return np.ma.array(pt, mask=mask, copy=False)
+
+
+ at match_args_return
+def pt_from_entropy(SA, entropy):
+    r"""Calculates potential temperature with reference pressure p_ref = 0 dbar
+    and with entropy as an input variable.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    entropy : array_like
+              specific entropy [J kg :sup:`-1` K :sup:`-1`]
+
+    Returns
+    -------
+    pt : array_like
+         potential temperature [:math:`^\circ` C (ITS-90)]
+         with reference sea pressure (p_ref) = 0 dbar.
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import seawater.gibbs as gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> entropy = [400.3892, 395.4378, 319.8668, 146.7910, 98.6471, 62.7919]
+    >>> gsw.pt_from_entropy(SA, entropy)
+    array([ 28.78317983,  28.42095483,  22.78495274,  10.23053207,
+             6.82921333,   4.32453778])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix  A.10.
+
+    Modifications:
+    2011-04-03. Trevor McDougall and Paul Barker.
+    """
+
+    SA = np.maximum(SA, 0)
+
+    part1 = 1 - SA / SSO
+    part2 = 1 - 0.05 * part1
+    ent_SA = (cp0 / Kelvin) * part1 * (1 - 1.01 * part1)
+    c = (entropy - ent_SA) * part2 / cp0
+    pt = Kelvin * (np.exp(c) - 1)
+    dentropy_dt = cp0 / ((Kelvin + pt) * part2)  # Initial dentropy_dt.
+
+    for Number_of_iterations in range(0, 3):
+        pt_old = pt
+        dentropy = entropy_from_pt(SA, pt_old) - entropy
+        # This is half way through the modified method
+        # (McDougall and Wotherspoon, 2012)
+        pt = pt_old - dentropy / dentropy_dt
+        ptm = 0.5 * (pt + pt_old)
+        dentropy_dt = -gibbs_pt0_pt0(SA, ptm)
+        pt = pt_old - dentropy / dentropy_dt
+
+    """maximum error of 2.2x10^-6 degrees C for one iteration. maximum error is
+    1.4x10^-14 degrees C for two iterations (two iterations is the default,
+    "for Number_of_iterations = 1:2")."""
+
+    return pt
+
+
+ at match_args_return
+def pt_from_t(SA, t, p, p_ref=0):
+    r"""Calculates potential temperature with the general reference pressure,
+    pr, from in situ temperature.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    p_ref : int, float, optional
+         reference pressure, default = 0
+
+    Returns
+    -------
+    pt : array_like
+         potential temperature [:math:`^\circ` C (ITS-90)]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    This function calls `entropy_part` which evaluates entropy except for the
+    parts which are a function of Absolute Salinity alone. A faster routine
+    exists pt0_from_t(SA,t,p) if p_ref is indeed zero dbar.
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.pt_from_t(SA, t, p)
+    array([ 28.78319682,  28.42098334,  22.7849304 ,  10.23052366,
+             6.82923022,   4.32451057])
+    >>> gsw.pt_from_t(SA, t, p, pr = 1000)
+    array([ 29.02665528,  28.662375  ,  22.99149634,  10.35341725,
+             6.92732954,   4.4036    ])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.1.
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of seawater
+    in terms of Conservative Temperature, and related properties of seawater.
+
+    Modifications:
+    2011-03-29. Trevor McDougall, David Jackett, Claire Roberts-Thomson and
+    Paul Barker.
+    """
+
+    p_ref = np.asanyarray(p_ref)
+
+    SA = np.maximum(SA, 0)
+
+    s1 = SA * 35. / SSO
+
+    pt = (t + (p - p_ref) * (8.65483913395442e-6 -
+                       s1 * 1.41636299744881e-6 -
+              (p + p_ref) * 7.38286467135737e-9 +
+                        t * (-8.38241357039698e-6 +
+                       s1 * 2.83933368585534e-8 +
+                        t * 1.77803965218656e-8 +
+              (p + p_ref) * 1.71155619208233e-10)))
+
+    dentropy_dt = cp0 / ((Kelvin + pt) *
+                         (1 - 0.05 * (1 - SA / SSO)))
+
+    true_entropy_part = entropy_part(SA, t, p)
+
+    for Number_of_iterations in range(0, 2, 1):
+        pt_old = pt
+        dentropy = entropy_part(SA, pt_old, p_ref) - true_entropy_part
+        pt = pt_old - dentropy / dentropy_dt  # half way through the method
+        ptm = 0.5 * (pt + pt_old)
+        dentropy_dt = -gibbs(n0, n2, n0, SA, ptm, p_ref)
+        pt = pt_old - dentropy / dentropy_dt
+
+    """maximum error of 6.3x10^-9 degrees C for one iteration.  maximum error
+    is 1.8x10^-14 degrees C for two iterations (two iterations is the default,
+    "for Number_of_iterations = 1:2).  These errors are over the full
+    "oceanographic funnel" of McDougall et al. (2010), which reaches down to
+    p = 8000 dbar."""
+
+    return pt
+
+
+ at match_args_return
+def t90_from_t48(t48):
+    r"""Converts IPTS-48 temperature to International Temperature Scale 1990
+    (ITS-90) temperature.  This conversion should be applied to all in-situ
+    data collected prior to 31/12/1967.
+
+    Parameters
+    ---------
+    t48 : array_like
+          in-situ temperature [:math:`^\circ` C (ITPS-48)]
+
+    Returns
+    -------
+    t90 : array_like
+          in-situ temperature [:math:`^\circ` C (ITS-90)]
+
+    References
+    ----------
+    .. [1] International Temperature Scales of 1948, 1968 and 1990, an ICES
+    note, available from http://www.ices.dk/ocean/procedures/its.htm
+
+    Modifications:
+    2011-03-29. Paul Barker and Trevor McDougall.
+    """
+
+    return (t48 - (4.4e-6) * t48 * (100 - t48)) / 1.00024
+
+
+ at match_args_return
+def t90_from_t68(t68):
+    r"""Converts IPTS-68 temperature to International Temperature Scale 1990
+    (ITS-90) temperature.  This conversion should be applied to all in-situ
+    data collected between 1/1/1968 and 31/12/1989.
+
+    Parameters
+    ---------
+    t68 : array_like
+          in-situ temperature [:math:`^\circ` C (ITPS-68)]
+
+    Returns
+    -------
+    t90 : array_like
+          in-situ temperature [:math:`^\circ` C (ITS-90)]
+
+    References
+    ----------
+    .. [1] International Temperature Scales of 1948, 1968 and 1990, an ICES
+    note, available from http://www.ices.dk/ocean/procedures/its.htm
+
+    Modifications:
+    2011-03-29. Paul Barker and Trevor McDougall.
+    """
+
+    # t90 = t68 / 1.00024
+    return t68 * 0.999760057586179
+
+
+ at match_args_return
+def t_from_CT(SA, CT, p):
+    r"""Calculates *in-situ* temperature from Conservative Temperature of
+    seawater.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+
+    Returns
+    -------
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.t_from_CT(SA, CT, p)
+    array([ 28.78558023,  28.43287225,  22.81032309,  10.26001075,
+             6.8862863 ,   4.40362445])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See sections 3.1 and 3.3.
+
+    Modifications:
+    2011-03-29. Trevor McDougall and Paul Barker
+    """
+
+    pt0 = pt_from_CT(SA, CT)
+    return pt_from_t(SA, pt0, 0, p)
+
+
+ at match_args_return
+def t_from_entropy(SA, entropy, p):
+    """
+    gsw_t_from_entropy                                    in-situ temperature
+                                                     as a function of entropy
+    =========================================================================
+
+    USAGE:
+     t = gsw_t_from_entropy(SA,entropy,p)
+
+    DESCRIPTION:
+     Calculates in-situ temperature with entropy as an input variable.
+
+    INPUT:
+     SA       =  Absolute Salinity                                   [ g/kg ]
+     entropy  =  specific entropy                                [ J/(kg*K) ]
+     p   =  sea pressure                                             [ dbar ]
+            ( i.e. absolute pressure - 10.1325 dbar )
+
+     SA & entropy need to have the same dimensions.
+     p may have dimensions 1x1 or Mx1 or 1xN or MxN, where SA & entropy are
+     MxN.
+
+    OUTPUT:
+     t   =  in-situ temperature (ITS-90)                            [ deg C ]
+
+    AUTHOR:
+     Trevor McDougall and Paul Barker                    [ help at teos-10.org ]
+
+    VERSION NUMBER: 3.03 (29th April, 2013)
+
+    REFERENCES:
+     IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
+      seawater - 2010: Calculation and use of thermodynamic properties.
+      Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+      UNESCO (English), 196 pp.  Available from http://www.TEOS-10.org
+       See appendix  A.10 of this TEOS-10 Manual.
+
+    """
+    pt = pt_from_entropy(SA, entropy)
+    #% Note that pt is potential temperature with a reference pressure of zero.
+    p0 = 0
+    return pt_from_t(SA, pt, p0, p)
+
+
+def z_from_depth(depth):
+    r"""Calculates height, z, from depth.  Note that in general height is
+    negative in the ocean.
+
+    Parameters
+    ---------
+    depth : array_like
+        depth [m]
+
+    Returns
+    -------
+    z : array_like
+        height [m]
+
+    Modifications:
+    2011-03-26. Winston.
+    """
+
+    return -depth
+
+
+ at match_args_return
+def z_from_p(p, lat, geo_strf_dyn_height=0):
+    r"""Calculates height from sea pressure using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p (McDougall et
+    al., 2011).  Dynamic height anomaly, geo_strf_dyn_height, if provided, must
+    be computed with its pr=0 (the surface).
+
+    Parameters
+    ----------
+    p : array_like
+        pressure [dbar]
+    lat : array_like
+          latitude in decimal degrees north [-90..+90]
+    geo_strf_dyn_height : float, optional
+                          dynamic height anomaly [ m :sup:`2` s :sup:`-2` ]
+
+    Returns
+    -------
+    z : array_like
+        height [m]
+
+    See Also
+    --------
+    # FIXME: enthalpy_SSO_0_CT25, changed!
+
+
+    Examples
+    --------
+    >>> import gsw
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> lat = 4
+    >>> gsw.z_from_p(p, lat)
+    array([  -9.94460074,  -49.71817465, -124.2728275 , -248.47044828,
+           -595.82618014, -992.0931748 ])
+
+    Notes
+    -----
+    At sea level z = 0, and since z (HEIGHT) is defined to be positive upwards,
+    it follows that while z is positive in the atmosphere, it is NEGATIVE in
+    the ocean.
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of seawater
+    in terms of Conservative Temperature, and related properties of seawater.
+
+    .. [3] Moritz (2000) Goedetic reference system 1980. J. Geodesy, 74,
+    128-133.
+
+    Modifications:
+    2011-03-26. Trevor McDougall, Claire Roberts-Thomson and Paul Barker.
+    """
+
+    X = np.sin(lat * DEG2RAD)
+    sin2 = X ** 2
+    B = 9.780327 * (1.0 + (5.2792e-3 + (2.32e-5 * sin2)) * sin2)
+    A = -0.5 * gamma * B
+    C = enthalpy_SSO_0_p(p) - geo_strf_dyn_height
+
+    return -2 * C / (B + np.sqrt(B ** 2 - 4 * A * C))
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/density_enthalpy_48.py b/gsw/gibbs/density_enthalpy_48.py
new file mode 100644
index 0000000..cacffa5
--- /dev/null
+++ b/gsw/gibbs/density_enthalpy_48.py
@@ -0,0 +1,1459 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .library import specvol_SSO_0_p
+from .constants import P0, db2Pascal, cp0
+from ..utilities import match_args_return
+
+__all__ = ['alpha',
+           'alpha_on_beta',
+           'alpha_on_beta_CT',
+           'beta',
+           'dynamic_enthalpy',
+           'enthalpy',
+           'enthalpy_diff',
+           'internal_energy',
+           'rho',
+           'rho_alpha_beta',
+           'SA_from_rho',
+           'sigma0',
+           'sigma1',
+           'sigma2',
+           'sigma3',
+           'sigma4',
+           'sound_speed',
+           'specvol',
+           'specvol_anom']
+
+
+# NOTE: these are from gsw_rho_alpha_beta.m
+v01 = 9.998420897506056e+2
+v02 = 2.839940833161907
+v03 = -3.147759265588511e-2
+v04 = 1.181805545074306e-3
+v05 = -6.698001071123802
+v06 = -2.986498947203215e-2
+v07 = 2.327859407479162e-4
+v08 = -3.988822378968490e-2
+v09 = 5.095422573880500e-4
+v10 = -1.426984671633621e-5
+v11 = 1.645039373682922e-7
+v12 = -2.233269627352527e-2
+v13 = -3.436090079851880e-4
+v14 = 3.726050720345733e-6
+v15 = -1.806789763745328e-4
+v16 = 6.876837219536232e-7
+v17 = -3.087032500374211e-7
+v18 = -1.988366587925593e-8
+v19 = -1.061519070296458e-11
+v20 = 1.550932729220080e-10
+v21 = 1.0
+v22 = 2.775927747785646e-3
+v23 = -2.349607444135925e-5
+v24 = 1.119513357486743e-6
+v25 = 6.743689325042773e-10
+v26 = -7.521448093615448e-3
+v27 = -2.764306979894411e-5
+v28 = 1.262937315098546e-7
+v29 = 9.527875081696435e-10
+v30 = -1.811147201949891e-11
+v31 = -3.303308871386421e-5
+v32 = 3.801564588876298e-7
+v33 = -7.672876869259043e-9
+v34 = -4.634182341116144e-11
+v35 = 2.681097235569143e-12
+v36 = 5.419326551148740e-6
+v37 = -2.742185394906099e-5
+v38 = -3.212746477974189e-7
+v39 = 3.191413910561627e-9
+v40 = -1.931012931541776e-12
+v41 = -1.105097577149576e-7
+v42 = 6.211426728363857e-10
+v43 = -1.119011592875110e-10
+v44 = -1.941660213148725e-11
+v45 = -1.864826425365600e-14
+v46 = 1.119522344879478e-14
+v47 = -1.200507748551599e-15
+v48 = 6.057902487546866e-17
+
+a01 = 2.839940833161907
+a02 = -6.295518531177023e-2
+a03 = 3.545416635222918e-3
+a04 = -2.986498947203215e-2
+a05 = 4.655718814958324e-4
+a06 = 5.095422573880500e-4
+a07 = -2.853969343267241e-5
+a08 = 4.935118121048767e-7
+a09 = -3.436090079851880e-4
+a10 = 7.452101440691467e-6
+a11 = 6.876837219536232e-7
+a12 = -1.988366587925593e-8
+a13 = -2.123038140592916e-11
+
+a14 = 2.775927747785646e-3
+a15 = -4.699214888271850e-5
+a16 = 3.358540072460230e-6
+a17 = 2.697475730017109e-9
+a18 = -2.764306979894411e-5
+a19 = 2.525874630197091e-7
+a20 = 2.858362524508931e-9
+a21 = -7.244588807799565e-11
+a22 = 3.801564588876298e-7
+a23 = -1.534575373851809e-8
+a24 = -1.390254702334843e-10
+a25 = 1.072438894227657e-11
+a26 = -3.212746477974189e-7
+a27 = 6.382827821123254e-9
+a28 = -5.793038794625329e-12
+a29 = 6.211426728363857e-10
+a30 = -1.941660213148725e-11
+a31 = -3.729652850731201e-14
+a32 = 1.119522344879478e-14
+a33 = 6.057902487546866e-17
+
+b01 = -6.698001071123802
+b02 = -2.986498947203215e-2
+b03 = 2.327859407479162e-4
+b04 = -5.983233568452735e-2
+b05 = 7.643133860820750e-4
+b06 = -2.140477007450431e-5
+b07 = 2.467559060524383e-7
+b08 = -1.806789763745328e-4
+b09 = 6.876837219536232e-7
+b10 = 1.550932729220080e-10
+b11 = -7.521448093615448e-3
+b12 = -2.764306979894411e-5
+b13 = 1.262937315098546e-7
+b14 = 9.527875081696435e-10
+b15 = -1.811147201949891e-11
+b16 = -4.954963307079632e-5
+b17 = 5.702346883314446e-7
+b18 = -1.150931530388857e-8
+b19 = -6.951273511674217e-11
+b20 = 4.021645853353715e-12
+b21 = 1.083865310229748e-5
+b22 = -1.105097577149576e-7
+b23 = 6.211426728363857e-10
+b24 = 1.119522344879478e-14
+
+c01 = -2.233269627352527e-2
+c02 = -3.436090079851880e-4
+c03 = 3.726050720345733e-6
+c04 = -1.806789763745328e-4
+c05 = 6.876837219536232e-7
+c06 = -6.174065000748422e-7
+c07 = -3.976733175851186e-8
+c08 = -2.123038140592916e-11
+c09 = 3.101865458440160e-10
+c10 = -2.742185394906099e-5
+c11 = -3.212746477974189e-7
+c12 = 3.191413910561627e-9
+c13 = -1.931012931541776e-12
+c14 = -1.105097577149576e-7
+c15 = 6.211426728363857e-10
+c16 = -2.238023185750219e-10
+c17 = -3.883320426297450e-11
+c18 = -3.729652850731201e-14
+c19 = 2.239044689758956e-14
+c20 = -3.601523245654798e-15
+c21 = 1.817370746264060e-16
+
+# Helper functions that are used by more than one user function.
+# FIXME: arrange all these things so that inputs to these
+# functions are done with ordinary ndarrays with nans, not
+# masked arrays.  We might need a different decorator for this.
+
+
+def v_hat_denominator(SA, CT, p, sqrtSA):
+    return (v01 + CT * (v02 + CT * (v03 + v04*CT)) +
+            SA *
+            (v05 + CT * (v06 + v07 * CT) + sqrtSA *
+             (v08 + CT * (v09 + CT * (v10 + v11 * CT)))) +
+            p *
+            (v12 + CT * (v13 + v14 * CT) + SA * (v15 + v16 * CT) +
+             p * (v17 + CT * (v18 + v19 * CT) + v20 * SA)))
+
+
+def v_hat_numerator(SA, CT, p, sqrtSA):
+    return (v21 + CT * (v22 + CT * (v23 + CT * (v24 + v25 * CT))) +
+            SA *
+            (v26 + CT * (v27 + CT * (v28 + CT * (v29 + v30 * CT))) +
+             v36 * SA + sqrtSA *
+             (v31 + CT * (v32 + CT * (v33 + CT * (v34 + v35 * CT))))) +
+            p *
+            (v37 + CT * (v38 + CT * (v39 + v40 * CT)) + SA *
+             (v41 + v42 * CT) + p *
+             (v43 + CT * (v44 + v45 * CT + v46 * SA) + p * (v47 + v48 * CT))))
+
+
+# Next 4 are from alpha on beta:
+def dvhatden_dCT(SA, CT, p, sqrtSA):
+    return (a01 + CT * (a02 + a03 * CT) + SA *
+            (a04 + a05 * CT + sqrtSA * (a06 + CT * (a07 + a08 * CT))) +
+            p * (a09 + a10 * CT + a11 * SA + p * (a12 + a13 * CT)))
+
+
+def dvhatnum_dCT(SA, CT, p, sqrtSA):
+    return (a14 + CT * (a15 + CT * (a16 + a17 * CT)) + SA *
+            (a18 + CT * (a19 + CT * (a20 + a21 * CT)) + sqrtSA *
+             (a22 + CT * (a23 + CT * (a24 + a25 * CT)))) + p *
+            (a26 + CT * (a27 + a28 * CT) + a29 * SA + p *
+             (a30 + a31 * CT + a32 * SA + a33 * p)))
+
+
+def dvhatden_dSA(SA, CT, p, sqrtSA):
+    return (b01 + CT * (b02 + b03 * CT) + sqrtSA *
+            (b04 + CT * (b05 + CT * (b06 + b07 * CT))) +
+            p * (b08 + b09 * CT + b10 * p))
+
+
+def dvhatnum_dSA(SA, CT, p, sqrtSA):
+    return(b11 + CT * (b12 + CT * (b13 + CT * (b14 + b15*CT)))
+           + sqrtSA * (b16 + CT * (b17 + CT * (b18 + CT * (b19 + b20*CT))))
+           + b21*SA
+           + p * (b22 + CT * (b23 + b24*p)))
+
+
+ at match_args_return
+def alpha_on_beta(SA, CT, p):
+    """
+     gsw_alpha_on_beta                           alpha/beta (48-term equation)
+    ==========================================================================
+
+     USAGE:
+     alpha_on_beta = gsw_alpha_on_beta(SA,CT,p)
+
+     DESCRIPTION:
+      Calculates alpha divided by beta, where alpha is the thermal expansion
+      coefficient and beta is the saline contraction coefficient of seawater
+      from Absolute Salinity and Conservative Temperature.  This function uses
+      the computationally-efficient 48-term expression for density in terms of
+      SA, CT and p (IOC et al., 2010).
+
+      Note that the 48-term equation has been fitted in a restricted range of
+      parameter space, and is most accurate inside the "oceanographic funnel"
+      described in IOC et al. (2010).  The GSW library function
+      "gsw_infunnel(SA,CT,p)" is avaialble to be used if one wants to test if
+      some of one's data lies outside this "funnel".
+
+     INPUT:
+      SA  =  Absolute Salinity                                        [ g/kg ]
+      CT  =  Conservative Temperature (ITS-90)                       [ deg C ]
+      p   =  sea pressure                                             [ dbar ]
+             ( i.e. absolute pressure - 10.1325 dbar )
+
+      SA & CT need to have the same dimensions.
+      p may have dimensions 1x1 or Mx1 or 1xN or MxN, where SA & CT are MxN.
+
+     OUTPUT:
+      alpha_on_beta  =  thermal expansion coefficient with respect to
+                        Conservative Temperature divided by the saline
+                        contraction coefficient at constant Conservative
+                        Temperature                           [ kg g^-1 K^-1 ]
+
+     AUTHOR:
+      Paul Barker and Trevor McDougall                    [ help at teos-10.org ]
+
+     VERSION NUMBER: 3.03 (10th May, 2013)
+
+     REFERENCES:
+      IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
+       seawater - 2010: Calculation and use of thermodynamic properties.
+       Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+       UNESCO (English), 196 pp.  Available from http://www.TEOS-10.org
+
+    """
+    SA = np.maximum(SA, 0)
+    sqrtSA = np.sqrt(SA)
+    args = SA, CT, p, sqrtSA
+
+    num = (dvhatnum_dCT(*args) * v_hat_denominator(*args) -
+           dvhatden_dCT(*args) * v_hat_numerator(*args))
+    denom = (dvhatden_dSA(*args) * v_hat_numerator(*args) -
+             dvhatnum_dSA(*args) * v_hat_denominator(*args))
+    return num / denom
+
+alpha_on_beta_CT = alpha_on_beta
+
+
+ at match_args_return
+def alpha(SA, CT, p):
+    r"""Calculates the thermal expansion coefficient of seawater with respect
+    to Conservative Temperature using the computationally-efficient 48-term
+    expression for density in terms of SA, CT and p (McDougall et al., 2011)
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    alpha : array_like
+            thermal expansion coefficient [K :math:`-1`]
+            with respect to Conservative Temperature
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel"
+    described in McDougall et al. (2011).  The GSW library function
+    "infunnel(SA, CT, p)" is available to be used if one wants to test if
+    some of one's data lies outside this "funnel".
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.18.3).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-03-23. Paul Barker and Trevor McDougall.
+    """
+    SA = np.maximum(SA, 0)
+    sqrtSA = np.sqrt(SA)
+    args = SA, CT, p, sqrtSA
+
+    spec_vol = v_hat_numerator(*args) / v_hat_denominator(*args)
+
+    return ((dvhatnum_dCT(*args) - dvhatden_dCT(*args) * spec_vol) /
+            v_hat_numerator(*args))
+
+
+ at match_args_return
+def beta(SA, CT, p):
+    r"""Calculates the saline (i.e. haline) contraction coefficient of seawater
+    at constant Conservative Temperature using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p (McDougall et al.,
+    2011).
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    beta : array_like
+           saline contraction coefficient [kg g :math:`-1`]
+           at constant Conservative Temperature.
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel"
+    described in McDougall et al. (2011).  The GSW library function
+    "infunnel(SA, CT, p)" is available to be used if one wants to test if some
+    of one's data lies outside this "funnel".
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.19.3).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-03-23. Paul Barker and Trevor McDougall.
+    """
+
+    SA = np.maximum(SA, 0)
+    sqrtSA = np.sqrt(SA)
+    args = SA, CT, p, sqrtSA
+
+    spec_vol = v_hat_numerator(*args) / v_hat_denominator(*args)
+
+    return ((dvhatden_dSA(*args) * spec_vol - dvhatnum_dSA(*args)) /
+            v_hat_numerator(*args))
+
+
+ at match_args_return
+def dynamic_enthalpy(SA, CT, p):
+    r"""Calculates dynamic enthalpy of seawater using the computationally-
+    efficient 48-term expression for density in terms of SA, CT and p
+    (McDougall et al., 2011).  Dynamic enthalpy is defined as enthalpy minus
+    potential enthalpy (Young, 2010).
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    dynamic_enthalpy : array_like
+                       dynamic enthalpy [J/kg]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA, CT, p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.2
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    .. [3] Young, W.R., 2010: Dynamic enthalpy, Conservative Temperature, and
+    the seawater Boussinesq approximation. Journal of Physical Oceanography,
+    40, 394-400.
+
+    Modifications:
+    2011-04-05. Trevor McDougall and Paul Barker.
+    """
+
+    SA = np.maximum(SA, 0)
+
+    sqrtSA = np.sqrt(SA)
+
+    a0 = (v21 + CT * (v22 + CT * (v23 + CT * (v24 + v25 * CT))) + SA *
+          (v26 + CT * (v27 + CT * (v28 + CT * (v29 + v30 * CT))) + v36 * SA +
+           sqrtSA * (v31 + CT * (v32 + CT * (v33 + CT * (v34 + v35 * CT))))))
+
+    a1 = v37 + CT * (v38 + CT * (v39 + v40 * CT)) + SA * (v41 + v42 * CT)
+
+    a2 = v43 + CT * (v44 + v45 * CT + v46 * SA)
+
+    a3 = v47 + v48 * CT
+
+    b0 = (v01 + CT * (v02 + CT * (v03 + v04 * CT)) + SA * (v05 + CT * (v06 +
+          v07 * CT) + sqrtSA * (v08 + CT * (v09 + CT * (v10 + v11 * CT)))))
+
+    b1 = 0.5 * (v12 + CT * (v13 + v14 * CT) + SA * (v15 + v16 * CT))
+
+    b2 = v17 + CT * (v18 + v19 * CT) + v20 * SA
+
+    b1sq = b1 * b1
+
+    sqrt_disc = np.sqrt(b1sq - b0 * b2)
+
+    N = a0 + (2 * a3 * b0 * b1 / b2 - a2 * b0) / b2
+    M = a1 + (4 * a3 * b1sq / b2 - a3 * b0 - 2 * a2 * b1) / b2
+
+    A = b1 - sqrt_disc
+    B = b1 + sqrt_disc
+
+    part = (N * b2 - M * b1) / (b2 * (B - A))
+
+    """This function calculates dynamic_enthalpy using the computationally-
+    efficient 48-term expression for density in terms of SA, CT and p.  If one
+    wanted to compute dynamic_enthalpy from SA, CT, and p with the full TEOS-10
+    Gibbs function, the following lines of code will enable this.
+
+    dynamic_enthalpy = dynamic_enthalpy_CT_exact(SA, CT, p)
+    """
+
+    return db2Pascal * (p * (a2 - 2 * a3 * b1 / b2 + 0.5 * a3 * p) / b2 +
+                        (M / (2 * b2)) *
+                        np.log(1 + p * (2 * b1 + b2 * p) / b0) + part *
+                        np.log(1 + (b2 * p * (B - A)) / (A * (B + b2 * p))))
+
+
+ at match_args_return
+def enthalpy(SA, CT, p):
+    r"""Calculates specific enthalpy of seawater using the computationally-
+    efficient 48-term expression for density in terms of SA, CT and p
+    (McDougall et al., 2011)
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    enthalpy : array_like
+               specific enthalpy [J/kg]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA, CT, p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (A.30.6).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-04-05. Trevor McDougall, David Jackett, Claire Roberts-Thomson and
+                Paul Barker.
+    """
+
+    SA = np.maximum(SA, 0)
+
+    sqrtSA = np.sqrt(SA)
+
+    a0 = (v21 + CT * (v22 + CT * (v23 + CT * (v24 + v25 * CT))) + SA *
+          (v26 + CT * (v27 + CT * (v28 + CT * (v29 + v30 * CT))) + v36 * SA +
+           sqrtSA * (v31 + CT * (v32 + CT * (v33 + CT * (v34 + v35 * CT))))))
+
+    a1 = v37 + CT * (v38 + CT * (v39 + v40 * CT)) + SA * (v41 + v42 * CT)
+
+    a2 = v43 + CT * (v44 + v45 * CT + v46 * SA)
+
+    a3 = v47 + v48 * CT
+
+    b0 = (v01 + CT * (v02 + CT * (v03 + v04 * CT)) + SA * (v05 + CT * (v06 +
+          v07 * CT) + sqrtSA * (v08 + CT * (v09 + CT * (v10 + v11 * CT)))))
+
+    b1 = 0.5 * (v12 + CT * (v13 + v14 * CT) + SA * (v15 + v16 * CT))
+
+    b2 = v17 + CT * (v18 + v19 * CT) + v20 * SA
+
+    b1sq = b1 * b1
+
+    sqrt_disc = np.sqrt(b1sq - b0 * b2)
+
+    N = a0 + (2 * a3 * b0 * b1 / b2 - a2 * b0) / b2
+    M = a1 + (4 * a3 * b1sq / b2 - a3 * b0 - 2 * a2 * b1) / b2
+
+    A = b1 - sqrt_disc
+    B = b1 + sqrt_disc
+
+    part = (N * b2 - M * b1) / (b2 * (B - A))
+
+    """This function calculates enthalpy using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p.  If one wanted to
+    compute enthalpy from SA, CT, and p with the full TEOS-10 Gibbs function,
+    the following lines of code will enable this.
+
+    pt = pt_from_CT(SA, CT)
+    t = pt_from_t(SA, pt, 0, p)
+    enthalpy = enthalpy_t_exact(SA, t, p)
+
+    or call the following, it is identical to the lines above.
+
+    enthalpy = enthalpy_CT_exact(SA, CT, p)
+    """
+
+    return (cp0 * CT + db2Pascal *
+            (p * (a2 - 2 * a3 * b1 / b2 + 0.5 * a3 * p) / b2 + (M / (2 * b2)) *
+             np.log(1 + p * (2 * b1 + b2 * p) / b0) + part *
+             np.log(1 + (b2 * p * (B - A)) / (A * (B + b2 * p)))))
+
+
+ at match_args_return
+def enthalpy_diff(SA, CT, p_shallow, p_deep):
+    r"""Calculates the difference of the specific enthalpy of seawater between
+    two different pressures, p_deep (the deeper pressure) and p_shallow (the
+    shallower pressure), at the same values of SA and CT.  This function uses
+    the computationally-efficient 48-term expression for density in terms of
+    SA, CT and p (McDougall et al., 2011).  The output (enthalpy_diff_CT) is
+    the specific enthalpy evaluated at (SA, CT, p_deep) minus the specific
+    enthalpy at (SA, CT, p_shallow).
+
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p_shallow : array_like
+                lower sea pressure [dbar]
+    p_deep : array_like
+             upper sea pressure [dbar]
+
+    Returns
+    -------
+    enthalpy_diff : array_like
+                    difference of specific enthalpy [J/kg]
+                    (deep minus shallow)
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA, CT, p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (3.32.2) and (A.30.6).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-03-21. Trevor McDougall & Paul Barker.
+    """
+
+    SA = np.maximum(SA, 0)
+
+    sqrtSA = np.sqrt(SA)
+
+    a0 = (v21 + CT * (v22 + CT * (v23 + CT * (v24 + v25 * CT))) + SA *
+          (v26 + CT * (v27 + CT * (v28 + CT * (v29 + v30 * CT))) + v36 * SA +
+           sqrtSA * (v31 + CT * (v32 + CT * (v33 + CT * (v34 + v35 * CT))))))
+
+    a1 = v37 + CT * (v38 + CT * (v39 + v40 * CT)) + SA * (v41 + v42 * CT)
+
+    a2 = v43 + CT * (v44 + v45 * CT + v46 * SA)
+
+    a3 = v47 + v48 * CT
+
+    b0 = (v01 + CT * (v02 + CT * (v03 + v04 * CT)) + SA * (v05 + CT * (v06 +
+          v07 * CT) + sqrtSA * (v08 + CT * (v09 + CT * (v10 + v11 * CT)))))
+
+    b1 = 0.5 * (v12 + CT * (v13 + v14 * CT) + SA * (v15 + v16 * CT))
+
+    b2 = v17 + CT * (v18 + v19 * CT) + v20 * SA
+
+    b1sq = b1 * b1
+
+    sqrt_disc = np.sqrt(b1sq - b0 * b2)
+
+    N = a0 + (2 * a3 * b0 * b1 / b2 - a2 * b0) / b2
+    M = a1 + (4 * a3 * b1sq / b2 - a3 * b0 - 2 * a2 * b1) / b2
+
+    A = b1 - sqrt_disc
+    B = b1 + sqrt_disc
+
+    delta_p = p_deep - p_shallow
+    p_sum = p_deep + p_shallow
+
+    part1 = b0 + p_shallow * (2 * b1 + b2 * p_shallow)
+    part2 = (B + b2 * p_deep) * (A + b2 * p_shallow)
+    part3 = (N * b2 - M * b1) / (b2 * (B - A))
+
+    """This function calculates enthalpy_diff using the computationally
+    efficient 48-term expression for density in terms of SA, CT and p.  If one
+    wanted to compute the enthalpy difference using the full TEOS-10 Gibbs
+    function, the following lines of code will enable this.
+
+    pt = pt_from_CT(SA, CT)
+    t_shallow = pt_from_t(SA, pt, 0, p_shallow)
+    t_deep = pt_from_t(SA, pt, 0, p_deep)
+    enthalpy_diff = (enthalpy_t_exact(SA, t_deep, p_deep) -
+                     enthalpy_t_exact(SA, t_shallow, p_shallow))
+
+    or call the following, it is identical to the lines above.
+
+    enthalpy_diff = enthalpy_diff_CT_exact(SA, CT, p_shallow, p_deep)
+    """
+
+    return db2Pascal * (delta_p * (a2 - 2 * a3 * b1 / b2 + 0.5 * a3 * p_sum) /
+                        b2 + (M / (2 * b2)) *
+                        np.log(1 + delta_p * (2 * b1 + b2 * p_sum) / part1) +
+                        part3 * np.log(1 + delta_p * b2 * (B - A) / part2))
+
+
+ at match_args_return
+def internal_energy(SA, CT, p):
+    r"""Calculates specific internal energy of seawater using the
+    computationally-efficient 48-term expression for density in terms of SA,
+    CT and p (McDougall et al., 2011).
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    internal_energy : array_like
+                      specific internal energy [J/kg]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel"
+    described in McDougall et al. (2011).  The GSW library function
+    "infunnel(SA, CT, p)" is available to be used if one wants to test if
+    some of one's data lies outside this "funnel".
+
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-04-04. Trevor McDougall and Paul Barker.
+    """
+
+    SA = np.maximum(SA, 0)
+
+    """This function calculates enthalpy using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p. If one wanted to
+    compute enthalpy from SA, CT, and p with the full TEOS-10 Gibbs function,
+    the following line of code will enable this.
+
+    internal_energy = internal_energy_CT_exact(SA, CT, p)
+    """
+
+    return (enthalpy(SA, CT, p) - (P0 + db2Pascal * p) * specvol(SA, CT, p))
+
+
+ at match_args_return
+def rho(SA, CT, p):
+    r"""Calculates in-situ density from Absolute Salinity and Conservative
+    Temperature, using the computationally-efficient 48-term expression for
+    density in terms of SA, CT and p (McDougall et al., 2011).
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    rho : array_like
+          in-situ density [kg/m**3]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The potential density with respect to reference pressure, pr, is obtained
+    by calling this function with the pressure argument being pr (i.e.
+    "rho(SA,CT,pr)").
+
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA,CT,p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix A.20 and appendix K.
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-04-18. Paul Barker and Trevor McDougall.
+    """
+
+    SA = np.maximum(SA, 0)
+    sqrtSA = np.sqrt(SA)
+    args = SA, CT, p, sqrtSA
+
+    """This function calculates rho using the computationally-efficient 48-term
+    expression for density in terms of SA, CT and p. If one wanted to compute
+    rho from SA, CT, and p with the full TEOS-10 Gibbs function, the following
+    lines of code will enable this.
+
+    pt0 = pt_from_CT(SA, CT)
+    t = pt_from_t(SA, pt0, 0, p)
+    rho = rho_t_exact(SA, t, p)
+
+    or call the following, it is identical to the lines above.
+
+    rho = rho_CT_exact(SA, CT, p)
+
+    or call the following, it is identical to the lines above.
+
+    rho,_ ,_ = rho_alpha_beta_CT_exact(SA, CT, p)
+    """
+
+    return v_hat_denominator(*args) / v_hat_numerator(*args)
+
+
+def rho_alpha_beta(SA, CT, p):
+    r"""Calculates in-situ density, the appropriate thermal expansion
+    coefficient and the appropriate saline contraction coefficient of seawater
+    from Absolute Salinity and Conservative Temperature.  This function uses
+    the computationally-efficient 48-term expression for density in terms of
+    SA, CT and p (McDougall et al., 2011).
+
+    The potential density (pot_rho) with respect to reference pressure p_ref is
+    obtained by calling this function with the pressure argument being p_ref as
+    in pot_rho, _, _] = rho_alpha_beta(SA, CT, p_ref).
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    rho : array_like
+          in-situ density [kg/m**3]
+    alpha : array_like
+            thermal expansion coefficient [K :math:`-1`]
+            with respect to Conservative Temperature
+    beta : array_like
+           saline contraction coefficient [kg g :math:`-1`]
+           at constant Conservative Temperature.
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA, CT, p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix A.20 and appendix K.
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-04-03. Paul Barker and Trevor McDougall.
+    """
+
+    return rho(SA, CT, p), alpha(SA, CT, p), beta(SA, CT, p)
+
+
+ at match_args_return
+def SA_from_rho(rho, CT, p):
+    r"""Calculates the Absolute Salinity of a seawater sample, for given values
+    of its density, Conservative Temperature and sea pressure (in dbar).  This
+    function uses the computationally-efficient 48-term expression for density
+    in terms of SA, CT and p (McDougall et al., 2011).
+
+    Parameters
+    ----------
+    rho : array_like
+          density of a seawater sample [kg/m**3]
+          This input has not had 1000 kg/m^3 subtracted from it
+          (e.g. 1026 kg m**-3), that is, it is density, NOT density anomaly.
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    This is expressed on the Reference-Composition Salinity Scale of
+    Millero et al. (2008).
+
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA, CT, p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.5
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    .. [3] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008:
+    The composition of Standard Seawater and the definition of the
+    Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72.
+
+    Modifications:
+    2011-04-04. Trevor McDougall and Paul Barker.
+    """
+
+    v_lab = 1. / rho
+    v_0 = specvol(np.zeros_like(rho), CT, p)
+    v_50 = specvol(50 * np.ones_like(rho), CT, p)
+
+    SA = 50 * (v_lab - v_0) / (v_50 - v_0)  # Initial estimate of SA.
+
+    SA[np.logical_or(SA < 0, SA > 50)] = np.ma.masked
+
+    v_SA = (v_50 - v_0) / 50.  # Initial v_SA estimate (SA derivative of v).
+
+    # Begin the modified Newton-Raphson iterative procedure.
+    for Number_of_iterations in range(0, 3):
+        SA_old = SA
+        delta_v = specvol(SA_old, CT, p) - v_lab
+        # Half way the mod. N-R method (McDougall and Wotherspoon, 2012)
+        SA = SA_old - delta_v / v_SA  # Half way through the mod. N-R method.
+        SA_mean = 0.5 * (SA + SA_old)
+        rho, alpha, beta = rho_alpha_beta(SA_mean, CT, p)
+        v_SA = -beta / rho
+        SA = SA_old - delta_v / v_SA
+        SA[np.logical_or(SA < 0, SA > 50)] = np.ma.masked
+
+    # After two iterations of this modified Newton-Raphson iteration,
+    # the error in SA is no larger than 8x10^-13 g kg^-1, which
+    # is machine precision for this calculation.
+    return SA
+
+
+def sigma0(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of 0 dbar,
+    this being this particular potential density minus 1000 kg/m^3.  This
+    function has inputs of Absolute Salinity and Conservative Temperature.
+    This function uses the computationally-efficient 48-term expression for
+    density in terms of SA, CT and p (McDougall et al., 2011).
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    sigma0 : array_like
+             potential density anomaly with [kg/m**3]
+             respect to a reference pressure of 0 dbar
+
+    See Also
+    --------
+    gsw.rho
+    """
+
+    """This function calculates sigma0 using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p.  If one wanted
+    to compute sigma0 with the full TEOS-10 Gibbs function expression for
+    density, the following lines of code will enable this.
+
+    sigma0 = rho_CT_exact(SA, CT, 0) - 1000
+    """
+
+    return rho(SA, CT, 0.) - 1000
+
+
+def sigma1(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of 1000
+    dbar, this being this particular potential density minus 1000 kg/m^3.
+    This function has inputs of Absolute Salinity and Conservative Temperature.
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    sigma1 : array_like
+             potential density anomaly with [kg/m**3]
+             respect to a reference pressure of 1000 dbar
+
+    See Also
+    --------
+    gsw.rho
+    """
+
+    """This function calculates sigma1 using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p.  If one wanted
+    to compute sigma1 with the full TEOS-10 Gibbs function expression for
+    density, the following lines of code will enable this.
+
+    rho1 = rho_CT_exact(SA, CT, 1000)
+    """
+
+    return rho(SA, CT, 1000.) - 1000
+
+
+def sigma2(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of 2000
+    dbar, this being this particular potential density minus 1000 kg/m^3.
+    This function has inputs of Absolute Salinity and Conservative Temperature.
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    sigma2 : array_like
+             potential density anomaly with [kg/m**3]
+             respect to a reference pressure of 2000 dbar
+
+    See Also
+    --------
+    gsw.rho
+    """
+
+    """This function calculates sigma2 using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p.  If one wanted
+    to compute sigma2 with the full TEOS-10 Gibbs function expression for
+    density, the following lines of code will enable this.
+
+    rho2 = rho_CT_exact(SA, CT, 2000.)
+    """
+
+    return rho(SA, CT, 2000.) - 1000
+
+
+def sigma3(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of 3000
+    dbar, this being this particular potential density minus 1000 kg/m^3.
+    This function has inputs of Absolute Salinity and Conservative Temperature.
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    sigma1 : array_like
+             potential density anomaly with [kg/m**3]
+             respect to a reference pressure of 3000 dbar
+
+    See Also
+    --------
+    gsw.rho
+    """
+
+    """This function calculates sigma3 using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p.  If one wanted
+    to compute sigma3 with the full TEOS-10 Gibbs function expression for
+    density, the following lines of code will enable this.
+
+    rho3 = rho_CT_exact(SA, CT, 3000.)
+    """
+
+    return rho(SA, CT, 3000.) - 1000
+
+
+def sigma4(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of 4000
+    dbar, this being this particular potential density minus 1000 kg/m^3.
+    This function has inputs of Absolute Salinity and Conservative Temperature.
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    sigma1 : array_like
+             potential density anomaly with [kg/m**3]
+             respect to a reference pressure of 4000 dbar
+
+    See Also
+    --------
+    gsw.rho
+    """
+
+    """This function calculates sigma3 using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p.  If one wanted
+    to compute sigma3 with the full TEOS-10 Gibbs function expression for
+    density, the following lines of code will enable this.
+
+    rho4 = rho_CT_exact(SA, CT, 4000.)
+    """
+
+    return rho(SA, CT, 4000.) - 1000
+
+
+ at match_args_return
+def sound_speed(SA, CT, p):
+    r"""Calculates the speed of sound in seawater.  This function has inputs of
+    Absolute Salinity and Conservative Temperature.  This function uses the
+    computationally-efficient 48-term expression for density in terms of SA,
+    CT and p (McDougall et al., 2011).
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    sound_speed : array_like
+                  speed of sound in seawater [m/s]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    Approximate with a r.m.s. of 6.7 cm s^-1.
+
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel"
+    described in McDougall et al. (2011).  The GSW library function
+    "infunnel(SA, CT, p)" is available to be used if one wants to test if
+    some of one's data lies outside this "funnel".
+
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.17.1).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-03-23. Paul Barker and Trevor McDougall.
+    """
+
+    SA = np.maximum(SA, 0)
+    sqrtSA = np.sqrt(SA)
+    args = SA, CT, p, sqrtSA
+
+    dvden_dp = (c01 + CT * (c02 + c03 * CT) + SA * (c04 + c05 * CT) + p *
+                (c06 + CT * (c07 + c08 * CT) + c09 * SA))
+
+    dvnum_dp = (c10 + CT * (c11 + CT * (c12 + c13 * CT)) + SA *
+                (c14 + c15 * CT) + p *
+                (c16 + CT * (c17 + c18 * CT + c19 * SA) + p *
+                 (c20 + c21 * CT)))
+
+    drho_dp = ((dvden_dp * v_hat_numerator(*args) - dvnum_dp *
+               v_hat_denominator(*args)) / (v_hat_numerator(*args) *
+               v_hat_numerator(*args)))
+
+    return 100 * np.sqrt(1. / drho_dp)
+
+
+ at match_args_return
+def specvol(SA, CT, p):
+    r"""Calculates specific volume from Absolute Salinity, Conservative
+    Temperature and pressure, using the computationally-efficient 48-term
+    expression for density (McDougall et al., 2011).
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    specvol : array_like
+              specific volume [m**3/kg]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA,CT,p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.7.2).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-03-18. Paul Barker and Trevor McDougall.
+    """
+
+    SA = np.maximum(SA, 0)
+
+    """This function calculates specvol using the computationally-efficient
+    48-term expression for density in terms of SA, CT and p. If one wanted to
+    compute specvol from SA, CT, and p with the full TEOS-10 Gibbs function,
+    the following lines of code will enable this.
+
+    pt = pt_from_CT(SA, CT)
+    t = pt_from_t(SA, pt, 0, p)
+    specvol = specvol_t_exact(SA, t, p)
+
+    or call the following, it is identical to the lines above.
+
+    specvol = specvol_CT_exact(SA, CT, p)
+    """
+
+    SA = np.maximum(SA, 0)
+    sqrtSA = np.sqrt(SA)
+    args = SA, CT, p, sqrtSA
+
+    return v_hat_numerator(*args) / v_hat_denominator(*args)
+
+
+ at match_args_return
+def specvol_anom(SA, CT, p):
+    r"""Calculates specific volume anomaly from Absolute Salinity, Conservative
+    Temperature and pressure.  It uses the computationally-efficient 48-term
+    expression for density as a function of SA, CT and p (McDougall et al.,
+    2011).  The reference value of Absolute Salinity is SSO and the reference
+    value of Conservative Temperature is equal to 0 degrees C.
+
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+
+    Returns
+    -------
+    specvol_anom : array_like
+                   specific volume anomaly [m**3/kg]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA,CT,p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (3.7.3).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-03-24. Paul Barker and Trevor McDougall.
+    """
+
+    SA = np.maximum(SA, 0)
+    sqrtSA = np.sqrt(SA)
+    args = SA, CT, p, sqrtSA
+
+    """This function calculates specvol_anom using the computationally-
+    efficient 48-term expression for density in terms of SA, CT and p.  If
+    one wanted to compute specvol_anom from SA, CT, and p with the full
+    TEOS-10 Gibbs function, the following lines of code will enable this.
+
+    pt = pt_from_CT(SA, CT)
+    t = pt_from_t(SA, pt, 0, p)
+    specvol_anom = specvol_anom_t_exact(SA, t, p)
+
+    or call the following, it is identical to the lines above.
+
+    specvol_anom = specvol_anom_CT_exact(SA, CT, p)
+    """
+
+    return (v_hat_numerator(*args) / v_hat_denominator(*args) -
+            specvol_SSO_0_p(p))
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/density_enthalpy_48_ct.py b/gsw/gibbs/density_enthalpy_48_ct.py
new file mode 100644
index 0000000..5e44463
--- /dev/null
+++ b/gsw/gibbs/density_enthalpy_48_ct.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+__all__ = ['alpha_CT',  # TODO
+           'beta_CT',  # TODO
+           'CT_from_rho',  # TODO
+           'CT_maxdensity',  # TODO
+           'dynamic_enthalpy_CT',  # TODO
+           'enthalpy_CT',  # TODO
+           'enthalpy_diff_CT',  # TODO
+           'internal_energy_CT',  # TODO
+           'rho_CT',  # TODO
+           'rho_alpha_beta_CT',  # TODO
+           'SA_from_rho_CT',  # TODO
+           'sigma0_CT',  # TODO
+           'sigma1_CT',  # TODO
+           'sigma2_CT',  # TODO
+           'sigma3_CT',  # TODO
+           'sigma4_CT',  # TODO
+           'sound_speed_CT',  # TODO
+           'specvol_CT',  # TODO
+           'specvol_anom_CT']  # TODO
+
+
+def alpha_CT():
+    pass
+
+
+def beta_CT():
+    pass
+
+
+def CT_from_rho():
+    pass
+
+
+def CT_maxdensity():
+    pass
+
+
+def dynamic_enthalpy_CT():
+    pass
+
+
+def enthalpy_CT():
+    pass
+
+
+def enthalpy_diff_CT():
+    pass
+
+
+def internal_energy_CT():
+    pass
+
+
+def rho_CT():
+    pass
+
+
+def rho_alpha_beta_CT():
+    pass
+
+
+def SA_from_rho_CT():
+    pass
+
+
+def sigma0_CT():
+    pass
+
+
+def sigma1_CT():
+    pass
+
+
+def sigma2_CT():
+    pass
+
+
+def sigma3_CT():
+    pass
+
+
+def sigma4_CT():
+    pass
+
+
+def sound_speed_CT():
+    pass
+
+
+def specvol_CT():
+    pass
+
+
+def specvol_anom_CT():
+    pass
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/density_enthalpy_ct_exact.py b/gsw/gibbs/density_enthalpy_ct_exact.py
new file mode 100644
index 0000000..d7351ee
--- /dev/null
+++ b/gsw/gibbs/density_enthalpy_ct_exact.py
@@ -0,0 +1,716 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .constants import cp0
+from ..utilities import match_args_return
+from .conversions import t_from_CT, CT_from_t, pt_from_CT
+from .thermodynamics_from_t import (t_from_rho_exact, rho_t_exact,
+                                    alpha_wrt_CT_t_exact, t_maxdensity_exact,
+                                    enthalpy_t_exact, beta_const_CT_t_exact,
+                                    specvol_t_exact, internal_energy_t_exact,
+                                    sigma0_pt0_exact, specvol_anom_t_exact,
+                                    sound_speed_t_exact)
+
+__all__ = ['alpha_CT_exact',
+           'beta_CT_exact',
+           'CT_from_rho_exact',
+           'CT_maxdensity_exact',
+           'dynamic_enthalpy_CT_exact',
+           'enthalpy_CT_exact',
+           'enthalpy_diff_CT_exact',
+           'internal_energy_CT_exact',
+           'rho_CT_exact',
+           'rho_alpha_beta_CT_exact',
+           'SA_from_rho_CT_exact',
+           'sigma0_CT_exact',
+           'sigma1_CT_exact',
+           'sigma2_CT_exact',
+           'sigma3_CT_exact',
+           'sigma4_CT_exact',
+           'sound_speed_CT_exact',
+           'specvol_CT_exact',
+           'specvol_anom_CT_exact']
+
+
+def alpha_CT_exact(SA, CT, p):
+    r"""Calculates the thermal expansion coefficient of seawater with respect
+    to Conservative Temperature from Absolute Salinity and Conservative
+    Temperature.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    alpha_CT_exact : array_like
+                     thermal expansion coefficient [K :sup:`-1`]
+                     with respect to Conservative Temperature
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This function uses the full Gibbs function.  There is an alternative to
+    calling this function, namely alpha_wrt_CT(SA, CT, p) which uses the
+    computationally efficient 48-term expression for density in terms of SA,
+    CT and p (McDougall et al., (2011)).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.18.3).
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    Modifications:
+    2011-03-23. David Jackett, Trevor McDougall and Paul Barker.
+    """
+    t = t_from_CT(SA, CT, p)
+    return alpha_wrt_CT_t_exact(SA, t, p)
+
+
+def beta_CT_exact(SA, CT, p):
+    r"""Calculates the saline (i.e. haline) contraction coefficient of seawater
+    at constant Conservative Temperature.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    beta_CT_exact : array_like
+                    thermal expansion coefficient [K :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This function uses the full Gibbs function.  There is an alternative to
+    calling this function, namely beta_const_CT(SA, CT, p) which uses the
+    computationally efficient 48-term expression for density in terms of SA, CT
+    and p (McDougall et al., (2011)).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.19.3).
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    Modifications:
+    2011-03-23. Trevor McDougall and Paul Barker.
+    """
+    t = t_from_CT(SA, CT, p)
+    return beta_const_CT_t_exact(SA, t, p)
+
+
+def CT_from_rho_exact(rho, SA, p):
+    r"""Calculates the in-situ temperature of a seawater sample, for given
+    values of its density, Absolute Salinity and sea pressure (in dbar).
+    Parameters
+    ----------
+    rho : array_like
+          density of a seawater sample [kg/m**3]
+          This input has not had 1000 kg/m^3 subtracted from it
+          (e.g. 1026 kg m**-3), that is, it is density, NOT density anomaly.
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    CT_multiple : array_like
+                  Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    At low salinities, in brackish water, there are two possible temperatures
+    for a single density.  This program will output both valid solutions
+    (t, t_multiple), if there is only one possible solution the second variable
+    will be set to NaN.
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.5.
+    Modifications:
+    2011-04-21. Trevor McDougall and Paul Barker.
+    """
+    t, t_multiple = t_from_rho_exact(rho, SA, p)
+    return CT_from_t(SA, t, p), CT_from_t(SA, t_multiple, p)
+
+
+def CT_maxdensity_exact(SA, p):
+    r"""Calculates the Conservative Temperature of maximum density of seawater.
+    This function returns the Conservative temperature at which the density of
+    seawater is a maximum, at given Absolute Salinity, SA, and sea pressure,
+    p (in dbar).
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    CT_maxdensity_exact : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+         at which the density of seawater is a maximum for given SA and p.
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.42.
+    Modifications:
+    2011-04-03. Trevor McDougall and Paul Barker.
+    """
+    t_max_exact = t_maxdensity_exact(SA, p)
+    return CT_from_t(SA, t_max_exact, p)
+
+
+def dynamic_enthalpy_CT_exact(SA, CT, p):
+    r"""Calculates the dynamic enthalpy of seawater from Absolute Salinity and
+    Conservative Temperature and pressure.  Dynamic enthalpy is defined as
+    enthalpy minus potential enthalpy (Young, 2010).
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    dynamic_enthalpy_CT_exact : array_like
+                                dynamic enthalpy [J/kg]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This function uses the full Gibbs function.  There is an alternative to
+    calling this function, namely dynamic_enthalpy(SA, CT, p), which uses the
+    computationally efficient 48-term expression for density in terms of SA, CT
+    and p (McDougall et al., 2011).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See apendix A.30.
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    .. [3] Young, W.R., 2010: Dynamic enthalpy, Conservative Temperature, and
+    the seawater Boussinesq approximation. Journal of Physical Oceanography,
+    40, 394-400.
+    Modifications:
+    2011-04-05. Trevor McDougall and Paul Barker.
+    """
+    t = t_from_CT(SA, CT, p)
+    return enthalpy_t_exact(SA, t, p) - cp0 * CT
+
+
+ at match_args_return
+def enthalpy_CT_exact(SA, CT, p):
+    r"""Calculates specific enthalpy of seawater from Absolute Salinity and
+    Conservative Temperature and pressure.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    enthalpy_CT_exact : array_like
+                        specific enthalpy  [J/kg]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This function uses the full Gibbs function.  There is an alternative to
+    calling this function, namely enthalpy_CT(SA, CT, p), which uses the
+    computationally-efficient 48-term expression for density in terms of SA, CT
+    and p (McDougall et al., 2011).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix A.11.
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    Modifications:
+    2011-04-06. Trevor McDougall and Paul Barker.
+    """
+    t = t_from_CT(SA, CT, p)
+    return enthalpy_t_exact(SA, t, p)
+
+
+def enthalpy_diff_CT_exact(SA, CT, p_shallow, p_deep):
+    r"""Calculates the difference of the specific enthalpy of seawater between
+    two different pressures, p_deep (the deeper pressure) and p_shallow (the
+    shallower pressure), at the same values of SA and CT.  The output
+    (enthalpy_diff_CT_exact) is the specific enthalpy evaluated at
+    (SA, CT, p_deep) minus the specific enthalpy at (SA,CT,p_shallow).
+    parameters
+    ----------
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p_shallow : array_like
+                lower sea pressure [dbar]
+    p_deep : array_like
+             upper sea pressure [dbar]
+    returns
+    -------
+    enthalpy_diff_CT_exact : array_like
+                             difference of specific enthalpy [J/kg]
+                             (deep minus shallow)
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This function uses the full Gibbs function.  There is an alternative to
+    calling this function, namely enthalpy_diff_CT(SA, CT, p), which uses the
+    computationally efficient 48-term expression for density in terms of SA, CT
+    and p (McDougall et al., 2011).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns (3.32.2).
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    Modifications:
+    2011-04-06. Trevor McDougall and Paul Barker.
+    """
+    t_shallow = t_from_CT(SA, CT, p_shallow)
+    t_deep = t_from_CT(SA, CT, p_deep)
+    return (enthalpy_t_exact(SA, t_deep, p_deep) -
+            enthalpy_t_exact(SA, t_shallow, p_shallow))
+
+
+def internal_energy_CT_exact(SA, CT, p):
+    r"""Calculates the specific internal energy of seawater from Absolute
+    Salinity, Conservative Temperature and pressure.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    internal_energy_CT_exact: array_like
+                              specific internal energy (u) [J/kg]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.11.1).
+    Modifications:
+    2011-04-05. Trevor McDougall.
+    """
+    t = t_from_CT(SA, CT, p)
+    return internal_energy_t_exact(SA, t, p)
+
+
+def rho_CT_exact(SA, CT, p):
+    r"""Calculates in-situ density from Absolute Salinity and Conservative
+    Temperature.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    rho_CT_exact : array_like
+                   in-situ density [kg/m**3]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    The potential density with respect to reference pressure, p_ref, is
+    obtained by calling this function with the pressure argument being p_ref
+    (i.e. "rho_CT_exact(SA, CT, p_ref)").  This function uses the full Gibbs
+    function.  There is an alternative to calling this function, namely
+    rho_CT(SA, CT, p), which uses the computationally efficient 48-term
+    expression for density in terms of SA, CT and p (McDougall et al., 2011).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.8.2).
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    Modifications:
+    2011-04-03. Trevor McDougall and Paul Barker.
+    """
+    t = t_from_CT(SA, CT, p)
+    return rho_t_exact(SA, t, p)
+
+
+def rho_alpha_beta_CT_exact(SA, CT, p):
+    r"""Calculates in-situ density, the appropriate thermal expansion
+    coefficient and the appropriate saline contraction coefficient of seawater
+    from Absolute Salinity and Conservative Temperature.
+    See the individual functions rho_CT_exact, alpha_CT_exact, and
+    beta_CT_exact.  Retained for compatibility with the Matlab GSW toolbox.
+    """
+    t = t_from_CT(SA, CT, p)
+    rho_CT_exact = rho_t_exact(SA, t, p)
+    alpha_CT_exact = alpha_wrt_CT_t_exact(SA, t, p)
+    beta_CT_exact = beta_const_CT_t_exact(SA, t, p)
+    return rho_CT_exact, alpha_CT_exact, beta_CT_exact
+
+
+def SA_from_rho_CT_exact(rho, CT, p):
+    r"""Calculates the Absolute Salinity of a seawater sample, for given values
+    of its density, Conservative Temperature and sea pressure (in dbar).
+    Parameters
+    ----------
+    rho : array_like
+          density of a seawater sample [kg/m**3]
+          This input has not had 1000 kg/m^3 subtracted from it
+          (e.g. 1026 kg m**-3), that is, it is density, NOT density anomaly.
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This function uses the full Gibbs function.  There is an alternative to
+    calling this function, namely SA_from_rho_CT(rho, CT, p), which uses the
+    computationally efficient 48-term expression for density in terms of SA, CT
+    and p (McDougall et al., 2011).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.5.
+    .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008:
+    The composition of Standard Seawater and the definition of the
+    Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72.
+    Modifications:
+    2011-04-05. Trevor McDougall and Paul Barker.
+    """
+    v_lab = 1. / rho
+    v_0 = specvol_CT_exact(np.zeros_like(rho), CT, p)
+    v_120 = specvol_CT_exact(120 * np.ones_like(rho), CT, p)
+    SA = 120 * (v_lab - v_0) / (v_120 - v_0)  # Initial estimate of SA.
+    SA[np.logical_or(SA < 0, SA > 120)] = np.ma.masked
+    v_SA = (v_120 - v_0) / 120  # Initial v_SA estimate (SA derivative of v).
+    # Begin the modified Newton-Raphson iterative procedure.
+    for Number_of_iterations in range(0, 3):
+        SA_old = SA
+        delta_v = specvol_CT_exact(SA_old, CT, p) - v_lab
+        # Half way the mod. N-R method (McDougall and Wotherspoon, 2012).
+        SA = SA_old - delta_v / v_SA
+        SA_mean = 0.5 * (SA + SA_old)
+        rho, alpha, beta = rho_alpha_beta_CT_exact(SA_mean, CT, p)
+        v_SA = -beta / rho
+        SA = SA_old - delta_v / v_SA
+        SA[np.logical_or(SA < 0, SA > 120)] = np.ma.masked
+    """After two iterations of this modified Newton-Raphson iteration, the
+    error in SA is no larger than 8x10^-13 g kg^-1, which is machine precision
+    for this calculation."""
+    return SA
+
+
+def sigma0_CT_exact(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of 0 dbar,
+    this being this particular potential density minus 1000 kg/m^3.  This
+    function has inputs of Absolute Salinity and Conservative Temperature.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    Returns
+    -------
+    sigma0_CT_exact: array_like
+                     Potential density anomaly with [kg/m**3]
+                     respect to a reference pressure of 0 dbar
+                     that is, this potential density - 1000 kg/m**3.
+    Notes
+    -----
+    Note that this function uses the full Gibbs function.  There is an
+    alternative to calling this function, namely gsw_sigma0_CT(SA,CT,p), which
+    uses the computationally efficient 48-term expression for density in terms
+    of SA, CT and p (McDougall et al., 2011).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (A.30.1).
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    Modifications:
+    2011-04-03. Trevor McDougall and Paul Barker.
+    """
+    pt0 = pt_from_CT(SA, CT)
+    return sigma0_pt0_exact(SA, pt0)
+
+
+def sigma1_CT_exact(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of
+    1000 dbar."""
+    t = t_from_CT(SA, CT, 1000.)
+    return rho_t_exact(SA, t, 1000.) - 1000
+
+
+def sigma2_CT_exact(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of
+    2000 dbar."""
+    t = t_from_CT(SA, CT, 2000.)
+    return rho_t_exact(SA, t, 2000.) - 1000
+
+
+def sigma3_CT_exact(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of
+    3000 dbar."""
+    t = t_from_CT(SA, CT, 3000.)
+    return rho_t_exact(SA, t, 3000.) - 1000
+
+
+def sigma4_CT_exact(SA, CT):
+    r"""Calculates potential density anomaly with reference pressure of
+    4000 dbar."""
+    t = t_from_CT(SA, CT, 4000.)
+    return rho_t_exact(SA, t, 4000.) - 1000
+
+
+def sound_speed_CT_exact(SA, CT, p):
+    r"""Calculates the speed of sound in seawater from Absolute Salinity and
+    Conservative Temperature and pressure.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+        Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    sound_speed_CT_exact : array_like
+    Speed of sound in seawater [m s :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.17.1).
+    Modifications:
+    2011-04-05. David Jackett, Paul Barker and Trevor McDougall.
+    """
+    t = t_from_CT(SA, CT, p)
+    return sound_speed_t_exact(SA, t, p)
+
+
+def specvol_CT_exact(SA, CT, p):
+    r"""Calculates specific volume from Absolute Salinity, Conservative
+    Temperature and pressure.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    specvol_CT_exact : array_like
+                       specific volume  [m**3/kg]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This function uses the full Gibbs function.  There is an alternative to
+    calling this function, namely specvol_CT(SA, CT, p), which uses the
+    computationally efficient 48-term expression for density in terms of SA, CT
+    and p (McDougall et al., 2011).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.7.2).
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    Modifications:
+    2011-04-06. Trevor McDougall and Paul Barker.
+    """
+    t = t_from_CT(SA, CT, p)
+    return specvol_t_exact(SA, t, p)
+
+
+def specvol_anom_CT_exact(SA, CT, p):
+    r"""Calculates specific volume anomaly from Absolute Salinity, Conservative
+    Temperature and pressure.  The reference value of Absolute Salinity is SSO
+    and the reference value of Conservative Temperature is equal to 0 deg C.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure [dbar]
+    Returns
+    -------
+    specvol_anom_CT_exact : array_like
+                            specific volume anomaly [m**3/kg]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This function uses the full Gibbs function.  There is an alternative to
+    calling this function, namely specvol_anom_CT(SA, CT, p), which uses the
+    computationally efficient 48-term expression for density in terms of SA, CT
+    and p (McDougall et al., 2011).
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (3.7.3).
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+    Modifications:
+    2011-04-06. Trevor McDougall and Paul Barker.
+    """
+    t = t_from_CT(SA, CT, p)
+    return specvol_anom_t_exact(SA, t, p)
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/derivatives.py b/gsw/gibbs/derivatives.py
new file mode 100644
index 0000000..11db147
--- /dev/null
+++ b/gsw/gibbs/derivatives.py
@@ -0,0 +1,677 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .library import gibbs
+from .constants import Kelvin, cp0, sfac
+from ..utilities import match_args_return
+from .conversions import pt_from_CT, pt_from_t
+
+__all__ = ['CT_first_derivatives',
+           'CT_second_derivatives',
+           'enthalpy_first_derivatives',
+           'enthalpy_second_derivatives',
+           'entropy_first_derivatives',
+           'entropy_second_derivatives',
+           'pt_first_derivatives',
+           'pt_second_derivatives']
+
+n0, n1, n2 = 0, 1, 2
+
+
+ at match_args_return
+def CT_first_derivatives(SA, pt):
+    r"""Calculates the following two derivatives of Conservative Temperature
+    (1) CT_SA, the derivative with respect to Absolute Salinity at constant
+        potential temperature (with pr = 0 dbar), and
+    (2) CT_pt, the derivative with respect to potential temperature (the
+        regular potential temperature which is referenced to 0 dbar) at
+        constant Absolute Salinity.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    pt : array_like
+         potential temperature referenced to a sea pressure of zero dbar
+         [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    CT_SA : array_like
+            The derivative of CT with respect to SA at constant potential
+            temperature reference sea pressure of 0 dbar.
+            [K (g kg :sup:`-1`) :sup:`-1`]
+
+    CT_pt : array_like
+            The derivative of CT with respect to pt at constant SA.
+            [ unitless ]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> pt = [28.7832, 28.4209, 22.7850, 10.2305, 6.8292, 4.3245]
+    >>> gsw.CT_first_derivatives(SA, pt)
+    array([[-0.04198109, -0.04155814, -0.03473921, -0.0187111 , -0.01407594,
+            -0.01057172],
+           [ 1.00281494,  1.00255482,  1.00164514,  1.00000377,  0.99971636,
+             0.99947433]])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (A.12.3) and (A.12.9a,b).
+
+    .. [2] McDougall T. J., D. R. Jackett, P. M. Barker, C. Roberts-Thomson, R.
+    Feistel and R. W. Hallberg, 2010:  A computationally efficient 25-term
+    expression for the density of seawater in terms of Conservative
+    Temperature, and related properties of seawater.
+
+    Modifications:
+    2010-08-05. Trevor McDougall and Paul Barker.
+    """
+
+    # FIXME: Matlab version 3.0 has a copy-and-paste of the gibbs function here
+    # instead of a call. Why?
+
+    abs_pt = Kelvin + pt
+
+    CT_pt = -(abs_pt * gibbs(n0, n2, n0, SA, pt, 0)) / cp0
+
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y_pt = 0.025 * pt
+
+    g_SA_T_mod = (1187.3715515697959 + x * (-1480.222530425046 + x *
+                  (2175.341332000392 + x * (-980.14153344888 +
+                  220.542973797483 * x) + y_pt * (-548.4580073635929 + y_pt *
+                  (592.4012338275047 + y_pt * (-274.2361238716608 +
+                  49.9394019139016 * y_pt)))) + y_pt * (-258.3988055868252 +
+                  y_pt * (-90.2046337756875 + y_pt * 10.50720794170734))) +
+                  y_pt * (3520.125411988816 + y_pt * (-1351.605895580406 +
+                  y_pt * (731.4083582010072 + y_pt * (-216.60324087531103 +
+                  25.56203650166196 * y_pt)))))
+
+    g_SA_T_mod *= 0.5 * sfac * 0.025
+
+    g_SA_mod = (8645.36753595126 + x * (-7296.43987145382 + x *
+                (8103.20462414788 + y_pt * (2175.341332000392 + y_pt *
+                (-274.2290036817964 + y_pt * (197.4670779425016 + y_pt *
+                (-68.5590309679152 + 9.98788038278032 * y_pt)))) + x *
+                (-5458.34205214835 - 980.14153344888 * y_pt + x *
+                (2247.60742726704 - 340.1237483177863 * x + 220.542973797483 *
+                y_pt))) + y_pt * (-1480.222530425046 + y_pt *
+                (-129.1994027934126 + y_pt * (-30.0682112585625 + y_pt *
+                (2.626801985426835))))) + y_pt * (1187.3715515697959 + y_pt *
+                (1760.062705994408 + y_pt * (-450.535298526802 + y_pt *
+                (182.8520895502518 + y_pt * (-43.3206481750622 +
+                4.26033941694366 * y_pt))))))
+
+    g_SA_mod *= 0.5 * sfac
+
+    CT_SA = (g_SA_mod - abs_pt * g_SA_T_mod) / cp0
+
+    return CT_SA, CT_pt
+
+
+ at match_args_return
+def CT_second_derivatives(SA, pt):
+    r"""Calculates the following three, second-order derivatives of
+    Conservative Temperature
+    (1) CT_SA_SA, the second derivative with respect to Absolute Salinity at
+        constant potential temperature (with p_ref = 0 dbar),
+    (2) CT_SA_pt, the derivative with respect to potential temperature (the
+        regular potential temperature which is referenced to 0 dbar) and
+        Absolute Salinity, and
+    (3) CT_pt_pt, the second derivative with respect to potential temperature
+        (the regular potential temperature which is referenced to 0 dbar) at
+        constant Absolute Salinity.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    pt : array_like
+         potential temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    CT_SA_SA : array_like
+               The second derivative of Conservative Temperature with respect
+               to Absolute Salinity at constant potential temperature (the
+               regular potential temperature which has reference sea pressure
+               of 0 dbar). [K/((g/kg)^2)]
+    CT_SA_pt : array_like
+               The derivative of Conservative Temperature with respect to
+               potential temperature (the regular one with p_ref = 0 dbar) and
+               Absolute Salinity. [1/(g/kg)]
+    CT_pt_pt : array_like
+               The second derivative of Conservative Temperature with respect
+               to potential temperature (the regular one with p_ref = 0 dbar)
+               at constant SA. [1/K]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix A.12.
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A
+    computationally efficient 48-term expression for the density of seawater in
+    terms of Conservative Temperature, and related properties of seawater.  To
+    be submitted to Ocean Science Discussions.
+
+    Modifications:
+    2011-03-29. Trevor McDougall.
+    """
+
+    dSA = 1e-3
+    SA_l = SA - dSA
+    SA_l = np.maximum(SA_l, 0)
+    SA_u = SA + dSA
+
+    CT_SA_l, _ = CT_first_derivatives(SA_l, pt)
+    CT_SA_u, _ = CT_first_derivatives(SA_u, pt)
+
+    CT_SA_SA = np.zeros_like(SA) * np.NaN
+    CT_SA_SA[SA_u != SA_l] = ((CT_SA_u[SA_u != SA_l] - CT_SA_l[SA_u != SA_l]) /
+                              (SA_u[SA_u != SA_l] - SA_l[SA_u != SA_l]))
+
+    # Increment of potential temperature is 0.01 degrees C.
+    dpt = 1e-2
+    pt_l = pt - dpt
+    pt_u = pt + dpt
+
+    CT_SA_l, CT_pt_l = CT_first_derivatives(SA, pt_l)
+    CT_SA_u, CT_pt_u = CT_first_derivatives(SA, pt_u)
+
+    CT_SA_pt = (CT_SA_u - CT_SA_l) / (pt_u - pt_l)
+    CT_pt_pt = (CT_pt_u - CT_pt_l) / (pt_u - pt_l)
+
+    return CT_SA_SA, CT_SA_pt, CT_pt_pt
+
+
+ at match_args_return
+def enthalpy_first_derivatives(SA, CT, p):
+    r"""Calculates the following three derivatives of specific enthalpy (h)
+    (1) h_SA, the derivative with respect to Absolute Salinity at
+        constant CT and p, and
+    (2) h_CT, derivative with respect to CT at constant SA and p.
+    (3) h_P, derivative with respect to pressure (in Pa) at constant SA and CT.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+
+    Returns
+    -------
+    h_SA : array_like
+           The first derivative of specific enthalpy with respect to Absolute
+           Salinity at constant CT and p. [J/(kg (g/kg))]  i.e. [J/g]
+    h_CT : array_like
+           The first derivative of specific enthalpy with respect to CT at
+           constant SA and p. [J/(kg K)]
+    h_P : array_like
+          The first partial derivative of specific enthalpy with respect to
+          pressure (in Pa) at fixed SA and CT.  Note that h_P is specific
+          volume (1/rho.)
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (A.11.18), (A.11.15) and (A.11.12.)
+
+    Modifications:
+    2010-09-24. Trevor McDougall.
+    """
+
+    # FIXME: The gsw 3.0 has the gibbs derivatives "copy-and-pasted" here
+    # instead of the calls to the library! Why?
+
+    pt0 = pt_from_CT(SA, CT)
+    t = pt_from_t(SA, pt0, 0, p)
+    temp_ratio = (Kelvin + t) / (Kelvin + pt0)
+
+    def enthalpy_derivative_SA(SA, CT, p):
+        return (gibbs(n1, n0, n0, SA, t, p) -
+                temp_ratio * gibbs(n1, n0, n0, SA, pt0, 0))
+
+    def enthalpy_derivative_CT(SA, CT, p):
+        return cp0 * temp_ratio
+
+    def enthalpy_derivative_p(SA, CT, p):
+        return gibbs(n0, n0, n1, SA, t, p)
+
+    return (enthalpy_derivative_SA(SA, CT, p),
+            enthalpy_derivative_CT(SA, CT, p),
+            enthalpy_derivative_p(SA, CT, p),)
+
+
+ at match_args_return
+def enthalpy_second_derivatives(SA, CT, p):
+    r"""Calculates the following three second-order derivatives of specific
+    enthalpy (h),
+    (1) h_SA_SA, second-order derivative with respect to Absolute Salinity
+        at constant CT & p.
+    (2) h_SA_CT, second-order derivative with respect to SA & CT at
+        constant p.
+    (3) h_CT_CT, second-order derivative with respect to CT at constant SA
+        and p.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+
+    Returns
+    -------
+    h_SA_SA : array_like
+              The second derivative of specific enthalpy with respect to
+              Absolute Salinity at constant CT & p. [J/(kg (g/kg)^2)]
+    h_SA_CT : array_like
+              The second derivative of specific enthalpy with respect to SA and
+              CT at constant p. [J/(kg K(g/kg))]
+    h_CT_CT : array_like
+              The second derivative of specific enthalpy with respect to CT at
+              constant SA and p. [J/(kg K^2)]
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (A.11.18), (A.11.15) and (A.11.12.)
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of seawater in
+    terms of Conservative Temperature, and related properties of seawater.  To
+    be submitted to Ocean Science Discussions.
+
+    Modifications:
+    2011-03-29. Trevor McDougall.
+    """
+
+    # NOTE: The Matlab version 3.0 mentions that this function is unchanged,
+    # but that's not true!
+
+    pt0 = pt_from_CT(SA, CT)
+    abs_pt0 = Kelvin + pt0
+    t = pt_from_t(SA, pt0, 0, p)
+    temp_ratio = (Kelvin + t) / abs_pt0
+
+    rec_gTT_pt0 = 1 / gibbs(n0, n2, n0, SA, pt0, 0)
+    rec_gTT_t = 1 / gibbs(n0, n2, n0, SA, t, p)
+    gST_pt0 = gibbs(n1, n1, n0, SA, pt0, 0)
+    gST_t = gibbs(n1, n1, n0, SA, t, p)
+    gS_pt0 = gibbs(n1, n0, n0, SA, pt0, 0)
+
+    part = ((temp_ratio * gST_pt0 * rec_gTT_pt0 - gST_t * rec_gTT_t) /
+            (abs_pt0))
+
+    factor = gS_pt0 / cp0
+
+    # h_CT_CT is naturally well-behaved as SA approaches zero.
+    def enthalpy_derivative_CT_CT(SA, CT, p):
+        return (cp0 ** 2 * ((temp_ratio * rec_gTT_pt0 - rec_gTT_t) /
+                            (abs_pt0 * abs_pt0)))
+
+    # h_SA_SA has a singularity at SA = 0, and blows up as SA approaches zero.
+    def enthalpy_derivative_SA_SA(SA, CT, p):
+        SA[SA < 1e-100] = 1e-100  # NOTE: Here is the changes from 2.0 to 3.0.
+        h_CT_CT = enthalpy_derivative_CT_CT(SA, CT, p)
+        return (gibbs(n2, n0, n0, SA, t, p) -
+                temp_ratio * gibbs(n2, n0, n0, SA, pt0, 0) +
+                temp_ratio * gST_pt0 ** 2 * rec_gTT_pt0 -
+                gST_t ** 2 * rec_gTT_t - 2.0 * gS_pt0 * part +
+                factor ** 2 * h_CT_CT)
+
+    """h_SA_CT should not blow up as SA approaches zero. The following lines of
+    code ensure that the h_SA_CT output of this function does not blow up in
+    this limit.  That is, when SA < 1e-100 g/kg, we force the h_SA_CT output to
+    be the same as if SA = 1e-100 g/kg."""
+
+    def enthalpy_derivative_SA_CT(SA, CT, p):
+        h_CT_CT = enthalpy_derivative_CT_CT(SA, CT, p)
+        return cp0 * part - factor * h_CT_CT
+
+    return (enthalpy_derivative_SA_SA(SA, CT, p),
+            enthalpy_derivative_SA_CT(SA, CT, p),
+            enthalpy_derivative_CT_CT(SA, CT, p))
+
+
+ at match_args_return
+def entropy_first_derivatives(SA, CT):
+    r"""Calculates the following two partial derivatives of specific entropy
+    (eta)
+    (1) eta_SA, the derivative with respect to Absolute Salinity at constant
+        Conservative Temperature, and
+    (2) eta_CT, the derivative with respect to Conservative Temperature at
+        constant Absolute Salinity.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    eta_SA : array_like
+             The derivative of specific entropy with respect to SA at constant
+             CT [J g :sup:`-1` K :sup:`-1`]
+    eta_CT : array_like
+             The derivative of specific entropy with respect to CT at constant
+             SA [ J (kg K :sup:`-2`) :sup:`-1` ]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236]
+    >>> gsw.entropy_first_derivatives(SA, CT)
+    array([[ -0.2632868 ,  -0.26397728,  -0.2553675 ,  -0.23806659,
+             -0.23443826,  -0.23282068],
+           [ 13.22103121,  13.23691119,  13.48900463,  14.08659902,
+             14.25772958,  14.38642995]])
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (A.12.8) and (P.14a,c).
+
+    Modifications:
+    2011-03-29. Trevor McDougall.
+    """
+    pt = pt_from_CT(SA, CT)
+
+    eta_SA = -(gibbs(n1, n0, n0, SA, pt, 0)) / (Kelvin + pt)
+    eta_CT = cp0 / (Kelvin + pt)
+    return eta_SA, eta_CT
+
+
+ at match_args_return
+def entropy_second_derivatives(SA, CT):
+    r"""Calculates the following three second-order partial derivatives of
+    specific entropy (eta)
+    (1) eta_SA_SA, the second derivative with respect to Absolute Salinity at
+        constant Conservative Temperature, and
+    (2) eta_SA_CT, the derivative with respect to Absolute Salinity and
+        Conservative Temperature.
+    (3) eta_CT_CT, the second derivative with respect to Conservative
+        Temperature at constant Absolute Salinity.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    eta_SA_SA : array_like
+                The second derivative of specific entropy with respect to SA at
+                constant CT [J (kg K (g kg :sup:`-1` ) :sup:`2`) :sup:`-1`]
+    eta_SA_CT : array_like
+                The second derivative of specific entropy with respect to
+                SA and CT [J (kg (g kg :sup:`-1` ) K :sup:`2`) :sup:`-1` ]
+    eta_CT_CT : array_like
+                The second derivative of specific entropy with respect to CT at
+                constant SA [J (kg K :sup:`3`) :sup:`-1` ]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> CT = [28.8099, 28.4392, 22.7862, 10.2262, 6.8272, 4.3236]
+    >>> gsw.entropy_second_derivatives(SA, CT)
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (P.14b) and (P.15a,b).
+
+    Modifications:
+    2011-03-29. Trevor McDougall and Paul Barker.
+    """
+
+    pt = pt_from_CT(SA, CT)
+    abs_pt = Kelvin + pt
+
+    CT_SA = ((gibbs(n1, n0, n0, SA, pt, 0) -
+             (abs_pt * gibbs(n1, n1, n0, SA, pt, 0))) / cp0)
+
+    CT_pt = -(abs_pt * gibbs(n0, n2, n0, SA, pt, 0)) / cp0
+
+    eta_CT_CT = - cp0 / (CT_pt * abs_pt ** 2)
+
+    eta_SA_CT = - CT_SA * eta_CT_CT
+
+    eta_SA_SA = -gibbs(n2, n0, n0, SA, pt, 0) / abs_pt - CT_SA * eta_SA_CT
+
+    return eta_SA_SA, eta_SA_CT, eta_CT_CT
+
+
+ at match_args_return
+def pt_first_derivatives(SA, CT):
+    r"""Calculates the following two partial derivatives of potential
+    temperature (the regular potential temperature whose reference sea
+    pressure is 0 dbar)
+    (1) pt_SA, the derivative with respect to Absolute Salinity at
+        constant Conservative Temperature, and
+    (2) pt_CT, the derivative with respect to Conservative Temperature at
+        constant Absolute Salinity.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    pt_SA : array_like
+            The derivative of potential temperature with respect to Absolute
+            Salinity at constant Conservative Temperature. [K/(g/kg)]
+    pt_CT : array_like
+            The derivative of potential temperature with respect to
+            Conservative Temperature at constant Absolute Salinity. [unitless]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (A.12.6), (A.12.3), (P.6) and (P.8).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A
+    computationally efficient 48-term expression for the density of seawater in
+    terms of Conservative Temperature, and related properties of seawater.  To
+    be submitted to Ocean Science Discussions.
+
+    Modifications:
+    2011-03-29. Trevor McDougall and Paul Barker.
+    """
+
+    pt = pt_from_CT(SA, CT)
+    abs_pt = Kelvin + pt
+
+    CT_SA = ((gibbs(n1, n0, n0, SA, pt, 0) - abs_pt *
+              gibbs(n1, n1, n0, SA, pt, 0)) / cp0)
+
+    CT_pt = - (abs_pt * gibbs(n0, n2, n0, SA, pt, 0)) / cp0
+
+    pt_SA = - CT_SA / CT_pt
+
+    pt_CT = 1.0 / CT_pt
+
+    return pt_SA, pt_CT
+
+
+ at match_args_return
+def pt_second_derivatives(SA, CT):
+    r"""Calculates the following three second-order derivatives of potential
+    temperature (the regular potential temperature which has a reference
+    sea pressure of 0 dbar),
+    (1) pt_SA_SA, the second derivative with respect to Absolute Salinity at
+        constant Conservative Temperature,
+    (2) pt_SA_CT, the derivative with respect to Conservative Temperature and
+        Absolute Salinity, and
+    (3) pt_CT_CT, the second derivative with respect to Conservative
+        Temperature at constant Absolute Salinity.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    pt_SA_SA : array_like
+               The second derivative of potential temperature (the regular
+               potential temperature which has reference sea pressure of 0
+               dbar) with respect to Absolute Salinity at constant Conservative
+               Temperature. [K/((g/kg)^2)]
+    pt_SA_CT : array_like
+               The derivative of potential temperature with respect to Absolute
+               Salinity and Conservative Temperature. [1/(g/kg)]
+    pt_CT_CT : array_like
+               The second derivative of potential temperature (the regular one
+               with p_ref = 0 dbar) with respect to Conservative Temperature at
+               constant SA. [1/K]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (A.12.9) and (A.12.10).
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011: A
+    computationally efficient 48-term expression for the density of seawater in
+    terms of Conservative Temperature, and related properties of seawater.  To
+    be submitted to Ocean Science Discussions.
+
+    Modifications:
+    2011-03-29. Trevor McDougall and Paul Barker.
+    """
+    # Increment of Absolute Salinity is 0.001 g/kg.
+    dSA = 1e-3
+    SA_l = SA - dSA
+    SA_l = np.maximum(SA_l, 0)
+    SA_u = SA + dSA
+    pt_SA_l, pt_CT_l = pt_first_derivatives(SA_l, CT)
+    pt_SA_u, pt_CT_u = pt_first_derivatives(SA_u, CT)
+    pt_SA_SA = (pt_SA_u - pt_SA_l) / (SA_u - SA_l)
+    # Can calculate this either way.
+    # pt_SA_CT = (pt_CT_u - pt_CT_l) / (SA_u - SA_l)
+
+    dCT = 1e-2
+    CT_l = CT - dCT
+    CT_u = CT + dCT
+    pt_SA_l, pt_CT_l = pt_first_derivatives(SA, CT_l)
+    pt_SA_u, pt_CT_u = pt_first_derivatives(SA, CT_u)
+
+    pt_SA_CT = (pt_SA_u - pt_SA_l) / (CT_u - CT_l)
+    pt_CT_CT = (pt_CT_u - pt_CT_l) / (CT_u - CT_l)
+
+    return pt_SA_SA, pt_SA_CT, pt_CT_CT
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/earth.py b/gsw/gibbs/earth.py
new file mode 100644
index 0000000..585a363
--- /dev/null
+++ b/gsw/gibbs/earth.py
@@ -0,0 +1,219 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .conversions import z_from_p
+from ..utilities import match_args_return
+from .constants import gamma, earth_radius, OMEGA
+
+
+__all__ = ['distance',
+           'f',
+           'grav']
+
+DEG2RAD = np.pi / 180
+
+
+ at match_args_return
+def distance(lon, lat, p=0):
+    r"""Calculates the distance in met res between successive points in the
+    vectors lon and lat, computed using the Haversine formula on a spherical
+    earth of radius 6,371 km, being the radius of a sphere having the same
+    volume as Earth.  For a spherical Earth of radius 6,371,000 m, one nautical
+    mile is 1,853.2488 m, thus one degree of latitude is 111,194.93 m.
+
+    Haversine formula:
+        R = earth's radius (mean radius = 6,371 km)
+
+    .. math::
+        a = \sin^2(\delta \text{lat}/2) +
+            \cos(\text{lat}_1) \cos(\text{lat}_2) \sin^2(\delta \text{lon}/2)
+
+        c = 2 \times \text{atan2}(\sqrt{a}, \sqrt{(1-a)})
+
+        d = R \times c
+
+    Parameters
+    ----------
+    lon : array_like
+          decimal degrees east [0..+360] or [-180 ... +180]
+    lat : array_like
+          latitude in decimal degrees north [-90..+90]
+    p : number or array_like. Default p = 0
+        pressure [dbar]
+
+    Returns
+    -------
+    dist: array_like
+          distance between points on a spherical Earth at pressure (p) [m]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    z is height and is negative in the oceanographic.
+
+    Distances are probably good to better than 1\% of the "true" distance on
+    the ellipsoidal earth.
+
+    Examples
+    --------
+    >>> import gsw
+    >>> lon = [159, 220]
+    >>> lat = [-35, 35]
+    >>> gsw.distance(lon, lat)
+    array([[ 10030974.652916]])
+    >>> p = [200, 1000]
+    >>> gsw.distance(lon, lat, p)
+    array([[ 10030661.63878009]])
+    >>> p = [[200], [1000]]
+    >>> gsw.distance(lon, lat, p)
+    array([[ 10030661.63878009],
+           [ 10029412.58776001]])
+
+    References
+    ----------
+    .. [1] http://www.eos.ubc.ca/~rich/map.html
+
+    Modifications:
+    2000-11-06. Rich Pawlowicz
+    2011-04-04. Paul Barker and Trevor McDougall
+    """
+    # FIXME? The argument handling seems much too complicated.
+    # Maybe we can come up with some simple specifications of
+    # what argument combinations are permitted, and handle everything
+    # with broadcasting. - EF
+
+    # FIXME: Eric what do you think? This assume p(stations, depth)
+    lon, lat, = np.atleast_2d(lon), np.atleast_2d(lat)
+
+    if (lon.size == 1) & (lat.size == 1):
+        raise ValueError('more than one point is needed to compute distance')
+    elif lon.ndim != lat.ndim:
+        raise ValueError('lon, lat must have the same dimension')
+
+    lon, lat, p = np.broadcast_arrays(lon, lat, p)
+
+    dlon = np.diff(lon * DEG2RAD)
+    dlat = np.diff(lat * DEG2RAD)
+
+    a = ((np.sin(dlat / 2)) ** 2 + np.cos(lat[:, :-1] * DEG2RAD) *
+         np.cos(lat[:, 1:] * DEG2RAD) * (np.sin(dlon / 2)) ** 2)
+
+    angles = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a))
+
+    p_mid = 0.5 * (p[:, 0:-1] + p[:, 0:-1])
+    lat_mid = 0.5 * (lat[:, :-1] + lat[:, 1:])
+
+    z = z_from_p(p_mid, lat_mid)
+
+    distance = (earth_radius + z) * angles
+
+    return distance
+
+
+def f(lat):
+    r"""Calculates the Coriolis parameter (f) defined by:
+        f = 2*omega*sin(lat)
+    where,
+        omega = 7.292115e-5 (Groten, 2004) [radians s :sup:`-1`]
+
+    Parameters
+    ----------
+    lat : array_like
+          latitude [degrees north]
+
+    Returns
+    -------
+    f : array_like
+        Coriolis paramter  [s :sup:`-1`]
+
+    References
+    ----------
+    .. [1] Groten, E., 2004: Fundamental Parameters and Current (2004) Best
+    Estimates of the Parameters of Common Relevance to Astronomy, Geodesy, and
+    Geodynamics. Journal of Geodesy, 77, pp. 724-797.
+
+    .. [2] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+
+    Modifications:
+    1993-04-20. Phil Morgan
+    2010-07-28. Paul Barker
+    """
+
+    lat = np.asanyarray(lat)
+    return 2 * OMEGA * np.sin(lat * DEG2RAD)
+
+
+ at match_args_return
+def grav(lat, p=0):
+    r"""Calculates acceleration due to gravity as a function of latitude and as
+    a function of pressure in the ocean.
+
+    Parameters
+    ----------
+    lat : array_like
+          latitude in decimal degrees north [-90...+90]
+    p : number or array_like. Default p = 0
+        pressure [dbar]
+
+    Returns
+    -------
+    g : array_like
+        gravity [m s :sup:`2`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    In the ocean z is negative.
+
+    Examples
+    --------
+    >>> import gsw
+    >>> lat = [-90, -60, -30, 0]
+    >>> p = 0
+    >>> gsw.grav(lat, p)
+    array([ 9.83218621,  9.81917886,  9.79324926,  9.780327  ])
+    >>> gsw.grav(45)
+    9.8061998770458008
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater -  2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+
+    .. [2] Moritz (2000) Goedetic reference system 1980. J. Geodesy, 74,
+    128-133.
+
+    .. [3] Saunders, P.M., and N.P. Fofonoff (1976) Conversion of pressure to
+    depth in the ocean. Deep-Sea Res.,pp. 109 - 111.
+
+    Modifications:
+    2011-03-29. Trevor McDougall & Paul Barker
+    """
+
+    X = np.sin(lat * DEG2RAD)
+    sin2 = X ** 2
+    gs = 9.780327 * (1.0 + (5.2792e-3 + (2.32e-5 * sin2)) * sin2)
+    z = z_from_p(p, lat)
+    # z is the height corresponding to p.
+    grav = gs * (1 - gamma * z)
+
+    return grav
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/freezing.py b/gsw/gibbs/freezing.py
new file mode 100644
index 0000000..c2f3cc3
--- /dev/null
+++ b/gsw/gibbs/freezing.py
@@ -0,0 +1,569 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .constants import SSO
+from .conversions import t_from_CT, CT_from_t
+from ..utilities import match_args_return
+
+__all__ = ['brineSA_CT',
+           'brineSA_t',
+           'CT_freezing',
+           't_freezing']
+
+# Constants:
+c = (0.017947064327968736, -6.076099099929818, 4.883198653547851,
+     -11.88081601230542, 13.34658511480257, -8.722761043208607,
+     2.082038908808201, -7.389420998107497, -2.110913185058476,
+     0.2295491578006229, -0.9891538123307282, -0.08987150128406496,
+     0.3831132432071728, 1.054318231187074, 1.065556599652796,
+     -0.7997496801694032, 0.3850133554097069, -2.078616693017569,
+     0.8756340772729538, -2.079022768390933, 1.596435439942262,
+     0.1338002171109174, 1.242891021876471)
+
+T = (0.002519, -5.946302841607319, 4.136051661346983,
+     -1.115150523403847e1, 1.476878746184548e1, -1.088873263630961e1,
+     2.961018839640730, -7.433320943962606, -1.561578562479883,
+     4.073774363480365e-2, 1.158414435887717e-2, -4.122639292422863e-1,
+     -1.123186915628260e-1, 5.715012685553502e-1, 2.021682115652684e-1,
+     4.140574258089767e-2, -6.034228641903586e-1, -1.205825928146808e-2,
+     -2.812172968619369e-1, 1.877244474023750e-2, -1.204395563789007e-1,
+     2.349147739749606e-1, 2.748444541144219e-3)
+
+# Adjust for the effects of dissolved air.  Note that
+# a = 0.502500117621 / 35.16504
+a, b = 0.014289763856964, 0.057000649899720
+
+P = (2.570124672768757e-1, -1.917742353032266e+1, -1.413382858617969e-2,
+     -5.427484830917552e-1, -4.126621135193472e-4, -4.176407833276121e-7,
+     4.688217641883641e-5, -3.039808885885726e-8, -4.990118091261456e-11,
+     -9.733920711119464e-9, -7.723324202726337e-12, 7.121854166249257e-16,
+     1.256474634100811e-12, 2.105103897918125e-15, 8.663811778227171e-19)
+
+
+ at match_args_return
+def brineSA_CT(CT, p, saturation_fraction=1):
+    r"""Calculates the Absolute Salinity of seawater at the freezing
+    temperature.  That is, the output is the Absolute Salinity of seawater,
+    with the fraction saturation_fraction of dissolved air, that is in
+    equilibrium with ice at Conservative Temperature CT and pressure p.  If the
+    input values are such that there is no positive value of Absolute Salinity
+    for which seawater is frozen, the output, brineSA_CT, is put equal to -99.
+
+    Parameters
+    ----------
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure  [dbar]
+    saturation_fraction : fraction between 0, 1.  The saturation fraction of
+                          dissolved air in seawater.  Default is 0 or
+                          completely saturated.
+
+    Returns
+    -------
+    brine_SA_CT : array_like
+                 Absolute Salinity of seawater when it freezes [ g/kg ]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See sections 3.33.
+
+    Modifications:
+    2011-28-03. Trevor McDougall and Paul Barker.
+
+    """
+
+    CT, p, saturation_fraction = np.broadcast_arrays(CT, p,
+                                                     saturation_fraction)
+
+    if np.logical_or(saturation_fraction < 0, saturation_fraction > 1).any():
+        raise ValueError('Saturation_fraction MUST be between zero and one.')
+
+    p_r = p * 1e-4
+    # Form the first estimate of brine_SA_CT from a polynomial in CT and p_r.
+    SA = -(CT + 9 * p_r) / 0.06  # A rough estimate to get the saturated CT.
+
+    SA = np.maximum(SA, 0)
+
+    CTsat = CT - (1 - saturation_fraction) * 1e-3 * (2.4 - a * SA) * (1 + b *
+                 (1 - SA / SSO))
+
+    SA = (P[0] + p * (P[2] + P[4] * CTsat + p * (P[5] + CTsat * (P[7] + P[9] *
+          CTsat) + p * (P[8] + CTsat * (P[10] + P[12] * CTsat) + p * (P[11] +
+          P[13] * CTsat + P[14] * p)))) + CTsat * (P[1] + CTsat *
+          (P[3] + P[6] * p)))
+
+    CT_freezing_zero_SA = (c[0] + p_r * (c[7] + p_r * (c[8] + c[9] * p_r)) -
+                           saturation_fraction * 2.4e-3 * (1 + b))
+
+    # Find CT > CT_freezing_zero_SA.  If this is the case, the input values
+    # represent seawater that is not frozen (at any positive SA).
+    Itw = (CT > CT_freezing_zero_SA)  # tw stands for "too warm"
+    SA[Itw] = np.ma.masked
+
+    # Find -SA_cut_off < SA < SA_cut_off, replace the above estimate of SA
+    # with one based on (CT_freezing_zero_SA - CT).
+    SA_cut_off = 2.5  # This is the band of SA within +- 2.5 g/kg of SA = 0,
+                      # which we treat differently in calculating the initial
+                      # values of both SA and dCT_dSA.
+
+    Ico = (np.abs(SA) < SA_cut_off)
+    Icoa = np.logical_and(SA < 0, SA >= -SA_cut_off)
+
+    SA[Icoa] = 0
+
+    # Find SA < -SA_cut_off, set them to NaN.
+    SA[SA < -SA_cut_off] = np.ma.masked
+
+    # Form the first estimate of dCT_dSA, the derivative of CT with respect
+    # to SA at fixed p.
+    SA_r = 0.01 * SA
+    x = np.sqrt(SA_r)
+
+    dCT_dSA_part = (2 * c[1] + x * (3 * c[2] + x * (4 * c[3] + x * (5 * c[4] +
+                    x * (6 * c[5] + 7 * c[6] * x)))) + p_r * (2 * c[10] + p_r *
+                    (2 * c[12] + p_r * (2 * c[15] + 4 * c[21] * x * x)) + x *
+                    x * (4 * c[13] + 4 * c[17] * p_r + 6 * c[19] * x * x) + x *
+                    (3 * c[11] + 3 * p_r * (c[14] + c[18] * p_r) + x * x * (5 *
+                    c[16] + 5 * c[20] * p_r + 7 * c[22] * x * x))))
+
+    dCT_dSA = 0.5 * 0.01 * dCT_dSA_part - saturation_fraction * 1e-3 * (-a *
+              (1 + b * (1 - SA / SSO)) - b * (2.4 - a * SA) / SSO)
+
+    # Now replace the estimate of SA with the one based on
+    # (CT_freezing_zero_SA - CT) when (np.abs(SA) < SA_cut_off).
+    SA[Ico] = (CT[Ico] - CT_freezing_zero_SA[Ico]) / dCT_dSA[Ico]
+
+    # Begin the modified Newton-Raphson method to solve the root of
+    # CT_freezing = CT for SA.
+    Number_of_Iterations = 2
+    for I_iter in range(0, Number_of_Iterations):
+        # CT_freezing temperature function evaluation (the forward function
+        # evaluation), the same as CT_freezing(SA, p, saturation_fraction).
+
+        SA_r = 0.01 * SA
+        x = np.sqrt(SA_r)
+        SA_old = SA
+        CT_freeze = (c[0] + SA_r * (c[1] + x * (c[2] + x * (c[3] + x * (c[4] +
+                     x * (c[5] + c[6] * x))))) + p_r * (c[7] + p_r * (c[8] +
+                     c[9] * p_r)) + SA_r * p_r * (c[10] + p_r * (c[12] + p_r *
+                     (c[15] + c[21] * SA_r)) + SA_r * (c[13] + c[17] * p_r +
+                     c[19] * SA_r) + x * (c[11] + p_r * (c[14] + c[18] * p_r) +
+                     SA_r * (c[16] + c[20] * p_r + c[22] * SA_r))) -
+                     saturation_fraction * 1e-3 * (2.4 - a * SA) * (1 + b *
+                     (1 - SA / SSO)))
+
+        SA = SA_old - (CT_freeze - CT) / dCT_dSA
+
+        # Half-way point of the modified Newton-Raphson solution method.
+        SA_r = 0.5 * 0.01 * (SA + SA_old)  # The mean value of SA and SA_old.
+        x = np.sqrt(SA_r)
+
+        dCT_dSA_part = 2 * c[1] + x * (3 * c[2] + x * (4 * c[3] + x * (5 *
+                       c[4] + x * (6 * c[5] + 7 * c[6] * x)))) + p_r * (2 *
+                       c[10] + p_r * (2 * c[12] + p_r * (2 * c[15] + 4 *
+                       c[21] * x * x)) + x * x * (4 * c[13] + 4 * c[17] *
+                       p_r + 6 * c[19] * x * x) + x * (3 * c[11] + 3 * p_r *
+                       (c[14] + c[18] * p_r) + x * x * (5 * c[16] + 5 * c[20] *
+                       p_r + 7 * c[22] * x * x)))
+
+        dCT_dSA = (0.5 * 0.01 * dCT_dSA_part - saturation_fraction * 1e-3 *
+                  (-a * (1 + b * (1 - SA / SSO)) - b * (2.4 - a * SA) / SSO))
+
+        SA = SA_old - (CT_freeze - CT) / dCT_dSA
+
+    """The following lines of code, if implemented, calculates the error of
+    this function in terms of Conservative Temperature, CT_error.  With
+    Number_of_Iterations = 1, the maximum error in CT is 2x10^-7 C.  With
+    Number_of_Iterations = 2, the maximum error in CT is 7x10^-15 C, which is
+    the machine precision of the computer.  Number_of_Iterations = 2 is what
+    we recommend.
+
+    SA_r = 0.01 * SA
+    x = np.sqrt(SA_r)
+    CT_freeze = c[0] + SA_r * (c[1] + x * (c[2] + x * (c[3] + x * (c[4] + x *
+                (c[5] + c[6] * x))))) + p_r * (c[7] + p_r * (c[8] + c[9] *
+                p_r)) + SA_r * p_r * (c[10] + p_r * (c[12] + p_r * (c[15] +
+                c[21] * SA_r)) + SA_r * (c[13] + c[17] * p_r + c[19] * SA_r) +
+                x * (c[11] + p_r * (c[14] + c[18] * p_r) + SA_r * (c[16] +
+                c[20] * p_r + c[22] * SA_r))) - saturation_fraction * 1e-3 *
+                (2.4 - a * SA) * (1 + b * (1 - SA / SSO))
+
+    CT_error = np.abs(CT_freeze - CT)
+
+    tmp = np.logical_or(p > 10000, SA > 120
+    out = np.logical_and(tmp, p + SA * 71.428571428571402 > 13571.42857142857)
+    CT_error[out] = np.ma.masked
+    """
+
+    brine_SA_CT = SA
+
+    tmp = np.logical_or(p > 10000, SA > 120)
+    out = np.logical_and(tmp, p + SA * 71.428571428571402 > 13571.42857142857)
+
+    brine_SA_CT[out] = np.ma.masked
+
+    # If the CT input is too warm, then there is no (positive) value of SA
+    # that represents frozen seawater.
+    brine_SA_CT[Itw] = -99  # NOTE: Mask these?
+
+    return brine_SA_CT
+
+
+ at match_args_return
+def brineSA_t(t, p, saturation_fraction=1):
+    r"""Calculates the Absolute Salinity of seawater at the freezing
+    temperature.  That is, the output is the Absolute Salinity of seawater,
+    with the fraction saturation_fraction of dissolved air, that is in
+    equilibrium with ice at in-situ temperature t and pressure p.  If the input
+    values are such that there is no positive value of Absolute Salinity for
+    which seawater is frozen, the output, brineSA_t, is put equal to -99.
+
+    Parameters
+    ----------
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure  [dbar]
+    saturation_fraction : fraction between 0, 1.  The saturation fraction of
+                          dissolved air in seawater.  Default is 0 or
+                          completely saturated.
+
+    Returns
+    -------
+    brine_SA_t : array_like
+                 Absolute Salinity of seawater when it freezes [ g/kg ]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See sections 3.33.
+
+    Modifications:
+    2011-28-03. Trevor McDougall and Paul Barker.
+
+    """
+
+    t, p, saturation_fraction = np.broadcast_arrays(t, p, saturation_fraction)
+
+    if np.logical_or(saturation_fraction < 0, saturation_fraction > 1).any():
+        raise ValueError('Saturation_fraction MUST be between zero and one.')
+
+    p_r = p * 1e-4
+
+    # Form the first estimate of brine_SA_t, called SA here, from a polynomial
+    # in CT and p_r.
+    SA = -(t + 9 * p_r) / 0.06  # A rough estimate to get the saturated CT.
+
+    SA = np.maximum(SA, 0)
+
+    CT = CT_from_t(SA, t, p)
+    CTsat = CT - (1 - saturation_fraction) * 1e-3 * (2.4 - a * SA) * (1 + b *
+            (1 - SA / SSO))
+
+    SA = P[0] + p * (P[2] + P[4] * CTsat + p * (P[5] + CTsat * (P[7] +
+         P[9] * CTsat) + p * (P[8] + CTsat * (P[10] + P[12] * CTsat) + p *
+         (P[11] + P[13] * CTsat + P[14] * p)))) + CTsat * (P[1] + CTsat *
+         (P[3] + P[6] * p))
+
+    t_freezing_zero_SA = t_freezing(np.zeros_like(t), p, saturation_fraction)
+
+    # Find t > t_freezing_zero_SA.  If this is the case, the input values
+    # represent seawater that is not frozen (at any positive SA).
+    Itw = (t > t_freezing_zero_SA)  # Itw stands for "I_too_warm"
+    SA[Itw] = np.ma.masked
+
+    # Find -SA_cut_off < SA < SA_cut_off, replace the above estimate of SA
+    # with one based on (t_freezing_zero_SA - t).
+    SA_cut_off = 2.5  # This is the band of SA within +- 2.5 g/kg of SA = 0,
+                      # which we treat differently in calculating the initial
+                      # values of both SA and dCT_dSA.
+
+    Ico = (np.abs(SA) < SA_cut_off)
+    Icoa = np.logical_and(SA < 0, SA >= -SA_cut_off)
+    SA[Icoa] = 0
+
+    # Find SA < -SA_cut_off, set them to masked.
+    SA[SA < -SA_cut_off] = np.ma.masked
+
+    # Form the first estimate of dt_dSA, the derivative of t with respect
+    # to SA at fixed p, using the coefficients, t0 ... t22 from t_freezing.
+    SA_r = 0.01 * SA
+    x = np.sqrt(SA_r)
+    dt_dSA_part = 2 * T[1] + x * (3 * T[2] + x * (4 * T[3] + x * (5 * T[4] +
+    x * (6 * T[5] + 7 * T[6] * x)))) + p_r * (2 * T[10] + p_r * (2 * T[12] +
+    p_r * (2 * T[15] + 4 * T[21] * x * x)) + x * x * (4 * T[13] + 4 * T[17] *
+    p_r + 6 * T[19] * x * x) + x * (3 * T[11] + 3 * p_r * (T[14] + T[18] *
+    p_r) + x * x * (5 * T[16] + 5 * T[20] * p_r + 7 * T[22] * x * x)))
+
+    dt_dSA = 0.5 * 0.01 * dt_dSA_part + saturation_fraction * 1e-3 / 70.33008
+
+    # Now replace the estimate of SA with the one based on
+    # (t_freezing_zero_SA - t) when (abs(SA) < SA_cut_off).
+    SA[Ico] = (t[Ico] - t_freezing_zero_SA[Ico]) / dt_dSA[Ico]
+
+    # Begin the modified Newton-Raphson method to find the root of
+    # t_freeze = t for SA.
+    Number_of_Iterations = 5
+    for I_iter in range(0, Number_of_Iterations):
+        SA_old = SA
+        t_freeze = t_freezing(SA_old, p, saturation_fraction)
+        SA = SA_old - (t_freeze - t) / dt_dSA
+        # Half-way point of the modified Newton-Raphson solution method.
+        SA_r = 0.5 * 0.01 * (SA + SA_old)  # Mean value of SA and SA_old.
+        x = np.sqrt(SA_r)
+        dt_dSA_part = (2 * T[1] + x * (3 * T[2] + x * (4 * T[3] + x * (5 *
+                       T[4] + x * (6 * T[5] + 7 * T[6] * x)))) + p_r *
+                       (2 * T[10] + p_r * (2 * T[12] + p_r * (2 * T[15] + 4 *
+                       T[21] * x * x)) + x * x * (4 * T[13] + 4 * T[17] * p_r +
+                       6 * T[19] * x * x) + x * (3 * T[11] + 3 * p_r * (T[14] +
+                       T[18] * p_r) + x * x * (5 * T[16] + 5 * T[20] * p_r +
+                       7 * T[22] * x * x))))
+
+        dt_dSA = (0.5 * 0.01 * dt_dSA_part + saturation_fraction * 1e-3 /
+                  70.33008)
+
+        SA = SA_old - (t_freeze - t) / dt_dSA
+
+    """The following lines of code, if implemented, calculate the error of this
+    function in terms of in-situ temperature.  With Number_of_Iterations = 4,
+    the max error in t is 3x10^-13 C.  With Number_of_Iterations = 5, the max
+    error in t is 2x10^-14 C, which is the machine precision of the computer.
+    Number_of_Iterations = 5 is what we recommend.
+
+    SA[SA < 0] = np.ma.masked
+
+    t_freeze = t_freezing(SA, p, saturation_fraction)
+    t_error = np.abs(t_freeze - t)
+    tmp = np.logical_or(p > 10000, SA > 120)
+    out = np.logical_and(tmp, p + SA * 71.428571428571402 > 13571.42857142857)
+    t_error[out] = np.ma.masked
+    """
+
+    brine_SA_t = SA
+    tmp = np.logical_or(p > 10000, SA > 120)
+    out = np.logical_and(tmp, p + SA * 71.428571428571402 > 13571.42857142857)
+    brine_SA_t[out] = np.ma.masked
+
+    brine_SA_t[Itw] = -99  # If the t input is too warm, then there is no
+                           # (positive) value of SA that represents frozen
+                           # seawater.
+
+    return brine_SA_t
+
+
+ at match_args_return
+def CT_freezing(SA, p, saturation_fraction=1):
+    r"""Calculates the Conservative Temperature at which seawater freezes.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    p : array_like
+        sea pressure  [dbar]
+    saturation_fraction : fraction between 0, 1.  The saturation fraction of
+                          dissolved air in seawater.  Default is 0 or
+                          completely saturated.
+
+    Returns
+    -------
+    CT_freezing : array_like
+          Conservative Temperature at freezing of
+          seawater [:math:`^\circ` C (ITS-90)]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See sections 3.33 and 3.34.
+
+    Modifications:
+    2011-11-04. Trevor McDougall, Paul Barker and Rainer Feistal.
+
+    """
+
+    SA, p, saturation_fraction = np.broadcast_arrays(SA, p,
+                                                     saturation_fraction)
+    if (SA < 0).any():
+        raise ValueError('SA must be non-negative!')
+
+    if np.logical_or(saturation_fraction < 0, saturation_fraction > 1).any():
+        raise ValueError('Saturation_fraction MUST be between zero and one.')
+
+    SA_r = SA * 1e-2
+    x = np.sqrt(SA_r)
+    p_r = p * 1e-4
+
+    CT_freeze = (c[0] + SA_r * (c[1] + x * (c[2] + x * (c[3] + x * (c[4] +
+                 x * (c[5] + c[6] * x))))) + p_r * (c[7] + p_r * (c[8] +
+                 c[9] * p_r)) + SA_r * p_r * (c[10] + p_r * (c[12] + p_r *
+                 (c[15] + c[21] * SA_r)) + SA_r * (c[13] + c[17] * p_r +
+                 c[19] * SA_r) + x * (c[11] + p_r * (c[14] + c[18] * p_r) +
+                 SA_r * (c[16] + c[20] * p_r + c[22] * SA_r))))
+
+    """The error of this fit ranges between -5e-4 K and 6e-4 K when compared
+    with the Conservative Temperature calculated from the exact in-situ
+    freezing temperature which is found by a Newton-Raphson iteration of the
+    equality of the chemical potentials of water in seawater and in ice.
+    (Note that the in-situ freezing temperature can be found by this exact
+    method using the function sea_ice_freezingtemperature_si in the SIA
+    library)."""
+
+    # Adjust for the effects of dissolved air.
+    a, b = 0.014289763856964, 0.057000649899720
+    # Note that a = 0.502500117621 / 35.16504
+
+    CT_freeze = (CT_freeze - saturation_fraction * (1e-3) *
+                 (2.4 - a * SA) * (1 + b * (1 - SA / 35.16504)))
+
+    tmp = np.logical_or(p > 10000, SA > 120)
+    out = np.logical_or(tmp, p + SA * 71.428571428571402 > 13571.42857142857)
+
+    CT_freeze[out] = np.ma.masked
+
+    return CT_freeze
+
+
+ at match_args_return
+def t_freezing(SA, p, saturation_fraction=1):
+    r"""Calculates the in-situ temperature at which seawater freezes.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    p : array_like
+        sea pressure  [dbar]
+    saturation_fraction : fraction between 0, 1.  The saturation fraction of
+                          dissolved air in seawater.  Default is 0 or
+                          completely saturated.
+
+    Returns
+    -------
+    t_freezing : array_like
+                  in-situ temperature at which seawater freezes
+                  [:math:`^\circ` C (ITS-90)]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See sections 3.33 and 3.34.
+
+    Modifications:
+    2011-11-03. Trevor McDougall, Paul Barker and Rainer Feistal.
+
+    """
+
+    """This function, t_freezing, calculates the in-situ freezing temperature,
+    t_freezing, of seawater by first evaluating a polynomial of the
+     Conservative Temperature at which seawater freezes, CT_freezing, using
+    the GSW function CT_freezing.  The in-situ freezing temperature is then
+    calculated using the GSW function t_from_CT.  However, if one wanted to
+    compute the in-situ freezing temperature directly from a single polynomial
+    expression without first calculating the Conservative Temperature at the
+    freezing point, the following lines of code achieve this.  The error of the
+    following fit is similar to that of the present function, t_freezing, and
+    ranges between -8e-4 K and 3e-4 K when compared with the in-situ freezing
+    temperature evaluated by Newton-Raphson iteration of the equality of the
+    chemical potentials of water in seawater and in ice.  (Note that the
+    in-situ freezing temperature can be found by this exact method using the
+    function sea_ice_freezingtemperature_si in the SIA library).
+
+    SA_r = SA * 1e-2
+    x = np.sqrt(SA_r)
+    p_r = p * 1e-4
+
+    t_freeze = T[0] + SA_r * (T[1] + x * (T[2] + x * (T[3] + x * (T[4] + x *
+               (T[5] + T[6] * x))))) + p_r * (T[7] + p_r * (T[8] + T[9] *
+               p_r)) + SA_r * p_r * (T[10] + p_r * (T[12] + p_r * (T[15] +
+               T[21] * SA_r)) + SA_r * (T[13] + T[17] * p_r + T[19] * SA_r) +
+               x * (T[11] + p_r * (T[14] + T[18] * p_r)  + SA_r * (T[16] +
+               T[20] * p_r + T[22] * SA_r)))
+
+    Adjust for the effects of dissolved air
+    t_freezing -= saturation_fraction * (1e-3) * (2.4 - SA / 70.33008)
+
+    """
+
+    SA, p, saturation_fraction = np.broadcast_arrays(SA, p,
+                                                     saturation_fraction)
+    if (SA < 0).any():
+        raise ValueError('SA must be non-negative!')
+
+    if np.logical_or(saturation_fraction < 0, saturation_fraction > 1).any():
+        raise ValueError('Saturation_fraction MUST be between zero and one.')
+
+    CT_freeze = CT_freezing(SA, p, saturation_fraction)
+
+    t_freeze = t_from_CT(SA, CT_freeze, p)
+
+    tmp = np.logical_or(p > 10000, SA > 120)
+    out = np.logical_or(tmp, p + SA * 71.428571428571402 > 13571.42857142857)
+
+    t_freeze[out] = np.ma.masked
+
+    return t_freeze
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/geostrophic.py b/gsw/gibbs/geostrophic.py
new file mode 100644
index 0000000..ee3b751
--- /dev/null
+++ b/gsw/gibbs/geostrophic.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+__all__ = ['geostrophic_velocity']  # TODO
+
+
+def geostrophic_velocity():
+    pass
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/geostrophic_48.py b/gsw/gibbs/geostrophic_48.py
new file mode 100644
index 0000000..62d643f
--- /dev/null
+++ b/gsw/gibbs/geostrophic_48.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+__all__ = ['geo_strf_Cunningham',  # TODO
+           'geo_strf_dyn_height',  # TODO
+           'geo_strf_dyn_height_pc',  # TODO
+           'geo_strf_isopycnal',  # TODO
+           'geof_str_isopycnal_pc',  # TODO
+           'geo_strf_Montgomery']  # TODO
+
+
+def geo_strf_Cunningham():
+    pass
+
+
+def geo_strf_dyn_height():
+    pass
+
+
+def geo_strf_dyn_height_pc():
+    pass
+
+
+def geo_strf_isopycnal():
+    pass
+
+
+def geof_str_isopycnal_pc():
+    pass
+
+
+def geo_strf_Montgomery():
+    pass
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/isobaric.py b/gsw/gibbs/isobaric.py
new file mode 100644
index 0000000..b11e243
--- /dev/null
+++ b/gsw/gibbs/isobaric.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+from .conversions import CT_from_pt
+from ..utilities import match_args_return
+
+
+__all__ = ['latentheat_evap_CT',
+           'latentheat_melting',
+           'latentheat_evap_t']
+
+
+ at match_args_return
+def latentheat_evap_CT(SA, CT):
+    pass
+
+
+ at match_args_return
+def latentheat_melting(SA, p):
+    pass
+
+
+ at match_args_return
+def latentheat_evap_t(SA, t):
+    r"""Calculates latent heat, or enthalpy, of evaporation at p = 0 (the
+    surface).  It is defined as a function of Absolute Salinity, SA, and
+    in-situ temperature, t, and is valid in the ranges 0 < SA < 40 g/kg and
+    0 < CT < 42 deg C.  The errors range between -0.4 and 0.6 J/kg.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    latentheat_evap_t : array_like
+        latent heat of evaporation [J kg :sup:`-1`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    See section 3.39.
+
+    Modifications:
+    2011-03-29. Paul Barker, Trevor McDougall & Rainer Feistel
+    """
+
+    CT = CT_from_pt(SA, t)
+    return latentheat_evap_CT(SA, CT)
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/library.py b/gsw/gibbs/library.py
new file mode 100644
index 0000000..5acdc1b
--- /dev/null
+++ b/gsw/gibbs/library.py
@@ -0,0 +1,1646 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .constants import sfac, SSO, db2Pascal
+from ..utilities import match_args_return, strip_mask, read_data
+
+__all__ = ['deltaSA_atlas',
+           'enthalpy_SSO_0_p',
+           'entropy_part',
+           'entropy_part_zerop',
+           'Fdelta',  # Seems to be new in V3.
+           'gibbs',
+           'gibbs_pt0_pt0',
+           'Hill_ratio_at_SP2',
+           'infunnel',
+           'interp_ref_cast',
+           'interp_SA_CT',
+           'SAAR',  # New in V3.
+           'SA_from_SP_Baltic',
+           'specvol_SSO_0_p',
+           'SP_from_SA_Baltic']
+
+
+class SA_table(object):
+    """
+    TODO: Write docstring.
+    """
+    # Central America barrier
+    x_ca = np.array([260.0, 272.59, 276.5, 278.65, 280.73, 295.217])
+    y_ca = np.array([19.55, 13.97, 9.6, 8.1, 9.33, 0.0])
+
+    def __init__(self, fname="gsw_data_v3_0.npz", max_p_fudge=10000,
+                 min_frac=0):
+        self.fname = fname
+        self.max_p_fudge = max_p_fudge
+        self.min_frac = min_frac
+        data = read_data(fname)
+        self.lon = data.longs_ref.astype(np.float)
+        self.lat = data.lats_ref.astype(np.float)
+        self.p = data.p_ref                # Depth levels
+        self.dlon = self.lon[1] - self.lon[0]
+        self.dlat = self.lat[1] - self.lat[0]
+        self.i_ca, self.j_ca = self.xy_to_ij(self.x_ca, self.y_ca)
+        # Make the order x, y, z:
+        # Start with deltaSA_ref (was delta_SA_ref in V2):
+        temp = data.deltaSA_ref.transpose((2, 1, 0)).copy()
+        self.dsa_ref = np.ma.masked_invalid(temp)
+        self.dsa_ref.data[self.dsa_ref.mask] = 0
+        # Now SAAR_ref, which did not exist in V2:
+        temp = data.SAAR_ref.transpose((2, 1, 0)).copy()
+        self.SAAR_ref = np.ma.masked_invalid(temp)
+        self.SAAR_ref.data[self.SAAR_ref.mask] = 0
+
+    def xy_to_ij(self, x, y):
+        """
+        Convert from lat/lon to grid index coordinates,
+        without truncation or rounding.
+        """
+        i = (x - self.lon[0]) / self.dlon
+        j = (y - self.lat[0]) / self.dlat
+        return i, j
+
+    def _central_america(self, di, dj, ii, jj, gm):
+        """
+        Use a line running through Central America to zero
+        the goodmask for grid points in the Pacific forming
+        the grid box around input locations in the Atlantic,
+        and vice-versa.
+        """
+        ix, jy = ii[0] + di, jj[0] + dj  # Reconstruction: minor inefficiency.
+        inear = ((ix >= self.i_ca[0]) & (ix <= self.i_ca[-1])
+                 & (jy >= self.j_ca[-1]) & (jy <= self.j_ca[0]))
+        if not inear.any():
+            return gm
+        inear_ind = inear.nonzero()[0]
+        ix = ix[inear]
+        jy = jy[inear]
+        ii = ii[:, inear]
+        jj = jj[:, inear]
+        jy_ca = np.interp(ix, self.i_ca, self.j_ca)
+        above = jy - jy_ca  # > 0 if input point is above dividing line
+        # Intersections of left and right grid lines with dividing line
+        jleft_ca = np.interp(ii[0], self.i_ca, self.j_ca)
+        jright_ca = np.interp(ii[1], self.i_ca, self.j_ca)
+        jgrid_ca = [jleft_ca, jright_ca, jright_ca, jleft_ca]
+        # Zero the goodmask for grid points on opposite side of divider
+        for i in range(4):
+            opposite = (above * (jj[i] - jgrid_ca[i])) < 0
+            gm[i, inear_ind[opposite]] = 0
+        return gm
+
+    def xy_interp(self, di, dj, ii, jj, k):
+        """
+        2-D interpolation, bilinear if all 4 surrounding
+        grid points are present, but treating missing points
+        as having the average value of the remaining grid
+        points. This matches the matlab V2 behavior.
+        """
+        # Array of weights, CCW around the grid box
+        w = np.vstack(((1 - di) * (1 - dj),  # lower left
+                      di * (1 - dj),         # lower right
+                      di * dj,               # upper right
+                      (1 - di) * dj))        # upper left
+        gm = ~self.dsa.mask[ii, jj, k]   # gm is "goodmask"
+        gm = self._central_america(di, dj, ii, jj, gm)
+        # Save a measure of real interpolation quality.
+        frac = (w * gm).sum(axis=0)
+        # Now loosen the interpolation, allowing a value to
+        # be calculated on a grid point that is masked.
+        # This matches the matlab gsw version 2 behavior.
+        jm_partial = gm.any(axis=0) & (~(gm.all(axis=0)))
+        # The weights of the unmasked points will be increased
+        # by the sum of the weights of the masked points divided
+        # by the number of unmasked points in the grid square.
+        # This is equivalent to setting the masked data values
+        # to the average of the unmasked values, and then
+        # unmasking, which is the matlab v2 implementation.
+        if jm_partial.any():
+            w_bad = w * (~gm)
+            w[:, jm_partial] += (w_bad[:, jm_partial].sum(axis=0) /
+                                 gm[:, jm_partial].sum(axis=0))
+        w *= gm
+        wsum = w.sum(axis=0)
+        valid = wsum > 0  # Only need to prevent division by zero here.
+        w[:, valid] /= wsum[valid]
+        w[:, ~valid] = 0
+        vv = self.dsa.data[ii, jj, k]
+        vv *= w
+        dsa = vv.sum(axis=0)
+        return dsa, frac
+
+    def _delta_SA(self, p, lon, lat):
+        """
+        Table lookup engine--to be called only from SAAR or SA_ref.
+        """
+        p = np.ma.masked_less(p, 0)
+        mask_in = np.ma.mask_or(np.ma.getmask(p), np.ma.getmask(lon))
+        mask_in = np.ma.mask_or(mask_in, np.ma.getmask(lat))
+        p, lon, lat = [np.ma.filled(a, 0).astype(float) for a in (p, lon, lat)]
+        p, lon, lat = np.broadcast_arrays(p, lon, lat)
+        if p.ndim > 1:
+            shape_in = p.shape
+            p, lon, lat = map(np.ravel, (p, lon, lat))
+            reshaped = True
+        else:
+            reshaped = False
+        p_orig = p.copy()  # Save for comparison to clipped p.
+        ix0, iy0 = self.xy_to_ij(lon, lat)
+        i0raw = np.floor(ix0).astype(int)
+        i0 = np.clip(i0raw, 0, len(self.lon) - 2)
+        di = ix0 - i0
+        j0raw = np.floor(iy0).astype(int)
+        j0 = np.clip(j0raw, 0, len(self.lat) - 2)
+        dj = iy0 - j0
+        # Start at lower left and go CCW; match order in _xy_interp.
+        ii = np.vstack((i0, i0 + 1, i0 + 1, i0))
+        jj = np.vstack((j0, j0, j0 + 1, j0 + 1))
+        k1 = np.searchsorted(self.p, p, side='right')
+        # Clip p and k1 at max p of grid cell.
+        kmax = (self.ndepth[ii, jj].max(axis=0) - 1)
+        mask_out = kmax.mask
+        kmax = kmax.filled(1)
+        clip_p = (p >= self.p[kmax])
+        p[clip_p] = self.p[kmax[clip_p]]
+        k1[clip_p] = kmax[clip_p]
+        k0 = k1 - 1
+        dsa0, frac0 = self.xy_interp(di, dj, ii, jj, k0)
+        dsa1, frac1 = self.xy_interp(di, dj, ii, jj, k1)
+        dp = np.diff(self.p)
+        pfrac = (p - self.p[k0]) / dp[k0]
+        delta_SA = dsa0 * (1 - pfrac) + dsa1 * pfrac
+        # Save intermediate results in case we are curious about
+        # them; the frac values are most likely to be useful.
+        # We won't bother to reshape them, though, and we may
+        # delete them later.
+        self.dsa0 = dsa0
+        self.frac0 = frac0
+        self.dsa1 = dsa1
+        self.frac1 = frac1
+        self.pfrac = pfrac
+        self.p_fudge = p_orig - p
+        # Editing options, in case we don't want to use
+        # values calculated from the wrong pressure, or from
+        # an incomplete SA table grid square.
+        mask_out |= self.p_fudge > self.max_p_fudge
+        mask_out |= self.frac1 < self.min_frac
+        delta_SA = np.ma.array(delta_SA, mask=mask_out, copy=False)
+        if reshaped:
+            delta_SA.shape = shape_in
+            self.p_fudge.shape = shape_in
+        if mask_in is not np.ma.nomask:
+            delta_SA = np.ma.array(delta_SA, mask=mask_in, copy=False)
+        return delta_SA
+
+    def SAAR(self, p, lon, lat):
+        """
+        Table lookup of salinity anomaly ratio, given pressure, lon, and lat.
+        """
+        self.dsa = self.SAAR_ref
+        # In V2,
+        # ndepth from the file disagrees with the unmasked count from
+        # SAAR_ref in a few places; this should be fixed in the
+        # file, but for now we will simply calculate ndepth directly from
+        # SAAR_ref.
+        # TODO: check to see whether this discrepancy is also found in V3.
+        # TODO: check: do we even need to calculate ndepth? It doesn't
+        #       appear to be used for anything.
+        #self.ndepth = np.ma.masked_invalid(data.ndepth_ref.T).astype(np.int8)
+        ndepth = self.dsa.count(axis=-1)
+        self.ndepth = np.ma.masked_equal(ndepth, 0)
+        return self._delta_SA(p, lon, lat)
+
+    def delta_SA_ref(self, p, lon, lat):
+        """
+        Table lookup of salinity anomaly reference value, given pressure,
+        lon, and lat.
+        """
+        self.dsa = self.dsa_ref
+        # See comment in previous method.
+        ndepth = self.dsa.count(axis=-1)
+        self.ndepth = np.ma.masked_equal(ndepth, 0)
+        return self._delta_SA(p, lon, lat)
+
+
+def Fdelta(p, lon, lat):
+    r"""Fdelta from the Absolute Salinity Anomaly Ratio (SAAR)::
+       Fdelta = (1 + r1)SAAR/(1 - r1*SAAR)
+              = (SA/Sstar) - 1
+    with r1 being the constant 0.35 based on the work of Pawlowicz et al.
+    (2011). Note that since SAAR is everywhere less than 0.001 in the global
+    ocean, Fdelta is only slightly different to 1.35*SAAR.
+    Parameters
+    ----------
+    p : array_like
+        pressure [dbar]
+    lon : array_like
+          decimal degrees east (will be treated modulo 360)
+    lat : array_like
+          decimal degrees (+ve N, -ve S) [-90..+90]
+    Returns
+    -------
+    Fdelta : masked array; masked where no nearby ocean is found in data
+           Ratio of SA to Sstar, minus 1 [unitless]
+    Notes
+    -----
+    The mask is only set when the observation is well and truly on dry
+    land; often the warning flag is not set until one is several hundred
+    kilometers inland from the coast.
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.  Available from http://www.TEOS-10.org
+    See section 2.5 and appendices A.4 and A.5 of this TEOS-10 Manual.
+    .. [2] McDougall, T.J., D.R. Jackett, F.J. Millero, R. Pawlowicz and
+    P.M. Barker, 2012: A global algorithm for estimating Absolute Salinity.
+    Ocean Science, 8, 1123-1134.
+    http://www.ocean-sci.net/8/1123/2012/os-8-1123-2012.pdf
+    .. [3] Pawlawicz, R., D.G. Wright and F.J. Millero, 2011; The effects of
+    biogeochemical processes on oceanic conductivity/salinty/density
+    relationships and the characterization of real seawater. Ocean Science,
+    7, 363-387.  http://www.ocean-sci.net/7/363/2011/os-7-363-2011.pdf
+    """
+    r = 0.35
+    saar, _ = SAAR(p, lon, lat)
+    Fdelta = ((1 + r) * saar) / (1 - r * saar)
+    return Fdelta
+
+
+ at match_args_return
+def Hill_ratio_at_SP2(t):
+    r"""TODO: Write docstring
+    Hill ratio at SP = 2
+    """
+    # USAGE:
+    #  Hill_ratio = Hill_ratio_at_SP2(t)
+    #
+    # DESCRIPTION:
+    #  Calculates the Hill ratio, which is the adjustment needed to apply for
+    #  Practical Salinities smaller than 2.  This ratio is defined at a
+    #  Practical Salinity = 2 and in-situ temperature, t using PSS-78. The Hill
+    #  ratio is the ratio of 2 to the output of the Hill et al. (1986) formula
+    #  for Practical Salinity at the conductivity ratio, Rt, at which Practical
+    #  Salinity on the PSS-78 scale is exactly 2.
+    #
+    # INPUT:
+    #  t  =  in-situ temperature (ITS-90)                  [ deg C ]
+    #
+    # OUTPUT:
+    #  Hill_ratio  =  Hill ratio at SP of 2                [ unitless ]
+    #
+    # AUTHOR:
+    #  Trevor McDougall and Paul Barker
+    #
+    # VERSION NUMBER: 3.0 (26th March, 2011)
+    SP2 = 2 * np.ones_like(t)
+    #------------------------------
+    # Start of the calculation
+    #------------------------------
+    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
+    g0 = 2.641463563366498e-1
+    g1 = 2.007883247811176e-4
+    g2 = -4.107694432853053e-6
+    g3 = 8.401670882091225e-8
+    g4 = -1.711392021989210e-9
+    g5 = 3.374193893377380e-11
+    g6 = -5.923731174730784e-13
+    g7 = 8.057771569962299e-15
+    g8 = -7.054313817447962e-17
+    g9 = 2.859992717347235e-19
+    k = 0.0162
+    t68 = t * 1.00024
+    ft68 = (t68 - 15) / (1 + k * (t68 - 15))
+    #--------------------------------------------------------------------------
+    # Find the initial estimates of Rtx (Rtx0) and of the derivative dSP_dRtx
+    # at SP = 2.
+    #--------------------------------------------------------------------------
+    Rtx0 = g0 + t68 * (g1 + t68 * (g2 + t68 * (g3 + t68 * (g4 + t68 * (g5
+              + t68 * (g6 + t68 * (g7 + t68 * (g8 + t68 * g9))))))))
+    dSP_dRtx = (a1 + (2 * a2 + (3 * a3 + (4 * a4 + 5 * a5 * Rtx0) * Rtx0) *
+                Rtx0) * Rtx0 + ft68 * (b1 + (2 * b2 + (3 * b3 + (4 * b4 + 5 *
+                b5 * Rtx0) * Rtx0) * Rtx0) * Rtx0))
+    #--------------------------------------------------------------------------
+    # Begin a single modified Newton-Raphson iteration to find Rt at SP = 2.
+    #--------------------------------------------------------------------------
+    SP_est = (a0 + (a1 + (a2 + (a3 + (a4 + a5 * Rtx0) * Rtx0) * Rtx0) * Rtx0) *
+              Rtx0 + ft68 * (b0 + (b1 + (b2 + (b3 + (b4 + b5 * Rtx0) * Rtx0) *
+              Rtx0) * Rtx0) * Rtx0))
+    Rtx = Rtx0 - (SP_est - SP2) / dSP_dRtx
+    Rtxm = 0.5 * (Rtx + Rtx0)
+    dSP_dRtx = (a1 + (2 * a2 + (3 * a3 + (4 * a4 + 5 * a5 * Rtxm) * Rtxm) *
+                Rtxm) * Rtxm + ft68 * (b1 + (2 * b2 + (3 * b3 + (4 * b4 + 5 *
+                b5 * Rtxm) * Rtxm) * Rtxm) * Rtxm))
+    Rtx = Rtx0 - (SP_est - SP2) / dSP_dRtx
+    # This is the end of one full iteration of the modified Newton-Raphson
+    # iterative equation solver.  The error in Rtx at this point is equivalent
+    # to an error in SP of 9e-16 psu.
+    x = 400 * Rtx * Rtx
+    sqrty = 10 * Rtx
+    part1 = 1 + x * (1.5 + x)
+    part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+    SP_Hill_raw_at_SP2 = SP2 - a0 / part1 - b0 * ft68 / part2
+    return 2. / SP_Hill_raw_at_SP2
+
+
+ at match_args_return
+def SAAR(p, lon, lat):
+    r"""Absolute Salinity Anomaly Ratio (excluding the Baltic Sea).
+    Calculates the Absolute Salinity Anomaly Ratio, SAAR, in the open ocean
+    by spatially interpolating the global reference data set of SAAR to the
+    location of the seawater sample.
+    This function uses version 3.0 of the SAAR look up table.
+
+    Parameters
+    ----------
+    p : array_like
+        pressure [dbar]
+    lon : array_like
+          decimal degrees east (will be treated modulo 360)
+    lat : array_like
+          decimal degrees (+ve N, -ve S) [-90..+90]
+
+    Returns
+    -------
+    SAAR : array
+           Absolute Salinity Anomaly Ratio [unitless]
+    in_ocean : boolean array
+
+    Notes
+    -----
+    The Absolute Salinity Anomaly Ratio in the Baltic Sea is evaluated
+    separately, since it is a function of Practical Salinity, not of space.
+    The present function returns a SAAR of zero for data in the Baltic Sea.
+    The correct way of calculating Absolute Salinity in the Baltic Sea is by
+    calling SA_from_SP.
+    The in_ocean flag is only set when the observation is well and truly on dry
+    land; often the warning flag is not set until one is several hundred
+    kilometers inland from the coast.
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm
+    for estimating Absolute Salinity in the global ocean.  Submitted to Ocean
+    Science. A preliminary version is available at Ocean Sci. Discuss.,
+    6, 215-242.
+    http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf
+    The algorithm is taken from the matlab implementation of the references,
+    but the numpy implementation here differs substantially from the
+    matlab implementation.
+    """
+    saar = SA_table().SAAR(p, lon, lat)
+    return saar, ~saar.mask
+
+
+def SA_from_SP_Baltic(SP, lon, lat):
+    r"""Computes absolute salinity from practical in the Baltic Sea.
+    Parameters
+    ----------
+    SP : array_like or masked array
+        Practical salinity (PSS-78)
+    lon, lat : array_like or masked arrays
+               geographical position
+    Returns
+    -------
+    SA : masked array, at least 1D
+         Absolute salinity   [g/kg]
+         masked where inputs are masked or position outside the Baltic
+    """
+    # Handle masked array input
+    input_mask = False
+    if np.ma.is_masked(SP):
+        input_mask = input_mask | SP.mask
+    if np.ma.is_masked(lon):
+        input_mask = input_mask | lon.mask
+    if np.ma.is_masked(lat):
+        input_mask = input_mask | lat.mask
+    SP, lon, lat = map(np.atleast_1d, (SP, lon, lat))
+    SP, lon, lat = np.broadcast_arrays(SP, lon, lat)
+    inds_baltic = in_Baltic(lon, lat)
+    #SA_baltic = np.ma.masked_all(SP.shape, dtype=np.float)
+    all_nans = np.nan + np.zeros_like(SP)
+    SA_baltic = np.ma.MaskedArray(all_nans, mask=~inds_baltic)
+    if np.any(inds_baltic):
+        SA_baltic[inds_baltic] = (((SSO - 0.087) / 35) *
+                                  SP[inds_baltic] + 0.087)
+    SA_baltic.mask = SA_baltic.mask | input_mask | np.isnan(SP)
+    return SA_baltic
+
+
+def SP_from_SA_Baltic(SA, lon, lat):
+    r"""Calculates Practical Salinity (SP) for the Baltic Sea, from a value
+    computed analytically from Absolute Salinity.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    lon : array_like
+          decimal degrees east [0..+360]
+    lat : array_like
+          decimal degrees (+ve N, -ve S) [-90..+90]
+    Returns
+    -------
+    SP_baltic : array_like
+                salinity [psu (PSS-78)], unitless
+    See Also
+    --------
+    SP_from_SA, SP_from_Sstar
+    Notes
+    -----
+    This program will only produce Practical Salinity values for the Baltic
+    Sea.
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] Feistel, R., S. Weinreben, H. Wolf, S. Seitz, P. Spitzer, B. Adel,
+    G. Nausch, B. Schneider and D. G. Wright, 2010c: Density and Absolute
+    Salinity of the Baltic Sea 2006-2009.  Ocean Science, 6, 3-24.
+    http://www.ocean-sci.net/6/3/2010/os-6-3-2010.pdf
+    .. [2] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    .. [3] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm
+    for estimating Absolute Salinity in the global ocean. Submitted to Ocean
+    Science. A preliminary version is available at Ocean Sci. Discuss.,
+    6, 215-242.
+    http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf
+    Modifications:
+    2010-07-23. David Jackett, Trevor McDougall & Paul Barker
+    """
+    SA, lon, lat = map(np.ma.masked_invalid, (SA, lon, lat))
+    lon, lat, SA = np.broadcast_arrays(lon, lat, SA)
+    inds_baltic = in_Baltic(lon, lat)
+    if not inds_baltic.sum():
+        return None
+    SP_baltic = np.ma.masked_all(SA.shape, dtype=np.float)
+    SP_baltic[inds_baltic] = ((35 / (SSO - 0.087)) *
+                              (SA[inds_baltic] - 0.087))
+    return SP_baltic
+# FIXME: Check if this is still used and remove it.
+
+
+def SP_from_SA_Baltic_old(SA, lon, lat):
+    r"""Calculates Practical Salinity (SP) for the Baltic Sea, from a value
+    computed analytically from Absolute Salinity.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    lon : array_like
+          decimal degrees east [0..+360]
+    lat : array_like
+          decimal degrees (+ve N, -ve S) [-90..+90]
+    Returns
+    -------
+    SP_baltic : array_like
+                salinity [psu (PSS-78)], unitless
+    See Also
+    --------
+    SP_from_SA, SP_from_Sstar
+    Notes
+    -----
+    This program will only produce Practical Salinity values for the Baltic
+    Sea.
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] Feistel, R., S. Weinreben, H. Wolf, S. Seitz, P. Spitzer, B. Adel,
+    G. Nausch, B. Schneider and D. G. Wright, 2010c: Density and Absolute
+    Salinity of the Baltic Sea 2006-2009.  Ocean Science, 6, 3-24.
+    http://www.ocean-sci.net/6/3/2010/os-6-3-2010.pdf
+    .. [2] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    .. [3] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm
+    for estimating Absolute Salinity in the global ocean. Submitted to Ocean
+    Science. A preliminary version is available at Ocean Sci. Discuss.,
+    6, 215-242.
+    http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf
+    Modifications:
+    2010-07-23. David Jackett, Trevor McDougall & Paul Barker
+    """
+    SA, lon, lat = map(np.ma.masked_invalid, (SA, lon, lat))
+    lon, lat, SA = np.broadcast_arrays(lon, lat, SA)
+    xb1, xb2, xb3 = 12.6, 7., 26.
+    xb1a, xb3a = 45., 26.
+    yb1, yb2, yb3 = 50., 59., 69.
+    inds_baltic = (xb2 < lon) & (lon < xb1a) & (yb1 < lat) & (lat < yb3)
+    if not inds_baltic.sum():
+        return None
+    SP_baltic = np.ma.masked_all(SA.shape, dtype=np.float)
+    xx_left = np.interp(lat[inds_baltic], [yb1, yb2, yb3], [xb1, xb2, xb3])
+    xx_right = np.interp(lat[inds_baltic], [yb1, yb3], [xb1a, xb3a])
+    inds_baltic1 = ((xx_left <= lon[inds_baltic]) &
+                    (lon[inds_baltic] <= xx_right))
+    if not inds_baltic1.sum():
+        return None
+    SP_baltic[inds_baltic[inds_baltic1]] = ((35 / (SSO - 0.087)) *
+                                            (SA[inds_baltic[inds_baltic1]] -
+                                             0.087))
+    return SP_baltic
+
+
+ at match_args_return
+def deltaSA_atlas(p, lon, lat):
+    r"""Absolute Salinity anomaly atlas value (excluding the Baltic Sea).
+    Calculates the Absolute Salinity anomaly atlas value, SA - SR,
+    in the open ocean by spatially interpolating the global reference
+    data set of deltaSA_atlas to the location of the seawater sample.
+    This function uses version 3.0 of the deltaSA_ref look up table.
+    Parameters
+    ----------
+    p : array_like
+        sea pressure (absolute pressure - 10.1325 dbar) [dbar]
+    lon : array_like
+          decimal degrees east (will be treated modulo 360)
+    lat : array_like
+          decimal degrees (+ve N, -ve S) [-90..+90]
+    Returns
+    -------
+    deltaSA_atlas : masked array; masked where no nearby ocean is found in data
+           Absolute Salinity anomaly atlas value  [g/kg]
+    Notes
+    -----
+    The Absolute Salinity anomaly atlas value in the Baltic Sea is
+    evaluated separately, since it is a function of Practical Salinity,
+    not of space. The present function returns a deltaSA_atlas of zero
+    for data in the Baltic Sea. The correct way of calculating Absolute
+    Salinity in the Baltic Sea is by calling SA_from_SP.
+    The mask is only set when the observation is well and truly on dry
+    land; often the warning flag is not set until one is several hundred
+    kilometers inland from the coast.
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm
+    for estimating Absolute Salinity in the global ocean.  Submitted to Ocean
+    Science. A preliminary version is available at Ocean Sci. Discuss.,
+    6, 215-242.
+    http://www.ocean-sci-discuss.net/6/215/2009/osd-6-215-2009-print.pdf
+    The algorithm is taken from the Matlab implementation of the references,
+    but the numpy implementation here differs substantially from the
+    Matlab implementation.
+    """
+    return SA_table().delta_SA_ref(p, lon, lat)
+
+
+def enthalpy_SSO_0_CT25(p):
+    r"""Calculates enthalpy at the Standard Ocean Salinity (SSO) and at a
+    Conservative Temperature of zero degrees C (CT=0), as a function of
+    pressure (p [dbar]) or enthalpy_CT25(35.16504,0,p).
+    Parameters
+    ----------
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    enthalpy_CT25 : array_like
+                    enthalpy_CT25 at (SSO, CT = 0, p), 25-term equation.
+                    [J kg :sup:`-1`]
+    Notes
+    -----
+    Uses a streamlined version of the 25-term CT version of the Gibbs function,
+    that is, a streamlined version of the code "enthalpy_CT25(SA,CT,p)"
+    Modifications:
+    """
+    p = np.asanyarray(p)
+    mask = np.ma.getmask(p)
+    p = np.ma.filled(p, 0)
+    a0 = 1 + SSO * (2.0777716085618458e-3 + np.sqrt(SSO) *
+                    3.4688210757917340e-6)
+    a1 = 6.8314629554123324e-6
+    b0 = 9.9984380290708214e2 + SSO * (2.8925731541277653e0 + SSO *
+                                       1.9457531751183059e-3)
+    b1 = 0.5 * (1.1930681818531748e-2 + SSO * 5.9355685925035653e-6)
+    b2 = -2.5943389807429039e-8
+    A = b1 - np.sqrt(b1 ** 2 - b0 * b2)
+    B = b1 + np.sqrt(b1 ** 2 - b0 * b2)
+    part = (a0 * b2 - a1 * b1) / (b2 * (B - A))
+    enthalpy_SSO_0_CT25 = (db2Pascal * ((a1 / (2 * b2)) *
+                           np.log(1 + p * (2 * b1 + b2 * p) / b0) + part *
+                           np.log(1 + (b2 * p * (B - A)) /
+                           (A * (B + b2 * p)))))
+    return np.ma.array(enthalpy_SSO_0_CT25, mask=mask, copy=False)
+
+
+# FIXME: Check if this is still used and remove it.
+def enthalpy_SSO_0_p(p):
+    r"""This function calculates enthalpy at the Standard Ocean Salinty, SSO,
+    and at a Conservative Temperature of zero degrees C, as a function of
+    pressure, p, in dbar, using a streamlined version of the 48-term CT
+    version of the Gibbs function, that is, a streamlined version of the
+    code "enthalpy(SA,CT,p).
+    Examples
+    --------
+    >>> import gsw
+    >>> p = np.array([10, 50, 125, 250, 600, 1000])
+    >>> gsw.library.enthalpy_SSO_0_p(p)
+    array([   97.26388276,   486.27439004,  1215.47518168,  2430.24919716,
+            5827.90973888,  9704.32296903])
+    Modifications:
+    VERSION NUMBER: 3.03 (29th April, 2013)
+    References
+    ----------
+    .. [1] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2013:  A
+    computationally efficient 48-term expression for the density of seawater in
+    terms of Conservative Temperature, and related properties of seawater.  To
+    be submitted to J. Atm. Ocean. Technol., xx, yyy-zzz.
+    """
+    v01 = 9.998420897506056e+2
+    v05 = -6.698001071123802
+    v08 = -3.988822378968490e-2
+    v12 = -2.233269627352527e-2
+    v15 = -1.806789763745328e-4
+    v17 = -3.087032500374211e-7
+    v20 = 1.550932729220080e-10
+    v21 = 1.0
+    v26 = -7.521448093615448e-3
+    v31 = -3.303308871386421e-5
+    v36 = 5.419326551148740e-6
+    v37 = -2.742185394906099e-5
+    v41 = -1.105097577149576e-7
+    v43 = -1.119011592875110e-10
+    v47 = -1.200507748551599e-15
+    a0 = v21 + SSO * (v26 + v36 * SSO + v31 * np.sqrt(SSO))
+    a1 = v37 + v41 * SSO
+    a2 = v43
+    a3 = v47
+    b0 = v01 + SSO * (v05 + v08 * np.sqrt(SSO))
+    b1 = 0.5 * (v12 + v15 * SSO)
+    b2 = v17 + v20 * SSO
+    b1sq = b1 ** 2
+    sqrt_disc = np.sqrt(b1sq - b0 * b2)
+    N = a0 + (2 * a3 * b0 * b1 / b2 - a2 * b0) / b2
+    M = a1 + (4 * a3 * b1sq / b2 - a3 * b0 - 2 * a2 * b1) / b2
+    A = b1 - sqrt_disc
+    B = b1 + sqrt_disc
+    part = (N * b2 - M * b1) / (b2 * (B - A))
+    return (db2Pascal * (p * (a2 - 2 * a3 * b1 / b2 + 0.5 * a3 * p) / b2 +
+            (M / (2 * b2)) * np.log(1 + p * (2 * b1 + b2 * p) / b0) + part *
+            np.log(1 + (b2 * p * (B - A)) / (A * (B + b2 * p)))))
+
+
+def entropy_part(SA, t, p):
+    r"""Calculates entropy, except that it does not evaluate any terms that are
+    functions of Absolute Salinity alone.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    entropy_part : array_like
+                   entropy minus the terms that due to SA alone
+                   [J kg :sup:`-1` K :sup:`-1`]
+    Notes
+    -----
+    By not calculating these terms, which are a function only of Absolute
+    Salinity, several unnecessary computations are avoided (including saving
+    the computation of a natural logarithm). These terms are a necessary part
+    of entropy, but are not needed when calculating potential temperature from
+    in situ temperature.
+    Modifications:
+    """
+    SA, t, p, mask = strip_mask(SA, t, p)
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y = t * 0.025
+    z = p * 1e-4
+    g03 = (z * (-270.983805184062 + z * (776.153611613101 + z *
+           (-196.51255088122 + (28.9796526294175 - 2.13290083518327 * z) *
+           z))) + y * (-24715.571866078 + z * (2910.0729080936 + z *
+           (-1513.116771538718 + z * (546.959324647056 + z *
+           (-111.1208127634436 + 8.68841343834394 * z)))) + y *
+           (2210.2236124548363 + z * (-2017.52334943521 + z *
+           (1498.081172457456 + z * (-718.6359919632359 +
+           (146.4037555781616 - 4.9892131862671505 * z) * z))) + y *
+           (-592.743745734632 + z * (1591.873781627888 + z *
+           (-1207.261522487504 + (608.785486935364 - 105.4993508931208 * z) *
+           z)) + y * (290.12956292128547 + z * (-973.091553087975 + z *
+           (602.603274510125 + z * (-276.361526170076 + 32.40953340386105 *
+           z))) + y * (-113.90630790850321 + y * (21.35571525415769 -
+           67.41756835751434 * z) + z * (381.06836198507096 + z *
+           (-133.7383902842754 + 49.023632509086724 * z))))))))
+
+    g08 = (x2 * (z * (729.116529735046 + z * (-343.956902961561 + z *
+           (124.687671116248 + z * (-31.656964386073 + 7.04658803315449 *
+           z)))) + x * (x * (y * (-137.1145018408982 + y *
+           (148.10030845687618 + y * (-68.5590309679152 + 12.4848504784754 *
+           y))) - 22.6683558512829 * z) + z * (-175.292041186547 +
+           (83.1923927801819 - 29.483064349429 * z) * z) + y *
+           (-86.1329351956084 + z * (766.116132004952 + z *
+           (-108.3834525034224 + 51.2796974779828 * z)) + y *
+           (-30.0682112585625 - 1380.9597954037708 * z + y *
+           (3.50240264723578 + 938.26075044542 * z)))) + y *
+           (1760.062705994408 + y * (-675.802947790203 + y *
+           (365.7041791005036 + y * (-108.30162043765552 + 12.78101825083098 *
+           y) + z * (-1190.914967948748 + (298.904564555024 -
+           145.9491676006352 * z) * z)) + z * (2082.7344423998043 + z *
+           (-614.668925894709 + (340.685093521782 - 33.3848202979239 * z) *
+           z))) + z * (-1721.528607567954 + z * (674.819060538734 + z *
+           (-356.629112415276 + (88.4080716616 - 15.84003094423364 * z) *
+           z))))))
+
+    entropy_part = -(g03 + g08) * 0.025
+    return np.ma.array(entropy_part, mask=mask, copy=False)
+
+
+def entropy_part_zerop(SA, pt0):
+    r"""Calculates entropy at a sea surface (p = 0 dbar), except that it does
+    not evaluate any terms that are functions of Absolute Salinity alone.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    pt0 : array_like
+          potential temperature relative to 0 dbar [:math:`^\circ` C (ITS-90)]
+    Returns
+    -------
+    entropy_part_zerop : array_like
+                         [J kg :sup:`-1` K :sup:`-1`]
+    Notes
+    -----
+    By not calculating these terms, which are a function only of Absolute
+    Salinity, several unnecessary computations are avoided (including saving
+    the computation of a natural logarithm). These terms are a necessary part
+    of entropy, but are not needed when calculating potential temperature from
+    in situ temperature.
+    Modifications:
+    """
+    SA, pt0, mask = strip_mask(SA, pt0)
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y = pt0 * 0.025
+    g03 = y * (-24715.571866078 + y * (2210.2236124548363 +
+    y * (-592.743745734632 + y * (290.12956292128547 +
+    y * (-113.90630790850321 + y * 21.35571525415769)))))
+    g08 = x2 * (x * (x * (y * (-137.1145018408982 + y *
+    (148.10030845687618 +
+    y * (-68.5590309679152 + 12.4848504784754 * y)))) +
+    y * (-86.1329351956084 + y * (-30.0682112585625 + y *
+    3.50240264723578))) +
+    y * (1760.062705994408 + y * (-675.802947790203 +
+    y * (365.7041791005036 + y * (-108.30162043765552 +
+    12.78101825083098 * y)))))
+    entropy_part_zerop = -(g03 + g08) * 0.025
+    return np.ma.array(entropy_part_zerop, mask=mask, copy=False)
+
+
+# FIXME: Check if this is still used and remove it.
+def gibbs(ns, nt, npr, SA, t, p):
+    r"""Calculates specific Gibbs energy and its derivatives up to order 2 for
+    seawater.
+    The Gibbs function approach allows the calculation of internal energy,
+    entropy, enthalpy, potential enthalpy and the chemical potentials of
+    seawater as well as the freezing temperature, and the latent heats of
+    freezing and of evaporation. These quantities were not available from
+    EOS-80 but are essential for the accurate accounting of heat in the ocean
+    and for the consistent and accurate treatment of air-sea and ice-sea heat
+    fluxes.
+    Parameters
+    ----------
+    ns : int
+         order of SA derivative [0, 1 or 2 ]
+    nt : int
+         order of t derivative [0, 1 or 2 ]
+    npr : int
+          order of p derivative [0, 1 or 2 ]
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    gibbs : array_like
+            Specific Gibbs energy or its derivatives.
+            Gibbs energy (ns=nt=npr=0) has units of:
+            [J kg :sup:`-1`]
+            Absolute Salinity derivatives are output in units of:
+            [(J kg :sup:`-1`) (g kg :sup:`-1`) :sup:`-ns`]
+            Temperature derivatives are output in units of:
+            [(J kg :sup:`-1`) K :sup:`-nt`]
+            Pressure derivatives are output in units of:
+            [(J kg :sup:`-1`) Pa :sup:`-npr`]
+            The mixed derivatives are output in units of:
+            [(J kg :sup:`-1`) (g kg :sup:`-1`) :sup:`-ns` K :sup:`-nt`
+            Pa :sup:`-npr`]
+    Notes
+    -----
+    The Gibbs function for seawater is that of TEOS-10 (IOC et al., 2010),
+    being the sum of IAPWS-08 for the saline part and IAPWS-09 for the pure
+    water part. These IAPWS releases are the officially blessed IAPWS
+    descriptions of Feistel (2008) and the pure water part of Feistel (2003).
+    Absolute Salinity, SA, in all of the GSW routines is expressed on the
+    Reference-Composition Salinity Scale of 2008 (RCSS-08) of Millero et al.
+    (2008).
+    The derivatives are taken with respect to pressure in Pa, not withstanding
+    that the pressure input into this routine is in dbar.
+    References
+    ----------
+    .. [1] Feistel, R., 2003: A new extended Gibbs thermodynamic potential of
+    seawater Progr. Oceanogr., 58, 43-114.
+    .. [2] Feistel, R., 2008: A Gibbs function for seawater thermodynamics
+    for -6 to 80 :math:`^\circ` C and salinity up to 120 g kg :sup:`-1`,
+    Deep-Sea Res. I, 55, 1639-1671.
+    .. [3] IAPWS, 2008: Release on the IAPWS Formulation 2008 for the
+    Thermodynamic Properties of Seawater. The International Association for the
+    Properties of Water and Steam. Berlin, Germany, September 2008, available
+    from http://www.iapws.org.  This Release is referred to as IAPWS-08.
+    .. [4] IAPWS, 2009: Supplementary Release on a Computationally Efficient
+    Thermodynamic Formulation for Liquid Water for Oceanographic Use. The
+    International Association for the Properties of Water and Steam. Doorwerth,
+    The Netherlands, September 2009, available from http://www.iapws.org.
+    This Release is referred to as IAPWS-09.
+    .. [5] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.6 and appendices A.6,  G and H.
+    .. [6] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008:
+    The composition of Standard Seawater and the definition of the
+    Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72.
+    Modifications:
+    2010-09-24. David Jackett, Paul Barker and Trevor McDougall
+    """
+    SA, t, p = np.asanyarray(SA), np.asanyarray(t), np.asanyarray(p)
+    SA = np.atleast_1d(SA)
+    nonzero_SA = np.any(SA > 0)
+    _SA = SA
+    _t = t
+    _p = p
+    SA = np.ma.filled(SA, 0)
+    t = np.ma.filled(t, 20)
+    p = np.ma.filled(p, 10)
+    SA, t, p = np.broadcast_arrays(SA, t, p)
+    gibbs = np.zeros(SA.shape, dtype=np.float)  # Use if all_masked is True
+    all_masked = False
+    # Ensure a full mask, so we can set elements if necessary.
+    mask = np.ma.mask_or(np.ma.getmaskarray(_SA), np.ma.getmask(_t))
+    mask = np.ma.mask_or(mask, np.ma.getmask(_p))
+    mask = np.ma.mask_or(mask, SA < 0)
+    ipos = (SA > 0)
+    # inpos = ~ipos  # FIXME: Assigned but never used.
+    if np.all(ipos):
+        ipos = slice(None)  # More efficient for usual case.
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y = t * 0.025
+    z = p * 1e-4  # The input pressure (p) is sea pressure in units of dbar.
+    if (ns == 0) & (nt == 0) & (npr == 0):
+        g03 = (101.342743139674 + z * (100015.695367145 +
+        z * (-2544.5765420363 + z * (284.517778446287 +
+        z * (-33.3146754253611 + (4.20263108803084 - 0.546428511471039 * z)
+        * z)))) +
+        y * (5.90578347909402 + z * (-270.983805184062 +
+        z * (776.153611613101 + z * (-196.51255088122 + (28.9796526294175 -
+        2.13290083518327 * z) * z))) +
+        y * (-12357.785933039 + z * (1455.0364540468 +
+        z * (-756.558385769359 + z * (273.479662323528 + z *
+        (-55.5604063817218 + 4.34420671917197 * z)))) +
+        y * (736.741204151612 + z * (-672.50778314507 +
+        z * (499.360390819152 + z * (-239.545330654412 + (48.8012518593872 -
+        1.66307106208905 * z) * z))) +
+        y * (-148.185936433658 + z * (397.968445406972 +
+        z * (-301.815380621876 + (152.196371733841 - 26.3748377232802 * z) *
+        z)) +
+        y * (58.0259125842571 + z * (-194.618310617595 +
+        z * (120.520654902025 + z * (-55.2723052340152 +
+        6.48190668077221 * z))) +
+        y * (-18.9843846514172 + y * (3.05081646487967 -
+        9.63108119393062 * z) +
+        z * (63.5113936641785 + z * (-22.2897317140459 +
+        8.17060541818112 * z)))))))))
+        if nonzero_SA:
+            g08 = x2 * (1416.27648484197 + z * (-3310.49154044839 +
+            z * (384.794152978599 + z * (-96.5324320107458 +
+            (15.8408172766824 - 2.62480156590992 * z) * z))) +
+            x * (-2432.14662381794 + x * (2025.80115603697 +
+            y * (543.835333000098 + y * (-68.5572509204491 +
+            y * (49.3667694856254 + y * (-17.1397577419788 +
+            2.49697009569508 * y))) - 22.6683558512829 * z) +
+            x * (-1091.66841042967 - 196.028306689776 * y +
+            x * (374.60123787784 - 48.5891069025409 * x +
+            36.7571622995805 * y) + 36.0284195611086 * z) +
+            z * (-54.7919133532887 + (-4.08193978912261 -
+            30.1755111971161 * z) * z)) +
+            z * (199.459603073901 + z * (-52.2940909281335 +
+            (68.0444942726459 - 3.41251932441282 * z) * z)) +
+            y * (-493.407510141682 + z * (-175.292041186547 +
+            (83.1923927801819 - 29.483064349429 * z) * z) +
+            y * (-43.0664675978042 + z * (383.058066002476 + z *
+            (-54.1917262517112 + 25.6398487389914 * z)) +
+            y * (-10.0227370861875 - 460.319931801257 * z + y *
+            (0.875600661808945 + 234.565187611355 * z))))) +
+            y * (168.072408311545 + z * (729.116529735046 +
+            z * (-343.956902961561 + z * (124.687671116248 + z *
+            (-31.656964386073 + 7.04658803315449 * z)))) +
+            y * (880.031352997204 + y * (-225.267649263401 +
+            y * (91.4260447751259 + y * (-21.6603240875311 +
+            2.13016970847183 * y) +
+            z * (-297.728741987187 + (74.726141138756 -
+            36.4872919001588 * z) * z)) +
+            z * (694.244814133268 + z * (-204.889641964903 +
+            (113.561697840594 - 11.1282734326413 * z) * z))) +
+            z * (-860.764303783977 + z * (337.409530269367 +
+            z * (-178.314556207638 + (44.2040358308 -
+            7.92001547211682 * z) * z))))))
+            g08[ipos] += x2[ipos] * (5812.81456626732 + 851.226734946706 *
+            y[ipos]) * np.log(x[ipos])
+        else:
+            g08 = 0
+        gibbs = g03 + g08
+    elif (ns == 1) & (nt == 0) & (npr == 0):
+        if nonzero_SA:
+            g08 = (8645.36753595126 + z * (-6620.98308089678 +
+            z * (769.588305957198 + z * (-193.0648640214916 +
+            (31.6816345533648 - 5.24960313181984 * z) * z))) +
+            x * (-7296.43987145382 + x * (8103.20462414788 +
+            y * (2175.341332000392 + y * (-274.2290036817964 +
+            y * (197.4670779425016 + y * (-68.5590309679152 +
+            9.98788038278032 * y))) - 90.6734234051316 * z) +
+            x * (-5458.34205214835 - 980.14153344888 * y +
+            x * (2247.60742726704 - 340.1237483177863 * x +
+            220.542973797483 * y) + 180.142097805543 * z) +
+            z * (-219.1676534131548 + (-16.32775915649044 -
+            120.7020447884644 * z) * z)) +
+            z * (598.378809221703 + z * (-156.8822727844005 +
+            (204.1334828179377 - 10.23755797323846 * z) * z)) +
+            y * (-1480.222530425046 + z * (-525.876123559641 +
+            (249.57717834054571 - 88.449193048287 * z) * z) +
+            y * (-129.1994027934126 + z * (1149.174198007428 +
+            z * (-162.5751787551336 + 76.9195462169742 * z)) +
+            y * (-30.0682112585625 - 1380.9597954037708 * z + y *
+            (2.626801985426835 + 703.695562834065 * z))))) +
+            y * (1187.3715515697959 + z * (1458.233059470092 +
+            z * (-687.913805923122 + z * (249.375342232496 + z *
+            (-63.313928772146 + 14.09317606630898 * z)))) +
+            y * (1760.062705994408 + y * (-450.535298526802 +
+            y * (182.8520895502518 + y * (-43.3206481750622 +
+            4.26033941694366 * y) +
+            z * (-595.457483974374 + (149.452282277512 -
+            72.9745838003176 * z) * z)) +
+            z * (1388.489628266536 + z * (-409.779283929806 +
+            (227.123395681188 - 22.2565468652826 * z) * z))) +
+            z * (-1721.528607567954 + z * (674.819060538734 +
+            z * (-356.629112415276 + (88.4080716616 -
+            15.84003094423364 * z) * z))))))
+            g08[ipos] = g08[ipos] + (11625.62913253464 + 1702.453469893412 *
+            y[ipos]) * np.log(x[ipos])
+            gibbs = 0.5 * sfac * g08
+        else:
+            all_masked = True
+    elif (ns == 0) & (nt == 1) & (npr == 0):
+        g03 = (5.90578347909402 + z * (-270.983805184062 +
+        z * (776.153611613101 + z * (-196.51255088122 +
+        (28.9796526294175 - 2.13290083518327 * z) * z))) +
+        y * (-24715.571866078 + z * (2910.0729080936 +
+        z * (-1513.116771538718 + z * (546.959324647056 + z *
+        (-111.1208127634436 + 8.68841343834394 * z)))) +
+        y * (2210.2236124548363 + z * (-2017.52334943521 +
+        z * (1498.081172457456 + z * (-718.6359919632359 +
+        (146.4037555781616 - 4.9892131862671505 * z) * z))) +
+        y * (-592.743745734632 + z * (1591.873781627888 +
+        z * (-1207.261522487504 + (608.785486935364 -
+        105.4993508931208 * z) * z)) +
+        y * (290.12956292128547 + z * (-973.091553087975 +
+        z * (602.603274510125 + z * (-276.361526170076 +
+        32.40953340386105 * z))) +
+        y * (-113.90630790850321 + y * (21.35571525415769 -
+        67.41756835751434 * z) +
+        z * (381.06836198507096 + z * (-133.7383902842754 +
+        49.023632509086724 * z))))))))
+        if nonzero_SA:
+            g08 = x2 * (168.072408311545 + z * (729.116529735046 +
+            z * (-343.956902961561 + z * (124.687671116248 + z *
+            (-31.656964386073 + 7.04658803315449 * z)))) +
+            x * (-493.407510141682 + x * (543.835333000098 + x *
+            (-196.028306689776 + 36.7571622995805 * x) +
+            y * (-137.1145018408982 + y * (148.10030845687618 + y *
+            (-68.5590309679152 + 12.4848504784754 * y))) -
+            22.6683558512829 * z) + z * (-175.292041186547 +
+            (83.1923927801819 - 29.483064349429 * z) * z) +
+            y * (-86.1329351956084 + z * (766.116132004952 + z *
+            (-108.3834525034224 + 51.2796974779828 * z)) +
+            y * (-30.0682112585625 - 1380.9597954037708 * z + y *
+            (3.50240264723578 + 938.26075044542 * z)))) +
+            y * (1760.062705994408 + y * (-675.802947790203 +
+            y * (365.7041791005036 + y * (-108.30162043765552 +
+            12.78101825083098 * y) +
+            z * (-1190.914967948748 + (298.904564555024 -
+            145.9491676006352 * z) * z)) +
+            z * (2082.7344423998043 + z * (-614.668925894709 +
+            (340.685093521782 - 33.3848202979239 * z) * z))) +
+            z * (-1721.528607567954 + z * (674.819060538734 +
+            z * (-356.629112415276 + (88.4080716616 -
+            15.84003094423364 * z) * z)))))
+            g08[ipos] += 851.226734946706 * x2[ipos] * np.log(x[ipos])
+            gibbs = (g03 + g08) * 0.025
+        else:
+            gibbs = g03
+    elif (ns == 0) & (nt == 0) & (npr == 1):
+        g03 = (100015.695367145 + z * (-5089.1530840726 +
+        z * (853.5533353388611 + z * (-133.2587017014444 +
+        (21.0131554401542 - 3.278571068826234 * z) * z))) +
+        y * (-270.983805184062 + z * (1552.307223226202 +
+        z * (-589.53765264366 + (115.91861051767 -
+        10.664504175916349 * z) * z)) +
+        y * (1455.0364540468 + z * (-1513.116771538718 +
+        z * (820.438986970584 + z * (-222.2416255268872 +
+        21.72103359585985 * z))) +
+        y * (-672.50778314507 + z * (998.720781638304 +
+        z * (-718.6359919632359 + (195.2050074375488 -
+        8.31535531044525 * z) * z)) +
+        y * (397.968445406972 + z * (-603.630761243752 +
+        (456.589115201523 - 105.4993508931208 * z) * z) +
+        y * (-194.618310617595 + y * (63.5113936641785 -
+        9.63108119393062 * y +
+        z * (-44.5794634280918 + 24.511816254543362 * z)) +
+        z * (241.04130980405 + z * (-165.8169157020456 +
+        25.92762672308884 * z))))))))
+        if nonzero_SA:
+            g08 = x2 * (-3310.49154044839 + z * (769.588305957198 +
+            z * (-289.5972960322374 + (63.3632691067296 -
+            13.1240078295496 * z) * z)) +
+            x * (199.459603073901 + x * (-54.7919133532887 +
+            36.0284195611086 * x - 22.6683558512829 * y +
+            (-8.16387957824522 - 90.52653359134831 * z) * z) +
+            z * (-104.588181856267 + (204.1334828179377 -
+            13.65007729765128 * z) * z) +
+            y * (-175.292041186547 + (166.3847855603638 -
+            88.449193048287 * z) * z +
+            y * (383.058066002476 + y * (-460.319931801257 +
+            234.565187611355 * y) +
+            z * (-108.3834525034224 + 76.9195462169742 * z)))) +
+            y * (729.116529735046 + z * (-687.913805923122 +
+            z * (374.063013348744 + z * (-126.627857544292 +
+            35.23294016577245 * z))) +
+            y * (-860.764303783977 + y * (694.244814133268 +
+            y * (-297.728741987187 + (149.452282277512 -
+            109.46187570047641 * z) * z) +
+            z * (-409.779283929806 + (340.685093521782 -
+            44.5130937305652 * z) * z)) +
+            z * (674.819060538734 + z * (-534.943668622914 +
+            (176.8161433232 - 39.600077360584095 * z) * z)))))
+        else:
+            g08 = 0
+        # Pressure derivative of the Gibbs function
+        # in units of (J kg :sup:`-1`) (Pa :sup:`-1`) = m :sup:`3` kg :sup:`-1`
+        gibbs = (g03 + g08) * 1e-8
+    elif (ns == 1) & (nt == 1) & (npr == 0):
+        if nonzero_SA:
+            g08 = (1187.3715515697959 + z * (1458.233059470092 +
+            z * (-687.913805923122 + z * (249.375342232496 + z *
+            (-63.313928772146 + 14.09317606630898 * z)))) +
+            x * (-1480.222530425046 + x * (2175.341332000392 + x *
+            (-980.14153344888 + 220.542973797483 * x) +
+            y * (-548.4580073635929 + y * (592.4012338275047 + y *
+            (-274.2361238716608 + 49.9394019139016 * y))) -
+            90.6734234051316 * z) + z * (-525.876123559641 +
+            (249.57717834054571 - 88.449193048287 * z) * z) +
+            y * (-258.3988055868252 + z * (2298.348396014856 +
+            z * (-325.1503575102672 + 153.8390924339484 * z)) +
+            y * (-90.2046337756875 - 4142.8793862113125 * z + y *
+            (10.50720794170734 + 2814.78225133626 * z)))) +
+            y * (3520.125411988816 + y * (-1351.605895580406 +
+            y * (731.4083582010072 + y * (-216.60324087531103 +
+            25.56203650166196 * y) +
+            z * (-2381.829935897496 + (597.809129110048 -
+            291.8983352012704 * z) * z)) +
+            z * (4165.4688847996085 + z * (-1229.337851789418 +
+            (681.370187043564 - 66.7696405958478 * z) * z))) +
+            z * (-3443.057215135908 + z * (1349.638121077468 +
+            z * (-713.258224830552 + (176.8161433232 -
+            31.68006188846728 * z) * z)))))
+            g08[ipos] = g08[ipos] + 1702.453469893412 * np.log(x[ipos])
+            gibbs = 0.5 * sfac * 0.025 * g08
+            # FIXME: commented by FF, g110 without nan did not pass
+            #mask[inpos] = True
+        else:
+            all_masked = True
+    elif (ns == 1) & (nt == 0) & (npr == 1):
+        g08 = (-6620.98308089678 + z * (1539.176611914396 +
+        z * (-579.1945920644748 + (126.7265382134592 -
+        26.2480156590992 * z) * z)) +
+        x * (598.378809221703 + x * (-219.1676534131548 +
+        180.142097805543 * x - 90.6734234051316 * y +
+        (-32.65551831298088 - 362.10613436539325 * z) * z) +
+        z * (-313.764545568801 + (612.4004484538132 -
+        40.95023189295384 * z) * z) +
+        y * (-525.876123559641 + (499.15435668109143 -
+        265.347579144861 * z) * z +
+        y * (1149.174198007428 + y * (-1380.9597954037708 +
+        703.695562834065 * y) +
+        z * (-325.1503575102672 + 230.7586386509226 * z)))) +
+        y * (1458.233059470092 + z * (-1375.827611846244 +
+        z * (748.126026697488 + z * (-253.255715088584 +
+        70.4658803315449 * z))) +
+        y * (-1721.528607567954 + y * (1388.489628266536 +
+        y * (-595.457483974374 + (298.904564555024 -
+        218.92375140095282 * z) * z) +
+        z * (-819.558567859612 + (681.370187043564 -
+        89.0261874611304 * z) * z)) +
+        z * (1349.638121077468 + z * (-1069.887337245828 +
+        (353.6322866464 - 79.20015472116819 * z) * z)))))
+        # Derivative of the Gibbs function is in units of
+        # (m :sup:`3` kg :sup:`-1`) / (g kg :sup:`-1`) = m :sup:`3` g :sup:`-1`
+        # that is, it is the derivative of specific volume with respect to
+        # Absolute Salinity measured in g kg :sup:`-1`
+        gibbs = g08 * sfac * 0.5e-8
+    elif (ns == 0) & (nt == 1) & (npr == 1):
+        g03 = (-270.983805184062 + z * (1552.307223226202 + z *
+        (-589.53765264366 +
+        (115.91861051767 - 10.664504175916349 * z) * z)) +
+        y * (2910.0729080936 + z * (-3026.233543077436 +
+        z * (1640.877973941168 + z * (-444.4832510537744 +
+        43.4420671917197 * z))) +
+        y * (-2017.52334943521 + z * (2996.162344914912 +
+        z * (-2155.907975889708 + (585.6150223126464 -
+        24.946065931335752 * z) * z)) +
+        y * (1591.873781627888 + z * (-2414.523044975008 +
+        (1826.356460806092 - 421.9974035724832 * z) * z) +
+        y * (-973.091553087975 + z * (1205.20654902025 + z *
+        (-829.084578510228 + 129.6381336154442 * z)) +
+        y * (381.06836198507096 - 67.41756835751434 * y + z *
+        (-267.4767805685508 + 147.07089752726017 * z)))))))
+        if nonzero_SA:
+            g08 = x2 * (729.116529735046 + z * (-687.913805923122 +
+            z * (374.063013348744 + z * (-126.627857544292 +
+            35.23294016577245 * z))) +
+            x * (-175.292041186547 - 22.6683558512829 * x +
+            (166.3847855603638 - 88.449193048287 * z) * z +
+            y * (766.116132004952 + y * (-1380.9597954037708 +
+            938.26075044542 * y) +
+            z * (-216.7669050068448 + 153.8390924339484 * z))) +
+            y * (-1721.528607567954 + y * (2082.7344423998043 +
+            y * (-1190.914967948748 + (597.809129110048 -
+            437.84750280190565 * z) * z) +
+            z * (-1229.337851789418 + (1022.055280565346 -
+            133.5392811916956 * z) * z)) +
+            z * (1349.638121077468 + z * (-1069.887337245828 +
+            (353.6322866464 - 79.20015472116819 * z) * z))))
+        else:
+            g08 = 0
+        # Derivative of the Gibbs function is in units of (m :sup:`3` (K kg))
+        # that is, the pressure of the derivative in Pa.
+        gibbs = (g03 + g08) * 2.5e-10
+    elif (ns == 2) & (nt == 0) & (npr == 0):
+        g08 = 2.0 * (8103.20462414788 +
+        y * (2175.341332000392 + y * (-274.2290036817964 +
+        y * (197.4670779425016 + y * (-68.5590309679152 +
+        9.98788038278032 * y))) - 90.6734234051316 * z) +
+        1.5 * x * (-5458.34205214835 - 980.14153344888 * y +
+        (4.0 / 3.0) * x * (2247.60742726704 - 340.1237483177863 * 1.25 *
+        x + 220.542973797483 * y) +
+        180.142097805543 * z) +
+        z * (-219.1676534131548 + (-16.32775915649044 -
+        120.7020447884644 * z) * z))
+        if nonzero_SA:
+            tmp = ((-7296.43987145382 + z * (598.378809221703 +
+            z * (-156.8822727844005 + (204.1334828179377 -
+            10.23755797323846 * z) * z)) +
+            y * (-1480.222530425046 + z * (-525.876123559641 +
+            (249.57717834054571 - 88.449193048287 * z) * z) +
+            y * (-129.1994027934126 + z * (1149.174198007428 +
+            z * (-162.5751787551336 + 76.9195462169742 * z)) +
+            y * (-30.0682112585625 - 1380.9597954037708 * z +
+            y * (2.626801985426835 + 703.695562834065 * z))))) / x +
+            (11625.62913253464 + 1702.453469893412 * y) / x2)
+            g08[ipos] += tmp[ipos]
+        gibbs = 0.25 * sfac ** 2 * g08
+    elif (ns == 0) & (nt == 2) & (npr == 0):
+        g03 = (-24715.571866078 + z * (2910.0729080936 + z *
+        (-1513.116771538718 + z * (546.959324647056 + z *
+        (-111.1208127634436 + 8.68841343834394 * z)))) +
+        y * (4420.4472249096725 + z * (-4035.04669887042 +
+        z * (2996.162344914912 + z * (-1437.2719839264719 +
+        (292.8075111563232 - 9.978426372534301 * z) * z))) +
+        y * (-1778.231237203896 + z * (4775.621344883664 +
+        z * (-3621.784567462512 + (1826.356460806092 -
+        316.49805267936244 * z) * z)) +
+        y * (1160.5182516851419 + z * (-3892.3662123519 +
+        z * (2410.4130980405 + z * (-1105.446104680304 +
+        129.6381336154442 * z))) +
+        y * (-569.531539542516 + y * (128.13429152494615 -
+        404.50541014508605 * z) +
+        z * (1905.341809925355 + z * (-668.691951421377 +
+        245.11816254543362 * z)))))))
+        if nonzero_SA:
+            g08 = x2 * (1760.062705994408 + x * (-86.1329351956084 +
+            x * (-137.1145018408982 + y * (296.20061691375236 +
+            y * (-205.67709290374563 + 49.9394019139016 * y))) +
+            z * (766.116132004952 + z * (-108.3834525034224 +
+            51.2796974779828 * z)) +
+            y * (-60.136422517125 - 2761.9195908075417 * z +
+            y * (10.50720794170734 + 2814.78225133626 * z))) +
+            y * (-1351.605895580406 + y * (1097.1125373015109 +
+            y * (-433.20648175062206 + 63.905091254154904 * y) +
+            z * (-3572.7449038462437 + (896.713693665072 -
+            437.84750280190565 * z) * z)) +
+            z * (4165.4688847996085 + z * (-1229.337851789418 +
+            (681.370187043564 - 66.7696405958478 * z) * z))) +
+            z * (-1721.528607567954 + z * (674.819060538734 +
+            z * (-356.629112415276 + (88.4080716616 -
+            15.84003094423364 * z) * z))))
+        else:
+            g08 = 0
+        gibbs = (g03 + g08) * 0.000625
+    elif (ns == 0) & (nt == 0) & (npr == 2):
+        g03 = (-5089.1530840726 + z * (1707.1066706777221 +
+        z * (-399.7761051043332 + (84.0526217606168 -
+        16.39285534413117 * z) * z)) +
+        y * (1552.307223226202 + z * (-1179.07530528732 +
+        (347.75583155301 - 42.658016703665396 * z) * z) +
+        y * (-1513.116771538718 + z * (1640.877973941168 +
+        z * (-666.7248765806615 + 86.8841343834394 * z)) +
+        y * (998.720781638304 + z * (-1437.2719839264719 +
+        (585.6150223126464 - 33.261421241781 * z) * z) +
+        y * (-603.630761243752 + (913.178230403046 -
+        316.49805267936244 * z) * z +
+        y * (241.04130980405 + y * (-44.5794634280918 +
+        49.023632509086724 * z) +
+        z * (-331.6338314040912 + 77.78288016926652 * z)))))))
+        if nonzero_SA:
+            g08 = x2 * (769.588305957198 + z * (-579.1945920644748 +
+            (190.08980732018878 - 52.4960313181984 * z) * z) +
+            x * (-104.588181856267 + x * (-8.16387957824522 -
+            181.05306718269662 * z) +
+            (408.2669656358754 - 40.95023189295384 * z) * z +
+            y * (166.3847855603638 - 176.898386096574 * z + y *
+            (-108.3834525034224 + 153.8390924339484 * z))) +
+            y * (-687.913805923122 + z * (748.126026697488 +
+            z * (-379.883572632876 + 140.9317606630898 * z)) +
+            y * (674.819060538734 + z * (-1069.887337245828 +
+            (530.4484299696 - 158.40030944233638 * z) * z) +
+            y * (-409.779283929806 + y * (149.452282277512 -
+            218.92375140095282 * z) +
+            (681.370187043564 - 133.5392811916956 * z) * z))))
+        else:
+            g08 = 0
+        # Second derivative of the Gibbs function with respect to pressure,
+        # measured in Pa; units of (J kg :sup:`-1`) (Pa :sup:`-2`).
+        gibbs = (g03 + g08) * 1e-16
+    else:
+        raise ValueError('Illegal derivative of the Gibbs function')
+    gibbs = np.ma.array(gibbs, mask=mask, copy=False)
+    # BÅ: Code below is not needed?  EF: it is needed.
+    if all_masked:
+        gibbs[:] = np.ma.masked
+    # Do not allow zero salinity with salinity derivatives
+    if ns > 0:
+        gibbs = np.ma.masked_where(SA == 0, gibbs)
+    return gibbs
+
+
+def gibbs_pt0_pt0(SA, pt0):
+    r"""Calculates the second derivative of the specific Gibbs function with
+    respect to temperature at zero sea pressure or _gibbs(0,2,0,SA,t,0).
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    pt0 : array_like
+          potential temperature relative to 0 dbar [:math:`^\circ` C (ITS-90)]
+    Returns
+    -------
+    gibbs_pt0_pt0 : array_like
+                    TODO: write the eq. for the second derivative of the
+                    specific Gibbs function. FIXME: [units]
+    Notes
+    -----
+    This library function is called by both "pt_from_CT(SA,CT)"
+    and "pt0_from_t(SA,t,p)".
+    Modifications:
+    """
+    SA, pt0, mask = strip_mask(SA, pt0)
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y = pt0 * 0.025
+    g03 = (-24715.571866078 +
+           y * (4420.4472249096725 +
+           y * (-1778.231237203896 +
+           y * (1160.5182516851419 +
+           y * (-569.531539542516 + y * 128.13429152494615)))))
+
+    g08 = (x2 * (1760.062705994408 + x * (-86.1329351956084 +
+           x * (-137.1145018408982 + y * (296.20061691375236 +
+           y * (-205.67709290374563 + 49.9394019139016 * y))) +
+           y * (-60.136422517125 + y * 10.50720794170734)) +
+           y * (-1351.605895580406 + y * (1097.1125373015109 +
+           y * (-433.20648175062206 + 63.905091254154904 * y)))))
+    gibbs_pt0_pt0 = (g03 + g08) * 0.000625
+    return np.ma.array(gibbs_pt0_pt0, mask=mask, copy=False)
+
+
+def in_Baltic(lon, lat):
+    """Check if positions are in the Baltic Sea
+    Parameters
+    ----------
+    lon, lat : array_like or masked arrays
+    Returns
+    -------
+    in_Baltic : boolean array (at least 1D)
+                True for points in the Baltic Sea
+                False for points outside, masked or NaN
+    """
+    lon, lat = np.atleast_1d(lon, lat)
+    # Polygon bounding the Baltic, (xb, yb)
+    # Effective boundary is the intersection of this polygon
+    # with rectangle defined by xmin, xmax, ymin, ymax
+    #
+    # start with southwestern point and go round cyclonically
+    xb = np.array([12.6, 45.0, 26.0,  7.0, 12.6])
+    yb = np.array([50.0, 50.0, 69.0, 59.0, 50.0])
+    # Enclosing rectangle
+    #xmin, xmax = xb.min(), xb.max()
+    #ymin, ymax = yb.min(), yb.max()
+    xmin, xmax = 7.0, 32.0
+    ymin, ymax = 52.0, 67.0
+    # First check if outside the rectangle
+    in_rectangle = ((xmin < lon) & (lon < xmax) &
+                    (ymin < lat) & (lat < ymax))
+    # Masked values are also considered outside the rectangle
+    if np.ma.is_masked(in_rectangle):
+        in_rectangle = in_rectangle.data & ~in_rectangle.mask
+    # Closer check for points in the rectangle
+    if np.any(in_rectangle):
+        lon, lat = np.broadcast_arrays(lon, lat)
+        in_baltic = np.zeros(lon.shape, dtype='bool')
+        lon1 = lon[in_rectangle]
+        lat1 = lat[in_rectangle]
+        # There are general ways of testing for point in polygon
+        # This works for this special configuration of points
+        xx_right = np.interp(lat1, yb[1:3], xb[1:3])
+        xx_left = np.interp(lat1, yb[-1:1:-1], xb[-1:1:-1])
+        in_baltic[in_rectangle] = (xx_left <= lon1) & (lon1 <= xx_right)
+        return in_baltic
+    else:  # Nothing inside the rectangle, return the False array.
+        return in_rectangle
+
+
+def infunnel(SA, CT, p):
+    r"""Oceanographic funnel check for the 25-term equation
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity            [g/kg]
+    CT : array_like
+         Conservative Temperature     [°C]
+    p  : array_like
+         sea pressure                 [dbar]
+           (ie. absolute pressure - 10.1325 dbar)
+    Returns
+    -------
+    in_funnel : boolean ndarray or scalar
+        True,  if SA, CT and p are inside the "funnel"
+        False, if SA, CT and p are outside the "funnel",
+               or one of the values are NaN or masked
+    Note. The term "funnel" describes the range of SA, CT and p over which
+    the error in the fit of the computationally-efficient 25-term
+    expression for density in terms of SA, CT and p was calculated
+    (McDougall et al., 2010).
+    author:
+    Trevor McDougall and Paul Barker
+    2011-02-27: Bjørn Ådlandsvik, python version
+    """
+    # Check variables and resize if necessary
+    scalar = np.isscalar(SA) and np.isscalar(CT) and np.isscalar(p)
+    SA, CT, p = np.broadcast_arrays(SA, CT, p)
+    input_nan = np.isnan(SA) | np.isnan(CT) | np.isnan(p)
+    infunnel = ((p <= 8000) &
+                (SA >= 0) &
+                (SA <= 42.2) &
+                (CT >= (-0.3595467 - 0.0553734 * SA)) &
+                ((p >= 5500) | (SA >= 0.006028 * (p - 500))) &
+                ((p >= 5500) | (CT <= (33.0 - 0.003818181818182 * p))) &
+                ((p <= 5500) | (SA >= 30.14)) &
+                ((p <= 5500) | (CT <= 12.0)))
+    infunnel = infunnel & np.logical_not(input_nan)
+    if scalar:
+        infunnel = bool(infunnel)
+    return infunnel
+
+
+def interp_SA_CT(SA, CT, p, p_i):
+    r"""TODO: Write docstring.
+    function [SA_i, CT_i] = interp_SA_CT(SA,CT,p,p_i)
+    interp_SA_CT                    linear interpolation to p_i on a cast
+    ==========================================================================
+    This function interpolates the cast with respect to the interpolating
+    variable p. This function finds the values of SA, CT at p_i on this cast.
+    """
+    return interp_S_T(SA, CT, p, p_i)
+
+
+def interp_S_T(S, T, z, znew, P=None):
+    r"""Linear interpolation of ndarrays *S* and *T* from *z* to *znew*.
+    Optionally interpolate a third ndarray, *P*.
+    *z* must be strictly increasing or strictly decreasing.  It must
+    be a 1-D array, and its length must match the last dimension
+    of *S* and *T*.
+    *znew* may be a scalar or a sequence.
+    It is assumed, but not checked, that *S*, *T*, and *z* are
+    all plain ndarrays, not masked arrays or other sequences.
+    Out-of-range values of *znew*, and *nan* in *S* and *T*,
+    yield corresponding *nan* in the output.
+    The basic algorithm is from scipy.interpolate.
+    """
+    isscalar = False
+    if not np.iterable(znew):
+        isscalar = True
+        znew = [znew]
+    znew = np.asarray(znew)
+    inverted = False
+    if z[1] - z[0] < 0:
+        inverted = True
+        z = z[::-1]
+        S = S[..., ::-1]
+        T = T[..., ::-1]
+        if P is not None:
+            P = P[..., ::-1]
+    if (np.diff(z) <= 0).any():
+        raise ValueError("z must be strictly increasing or decreasing")
+    hi = np.searchsorted(z, znew)
+    hi = hi.clip(1, len(z) - 1).astype(int)
+    lo = hi - 1
+    z_lo = z[lo]
+    z_hi = z[hi]
+    S_lo = S[lo]
+    S_hi = S[hi]
+    T_lo = T[lo]
+    T_hi = T[hi]
+    zratio = (znew - z_lo) / (z_hi - z_lo)
+    Si = S_lo + (S_hi - S_lo) * zratio
+    Ti = T_lo + (T_hi - T_lo) * zratio
+    if P is not None:
+        Pi = P[lo] + (P[hi] - P[lo]) * zratio
+    if inverted:
+        Si = Si[..., ::-1]
+        Ti = Ti[..., ::-1]
+        if P is not None:
+            Pi = Pi[..., ::-1]
+    outside = (znew < z.min()) | (znew > z.max())
+    if np.any(outside):
+        Si[..., outside] = np.nan
+        Ti[..., outside] = np.nan
+        if P is not None:
+            Pi[..., outside] = np.nan
+    if isscalar:
+        Si = Si[0]
+        Ti = Ti[0]
+        if P is not None:
+            Pi = Pi[0]
+    if P is None:
+        return Si, Ti
+    return Si, Ti, Pi
+
+
+def interp_ref_cast(spycnl, A="gn"):
+    r"""Translation of:
+    [SA_iref_cast, CT_iref_cast, p_iref_cast] = interp_ref_cast(spycnl, A)
+    interp_ref_cast            linear interpolation of the reference cast
+    ==========================================================================
+    This function interpolates the reference cast with respect to the
+    interpolating variable "spycnl".  This reference cast is at the location
+    188E,4N from the reference data set which underlies the Jackett &
+    McDougall (1997) Neutral Density computer code.  This function finds the
+    values of SA, CT and p on this reference cast which correspond to the
+    value of isopycnal which is passed to this function from the function
+    "geo_strf_isopycnal_CT".  The isopycnal could be either gamma_n or
+    sigma_2. If A is set to any of the following 's2','S2','sigma2','sigma_2'
+    the interpolation will take place in sigma 2 space, any other input
+    will result in the programme working in gamma_n space.
+    VERSION NUMBER: 3.0 (14th April, 2011)
+    REFERENCE:
+    Jackett, D. R. and T. J. McDougall, 1997: A neutral density variable
+    for the world<92>s oceans. Journal of Physical Oceanography, 27, 237-263.
+    FIXME? Do we need argument checking here to handle masked arrays,
+    etc.?  I suspect not, since I don't think this is intended to be
+    user-callable, but is instead used internally by user-callable
+    functions.
+    Note: The v3.03 matlab code is incorrectly using approximate numbers
+    for the gamma_n case, even when the sigma_2 case is in effect.
+    That bug is fixed here.
+    """
+    if A.lower() in ["s2", "sigma2", "sigma_2"]:
+        A = "s2"
+    gsw_data = read_data("gsw_data_v3_0.npz")
+    SA_ref = gsw_data.SA_ref_cast
+    CT_ref = gsw_data.CT_ref_cast
+    p_ref = gsw_data.p_ref_cast
+    if A == "s2":
+        zvar_ref = gsw_data.sigma_2_ref_cast
+    else:
+        zvar_ref = gsw_data.gamma_n_ref_cast
+    zvar_new = spycnl
+    Si, Ci, Pi = interp_S_T(SA_ref, CT_ref, zvar_ref, zvar_new, P=p_ref)
+    shallower = spycnl <= zvar_ref[0]
+    deeper = spycnl >= zvar_ref[-1]
+    if shallower.any():
+        Si[shallower] = SA_ref[0]
+        Ci[shallower] = CT_ref[0]
+        Pi[shallower] = p_ref[0]
+    if deeper.any():
+        Si[deeper] = SA_ref[-1]
+        Ci[deeper] = CT_ref[-1]
+        Pi[deeper] = p_ref[-1]
+    return Si, Ci, Pi
+
+
+def specvol_SSO_0_CT25(p):
+    r"""Calculates specific volume at the Standard Ocean Salinity (SSO) and
+    Conservative Temperature of zero degrees C (CT=0), as a function of
+    pressure (p [dbar]) or spec_vol_CT25(35.16504,0,p).
+    Parameters
+    ----------
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    specvol_SSO_0_CT25 : array_like
+                         Specific volume at (SSO, CT=0, p), 25-term equation.
+                         [m :sup:`3` kg :sup:`-1`]
+    Notes
+    -----
+    It uses a streamlined version of the 25-term CT version of specific volume
+    that is, a streamlined version of the code "rho_alpha_beta_CT25(SA,CT,p)"
+    Modifications
+    """
+    p = np.asanyarray(p)
+    # No need to strip mask and replace it here; the calculation is simple.
+    specvol_SSO_0_CT25 = ((1. + SSO * (2.0777716085618458e-003 + np.sqrt(SSO) *
+                          3.4688210757917340e-006) + p *
+                           6.8314629554123324e-006) /
+                          (9.9984380290708214e+002 + SSO *
+                           (2.8925731541277653e+000 + SSO *
+                            1.9457531751183059e-003) + p *
+                           (1.1930681818531748e-002 + SSO *
+                            5.9355685925035653e-006 + p *
+                            -2.5943389807429039e-008)))
+    return specvol_SSO_0_CT25
+
+
+# Salinity lib functions
+def specvol_SSO_0_p(p):
+    r"""This function calculates specific volume at the Standard Ocean
+    Salinity, SSO, and at a Conservative Temperature of zero degrees C, as a
+    function of pressure, p, in dbar, using a streamlined version of the
+    48-term CT version of specific volume, that is, a streamlined version of
+    the code "specvol(SA, CT, p)".
+    Modifications:
+    """
+    v01 = 9.998420897506056e+2
+    v05 = -6.698001071123802
+    v08 = -3.988822378968490e-2
+    v12 = -2.233269627352527e-2
+    v15 = -1.806789763745328e-4
+    v17 = -3.087032500374211e-7
+    v20 = 1.550932729220080e-10
+    v21 = 1.0
+    v26 = -7.521448093615448e-3
+    v31 = -3.303308871386421e-5
+    v36 = 5.419326551148740e-6
+    v37 = -2.742185394906099e-5
+    v41 = -1.105097577149576e-7
+    v43 = -1.119011592875110e-10
+    v47 = -1.200507748551599e-15
+    return ((v21 + SSO * (v26 + v36 * SSO + v31 * np.sqrt(SSO)) + p *
+            (v37 + v41 * SSO + p * (v43 + v47 * p))) / (v01 + SSO *
+            (v05 + v08 * np.sqrt(SSO)) + p * (v12 + v15 * SSO + p *
+            (v17 + v20 * SSO))))
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/neutral_nonlinear_48.py b/gsw/gibbs/neutral_nonlinear_48.py
new file mode 100644
index 0000000..a27a4f8
--- /dev/null
+++ b/gsw/gibbs/neutral_nonlinear_48.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+__all__ = ['cabbeling',  # TODO
+           'isopycnal_slope_ratio',  # TODO
+           'isopycnal_vs_ntp_CT_ratio',  # TODO
+           'ntp_pt_vs_CT_ratio',  # TODO
+           'thermobaric']  # TODO
+
+
+def cabbeling():
+    pass
+
+
+def isopycnal_slope_ratio():
+    pass
+
+
+def isopycnal_vs_ntp_CT_ratio():
+    pass
+
+
+def ntp_pt_vs_CT_ratio():
+    pass
+
+
+def thermobaric():
+    pass
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/practical_salinity.py b/gsw/gibbs/practical_salinity.py
new file mode 100644
index 0000000..0fec4a7
--- /dev/null
+++ b/gsw/gibbs/practical_salinity.py
@@ -0,0 +1,754 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .library import Hill_ratio_at_SP2
+from ..utilities import match_args_return
+
+__all__ = ['C_from_SP',
+           'R_from_SP',
+           'SK_from_SP',
+           'SP_from_C',
+           'SP_from_R',
+           'SP_from_SK',
+           'SP_salinometer']
+
+# Constants.
+a = (0.0080, -0.1692, 25.3851, 14.0941, -7.0261, 2.7081)
+b = (0.0005, -0.0056, -0.0066, -0.0375, 0.0636, -0.0144)
+c = (0.6766097, 2.00564e-2, 1.104259e-4, -6.9698e-7, 1.0031e-9)
+d = (3.426e-2, 4.464e-4, 4.215e-1, -3.107e-3)
+e = (2.070e-5, -6.370e-10, 3.989e-15)
+P = (4.577801212923119e-3, 1.924049429136640e-1, 2.183871685127932e-5,
+     -7.292156330457999e-3, 1.568129536470258e-4, -1.478995271680869e-6,
+     9.086442524716395e-4, -1.949560839540487e-5, -3.223058111118377e-6,
+     1.175871639741131e-7, -7.522895856600089e-5, -2.254458513439107e-6,
+     6.179992190192848e-7, 1.005054226996868e-8, -1.923745566122602e-9,
+     2.259550611212616e-6, 1.631749165091437e-7, -5.931857989915256e-9,
+     -4.693392029005252e-9, 2.571854839274148e-10, 4.198786822861038e-12)
+q = (5.540896868127855e-5, 2.015419291097848e-1, -1.445310045430192e-5,
+     -1.567047628411722e-2, 2.464756294660119e-4, -2.575458304732166e-7,
+     5.071449842454419e-3, -9.081985795339206e-5, -3.635420818812898e-6,
+     2.249490528450555e-8, -1.143810377431888e-3, 2.066112484281530e-5,
+     7.482907137737503e-7, 4.019321577844724e-8, -5.755568141370501e-10,
+     1.120748754429459e-4, -2.420274029674485e-6, -4.774829347564670e-8,
+     -4.279037686797859e-9, -2.045829202713288e-10, 5.025109163112005e-12)
+r = (3.432285006604888e-3, 1.672940491817403e-1, 2.640304401023995e-5,
+     1.082267090441036e-1, -6.296778883666940e-5, -4.542775152303671e-7,
+     -1.859711038699727e-1, 7.659006320303959e-4, -4.794661268817618e-7,
+     8.093368602891911e-9, 1.001140606840692e-1, -1.038712945546608e-3,
+     -6.227915160991074e-6, 2.798564479737090e-8, -1.343623657549961e-10,
+     1.024345179842964e-2, 4.981135430579384e-4, 4.466087528793912e-6,
+     1.960872795577774e-8, -2.723159418888634e-10, 1.122200786423241e-12)
+u = (5.180529787390576e-3, 1.052097167201052e-3, 3.666193708310848e-5,
+     7.112223828976632, -3.631366777096209e-4, -7.336295318742821e-7,
+     -1.576886793288888e+2, -1.840239113483083e-3, 8.624279120240952e-6,
+     1.233529799729501e-8, 1.826482800939545e+3, 1.633903983457674e-1,
+     -9.201096427222349e-5, -9.187900959754842e-8, -1.442010369809705e-10,
+     -8.542357182595853e+3, -1.408635241899082, 1.660164829963661e-4,
+     6.797409608973845e-7, 3.345074990451475e-10, 8.285687652694768e-13)
+k = 0.0162
+
+a, b, c, d, e, P, q, r, u, k = map(np.asarray, (a, b, c, d, e, P, q, r, u, k))
+
+
+def C_from_SP(SP, t, p):
+    r"""Calculates conductivity, C, from (SP, t, p) using PSS-78 in the range
+    2 < SP < 42. If the input Practical Salinity is less than 2 then a modified
+    form of the Hill et al. (1986) fomula is used for Practical Salinity. The
+    modification of the Hill et al. (1986) expression is to ensure that it is
+    exactly consistent with PSS-78 at SP = 2.
+
+    The conductivity ratio returned by this function is consistent with the
+    input value of Practical Salinity, SP, to 2x10^-14 psu over the full range
+    of input parameters (from pure fresh water up to SP = 42 psu). This error
+    of 2x10^-14 psu is machine precision at typical seawater salinities.  This
+    accuracy is achieved by having four different polynomials for the starting
+    value of Rtx (the square root of Rt) in four different ranges of SP, and by
+    using one and a half iterations of a computationally efficient modified
+    Newton-Raphson technique to find the root of the equation.
+
+    Parameters
+    ----------
+    SP : array
+         Practical Salinity [psu (PSS-78), unitless]
+    t : array
+        in-situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array
+        sea pressure [dbar]
+        (i.e. absolute pressure - 10.1325 dbar)
+
+    Returns
+    -------
+    C : array
+        conductivity [mS cm :sup:`-1`]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    Note that strictly speaking PSS-78 (Unesco, 1983) defines Practical
+    Salinity in terms of the conductivity ratio, R, without actually
+    specifying the value of C(35,15,0) (which we currently take to be
+    42.9140 mS/cm).
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] Hill, K.D., T.M. Dauphinee and D.J. Woods, 1986: The extension of
+    the Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng.,
+    OE-11, 1, 109 - 112.
+
+    .. [2] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix E.
+
+    .. [3] Unesco, 1983: Algorithms for computation of fundamental properties
+    of seawater.  Unesco Technical Papers in Marine Science, 44, 53 pp.
+    """
+
+    C = 42.9140 * R_from_SP(SP, t, p)
+
+    return C
+
+
+ at match_args_return
+def R_from_SP(SP, t, p):
+    r"""Calculates conductivity ratio from (SP, t, p) using PSS-78 in the range
+    2 < SP < 42.  If the input Practical Salinity is less than 2 then a
+    modified form of the Hill et al. (1986) formula is used for Practical
+    Salinity.  The modification of the Hill et al. (1986) expression is to
+    ensure that it is exactly consistent with PSS-78 at SP = 2.
+
+    The conductivity ratio returned by this function is consistent with the
+    input value of Practical Salinity, SP, to 2x10^-14 psu over the full range
+    of input parameters (from pure fresh water up to SP = 42 psu).  This error
+    of 2x10^-14 psu is machine precision at typical seawater salinities.  This
+    accuracy is achieved by having four different polynomials for the starting
+    value of Rtx (the square root of Rt) in four different ranges of SP, and by
+    using one and a half iterations of a computationally efficient modified
+    Newton-Raphson technique to find the root of the equation.
+
+    Parameters
+    ----------
+    SP : array
+         Practical Salinity [psu (PSS-78), unitless]
+    t : array_like
+        in-situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array
+        sea pressure [dbar]
+        (i.e. absolute pressure - 10.1325 dbar)
+
+    Returns
+    -------
+    R : array_like
+        conductivity ratio [unitless]
+
+    Examples
+    --------
+    TODO
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    Strictly speaking PSS-78 (Unesco, 1983) defines Practical Salinity in terms
+    of the conductivity ratio, R, without actually specifying the value of
+    C(35, 15, 0) (which we currently take to be 42.9140 mS cm^-1.
+    Culkin and Smith, 1980).
+
+    References
+    ----------
+    .. [1] Culkin and Smith, 1980:  Determination of the Concentration of
+    Potassium Chloride Solution Having the Same Electrical Conductivity, at
+    15C and Infinite Frequency, as Standard Seawater of Salinity 35.0000
+    (Chlorinity 19.37394), IEEE J. Oceanic Eng, 5, 22-23.
+
+    .. [2] Hill, K.D., T.M. Dauphinee & D.J. Woods, 1986: The extension of the
+    Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng.,
+    11, 109 - 112.
+
+    .. [3] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.  Appendix E.
+
+    .. [4] Unesco, 1983: Algorithms for computation of fundamental properties
+    of seawater.  Unesco Technical Papers in Marine Science, 44, 53 pp.
+
+    Modifications:
+    2011-04-06. Paul Barker, Trevor McDougall and Rich Pawlowicz.
+    """
+
+    # These few lines ensure that SP is non-negative.
+    if (SP < 0).any():
+        raise ValueError('R_from_SP: SP must be non-negative!')
+
+    SP, t, p = np.broadcast_arrays(SP, t, p)
+
+    # Setting up the constants
+    t68 = t * 1.00024
+    ft68 = (t68 - 15) / (1 + k * (t68 - 15))
+
+    x = np.sqrt(SP)
+    Rtx = np.zeros_like(SP) * np.NaN
+
+    # Finding the starting value of Rtx, the square root of Rt, using four
+    # different polynomials of SP and t68.
+    # TODO: Test case that cover all those "ifs"
+    I = SP >= 9
+    if I.any():
+        Rtx[I] = (P[0] + x[I] * (P[1] + P[4] * t68[I] + x[I] * (P[3] + P[7] *
+                  t68[I] + x[I] * (P[6] + P[11] * t68[I] + x[I] * (P[10] +
+                  P[16] * t68[I] + x[I] * P[15])))) + t68[I] * (P[2] +
+                  t68[I] * (P[5] + x[I] * x[I] * (P[12] + x[I] * P[17]) +
+                  P[8] * x[I] + t68[I] * (P[9] + x[I] * (P[13] + x[I] *
+                  P[18]) + t68[I] * (P[14] + P[19] * x[I] + P[20] * t68[I])))))
+
+    I = np.logical_and(SP >= 0.25, SP < 9)
+    if I.any():
+        Rtx[I] = (q[0] + x[I] * (q[1] + q[4] * t68[I] + x[I] * (q[3] + q[7] *
+                  t68[I] + x[I] * (q[6] + q[11] * t68[I] + x[I] * (q[10] +
+                  q[16] * t68[I] + x[I] * q[15])))) + t68[I] * (q[2] +
+                  t68[I] * (q[5] + x[I] * x[I] * (q[12] + x[I] * q[17]) +
+                  q[8] * x[I] + t68[I] * (q[9] + x[I] * (q[13] + x[I] *
+                  q[18]) + t68[I] * (q[14] + q[19] * x[I] + q[20] * t68[I])))))
+
+    I = np.logical_and(SP >= 0.003, SP < 0.25)
+    if I.any():
+        Rtx[I] = (r[0] + x[I] * (r[1] + r[4] * t68[I] + x[I] * (r[3] + r[7] *
+                  t68[I] + x[I] * (r[6] + r[11] * t68[I] + x[I] * (r[10] +
+                  r[16] * t68[I] + x[I] * r[15])))) + t68[I] * (r[2] +
+                  t68[I] * (r[5] + x[I] * x[I] * (r[12] + x[I] * r[17]) +
+                  r[8] * x[I] + t68[I] * (r[9] + x[I] * (r[13] + x[I] *
+                  r[18]) + t68[I] * (r[14] + r[19] * x[I] + r[20] * t68[I])))))
+
+    I = SP < 0.003
+    if I.any():
+        Rtx[I] = (u[0] + x[I] * (u[1] + u[4] * t68[I] + x[I] * (u[3] + u[7] *
+                  t68[I] + x[I] * (u[6] + u[11] * t68[I] + x[I] * (u[10] +
+                  u[16] * t68[I] + x[I] * u[15])))) + t68[I] * (u[2] +
+                  t68[I] * (u[5] + x[I] * x[I] * (u[12] + x[I] * u[17]) +
+                  u[8] * x[I] + t68[I] * (u[9] + x[I] * (u[13] + x[I] *
+                  u[18]) + t68[I] * (u[14] + u[19] * x[I] + u[20] * t68[I])))))
+
+    # Finding the starting value of dSP_dRtx, the derivative of SP with
+    # respect to Rtx.
+    dSP_dRtx = (a[1] + (2 * a[2] + (3 * a[3] + (4 * a[4] + 5 * a[5] * Rtx) *
+                Rtx) * Rtx) * Rtx + ft68 * (b[1] + (2 * b[2] + (3 * b[3] +
+                (4 * b[4] + 5 * b[5] * Rtx) * Rtx) * Rtx) * Rtx))
+
+    # TODO: Test case that cover all those "ifs"
+    I2 = SP < 2
+    if I2.any():
+        x = 400 * (Rtx[I2] ** 2)
+        sqrty = 10 * Rtx[I2]
+        part1 = 1 + x * (1.5 + x)
+        part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+        Hill_ratio = Hill_ratio_at_SP2(t[I2])
+        dSP_dRtx[I2] = (dSP_dRtx[I2] + a[0] * 800 * Rtx[I2] * (1.5 + 2 * x) /
+                        (part1 ** 2) + b[0] * ft68[I2] * (10 + sqrty * (20 +
+                        30 * sqrty)) / (part2 ** 2))
+
+        dSP_dRtx[I2] = Hill_ratio * dSP_dRtx[I2]
+
+    """One iteration through the modified Newton-Raphson method achieves an
+    error in Practical Salinity of about 10^-12 for all combinations of the
+    inputs.  One and a half iterations of the modified Newton-Raphson method
+    achieves a maximum error in terms of Practical Salinity of better than
+    2x10^-14 everywhere.
+
+    We recommend one and a half iterations of the modified Newton-Raphson
+    method."""
+
+    # Begin the modified Newton-Raphson method.
+    SP_est = (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) *
+              Rtx) * Rtx) * Rtx + ft68 * (b[0] + (b[1] + (b[2] + (b[3] +
+              (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx))
+
+    # TODO: Test case that cover all those "ifs"
+    I2 = SP_est < 2
+    if I2.any():
+        x = 400 * (Rtx[I2] ** 2)
+        sqrty = 10 * Rtx[I2]
+        part1 = 1 + x * (1.5 + x)
+        part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+        SP_Hill_raw = SP_est[I2] - a[0] / part1 - b[0] * ft68[I2] / part2
+        Hill_ratio = Hill_ratio_at_SP2(t[I2])
+        SP_est[I2] = Hill_ratio * SP_Hill_raw
+
+    Rtx_old = Rtx
+    Rtx = Rtx_old - (SP_est - SP) / dSP_dRtx
+
+    # This mean value of Rtx, Rtxm, is the value of Rtx at which the
+    # derivative dSP_dRtx is evaluated.
+    Rtxm = 0.5 * (Rtx + Rtx_old)
+
+    dSP_dRtx = (a[1] +
+                (2 * a[2] + (3 * a[3] + (4 * a[4] + 5 * a[5] * Rtxm) * Rtxm) *
+                 Rtxm) * Rtxm + ft68 *
+                (b[1] + (2 * b[2] + (3 * b[3] + (4 * b[4] + 5 * b[5] * Rtxm) *
+                                     Rtxm) * Rtxm) * Rtxm))
+
+    # TODO: Test case that cover all those "ifs"
+    I2 = SP_est < 2
+    if I2.any():
+        x = 400 * (Rtxm[I2] ** 2)
+        sqrty = 10 * Rtxm[I2]
+        part1 = 1 + x * (1.5 + x)
+        part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+        dSP_dRtx[I2] = (dSP_dRtx[I2] + a[0] * 800 * Rtxm[I2] * (1.5 + 2 *
+                        x) / (part1 ** 2) + b[0] * ft68[I2] * (10 + sqrty *
+                        (20 + 30 * sqrty)) / (part2 ** 2))
+        Hill_ratio = Hill_ratio_at_SP2(t[I2])
+        dSP_dRtx[I2] = Hill_ratio * dSP_dRtx[I2]
+
+    # End of the one full iteration of the modified Newton-Raphson technique.
+    Rtx = Rtx_old - (SP_est - SP) / dSP_dRtx  # Updated Rtx
+
+    #  Now we do another half iteration of the modified Newton-Raphson
+    #  technique, making a total of one and a half modified N-R iterations.
+    SP_est = (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) *
+                              Rtx) * Rtx) * Rtx + ft68 *
+              (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) *
+                               Rtx) * Rtx) * Rtx))
+
+    # TODO: Test case that cover all those "ifs"
+    I2 = SP_est < 2
+    if I2.any():
+        x = 400 * (Rtx[I2] ** 2)
+        sqrty = 10 * Rtx[I2]
+        part1 = 1 + x * (1.5 + x)
+        part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+        SP_Hill_raw = SP_est[I2] - a[0] / part1 - b[0] * ft68[I2] / part2
+        Hill_ratio = Hill_ratio_at_SP2(t[I2])
+        SP_est[I2] = Hill_ratio * SP_Hill_raw
+
+    Rtx = Rtx - (SP_est - SP) / dSP_dRtx
+
+    """ TODO: add this as a kw.
+    Return the error, SP_error, in Rtx (in terms of psu).
+
+    SP_est = (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) *
+            Rtx) * Rtx) * Rtx + ft68 * (b[0] + (b[1] + (b[2] + (b[3] +
+            (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx))
+    I2 = SP_est < 2
+    if I2.any():
+        x = 400 * (Rtx[I2] ** 2)
+        sqrty = 10 * Rtx[I2]
+        part1 = 1 + x * (1.5 + x)
+        part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+        SP_Hill_raw = SP_est[I2] - a[0] / part1 - b[0] * ft68[I2] / part2
+        Hill_ratio = Hill_ratio_at_SP2(t[I2])
+        SP_est[I2] = Hill_ratio * SP_Hill_raw
+
+    SP_error = np.abs(SP - SP_est)
+
+    This is the end of the error testing
+    """
+
+    # Now go from Rtx to Rt and then to the conductivity ratio R at pressure p.
+    Rt = Rtx ** 2
+    A = d[2] + d[3] * t68
+    B = 1 + d[0] * t68 + d[1] * t68 ** 2
+    C = p * (e[0] + e[1] * p + e[2] * p ** 2)
+    # rt_lc (i.e. rt_lower_case) corresponds to rt as defined in the
+    # UNESCO 44 (1983) routines.
+    rt_lc = c[0] + (c[1] + (c[2] + (c[3] + c[4] * t68) * t68) * t68) * t68
+
+    D = B - A * rt_lc * Rt
+    E = rt_lc * Rt * A * (B + C)
+    Ra = np.sqrt(D ** 2 + 4 * E) - D
+
+    return 0.5 * Ra / A
+
+
+ at match_args_return
+def SK_from_SP(SP):
+    r"""Calculates Knudsen Salinity from Practical Salinity.
+
+    Parameters
+    ----------
+    SP : array
+         Practical Salinity [psu (PSS-78), unitless]
+
+    Returns
+    -------
+    SK : array_like
+         Knudsen Salinity [parts per thousand, ppt]
+
+    Examples
+    --------
+    TODO
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.  See Appendix A.3.
+
+    Modifications:
+    2011-11-16. Trevor McDougall and Paul Barker.
+    """
+    SP = np.maximum(SP, 0)  # Ensure that SP is non-negative.
+
+    return 0.03 + SP * (1.805 / 1.80655)
+
+
+ at match_args_return
+def SP_from_C(C, t, p):
+    r"""Calculates Practical Salinity, SP, from conductivity, C, primarily
+    using the PSS-78 algorithm.  Note that the PSS-78 algorithm for Practical
+    Salinity is only valid in the range 2 < SP < 42.  If the PSS-78 algorithm
+    produces a Practical Salinity that is less than 2 then the Practical
+    Salinity is recalculated with a modified form of the Hill et al. (1986)
+    formula. The modification of the Hill et al. (1986) expression is to ensure
+    that it is exactly consistent with PSS-78 at SP = 2.  Note that the input
+    values of conductivity need to be in units of mS/cm (not S/m).
+
+    Parameters
+    ----------
+    C : array
+        conductivity [mS cm :sup:`-1`]
+    t : array
+        in-situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array
+        sea pressure [dbar]
+        (i.e. absolute pressure - 10.1325 dbar)
+
+    Returns
+    -------
+    SP : array
+         Practical Salinity [psu (PSS-78), unitless]
+
+    Examples
+    --------
+    TODO
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    References
+    ----------
+    .. [1] Culkin and Smith, 1980:  Determination of the Concentration of
+    Potassium Chloride Solution Having the Same Electrical Conductivity, at
+    15C and Infinite Frequency, as Standard Seawater of Salinity 35.0000
+    (Chlorinity 19.37394), IEEE J. Oceanic Eng, 5, 22-23.
+
+    .. [2] Hill, K.D., T.M. Dauphinee & D.J. Woods, 1986: The extension of the
+    Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng., 11,
+    109 - 112.
+
+    .. [3] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.  Appendix E.
+
+    .. [4] Unesco, 1983: Algorithms for computation of fundamental properties
+    of seawater.  Unesco Technical Papers in Marine Science, 44, 53 pp.
+
+    Modifications:
+    2011-04-01. Paul Barker, Trevor McDougall and Rich Pawlowicz.
+    """
+
+    C, t, p = np.broadcast_arrays(C, t, p)
+
+    t68 = t * 1.00024
+    ft68 = (t68 - 15) / (1 + k * (t68 - 15))
+
+    # The dimensionless conductivity ratio, R, is the conductivity input, C,
+    # divided by the present estimate of C(SP=35, t_68=15, p=0) which is
+    # 42.9140 mS/cm (=4.29140 S/m), (Culkin and Smith, 1980).
+
+    R = 0.023302418791070513 * C  # 0.023302418791070513 = 1./42.9140
+
+    # rt_lc corresponds to rt as defined in the UNESCO 44 (1983) routines.
+    rt_lc = c[0] + (c[1] + (c[2] + (c[3] + c[4] * t68) * t68) * t68) * t68
+    Rp = (1 + (p * (e[0] + e[1] * p + e[2] * p ** 2)) /
+         (1 + d[0] * t68 + d[1] * t68 ** 2 + (d[2] + d[3] * t68) * R))
+    Rt = R / (Rp * rt_lc)
+
+    Rt[Rt < 0] = np.ma.masked
+    Rtx = np.sqrt(Rt)
+
+    SP = (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) *
+                  Rtx) * Rtx + ft68 *
+          (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) *
+                   Rtx) * Rtx))
+
+    # The following section of the code is designed for SP < 2 based on the
+    # Hill et al. (1986) algorithm.  This algorithm is adjusted so that it is
+    # exactly equal to the PSS-78 algorithm at SP = 2.
+
+    I2, = np.nonzero(np.ravel(SP) < 2)
+    if len(I2) > 0:
+        Hill_ratio = Hill_ratio_at_SP2(t[I2])
+        x = 400 * Rt[I2]
+        sqrty = 10 * Rtx[I2]
+        part1 = 1 + x * (1.5 + x)
+        part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+        SP_Hill_raw = SP[I2] - a[0] / part1 - b[0] * ft68[I2] / part2
+        SP[I2] = Hill_ratio * SP_Hill_raw
+
+    SP = np.maximum(SP, 0)  # Ensure that SP is non-negative.
+
+    return SP
+
+
+ at match_args_return
+def SP_from_R(R, t, p):
+    r"""Calculates Practical Salinity, SP, from the conductivity ratio, R,
+    primarily using the PSS-78 algorithm.  Note that the PSS-78 algorithm for
+    Practical Salinity is only valid in the range 2 < SP < 42.  If the PSS-78
+    algorithm produces a Practical Salinity that is less than 2 then the
+    Practical Salinity is recalculated with a modified form of the Hill et al.
+    (1986) formula.  The modification of the Hill et al. (1986) expression are
+    to ensure that it is exactly consistent with PSS-78 at SP = 2.
+
+    Parameters
+    ----------
+    R : array_like
+        conductivity ratio [unitless]
+    t : array_like
+        in-situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array
+        sea pressure [dbar]
+        (i.e. absolute pressure - 10.1325 dbar)
+
+    Returns
+    -------
+    SP : array
+         Practical Salinity [psu (PSS-78), unitless]
+
+    Examples
+    --------
+    TODO
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    References
+    ----------
+    .. [1] Culkin and Smith, 1980:  Determination of the Concentration of
+    Potassium Chloride Solution Having the Same Electrical Conductivity, at
+    15C and Infinite Frequency, as Standard Seawater of Salinity 35.0000
+    (Chlorinity 19.37394), IEEE J. Oceanic Eng, 5, 22-23.
+
+    .. [2] Hill, K.D., T.M. Dauphinee & D.J. Woods, 1986: The extension of the
+    Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng.,
+    11, 109 - 112.
+
+    .. [3] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.  Appendix E.
+
+    .. [4] Unesco, 1983: Algorithms for computation of fundamental properties
+    of seawater.  Unesco Technical Papers in Marine Science, 44, 53 pp.
+
+    Modifications:
+    2011-04-01. Paul Barker, Trevor McDougall and Rich Pawlowicz.
+    """
+
+    R, t, p = np.broadcast_arrays(R, t, p)
+
+    t68 = t * 1.00024
+    ft68 = (t68 - 15) / (1 + k * (t68 - 15))
+
+    # rt_lc corresponds to rt as defined in the UNESCO 44 (1983) routines.
+    rt_lc = c[0] + (c[1] + (c[2] + (c[3] + c[4] * t68) * t68) * t68) * t68
+    Rp = (1 + (p * (e[0] + e[1] * p + e[2] * p ** 2)) /
+         (1 + d[0] * t68 + d[1] * t68 ** 2 + (d[2] + d[3] * t68) * R))
+    Rt = R / (Rp * rt_lc)
+
+    Rt[Rt < 0] = np.ma.masked
+    Rtx = np.sqrt(Rt)
+
+    SP = (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) *
+                  Rtx) * Rtx + ft68 *
+          (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) *
+                   Rtx) * Rtx))
+
+    # The following section of the code is designed for SP < 2 based on the
+    # Hill et al. (1986) algorithm.  This algorithm is adjusted so that it is
+    # exactly equal to the PSS-78 algorithm at SP = 2.
+
+    I2 = SP < 2
+    if I2.any():
+        Hill_ratio = Hill_ratio_at_SP2(t[I2])
+        x = 400 * Rt[I2]
+        sqrty = 10 * Rtx[I2]
+        part1 = 1 + x * (1.5 + x)
+        part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+        SP_Hill_raw = SP[I2] - a[0] / part1 - b[0] * ft68[I2] / part2
+        SP[I2] = Hill_ratio * SP_Hill_raw
+
+    SP = np.maximum(SP, 0)  # Ensure that SP is non-negative.
+
+    return SP
+
+
+ at match_args_return
+def SP_from_SK(SK):
+    r"""Calculates Practical Salinity from Knudsen Salinity.
+
+    Parameters
+    ----------
+    SK : array_like
+         Knudsen Salinity [parts per thousand, ppt]
+
+    Returns
+    -------
+    SP : array
+         Practical Salinity [psu (PSS-78), unitless]
+
+    Examples
+    --------
+    TODO
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.  See Appendix A.3.
+
+    Modifications:
+    2011-11-16. Trevor McDougall and Paul Barker.
+    """
+
+    SP = (SK - 0.03) * (1.80655 / 1.805)
+    return np.maximum(SP, 0)  # Ensure that SP is non-negative.
+
+
+ at match_args_return
+def SP_salinometer(Rt, t):
+    r"""Calculates Practical Salinity SP from a salinometer, primarily using
+    the PSS-78 algorithm.  Note that the PSS-78 algorithm for Practical
+    Salinity is only valid in the range 2 < SP < 42.  If the PSS-78 algorithm
+    produces a Practical Salinity that is less than 2 then the Practical
+    Salinity is recalculated with a modified form of the Hill et al. (1986)
+    formula. The modification of the Hill et al. (1986) expression is to
+    ensure that it is exactly consistent with PSS-78 at SP = 2.
+
+    A laboratory salinometer has the ratio of conductivities, Rt, as an output,
+    and the present function uses this conductivity ratio and the temperature t
+    of the salinometer bath as the two input variables.
+
+    Parameters
+    ----------
+    Rt : array
+         C(SP,t_68,0)/C(SP=35,t_68,0) [unitless]
+         conductivity ratio
+         :math:`R = \frac{C(S, t_68, 0)}{C(35, 15(IPTS-68),0)} [unitless]
+
+    t : array
+        Temperature of the bath of the salinometer [:math:`^\circ` C (ITS-90)]
+
+    Returns
+    -------
+    SP : array
+         Practical Salinity [psu (PSS-78), unitless]
+
+    See Also
+    --------
+    TODO: sw.sals
+
+    Notes
+    -----
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    -----------
+    ..[1] Fofonoff, P. and R.C. Millard Jr. 1983: Algorithms for computation of
+    fundamental properties of seawater.  Unesco Tech. Pap. in Mar. Sci., 44,
+    53 pp.
+
+    ..[2] Hill, K.D., T.M. Dauphinee & D.J. Woods, 1986: The extension of the
+    Practical Salinity Scale 1978 to low salinities. IEEE J. Oceanic Eng., 11,
+    109 - 112.
+
+    .. [3] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix E of this TEOS-10 Manual, and in
+    particular, Eqns. (E.2.1) and (E.2.6).
+
+    Modifications:
+    2011-04-30. Paul Barker, Trevor McDougall and Rich Pawlowicz. Version 3.0
+    """
+
+    Rt, t = np.broadcast_arrays(Rt, t)
+
+    t68 = t * 1.00024
+    ft68 = (t68 - 15) / (1 + k * (t68 - 15))
+
+    Rt[Rt < 0] = np.ma.masked
+    Rtx = np.sqrt(Rt)
+
+    SP = (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) *
+                  Rtx) * Rtx + ft68 *
+          (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) *
+                   Rtx) * Rtx))
+
+    """The following section of the code is designed for SP < 2 based on the
+    Hill et al. (1986) algorithm.  This algorithm is adjusted so that it is
+    exactly equal to the PSS-78 algorithm at SP = 2."""
+
+    I2 = SP < 2
+    if I2.any():
+        Hill_ratio = Hill_ratio_at_SP2(t[I2])
+        x = 400 * Rt[I2]
+        sqrty = 10 * Rtx[I2]
+        part1 = 1 + x * (1.5 + x)
+        part2 = 1 + sqrty * (1 + sqrty * (1 + sqrty))
+        SP_Hill_raw = SP[I2] - a[0] / part1 - b[0] * ft68[I2] / part2
+        SP[I2] = Hill_ratio * SP_Hill_raw
+    # Ensure that SP is non-negative.
+    SP = np.maximum(SP, 0)
+    return SP
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/steric.py b/gsw/gibbs/steric.py
new file mode 100644
index 0000000..62284a7
--- /dev/null
+++ b/gsw/gibbs/steric.py
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+from ..utilities import match_args_return
+from .geostrophic_48 import geo_strf_dyn_height
+
+__all__ = ['steric_height']
+
+
+ at match_args_return
+def steric_height(SA, CT, p, p_ref):
+    r"""Calculates steric height anomaly as the pressure integral of specific
+    volume anomaly from the pressure p of the "bottle" to the reference
+    pressure p_ref, divided by the constant value of the gravitational
+    acceleration, 9.7963 m s^-2.  That is, this function returns the dynamic
+    height anomaly divided by 9.7963 m s^-2; this being  the gravitational
+    acceleration averaged over the surface of the global ocean (see page 46 of
+    Griffies, 2004).  Hence, steric_height is the steric height anomaly with
+    respect to a given reference pressure p_ref.
+
+    Dynamic height anomaly is the geostrophic streamfunction for the difference
+    between the horizontal velocity at the pressure concerned, p, and the
+    horizontal velocity at p_ref.  Dynamic height anomaly is the exact
+    geostrophic streamfunction in isobaric surfaces even though the
+    gravitational acceleration varies with latitude and pressure.  Steric
+    height anomaly, being simply proportional to dynamic height anomaly, is
+    also an exact geostrophic streamfunction in an isobaric surface (up to the
+    constant of proportionality, 9.7963 m s^-2).
+
+    Note however that steric_height is not exactly the height (in meters) of an
+    isobaric surface above a geopotential surface.  It is tempting to divide
+    dynamic height anomaly by the local value of the gravitational
+    acceleration, but doing so robs the resulting quantity of either being
+
+    (i)  an exact geostrophic streamfunction, or
+    (ii) exactly the height of an isobaric surface above a geopotential
+    surface.
+
+    By using a constant value of the gravitational acceleration, we have
+    retained the first of these two properties.  So it should be noted that
+    because of the variation of the gravitational acceleration with latitude,
+    steric_height does not exactly represent the height of an isobaric surface
+    above a geopotential surface under the assumption of geostropy.
+
+    The reference values used for the specific volume anomaly are
+    SSO = 35.16504 g/kg and CT = 0 deg C.  This function calculates specific
+    volume anomaly using the computationally efficient 48-term expression for
+    specific volume of McDougall et al. (2011).  Note that the 48-term equation
+    has been fitted in a restricted range of parameter space, and is most
+    accurate inside the "oceanographic funnel" described in McDougall et al.
+    (2011) and IOC et al. (2010).  For dynamical oceanography we may take the
+    48-term rational function expression for density as essentially reflecting
+    the full accuracy of TEOS-10.  The GSW internal library function
+    "infunnel(SA,CT,p)" is available to be used if one wants to test if some of
+    one's data lies outside this "funnel".
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    p_ref : int, float, optional
+        reference pressure, default = 0
+
+    Returns
+    -------
+    steric_height : array_like
+                    dynamic height anomaly divided by 9.7963 m s^-2  [m]
+
+    Notes
+    -----
+    If p_ref exceeds the pressure of the deepest "bottle" on a vertical
+    profile, the steric height anomaly for each "bottle" on the whole vertical
+    profile is returned as NaN.
+
+    See Also
+    --------
+    TODO
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.27.
+
+    .. [2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of seawater
+    in terms of Conservative Temperature, and related properties of seawater.
+
+    .. [3] Griffies, S. M., 2004: Fundamentals of Ocean Climate Models.
+    Princeton, NJ: Princeton University Press, 518 pp + xxxiv.
+
+    Modifications:
+    2010-05-20. Trevor McDougall and Paul Barker.
+    """
+
+    p_ref = np.asanyarray(p_ref)
+
+    p_ref = np.unique(p_ref)
+
+    if not np.isscalar(p_ref):
+        raise ValueError('The reference pressure p_ref must be unique')
+
+    if (p_ref < 0).any():
+        raise ValueError('The reference pressure p_ref must be positive')
+
+    if (SA < 0).any():
+        raise ValueError('The Absolute Salinity must be positive!')
+
+    # Start of the calculation.
+    if p.max() < p_ref.max():
+        raise ValueError('The reference pressure p_ref is deeper than bottles')
+
+    dynamic_height_anomaly = geo_strf_dyn_height(SA, CT, p, p_ref)
+    const_grav = 9.7963  # Griffies, 2004.
+
+    return dynamic_height_anomaly / const_grav
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/thermodynamics_from_t.py b/gsw/gibbs/thermodynamics_from_t.py
new file mode 100644
index 0000000..c17d6b0
--- /dev/null
+++ b/gsw/gibbs/thermodynamics_from_t.py
@@ -0,0 +1,1750 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .library import gibbs
+from .freezing import t_freezing
+from ..utilities import match_args_return, strip_mask
+from .conversions import (pt_from_CT, pt_from_t, pt0_from_t, CT_from_t,
+                          t_from_CT)
+from .constants import Kelvin, db2Pascal, P0, SSO, cp0, R, sfac, M_S
+
+__all__ = ['adiabatic_lapse_rate_from_t',
+           'adiabatic_lapse_rate_from_CT',
+           'alpha_wrt_CT_t_exact',
+           'alpha_wrt_pt_t_exact',
+           'alpha_wrt_t_exact',
+           'beta_const_CT_t_exact',
+           'beta_const_pt_t_exact',
+           'beta_const_t_exact',
+           'chem_potential_relative_t_exact',
+           'chem_potential_salt_t_exact',
+           'chem_potential_water_t_exact',
+           'cp_t_exact',
+           'deltaSA_from_rho_t_exact',
+           'dynamic_enthalpy_t_exact',
+           'enthalpy_t_exact',
+           'entropy_t_exact',
+           'Helmholtz_energy_t_exact',
+           'internal_energy_t_exact',
+           'isochoric_heat_cap_t_exact',
+           'kappa_const_t_exact',
+           'kappa_t_exact',
+           'osmotic_coefficient_t_exact',
+           'osmotic_pressure_t_exact',
+           'pot_rho_t_exact',
+           'rho_t_exact',
+           'SA_from_rho_t',
+           'SA_from_rho_t_exact',
+           'sigma0_pt0_exact',
+           'sound_speed_t_exact',
+           'specvol_anom_t_exact',
+           'specvol_t_exact',
+           't_from_rho_exact',
+           't_maxdensity_exact']
+
+n0, n1, n2 = 0, 1, 2
+
+
+ at match_args_return
+def adiabatic_lapse_rate_from_t(SA, t, p):
+    """
+     gsw_adiabatic_lapse_rate_from_t                      adiabatic lapse rate
+    ==========================================================================
+
+     USAGE:
+      adiabatic_lapse_rate = gsw_adiabatic_lapse_rate_from_t(SA,t,p)
+
+     DESCRIPTION:
+      Calculates the adiabatic lapse rate of sea water
+
+     INPUT:
+      SA  =  Absolute Salinity                                        [ g/kg ]
+      t   =  in-situ temperature (ITS-90)                            [ deg C ]
+      p   =  sea pressure                                             [ dbar ]
+             ( i.e. absolute pressure - 10.1325 dbar )
+
+      SA & t need to have the same dimensions.
+      p may have dimensions 1x1 or Mx1 or 1xN or MxN, where SA & t are MxN.
+
+     OUTPUT:
+      adiabatic_lapse_rate  =  adiabatic lapse rate                   [ K/Pa ]
+        Note.  The output is in unit of degress Celsius per Pa,
+          (or equivilently K/Pa) not in units of K/dbar.
+
+     AUTHOR:
+      Trevor McDougall and Paul Barker                    [ help at teos-10.org ]
+
+     VERSION NUMBER: 3.03 (29th April, 2013)
+
+     REFERENCES:
+      IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
+       seawater - 2010: Calculation and use of thermodynamic properties.
+       Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+       UNESCO (English), 196 pp.  Available from http://www.TEOS-10.org.
+        See Eqn. (2.22.1) of this TEOS-10 Manual.
+
+    """
+    return -gibbs(n0, n1, n1, SA, t, p) / (gibbs(n0, n2, n0, SA, t, p))
+
+ at match_args_return
+def adiabatic_lapse_rate_from_CT(SA, CT, p):
+    """
+     gsw_adiabatic_lapse_rate_from_CT                     adiabatic lapse rate
+    ==========================================================================
+
+     USAGE:
+      adiabatic_lapse_rate = gsw_adiabatic_lapse_rate_from_CT(SA,CT,p)
+
+     DESCRIPTION:
+      Calculates the adiabatic lapse rate of sea water from Conservative
+      Temperature.
+
+     INPUT:
+      SA  =  Absolute Salinity                                        [ g/kg ]
+      CT  =  Conservative Temperature (ITS-90)                       [ deg C ]
+      p   =  sea pressure                                             [ dbar ]
+             ( i.e. absolute pressure - 10.1325 dbar )
+
+      SA & CT need to have the same dimensions.
+      p may have dimensions 1x1 or Mx1 or 1xN or MxN, where SA & CT are MxN.
+
+     OUTPUT:
+      adiabatic_lapse_rate  =  adiabatic lapse rate                   [ K/Pa ]
+        Note.  The output is in unit of degress Celsius per Pa,
+          (or equivilently K/Pa) not in units of K/dbar.
+
+     AUTHOR:
+      Trevor McDougall and Paul Barker                    [ help at teos-10.org ]
+
+     VERSION NUMBER: 3.03 (29th April, 2013)
+
+     REFERENCES:
+      IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of
+       seawater - 2010: Calculation and use of thermodynamic properties.
+       Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+       UNESCO (English), 196 pp.  Available from http://www.TEOS-10.org.
+        See Eqn. (2.22.1) of this TEOS-10 Manual.
+
+    """
+    t = t_from_CT(SA, CT, p)
+
+    return -gibbs(n0, n1, n1, SA, t, p) / gibbs(n0, n2, n0, SA, t, p)
+
+
+ at match_args_return
+def alpha_wrt_CT_t_exact(SA, t, p):
+    r"""Calculates the thermal expansion coefficient of seawater with respect
+    to Conservative Temperature.
+    Parameters
+    ----------
+    SA : array_like
+        Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    alpha_wrt_CT : array_like
+                   thermal expansion coefficient [K :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.alpha_wrt_CT_t_exact(SA, t, p)
+    array([ 0.00032471,  0.00032272,  0.00028118,  0.00017314,  0.00014627,
+            0.00012943])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.18.3).
+    Modifications:
+    2011-03-29. Trevor McDougall and Paul Barker
+    """
+    pt0 = pt0_from_t(SA, t, p)
+    factor = -cp0 / ((Kelvin + pt0) * gibbs(n0, n2, n0, SA, t, p))
+    return factor * (gibbs(n0, n1, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p))
+
+
+ at match_args_return
+def alpha_wrt_pt_t_exact(SA, t, p):
+    r"""Calculates the thermal expansion coefficient of seawater with respect
+    to potential temperature, with a reference pressure of zero.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    alpha_wrt_pt : array_like
+                   thermal expansion coefficient [K :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.alpha_wrt_pt_t_exact(SA, t, p)
+    array([ 0.00032562,  0.00032355,  0.00028164,  0.00017314,  0.00014623,
+            0.00012936])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.18.2).
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker
+    """
+    pt0 = pt0_from_t(SA, t, p)
+    factor = gibbs(n0, n2, n0, SA, pt0, 0) / gibbs(n0, n2, n0, SA, t, p)
+    return factor * (gibbs(n0, n1, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p))
+
+
+ at match_args_return
+def alpha_wrt_t_exact(SA, t, p):
+    r"""Calculates the thermal expansion coefficient of seawater with respect
+    to in situ temperature.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    alpha_wrt_t : array_like
+                  thermal expansion coefficient [K :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.alpha_wrt_t_exact(SA, t, p)
+    array([ 0.0003256 ,  0.00032345,  0.00028141,  0.00017283,  0.00014557,
+            0.00012836])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.18.1)
+    .. [2] McDougall, T.J., D.R. Jackett and F.J. Millero, 2010: An algorithm
+    for estimating Absolute Salinity in the global ocean. Submitted to Ocean
+    Science. A preliminary version is available at Ocean Sci. Discuss.,
+    6, 215-242.
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker
+    """
+    return gibbs(n0, n1, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p)
+
+
+ at match_args_return
+def beta_const_CT_t_exact(SA, t, p):
+    r"""Calculates the saline (i.e. haline) contraction coefficient of seawater
+    at constant Conservative Temperature.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    beta_const_CT : array_like
+                    saline contraction coefficient [kg g :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.beta_const_CT_t_exact(SA, t, p)
+    array([ 0.00071749,  0.00071765,  0.00072622,  0.00075051,  0.00075506,
+            0.00075707])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.19.3)
+    Modifications:
+    2010-07-23. David Jackett, Trevor McDougall and Paul Barker
+    """
+    # TODO: Original GSW-V3 re-implements gibbs, check what to do here!
+    pt0 = pt0_from_t(SA, t, p)
+    factora = (gibbs(n1, n1, n0, SA, t, p) - gibbs(n1, n0, n0, SA, pt0, 0) /
+               (Kelvin + pt0))
+    factor = (factora / (gibbs(n0, n0, n1, SA, t, p) *
+              gibbs(n0, n2, n0, SA, t, p)))
+    return (gibbs(n0, n1, n1, SA, t, p) * factor -
+            gibbs(n1, n0, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p))
+
+
+ at match_args_return
+def beta_const_pt_t_exact(SA, t, p):
+    r"""Calculates the saline (i.e. haline) contraction coefficient of seawater
+    at constant potential temperature with a reference pressure of 0 dbar.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    beta_const_pt : array_like
+                    saline contraction coefficient [kg g :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.beta_const_pt_t_exact(SA, t, p)
+    array([ 0.00073112,  0.00073106,  0.00073599,  0.00075375,  0.00075712,
+            0.00075843])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.19.2)
+    Modifications:
+    2011-04-10. Trevor McDougall and Paul Barker
+    """
+    # NOTE: The original Matlab toolbox re-implement some code here.  Why?
+    pt0 = pt0_from_t(SA, t, p)
+    factora = gibbs(n1, n1, n0, SA, t, p) - gibbs(n1, n1, n0, SA, pt0, 0)
+    factor = (factora / (gibbs(n0, n0, n1, SA, t, p) *
+              gibbs(n0, n2, n0, SA, t, p)))
+    return (gibbs(n0, n1, n1, SA, t, p) * factor -
+            gibbs(n1, n0, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p))
+
+
+ at match_args_return
+def beta_const_t_exact(SA, t, p):
+    r"""Calculates the saline (i.e. haline) contraction coefficient of seawater
+    at constant in situ temperature.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    beta_const_t : array_like
+                   saline contraction coefficient [kg g :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.beta_const_t_exact(SA, t, p)
+    array([ 0.00073112,  0.00073107,  0.00073602,  0.00075381,  0.00075726,
+            0.00075865])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.19.1)
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker
+    """
+    return -gibbs(n1, n0, n1, SA, t, p) / gibbs(n0, n0, n1, SA, t, p)
+
+
+ at match_args_return
+def chem_potential_relative_t_exact(SA, t, p):
+    r"""Calculates the adiabatic lapse rate of seawater.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    chem_potential_relative : array_like
+                              relative chemical potential [J/g]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.chem_potential_relative_t_exact(SA, t, p)
+    array([ 79.4254481 ,  79.25989214,  74.69154859,  65.64063719,
+            61.22685656,  57.21298557])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    Modifications:
+    2013-04-15. Trevor McDougall and Paul Barker
+    """
+    n0 = 0
+    n1 = 1
+    return gibbs(n1, n0, n0, SA, t, p)
+
+
+ at match_args_return
+def chem_potential_salt_t_exact(SA, t, p):
+    r"""Calculates the chemical potential of salt in seawater.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    chem_potential_salt : array_like
+        chemical potential of salt in seawater [J kg :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.chem_potential_salt_t_exact(SA, t, p)
+    array([-8466.13569818, -7928.8256562 , -5029.28859129,  -568.42714556,
+            3396.79366004,  7612.64743154])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.9.
+    Modifications:
+    2010-03-29. Trevor McDougall and Paul Barker
+    """
+    return (chem_potential_relative_t_exact(SA, t, p) +
+            chem_potential_water_t_exact(SA, t, p))
+
+
+ at match_args_return
+def chem_potential_water_t_exact(SA, t, p):
+    r"""Calculates the chemical potential of water in seawater.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    chem_potential_water : array_like
+                           chemical potential of water in seawater
+                           [J/g]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.chem_potential_water_t_exact(SA, t, p)
+    array([-8545.56114628, -8008.08554834, -5103.98013987,  -634.06778275,
+            3335.56680347,  7555.43444597])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    Modifications:
+    2013-04-15. Trevor McDougall and Paul Barker
+    """
+    SA, t, p, mask = strip_mask(SA, t, p)
+    # FIXME: Ugly copy from gibbs, why?
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y = t * 0.025
+    z = p * 1e-4  # Pressure (p) is sea pressure in units of dbar.
+    g03_g = (101.342743139674 + z * (100015.695367145 +
+             z * (-2544.5765420363 + z * (284.517778446287 +
+             z * (-33.3146754253611 + (4.20263108803084 -
+             0.546428511471039 * z) * z)))) +
+             y * (5.90578347909402 + z * (-270.983805184062 +
+             z * (776.153611613101 + z * (-196.51255088122 +
+             (28.9796526294175 - 2.13290083518327 * z) * z))) +
+             y * (-12357.785933039 + z * (1455.0364540468 +
+             z * (-756.558385769359 + z * (273.479662323528 +
+             z * (-55.5604063817218 + 4.34420671917197 * z)))) +
+             y * (736.741204151612 + z * (-672.50778314507 +
+             z * (499.360390819152 + z * (-239.545330654412 +
+             (48.8012518593872 - 1.66307106208905 * z) * z))) +
+             y * (-148.185936433658 + z * (397.968445406972 +
+             z * (-301.815380621876 + (152.196371733841 -
+             26.3748377232802 * z) * z)) +
+             y * (58.0259125842571 + z * (-194.618310617595 +
+             z * (120.520654902025 + z * (-55.2723052340152 +
+             6.48190668077221 * z))) +
+             y * (-18.9843846514172 + y * (3.05081646487967 -
+             9.63108119393062 * z) +
+             z * (63.5113936641785 + z * (-22.2897317140459 +
+             8.17060541818112 * z)))))))))
+    g08_g = x2 * (1416.27648484197 +
+        x * (-2432.14662381794 + x * (2025.80115603697 +
+        y * (543.835333000098 + y * (-68.5572509204491 +
+        y * (49.3667694856254 + y * (-17.1397577419788 +
+        2.49697009569508 * y))) - 22.6683558512829 * z) +
+        x * (-1091.66841042967 - 196.028306689776 * y +
+        x * (374.60123787784 - 48.5891069025409 * x +
+        36.7571622995805 * y) + 36.0284195611086 * z) +
+        z * (-54.7919133532887 + (-4.08193978912261 -
+        30.1755111971161 * z) * z)) +
+        z * (199.459603073901 + z * (-52.2940909281335 +
+        (68.0444942726459 - 3.41251932441282 * z) * z)) +
+        y * (-493.407510141682 + z * (-175.292041186547 +
+        (83.1923927801819 - 29.483064349429 * z) * z) +
+        y * (-43.0664675978042 + z * (383.058066002476 +
+        z * (-54.1917262517112 + 25.6398487389914 * z)) +
+        y * (-10.0227370861875 - 460.319931801257 * z + y *
+        (0.875600661808945 + 234.565187611355 * z))))) +
+        y * (168.072408311545))
+    g_SA_part = (8645.36753595126 +
+        x * (-7296.43987145382 + x * (8103.20462414788 +
+        y * (2175.341332000392 + y * (-274.2290036817964 +
+        y * (197.4670779425016 + y * (-68.5590309679152 +
+        9.98788038278032 * y))) - 90.6734234051316 * z) +
+        x * (-5458.34205214835 - 980.14153344888 * y +
+        x * (2247.60742726704 - 340.1237483177863 * x +
+        220.542973797483 * y) + 180.142097805543 * z) +
+        z * (-219.1676534131548 + (-16.32775915649044 -
+        120.7020447884644 * z) * z)) +
+        z * (598.378809221703 + z * (-156.8822727844005 +
+        (204.1334828179377 - 10.23755797323846 * z) * z)) +
+        y * (-1480.222530425046 + z * (-525.876123559641 +
+        (249.57717834054571 - 88.449193048287 * z) * z) +
+        y * (-129.1994027934126 + z * (1149.174198007428 +
+        z * (-162.5751787551336 + 76.9195462169742 * z)) +
+        y * (-30.0682112585625 - 1380.9597954037708 * z + y *
+        (2.626801985426835 + 703.695562834065 * z))))) +
+        y * (1187.3715515697959))
+    chem_potential_water = g03_g + g08_g - 0.5 * sfac * SA * g_SA_part
+    # V3.03: convert from J/kg to J/g.
+    # See section 2.9 of TEOS-10 manual.
+    chem_potential_water *= 1e-3
+    return np.ma.array(chem_potential_water, mask=mask, copy=False)
+
+
+ at match_args_return
+def cp_t_exact(SA, t, p):
+    r"""Calculates the isobaric heat capacity of seawater.
+    Parameters
+    ----------
+    SA : array_like
+        Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    cp_t_exact : array_like
+        heat capacity of seawater [J kg :sup:`-1` K :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.cp_t_exact(SA, t, p)
+    array([ 4002.88800396,  4000.98028393,  3995.54646889,  3985.07676902,
+            3973.59384348,  3960.18408479])
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker
+    """
+    return -(t + Kelvin) * gibbs(n0, n2, n0, SA, t, p)
+
+
+ at match_args_return
+def deltaSA_from_rho_t_exact(rho, SP, t, p):
+    pass
+
+
+ at match_args_return
+def dynamic_enthalpy_t_exact(SA, t, p):
+    r"""Calculates the dynamic enthalpy of seawater from Absolute Salinity, in
+    situ temperature and pressure.  Dynamic enthalpy was defined by Young
+    (2010) as the difference between enthalpy and potential enthalpy. Note that
+    this function uses the full TEOS-10 Gibbs function (i.e. the sum of the
+    IAPWS-09 and IAPWS-08 Gibbs functions, see the TEOS-10 Manual, IOC et al.
+    (2010)).
+    Parameters
+    ----------
+    SA : array_like
+        Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    dynamic_enthalpy_t_exact : array_like
+        dynamic enthalpy [J :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    .. [2] Young, W.R., 2010: Dynamic enthalpy, Conservative Temperature, and
+    the seawater. Boussinesq approximation. Journal of Physical Oceanography,
+    40, 394-400.
+    Modifications:
+    2011-04-11. Trevor McDougall and Paul Barker
+    """
+    CT = CT_from_t(SA, t, p)
+    return enthalpy_t_exact(SA, t, p) - cp0 * CT
+
+
+ at match_args_return
+def enthalpy_t_exact(SA, t, p):
+    r"""Calculates the specific enthalpy of seawater.
+    The specific enthalpy of seawater :math:`h` is given by:
+    .. math::
+        h(SA, t, p) = g + (T_0 + t)\eta =
+                      g - (T_0 + t) \frac{\partial g}{\partial T}\Big|_{SA,p}
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    enthalpy : array_like
+               specific enthalpy [J kg :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.enthalpy(SA, t, p)
+    array([ 115103.26047838,  114014.8036012 ,   92179.9209311 ,
+             43255.32838089,   33087.21597002,   26970.5880448 ])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See appendix A.11.
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker.
+    """
+    return (gibbs(n0, n0, n0, SA, t, p) -
+            (t + Kelvin) * gibbs(n0, n1, n0, SA, t, p))
+
+
+ at match_args_return
+def entropy_t_exact(SA, t, p):
+    r"""Calculates specific entropy of seawater.
+    The specific entropy of seawater :math:`\eta` is given by:
+    .. math::
+        \eta(SA, t, p) = -g_T = \frac{\partial g}{\partial T}\Big|_{SA,p}
+    When taking derivatives with respect to *in situ* temperature, the symbol
+    :math:`T` will be used for temperature in order that these derivatives not
+    be confused with time derivatives.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    entropy : array_like
+              specific entropy [J kg :sup:`-1` K :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.entropy_t_exact(SA, t, p)
+    array([ 400.38942528,  395.43817843,  319.8664982 ,  146.79088159,
+             98.64734087,   62.79150873])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker.
+    """
+    return -gibbs(n0, n1, n0, SA, t, p)
+
+
+ at match_args_return
+def Helmholtz_energy_t_exact(SA, t, p):
+    r"""Calculates the Helmholtz energy of seawater.
+    The specific Helmholtz energy of seawater :math:`f` is given by:
+    .. math::
+        f(SA, t, p) = g - (p + P_0) \nu =
+                      g - (p + P_0) \frac{\partial g}{\partial P}\Big|_{SA,T}
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    Helmholtz_energy : array_like
+                       Helmholtz energy [J kg :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.Helmholtz_energy_t_exact(SA, t, p)
+    array([-5985.58288209, -5830.81845224, -3806.96617841,  -877.66369421,
+            -462.17033905,  -245.50407205])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.13.
+    Modifications:
+    2011-03-29. Trevor McDougall
+    """
+    return (gibbs(n0, n0, n0, SA, t, p) -
+            (db2Pascal * p + P0) * gibbs(n0, n0, n1, SA, t, p))
+
+
+ at match_args_return
+def internal_energy_t_exact(SA, t, p):
+    r"""Calculates the Helmholtz energy of seawater.
+    The specific internal energy of seawater :math:`u` is given by:
+    .. math::
+        u(SA, t, p) = g + (T_0 + t)\eta - (p + P_0)\nu =
+                      g - (T_0 + t)\frac{\partial g}{\partial T}\Big|_{SA,p} -
+                          (p + P_0)\frac{\partial g}{\partial P}\Big|_{SA,T}
+    where :math:`T_0` is the Celsius zero point, 273.15 K and
+    :math:`P_0` = 101 325 Pa is the standard atmosphere pressure.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    internal_energy (u) : array_like
+                          specific internal energy [J kg :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.internal_energy_t_exact(SA, t, p)
+    array([ 114906.23847309,  113426.57417062,   90860.81858842,
+             40724.34005719,   27162.66600185,   17182.50522667])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.11.1)
+    Modifications:
+    2011-03-29. Trevor McDougall
+    """
+    return (gibbs(n0, n0, n0, SA, t, p) -
+            (Kelvin + t) * gibbs(n0, n1, n0, SA, t, p) -
+            (db2Pascal * p + P0) * gibbs(n0, n0, n1, SA, t, p))
+
+
+ at match_args_return
+def isochoric_heat_cap_t_exact(SA, t, p):
+    r"""Calculates the isochoric heat capacity of seawater.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    isochoric_heat_cap : array_like
+                         isochoric heat capacity [J kg :sup:`-1` K :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.isochoric_heat_cap_t_exact(SA, t, p)
+    array([ 3928.13708702,  3927.27381633,  3941.36418525,  3966.26126146,
+            3960.50903222,  3950.13901342])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.21.
+    Modifications:
+    2011-03-29. Trevor McDougall
+    """
+    return (-(Kelvin + t) * (gibbs(n0, n2, n0, SA, t, p) -
+            gibbs(n0, n1, n1, SA, t, p) ** 2 / gibbs(n0, n0, n2, SA, t, p)))
+
+
+ at match_args_return
+def kappa_const_t_exact(SA, t, p):
+    r"""Calculates isothermal compressibility of seawater at constant in situ
+    temperature.
+    .. math::
+        \kappa^t(SA, t, p) =
+                       \rho^{-1}\frac{\partial \rho}{\partial P}\Big|_{SA,T} =
+                       -\nu^{-1}\frac{\partial \nu}{\partial P}\Big|_{SA,T} =
+                       -\frac{g_{PP}}{g_P}
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    kappa : array_like
+            Isothermal compressibility [Pa :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This is the compressibility of seawater at constant in situ temperature.
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.kappa_const_t_exact(SA, t, p)
+    array([  4.19071646e-10,   4.18743202e-10,   4.22265764e-10,
+             4.37735100e-10,   4.40373818e-10,   4.41156577e-10])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.15.1)
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker
+    """
+    return -gibbs(n0, n0, n2, SA, t, p) / gibbs(n0, n0, n1, SA, t, p)
+
+
+ at match_args_return
+def kappa_t_exact(SA, t, p):
+    r"""Calculates the isentropic compressibility of seawater.
+    When the entropy and Absolute Salinity are held constant while the pressure
+    is changed, the isentropic and isohaline compressibility
+    :math:`kappa` is obtained:
+    .. math::
+        \kappa(SA, t, p) =
+                   \rho^{-1}\frac{\partial \rho}{\partial P}\Big|_{SA,\eta} =
+                   -\nu^{-1}\frac{\partial \nu}{\partial P}\Big|_{SA,\eta} =
+                   \rho^{-1}\frac{\partial \rho}{\partial P}\Big|_{SA,\theta} =
+                   -\nu^{-1}\frac{\partial \nu}{\partial P}\Big|_{SA,\theta} =
+                   -\frac{ (g_{TP}^2 - g_{TT} g_{PP} ) }{g_P g_{TT}}
+    The isentropic and isohaline compressibility is sometimes called simply the
+    isentropic compressibility (or sometimes the "adiabatic compressibility"),
+    on the unstated understanding that there is also no transfer of salt during
+    the isentropic or adiabatic change in pressure.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    kappa : array_like
+            Isentropic compressibility [Pa :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    The output is Pascal and not dbar.
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.kappa_t_exact(SA, t, p)
+    array([  4.11245799e-10,   4.11029072e-10,   4.16539558e-10,
+             4.35668338e-10,   4.38923693e-10,   4.40037576e-10])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (2.16.1) and the row for kappa in
+    Table P.1 of appendix P
+    Modifications:
+    2011-03-23. David Jackett, Trevor McDougall and Paul Barker
+    """
+    return ((gibbs(n0, n1, n1, SA, t, p) ** 2 - gibbs(n0, n2, n0, SA, t, p) *
+            gibbs(n0, n0, n2, SA, t, p)) / (gibbs(n0, n0, n1, SA, t, p) *
+            gibbs(n0, n2, n0, SA, t, p)))
+
+
+ at match_args_return
+def osmotic_coefficient_t_exact(SA, t, p):
+    r"""Calculates the osmotic coefficient of seawater.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    osmotic_coefficient : array_like
+                          osmotic coefficient of seawater [unitless]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.osmotic_coefficient_t_exact(SA,t , p)
+    array([ 0.90284718,  0.90298624,  0.90238866,  0.89880927,  0.89801054,
+            0.89767912])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    Modifications:
+    2011-04-01. Trevor McDougall and Paul Barker.
+    2012-11-15. Trevor McDougall and Paul Barker.
+    """
+    SA = np.maximum(SA, 0)
+    k = M_S / R
+    part = k * (1000 - SA) / (Kelvin + t)
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y = t * 0.025
+    # Note that the input pressure (p) is sea pressure in units of dbar.
+    z = p / db2Pascal
+    oc = (7.231916621570606e1, 1.059039593127674e1, -3.025914794694813e1,
+          5.040733670521486e1, -4.074543321119333e1, 1.864215613820487e1,
+          -3.022566485046178, -6.138647522851840, 1.353207379758663e1,
+          -7.316560781114737, 1.829232499785750, -5.358042980767074e-1,
+          -1.705887283375562, -1.246962174707332e-1, 1.228376913546017,
+          1.089364009088042e-2, -4.264828939262248e-1, 6.213127679460041e-2,
+          2.481543497315280, -1.363368964861909, -5.640491627443773e-1,
+          1.344724779893754, -2.180866793244492, 4.765753255963401,
+          -5.726993916772165, 2.918303792060746, -6.506082399183509e-1,
+          -1.015695507663942e-1, 1.035024326471108, -6.742173543702397e-1,
+          8.465642650849419e-1, -7.508472135244717e-1, -3.668086444057845e-1,
+          3.189939162107803e-1, -4.245629194309487e-2)
+    tl = (oc[0] + oc[1] * y + x * (oc[2] + x * (oc[3] + x * (oc[4] + x *
+         (oc[5] + oc[6] * x))) + y * (oc[7] + x * (oc[8] + x *
+         (oc[9] + oc[10] * x)) + y * (oc[11] + oc[12] * x + y * (oc[13] +
+         oc[14] * x + y * (oc[15] + x * (oc[16] + oc[17] * y))))) + z *
+         (oc[18] + x * (oc[19] + oc[20] * y + oc[21] * x) + y * (oc[22] + y *
+         (oc[23] + y * (oc[24] + oc[25] * y))) + z * (oc[26] + oc[27] * x + y *
+         (oc[28] + oc[29] * y) + z * (oc[30] + oc[31] * x + y * (oc[32] +
+         oc[33] * y) + oc[34] * z)))))
+    return tl * part
+
+
+ at match_args_return
+def osmotic_pressure_t_exact(SA, t, pw):
+    r"""Calculates the osmotic pressure of seawater.
+    Parameters
+    ----------
+    SA : array_like
+        Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    pw : array_like
+        sea pressure of the pure water side [dbar]
+    Returns
+    -------
+    osmotic_pressure_t_exact : array_like
+        dynamic osmotic pressure of seawater [dbar]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.41.
+    Modifications:
+    2011-05-26. Trevor McDougall and Paul Barker
+    """
+    SA = np.maximum(SA, 0)
+    gibbs_pure_water = gibbs(0, 0, 0, 0, t, pw)
+    # Initial guess of p, in dbar.
+    p = pw + 235.4684
+    # Initial guess of df/dp.
+    df_dp = -db2Pascal * (gibbs(n0, n0, n1, SA, t, p) -
+                          SA * gibbs(n1, n0, n1, SA, t, p))
+    for Number_of_iterations in range(0, 2):
+        p_old = p
+        f = gibbs_pure_water - chem_potential_water_t_exact(SA, t, p_old)
+        # This is half way through the modified N-R method.
+        p = p_old - f / df_dp
+        p_mean = 0.5 * (p + p_old)
+        df_dp = -db2Pascal * (gibbs(0, 0, 1, SA, t, p_mean) -
+                              SA * gibbs(1, 0, 1, SA, t, p_mean))
+        p = p_old - f / df_dp
+    # After two iterations though the modified Newton-Raphson technique the
+    # maximum error is 6x10^-12 dbar.
+    # Osmotic pressure of seawater in dbar.
+    return p - pw
+
+
+ at match_args_return
+def pot_rho_t_exact(SA, t, p, p_ref=0):
+    r"""Calculates potential density of seawater.
+    Parameters
+    ----------
+    SA : array_like
+        Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    p_ref : int, float, optional
+        reference pressure, default = 0
+    Returns
+    -------
+    pot_rho : array_like
+              potential density  [kg m :sup:`-3`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.pot_rho_t_exact(SA, t, p)
+    array([ 1021.79814581,  1022.05248442,  1023.89358365,  1026.66762112,
+            1027.10723087,  1027.40963126])
+    >>> gsw.pot_rho(SA, t, p, p_ref=1000)
+    array([ 1025.95554512,  1026.21306986,  1028.12563226,  1031.1204547 ,
+            1031.63768355,  1032.00240412])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.4.
+    Modifications:
+    2011-03-29. David Jackett, Trevor McDougall and Paul Barker
+    """
+    pt = pt_from_t(SA, t, p, p_ref=p_ref)
+    return rho_t_exact(SA, pt, p_ref)
+
+
+ at match_args_return
+def rho_t_exact(SA, t, p):
+    r"""Calculates in situ density of seawater from Absolute Salinity and in
+    situ temperature.
+    Parameters
+    ----------
+    SA : array_like
+        Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    rho_t_exact : array_like
+        in situ density [kg m :sup:`-3`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.rho(SA, t, p)
+    array([ 1021.84017319,  1022.26268993,  1024.42771594,  1027.79020181,
+            1029.83771473,  1032.00240412])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.8.
+    Modifications:
+    2011-03-29. Paul Barker, David Jackett and Trevor McDougal
+    """
+    return 1. / gibbs(n0, n0, n1, SA, t, p)
+
+
+ at match_args_return
+def SA_from_rho_t(rho, t, p):
+    return None
+
+
+ at match_args_return
+def SA_from_rho_t_exact(rho, t, p):
+    r"""Calculates the Absolute Salinity of a seawater sample, for given values
+    of its density, in situ temperature and sea pressure (in dbar).
+    One use for this function is in the laboratory where a measured value of
+    the in situ density :math:`\rho` of a seawater sample may have been made at
+    the laboratory temperature :math:`t` and at atmospheric pressure :math:`p`.
+    The present function will return the Absolute Salinity SA of this seawater
+    sample.
+    Parameters
+    ----------
+    rho : array_like
+          in situ density [kg m :sup:`-3`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    This is expressed on the Reference-Composition Salinity Scale of
+    Millero et al. (2008).
+    After two iterations of a modified Newton-Raphson iteration,
+    the error in SA is typically no larger than
+    2 :math:`^\times` 10 :sup:`-13` [g kg :sup:`-1`]
+    Examples
+    --------
+    >>> import gsw
+    >>> rho = [1021.839, 1022.262, 1024.426, 1027.792, 1029.839, 1032.002]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.SA_from_rho_t_exact(rho, t, p)
+    array([ 34.71022966,  34.89057683,  35.02332421,  34.84952096,
+            34.73824809,  34.73188384])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.5.
+    .. [2] Millero, F. J., R. Feistel, D. G. Wright, and T. J. McDougall, 2008:
+    The composition of Standard Seawater and the definition of the
+    Reference-Composition Salinity Scale, Deep-Sea Res. I, 55, 50-72.
+    Modifications:
+    2011-03-28. Trevor McDougall and Paul Barker.
+    """
+    v_lab = np.ones_like(rho) / rho
+    v_0 = gibbs(n0, n0, n1, 0, t, p)
+    v_120 = gibbs(n0, n0, n1, 120, t, p)
+    # Initial estimate of SA.
+    SA = 120 * (v_lab - v_0) / (v_120 - v_0)
+    Ior = np.logical_or(SA < 0, SA > 120)
+    # Initial estimate of v_SA, SA derivative of v
+    v_SA = (v_120 - v_0) / 120
+    for k in range(0, 2):
+        SA_old = SA
+        delta_v = gibbs(n0, n0, n1, SA_old, t, p) - v_lab
+        # Half way the mod. N-R method (McDougall and Wotherspoon, 2012)
+        SA = SA_old - delta_v / v_SA
+        SA_mean = 0.5 * (SA + SA_old)
+        v_SA = gibbs(n1, n0, n1, SA_mean, t, p)
+        SA = SA_old - delta_v / v_SA
+    SA[Ior] = np.ma.masked
+    return SA
+
+
+ at match_args_return
+def sigma0_pt0_exact(SA, pt0):
+    r"""Calculates potential density anomaly with reference sea pressure of
+    zero (0) dbar.  The temperature input to this function is potential
+    temperature referenced to zero dbar.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    pt0 : array_like
+          potential temperature [:math:`^\circ` C (ITS-90)]
+          with respect to a reference sea pressure of 0 dbar
+    Returns
+    -------
+    sigma0_pt0_exact : array_like
+                       potential density anomaly [kg m :sup:`-3`]
+                       respect to a reference pressure of 0 dbar
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.rho(SA, t, p)
+    array([ 1021.84017319,  1022.26268993,  1024.42771594,  1027.79020181,
+            1029.83771473,  1032.00240412])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (3.6.1).
+    Modifications:
+    2011-03-29. Trevor McDougal and Paul Barker.
+    """
+    SA = np.maximum(SA, 0)  # Ensure that SA is non-negative.
+    x2 = sfac * SA
+    x = np.sqrt(x2)
+    y = pt0 * 0.025
+    g03 = (100015.695367145 +
+           y * (-270.983805184062 +
+           y * (1455.0364540468 +
+           y * (-672.50778314507 +
+           y * (397.968445406972 +
+           y * (-194.618310617595 +
+           y * (63.5113936641785 -
+           y * 9.63108119393062)))))))
+    g08 = x2 * (-3310.49154044839 +
+                x * (199.459603073901 +
+                x * (-54.7919133532887 +
+                x * 36.0284195611086 -
+                y * 22.6683558512829) +
+                y * (-175.292041186547 +
+                y * (383.058066002476 +
+                y * (-460.319931801257 +
+                y * 234.565187611355)))) +
+                y * (729.116529735046 +
+                y * (-860.764303783977 +
+                y * (694.244814133268 +
+                y * (-297.728741987187)))))
+    """The above code is exactly the same as the following two lines of code.
+    sigma0_pt_exact = rho_t_exact(SA, pt0, 0.) - 1000
+    """
+    return 100000000. / (g03 + g08) - 1000.0
+
+
+ at match_args_return
+def sound_speed_t_exact(SA, t, p):
+    r"""Calculates the speed of sound in seawater.
+    The speed of sound in seawater :math:`c` is given by:
+    .. math::
+        c(SA, t, p) = \sqrt{ \partial P  / \partial \rho |_{SA,\eta}} =
+                      \sqrt{(\rho\kappa)^{-1}} =
+                      g_P \sqrt{g_{TT}/(g^2_{TP} - g_{TT}g_{PP})}
+    Note that in these expressions, since sound speed is in m s :sup`-1` and
+    density has units of kg m :sup:`-3` it follows that the pressure of the
+    partial derivatives must be in Pa and the isentropic compressibility
+    :math:`kappa` must have units of Pa :sup:`-1`. The sound speed c produced
+    by both the SIA and the GSW software libraries (appendices M and N) has
+    units of m s :sup:`-1`.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    sound_speed : array_like
+                  speed of sound in seawater [m s :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.sound_speed_t_exact(SA, t, p)
+    array([ 1542.61580359,  1542.70353407,  1530.84497914,  1494.40999692,
+            1487.37710252,  1483.93460908])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (2.17.1)
+    Modifications:
+    2011-03-29. David Jackett, Paul Barker and Trevor McDougall.
+    """
+    return (gibbs(n0, n0, n1, SA, t, p) * np.sqrt(gibbs(n0, n2, n0, SA, t, p) /
+            (gibbs(n0, n1, n1, SA, t, p) ** 2 - gibbs(n0, n2, n0, SA, t, p) *
+            gibbs(n0, n0, n2, SA, t, p))))
+
+
+ at match_args_return
+def specvol_anom_t_exact(SA, t, p):
+    r"""Calculates specific volume anomaly from Absolute Salinity, in situ
+    temperature and pressure, using the full TEOS-10 Gibbs function.
+    The reference value of Absolute Salinity is SSO and the reference value of
+    Conservative Temperature is equal to 0 :math:`^\circ` C.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    specvol_anom_t_exact : array_like
+        specific volume anomaly  [m :sup:`3` kg :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.specvol_anom_t_exact(SA, t, p)
+    array([  6.01044463e-06,   5.78602432e-06,   4.05564999e-06,
+             1.42198662e-06,   1.04351837e-06,   7.63964850e-07])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (3.7.3)
+    Modifications:
+    2011-03-23. Trevor McDougall and Paul Barker
+    """
+    pt_zero = pt_from_CT(SSO, 0)
+    t_zero = pt_from_t(SSO, pt_zero, 0, p)
+    return (gibbs(n0, n0, n1, SA, t, p) -
+            gibbs(n0, n0, n1, SSO, t_zero, p))
+
+
+ at match_args_return
+def specvol_t_exact(SA, t, p):
+    r"""Calculates the specific volume of seawater.
+    Parameters
+    ----------
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    specvol : array_like
+              specific volume [m :sup:`3` kg :sup:`-1`]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    >>> import gsw
+    >>> SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+    >>> t = [28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]
+    >>> p = [10, 50, 125, 250, 600, 1000]
+    >>> gsw.specvol(SA, t, p)
+    array([ 0.00097863,  0.00097822,  0.00097615,  0.00097296,  0.00097103,
+            0.00096899])
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 2.7.
+    Modifications:
+    2011-03-23. David Jackett and Paul Barker.
+    """
+    return gibbs(n0, n0, n1, SA, t, p)
+
+
+ at match_args_return
+def t_from_rho_exact(rho, SA, p):
+    r"""Calculates the in-situ temperature of a seawater sample, for given
+    values of its density, Absolute Salinity and sea pressure (in dbar).
+    Parameters
+    ----------
+    rho : array_like
+          in situ density [kg m :sup:`-3`]
+    SA : array_like
+         Absolute salinity [g kg :sup:`-1`]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    t : array_like
+        in situ temperature [:math:`^\circ` C (ITS-90)]
+    t_multiple : array_like
+                 in situ temperature [:math:`^\circ` C (ITS-90)]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    At low salinities, in brackish water, there are two possible temperatures
+    for a single density.  This program will output both valid solutions
+    (t, t_multiple), if there is only one possible solution the second variable
+    will be set to NaN.
+    Examples
+    --------
+    TODO
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp.
+    Modifications:
+    2011-04-21. Trevor McDougall and Paul Barker.
+    """
+    """alpha_limit is the positive value of the thermal expansion coefficient
+    which is used at the freezing temperature to distinguish between I_salty
+    and I_fresh."""
+    alpha_limit = 1e-5
+    """rec_half_rho_TT is a constant representing the reciprocal of half the
+    second derivative of density with respect to temperature near the
+    temperature of maximum density."""
+    rec_half_rho_TT = -110.0
+    t_a, t_b = None, None
+    t = np.zeros_like(SA) * np.NaN
+    t_multiple = np.zeros_like(SA) * np.NaN
+    I_SA = np.logical_or(SA < 0, SA > 42)
+    I_p = np.logical_or(p < -1.5, p > 12000)
+    I_SA_p = np.logical_or(I_SA, I_p)
+    SA[I_SA_p] = np.ma.masked
+    rho_40 = rho_t_exact(SA, 40 * np.ones_like(SA), p)
+    SA[(rho - rho_40) < 0] = np.ma.masked
+    t_max_rho = t_maxdensity_exact(SA, p)
+    rho_max = rho_t_exact(SA, t_max_rho, p)
+    rho_extreme = rho_max.copy()
+    t_freeze = t_freezing(SA, p)  # Assumes seawater is saturated with air.
+    rho_freezing = rho_t_exact(SA, t_freeze, p)
+    # Set rhos greater than those at the freezing point to be equal to the
+    # freezing point.
+    I_fr_gr_max = (t_freeze - t_max_rho) > 0
+    rho_extreme[I_fr_gr_max] = rho_freezing[I_fr_gr_max]
+    SA[rho > rho_extreme] = np.ma.masked
+    SA[np.isnan(SA * p * rho)] = np.ma.masked
+    alpha_freezing = alpha_wrt_t_exact(SA, t_freeze, p)
+    I_salty = alpha_freezing > alpha_limit
+    if I_salty.any():
+        t_diff = 40. * np.ones_like(I_salty) - t_freeze[I_salty]
+        top = (rho_40[I_salty] - rho_freezing[I_salty] +
+               rho_freezing[I_salty] * alpha_freezing[I_salty] * t_diff)
+        a = top / (t_diff ** 2)
+        b = -rho_freezing[I_salty] * alpha_freezing[I_salty]
+        c = rho_freezing[I_salty] - rho[I_salty]
+        sqrt_disc = np.sqrt(b ** 2 - 4 * a * c)
+        # The value of t[I_salty] is the initial guess `t` in the range of
+        # I_salty.
+        t[I_salty] = t_freeze[I_salty] + 0.5 * (-b - sqrt_disc) / a
+    I_fresh = alpha_freezing <= alpha_limit
+    if I_fresh.any():
+        t_diff = 40 * np.ones_like[I_fresh] - t_max_rho[I_fresh]
+        factor = ((rho_max[I_fresh] - rho[I_fresh]) / (rho_max[I_fresh] -
+                                                       rho_40[I_fresh]))
+        delta_t = t_diff * np.sqrt(factor)
+        I_fresh_NR = delta_t > 5
+        if I_fresh_NR.any():
+            t[I_fresh[I_fresh_NR]] = (t_max_rho[I_fresh[I_fresh_NR]] +
+                                      delta_t[I_fresh_NR])
+        I_quad = delta_t <= 5
+        if I_quad.any():
+            t_a = np.zeros_like(SA) * np.NaN
+            # Set the initial value of the quadratic solution roots.
+            t_a[I_fresh[I_quad]] = (t_max_rho[I_fresh[I_quad]] +
+                                    np.sqrt(rec_half_rho_TT *
+                                            (rho[I_fresh[I_quad]] -
+                                             rho_max[I_fresh[I_quad]])))
+            for Number_of_iterations in range(0, 6):
+                t_old = t_a
+                rho_old = rho_t_exact(SA, t_old, p)
+                factorqa = (rho_max - rho) / (rho_max - rho_old)
+                t_a = t_max_rho + (t_old - t_max_rho) * np.sqrt(factorqa)
+            t_a[t_freezing - t_a < 0] = np.ma.masked
+            t_b = np.zeros_like(SA) * np.NaN
+            # Set the initial value of the quadratic solution routes.
+            t_b[I_fresh[I_quad]] = (t_max_rho[I_fresh[I_quad]] -
+                                    np.sqrt(rec_half_rho_TT *
+                                            (rho[I_fresh[I_quad]] -
+                                             rho_max[I_fresh[I_quad]])))
+            for Number_of_iterations in range(0, 6):
+                t_old = t_b.copy()
+                rho_old = rho_t_exact(SA, t_old, p)
+                factorqb = (rho_max - rho) / (rho_max - rho_old)
+                t_b = t_max_rho + (t_old - t_max_rho) * np.sqrt(factorqb)
+                # After seven iterations of this quadratic iterative procedure,
+                # the error in rho is no larger than 4.6x10^-13 kg/m^3.
+            t_b[t_freezing - t_b < 0] = np.ma.masked
+            # Begin the modified Newton-Raphson iterative method, which will
+            # only operate on non-masked data.
+    v_lab = np.ones_like(rho) / rho
+    v_t = gibbs(0, 1, 1, SA, t, p)
+    for Number_of_iterations in range(0, 3):
+        t_old = t.copy()
+        delta_v = gibbs(0, 0, 1, SA, t_old, p) - v_lab
+        t = t_old - delta_v / v_t  # Half way through the modified N-R method.
+        t_mean = 0.5 * (t + t_old)
+        v_t = gibbs(0, 1, 1, SA, t_mean, p)
+        t = t_old - delta_v / v_t
+    if t_a:
+        t[~np.isnan(t_a)] = t_a[~np.isnan(t_a)]
+    if t_b:
+        t_multiple[~np.isnan(t_b)] = t_b[~np.isnan(t_b)]
+    # After three iterations of this modified Newton-Raphson iteration,
+    # the error in rho is no larger than 4.6x10^-13 kg/m^3.
+    return t, t_multiple
+
+
+ at match_args_return
+def t_maxdensity_exact(SA, p):
+    r"""Calculates the in-situ temperature of maximum density of seawater.
+    This function returns the in-situ temperature at which the density of
+    seawater is a maximum, at given Absolute Salinity, SA, and sea pressure, p
+    (in dbar).
+    Parameters
+    ----------
+    SA : array_like
+        Absolute salinity [g kg :sup:`-1`]
+    p : array_like
+        pressure [dbar]
+    Returns
+    -------
+    t_maxdensity_exact : array_like
+        max in-situ temperature [:math:`^\circ` C]
+    See Also
+    --------
+    TODO
+    Notes
+    -----
+    TODO
+    Examples
+    --------
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.42.
+    Modifications:
+    2011-04-03. Trevor McDougall and Paul Barker
+    """
+    # The temperature increment for calculating the gibbs_PTT derivative.
+    dt = 0.001
+    t = 3.978 - 0.22072 * SA  # The initial guess of t_maxden.
+    gibbs_PTT = 1.1e-8  # The initial guess for g_PTT.
+    for Number_of_iterations in range(0, 3):
+        t_old = t
+        gibbs_PT = gibbs(n0, n1, n1, SA, t_old, p)
+        # Half way through the mod. method (McDougall and Wotherspoon, 2012)
+        t = t_old - gibbs_PT / gibbs_PTT
+        t_mean = 0.5 * (t + t_old)
+        gibbs_PTT = (gibbs(n0, n1, n1, SA, t_mean + dt, p) -
+                     gibbs(n0, n1, n1, SA, t_mean - dt, p)) / (dt + dt)
+        t = t_old - gibbs_PT / gibbs_PTT
+    # After three iterations of this modified Newton-Raphson iteration, the
+    # error in t_maxdensity_exact is typically no larger than 1x10^-15 deg C.
+    return t
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/gibbs/water_column_48.py b/gsw/gibbs/water_column_48.py
new file mode 100644
index 0000000..1955066
--- /dev/null
+++ b/gsw/gibbs/water_column_48.py
@@ -0,0 +1,344 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import numpy as np
+
+from .earth import grav
+from .constants import db2Pascal
+from ..utilities import match_args_return
+from .density_enthalpy_48 import rho_alpha_beta
+
+__all__ = ['IPV_vs_fNsquared_ratio',
+           'Nsquared',
+           'Turner_Rsubrho']
+
+
+#FIXME: @match_args_return
+def IPV_vs_fNsquared_ratio(SA, CT, p, p_ref=0):
+    r"""Calculates the ratio of the vertical gradient of potential density to
+    the vertical gradient of locally-referenced potential density.  This
+    ratio is also the ratio of the planetary Isopycnal Potential Vorticity
+    (IPV) to f times N^2, hence the name for this variable,
+    IPV_vs_fNsquared_ratio (see Eqn. (3.20.5) of IOC et al. (2010)).  The
+    reference sea pressure, p_ref, of the potential density surface must
+    have a constant value.
+
+    IPV_vs_fNsquared_ratio is evaluated at the mid pressure between the
+    individual data points in the vertical.  This function uses the
+    computationally-efficient 48-term expression for density in terms of
+    SA, CT and p (McDougall et al., 2011).
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure  [dbar]
+    p_ref : int, float, optional
+         reference pressure, default = 0
+
+    Returns
+    -------
+    IPV_vs_fNsquared_ratio : array_like
+         The ratio of the vertical gradient of potential density,
+         on the same (M-1)xN grid as p_mid. [unitless]
+         referenced to p_ref, to the vertical gradient of locally-
+         referenced potential density.
+
+    p_mid : array_like
+            Mid pressure between p grid [dbar]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA, CT, p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqn. (3.20.5).
+
+    ..[2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-03-23. Trevor McDougall & Paul Barker
+    """
+    p_ref = np.unique(np.asanyarray(p_ref))
+
+    # BUG
+    #if not np.isscalar(p_ref):
+        #raise ValueError('The reference pressure p_ref must be unique')
+
+    if SA.ndim == 1:
+        raise ValueError('There must be at least 2 columns.')
+
+    SA = np.maximum(SA, 0)
+
+    SA, CT, p, p_ref = np.broadcast_arrays(SA, CT, p, p_ref)
+
+    p_ref = p_ref[:-1, ...]
+
+    p_mid = 0.5 * (p[0:-1, ...] + p[1:, ...])
+    SA_mid = 0.5 * (SA[0:-1, ...] + SA[1:, ...])
+    CT_mid = 0.5 * (CT[0:-1, ...] + CT[1:, ...])
+
+    dSA = SA[0:-1, ...] - SA[1:, ...]
+    dCT = CT[0:-1, ...] - CT[1:, ...]
+
+    [dummy, alpha, beta] = rho_alpha_beta(SA_mid, CT_mid, p_mid)
+
+    _, alpha, beta = rho_alpha_beta(SA_mid, CT_mid, p_mid)
+    _, alpha_pref, beta_pref = rho_alpha_beta(SA_mid, CT_mid, p_ref)
+
+    """This function calculates IPV_vs_fNsquared_ratio using the
+    computationally efficient 48-term expression for density in terms of SA,
+    CT and p.  If one wanted to compute this with the full TEOS-10 Gibbs
+    function expression for density, the following lines of code will enable
+    this.
+
+    pt_mid = pt_from_CT(SA_mid, CT_mid)
+    pr0 = np.zeros_like(SA_mid)
+    t_mid = pt_from_t(SA_mid, pt_mid, pr0, p_mid)
+    beta = beta_const_CT_t_exact(SA_mid, t_mid, p_mid)
+    alpha = alpha_wrt_CT_t_exact(SA_mid, t_mid, p_mid)
+    beta_pref = beta_const_CT_t_exact(SA_mid, t_mid, p_ref)
+    alpha_pref = alpha_wrt_CT_t_exact(SA_mid, t_mid, p_ref)
+    """
+
+    numerator = dCT * alpha_pref - dSA * beta_pref
+    denominator = dCT * alpha - dSA * beta
+
+    """IPV_vs_fNsquared_ratio = np.zeros_like(SA_mid) * np.NaN
+    I = denominator != 0.
+    IPV_vs_fNsquared_ratio[I] = numerator[I] / denominator[I]"""
+
+    IPV_vs_fNsquared_ratio = numerator / denominator
+
+    return IPV_vs_fNsquared_ratio, p_mid
+
+
+## In the following, we are assuming the p dimension comes
+#  first.  This follows the matlab code, (Fortran order)
+#  but is unnatural in Python (C order).
+#  We might need to deal with this in a better way.
+
+ at match_args_return
+def Nsquared(SA, CT, p, lat=None):
+    r"""Calculates the buoyancy frequency squared (N^2)
+    (i.e. the Brunt-Väisälä frequency squared) at the
+    mid pressure from the equation::
+
+           2      2             beta.d(SA) - alpha.d(CT)
+         N   =  g   rho_local   ------------------------
+                                          dP
+
+    dP in the above formula is in Pascals
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure  [dbar]
+    lat : array_like, optional
+          latitude in decimal degrees north [-90..+90]
+          If lat is not supplied, a default gravitational acceleration of
+          9.7963 m/s^2 (Griffies, 2004) will be used.
+
+    Returns
+    -------
+    N2 : array_like
+         Brunt-Väisälä frequency squared [1 s :math:`-2`]
+    p_mid : array_like
+            Mid pressure between p grid [dbar]
+
+    Notes
+    -----
+    This routine uses rho from the computationally efficient 48-term expression
+    for density in terms of SA, CT and p.
+
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    IOC et al. (2010).  The GSW library function "infunnel(SA, CT, p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See section 3.10 and Eqn. (3.10.2).
+
+    ..[2] Griffies, S. M., 2004: Fundamentals of Ocean Climate Models.
+    Princeton, NJ: Princeton University Press, 518 pp + xxxiv.
+
+    Modifications:
+    2013-04-29. Trevor McDougall & Paul Barker
+    """
+
+    if lat is not None:
+        g = grav(lat, p)
+        SA, CT, p, g = np.broadcast_arrays(SA, CT, p, g)
+    else:
+        g = 9.7963  # Standard value from Griffies (2004).
+        SA, CT, p = np.broadcast_arrays(SA, CT, p)
+
+    ishallow = (slice(0, -1), Ellipsis)
+    ideep = (slice(1, None), Ellipsis)
+
+    def mid(x):
+        return 0.5 * (x[ideep] + x[ishallow])
+
+    def delta(x):
+        return x[ideep] - x[ishallow]
+
+    vars = SA, CT, p
+    SA_mid, CT_mid, p_mid = [mid(x) for x in vars]
+    dSA, dCT, dp = [delta(x) for x in vars]
+
+    rho_mid, alpha_mid, beta_mid = rho_alpha_beta(SA_mid, CT_mid, p_mid)
+
+    if lat is not None:
+        grav_mid = mid(g)
+    else:
+        grav_mid = g
+
+    N2 = (grav_mid ** 2 / db2Pascal) * (rho_mid / dp)
+    N2 *= (beta_mid * dSA - alpha_mid * dCT)
+
+    return N2, p_mid
+
+
+#FIXME: @match_args_return
+def Turner_Rsubrho(SA, CT, p):
+    r"""Calculates the Turner angle and the Rsubrho as a function of pressure
+    down a vertical water column.  These quantities express the relative
+    contributions of the vertical gradients of Conservative Temperature and
+    Absolute Salinity to the vertical stability (the square of the
+    Brunt-Väisälä Frequency squared, N^2).  `Tu` and `Rsubrho` are evaluated at
+    the mid pressure between the individual data points in the vertical.  This
+    function uses computationally-efficient 48-term expression for density in
+    terms of SA, CT and p (McDougall et al., 2011).  Note that in the
+    double-diffusive literature, papers concerned with the "diffusive" form of
+    double-diffusive convection often define the stability ratio as the
+    reciprocal of what is defined here as the stability ratio.
+
+    Parameters
+    ----------
+    SA : array_like
+         Absolute Salinity  [g/kg]
+    CT : array_like
+         Conservative Temperature [:math:`^\circ` C (ITS-90)]
+    p : array_like
+        sea pressure  [dbar]
+
+    Returns
+    -------
+    Tu : array_like
+         Turner angle, on the same (M-1)xN grid as p_mid. [degrees of rotation]
+    Rsubrho : array_like
+              Stability Ratio, on the same (M-1)xN grid as p_mid. [unitless]
+    p_mid : array_like
+            Mid pressure between p grid [dbar]
+
+    See Also
+    --------
+    TODO
+
+    Notes
+    -----
+    The 48-term equation has been fitted in a restricted range of parameter
+    space, and is most accurate inside the "oceanographic funnel" described in
+    McDougall et al. (2011).  The GSW library function "infunnel(SA, CT, p)" is
+    available to be used if one wants to test if some of one's data lies
+    outside this "funnel".
+
+    Examples
+    --------
+    TODO
+
+    References
+    ----------
+    .. [1] IOC, SCOR and IAPSO, 2010: The international thermodynamic equation
+    of seawater - 2010: Calculation and use of thermodynamic properties.
+    Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
+    UNESCO (English), 196 pp. See Eqns. (3.15.1) and (3.16.1).
+
+    ..[2] McDougall T.J., P.M. Barker, R. Feistel and D.R. Jackett, 2011:  A
+    computationally efficient 48-term expression for the density of
+    seawater in terms of Conservative Temperature, and related properties
+    of seawater.
+
+    Modifications:
+    2011-03-26. Trevor McDougall & Paul Barker
+    """
+
+    if SA.ndim == 1:
+        raise ValueError('There must be at least 2 columns.')
+
+    SA = np.maximum(SA, 0)
+
+    SA, CT, p = np.broadcast_arrays(SA, CT, p)
+
+    p_mid = 0.5 * (p[0:-1, ...] + p[1:, ...])
+    SA_mid = 0.5 * (SA[0:-1, ...] + SA[1:, ...])
+    CT_mid = 0.5 * (CT[0:-1, ...] + CT[1:, ...])
+
+    dSA = SA[0:-1, ...] - SA[1:, ...]
+    dCT = CT[0:-1, ...] - CT[1:, ...]
+
+    [dummy, alpha, beta] = rho_alpha_beta(SA_mid, CT_mid, p_mid)
+
+    """This function evaluates Tu and Rsubrho using the computationally
+    efficient 48-term expression for density in terms of SA, CT and p. If one
+    wanted to compute Tu and Rsubrho using the full TEOS-10 Gibbs function
+    expression for density, the following lines of code would do that.
+
+    pt_mid = pt_from_CT(SA_mid, CT_mid)
+    pr0 = np.zeros_like(SA_mid)
+    t_mid = pt_from_t(SA_mid, pt_mid, pr0, p_mid)
+    beta = beta_const_CT_t_exact(SA_mid, t_mid, p_mid)
+    alpha = alpha_wrt_CT_t_exact(SA_mid, t_mid, p_mid)
+    """
+
+    Tu = np.arctan2((alpha * dCT + beta * dSA), (alpha * dCT - beta * dSA))
+
+    Tu = Tu * (180 / np.pi)
+
+    Rsubrho = np.zeros_like(dSA) + np.NaN
+
+    Inz = dSA != 0
+    Rsubrho[Inz] = (alpha[Inz] * dCT[Inz]) / (beta[Inz] * dSA[Inz])
+
+    return Tu, Rsubrho, p_mid
+
+
+if __name__ == '__main__':
+    import doctest
+    doctest.testmod()
diff --git a/gsw/test/__init__.py b/gsw/test/__init__.py
new file mode 100644
index 0000000..026fed5
--- /dev/null
+++ b/gsw/test/__init__.py
@@ -0,0 +1 @@
+# dummy--just to make it a sub-package
diff --git a/gsw/test/check_functions.py b/gsw/test/check_functions.py
new file mode 100644
index 0000000..3cc6d88
--- /dev/null
+++ b/gsw/test/check_functions.py
@@ -0,0 +1,194 @@
+import os
+import sys
+import logging
+
+import numpy as np
+
+
+import gsw
+from gsw.gibbs import *
+from gsw.utilities import Bunch
+
+log = logging.getLogger()
+logging.basicConfig()
+
+try:
+    mfiledir = sys.argv[1]
+except IndexError:
+    mfiledir = "../../../../TEOS-10/matlab_gsw_V3_03"
+
+mfile = os.path.join(mfiledir, "gsw_check_functions.m")
+mfilelines = open(mfile, 'rt').readlines()
+
+
+def find(x):
+    """
+    Numpy equivalent to Matlab find.
+    """
+    return np.nonzero(x.flatten())[0]
+
+
+first_pass = []
+
+concat = False
+for line in mfilelines:
+    line = line.strip()
+    if concat:
+        if line.endswith('...'):
+            line = line[:-3]
+        first_pass[-1] += line
+        if line.endswith(';'):
+            concat = False
+        continue
+    if '=' in line and (line.startswith('gsw_') or line.startswith('[gsw_')):
+        if line.endswith('...'):
+            line = line[:-3]
+            concat = True
+        first_pass.append(line)
+
+second_pass = []
+
+for line in first_pass:
+    if not '(' in line:
+        continue
+    if 'which' in line:
+        continue
+    line = line.replace('gsw_', '')
+    if line.startswith('['):
+        line = line[1:].replace(']', '')
+    if line.endswith(';'):
+        line = line[:-1]
+    line = line.replace('(I)', '')  # For deltaSA_atlas.
+    second_pass.append(line)
+
+pairs = []
+
+for i in range(len(second_pass)):
+    if 'find(' in second_pass[i] and not 'find(' in second_pass[i-1]:
+        pairs.extend(second_pass[i-1:i+1])
+
+
+def group_or(line):
+    """
+    Numpy wart: using bitwise or as a fake elementwise logical or,
+    we need to add parentheses.
+    """
+    if not ('find(' in line and '|' in line):
+        return line
+    i0 = line.index('find(') + 5
+    head = line[:i0]
+    tail = line[i0:]
+    parts = tail.replace('|', ') | (')
+    new = head + '(' + parts + ')'
+    return new
+
+final = [group_or(line) for line in pairs]
+
+
+class FunctionCheck(object):
+    def __init__(self, linepair):
+        self.linepair = linepair
+        self.runline = linepair[0]
+        self.testline = linepair[1]
+
+        # parse the line that runs the function
+        head, tail = self.runline.split('=')
+        self.outstrings = [s.strip() for s in head.split(',')]
+        self.outstr = ','.join(self.outstrings)
+        funcstr, argpart = tail.split('(', 1)
+        self.name = funcstr.strip()
+        self.argstrings = [s.strip() for s in argpart[:-1].split(',')]
+        self.argstr = ','.join(self.argstrings)
+
+        # parse the line that checks the results
+        head, tail = self.testline.split('=', 1)
+        self.resultstr = head.strip()  # cv.I*
+        head, tail = tail.split('(', 1)
+        self.teststr = tail.strip()[:-1]   # argument of "find()"
+
+        # To be set when run() is successful
+        self.outlist = None
+        self.result = None   # will be a reference to the cv.I* array
+        self.passed = None   # will be set to True or False
+
+        # To be set if run() is not successful
+        self.exception = None
+
+    def __str__(self):
+        return self.runline
+
+    def run(self):
+        try:
+            exec(self.runline)
+            # In Matlab, the number of output arguments varies
+            # depending on the LHS of the assignment, but Python
+            # always returns the full set.  Here we handle the
+            # case where Python is returning 2 (or more) but
+            # the LHS is assigning only the first.
+            if len(self.outstrings) == 1:
+                if isinstance(eval(self.outstr), tuple):
+                    exec("%s = %s[0]" % (self.outstr, self.outstr))
+            self.outlist = [eval(s) for s in self.outstrings]
+            exec(self.testline)
+            self.result = eval(self.resultstr)
+            self.passed = len(self.result) == 0
+
+        except Exception as e:
+            self.exception = e
+
+checks = []
+for i in range(0, len(final), 2):
+    pair = final[i:i+2]
+    checks.append(FunctionCheck(pair))
+
+
+datadir = os.path.join(os.path.dirname(gsw.utilities.__file__), 'data')
+cv = Bunch(np.load(os.path.join(datadir, 'gsw_cv_v3_0.npz')))
+cf = Bunch()
+
+for fc in checks:
+    fc.run()
+
+passes = [f.name for f in checks if f.passed]
+failures = [f.name for f in checks if f.passed is False]
+
+run_problems = [f.name for f in checks if f.exception is not None]
+
+etypes = [NameError, UnboundLocalError, TypeError, AttributeError]
+ex_dict = dict()
+for exc in etypes:
+    elist = [(f.name, f.exception) for f in checks if
+             isinstance(f.exception, exc)]
+    ex_dict[exc] = elist
+
+print "\n%s tests were translated from gsw_check_functions.m" % len(checks)
+print "\n%s tests ran with no error and with correct output" % len(passes)
+print "\n%s tests had an output mismatch:" % len(failures)
+print " ", "\n  ".join(failures)
+
+print "\n%s exceptions were raised as follows:" % len(run_problems)
+for exc in etypes:
+    print "  ", exc.__name__
+    strings = ["     %s : %s" % e for e in ex_dict[exc]]
+    print "\n".join(strings)
+    print ""
+
+checkbunch = Bunch([(c.name, c) for c in checks])
+
+
+def find_arguments():
+    argset = set()
+    for c in checks:
+        argset.update(c.argstrings)
+    argsetlist = list(argset)
+    argsetlist.sort()
+    return argsetlist
+
+
+def find_arglists():
+    alset = set()
+    for c in checks:
+        alset.update([c.argstr])
+    arglists = list(alset)
+    arglists.sort()
+    return arglists
diff --git a/gsw/test/signatures.py b/gsw/test/signatures.py
new file mode 100644
index 0000000..fddcdb1
--- /dev/null
+++ b/gsw/test/signatures.py
@@ -0,0 +1,178 @@
+"""
+Functions for parsing gsw mfiles.
+
+These might become useful in a scheme for automating docstring
+generation.
+"""
+
+import os
+import sys
+import glob
+from collections import OrderedDict
+
+import logging
+
+from gsw.gibbs import *
+
+log = logging.getLogger()
+logging.basicConfig()
+
+try:
+    mfiledir = sys.argv[1]
+except IndexError:
+    mfiledir = "../../../../TEOS-10/matlab_gsw_V3_03"
+
+subdirs = ['./', 'library', 'thermodynamics_from_t']
+
+mfile = os.path.join(mfiledir, "gsw_check_functions.m")
+mfilelines = open(mfile, 'rt').readlines()
+
+
+def funcline_parts(base, topline):
+    """
+    Parse the m-file function declaration.
+
+    Returns [base, arguments, outputs] where base is the
+    function name without the gsw_ prefix, arguments is a
+    tuple of strings, and outputs is a tuple of strings.
+    """
+
+    cmd = topline.split(None, 1)[1]
+
+    parts = cmd.split('=')
+    if len(parts) == 1:
+        out = ''
+        func_call = parts[0].strip()
+    else:
+        out = parts[0].strip()
+        if out.startswith('['):
+            out = out[1:-1]
+        func_call = parts[1].strip()
+    out = [a.strip() for a in out.split(',')]
+
+    parts = func_call.split('(')
+    if len(parts) == 1:
+        argstring = ''
+    else:
+        argstring = parts[1][:-1]
+
+    args = [a.strip() for a in argstring.split(',')]
+
+    parts = [base[4:], tuple(args), tuple(out)]
+    return parts
+
+help_sections = ['USAGE:',
+                 'DESCRIPTION:',
+                 'INPUT:',
+                 'OPTIONAL:',
+                 'OUTPUT:',
+                 'AUTHOR:',
+                 'VERSION NUMBER:',
+                 'REFERENCES:',
+                 ]
+
+
+def helptext_parts(lines):
+    """
+    Parse the help text from gsw m-files.
+
+    Returns [lines, indexdict], where lines are the lines of
+    text with extraneous material removed, and indexdict is
+    a dictionary in which the keys are the help sections and
+    the values are the indices into lines where the section
+    titles are found.
+    """
+    helplines = []
+    parts = OrderedDict()
+    for line in lines[2:]:
+        line = line.rstrip()
+        if line.startswith('%'):
+            if line.endswith('=========================='):
+                continue
+            helplines.append(line[1:])
+        else:
+            break
+    for i, line in enumerate(helplines):
+        for section in help_sections:
+            if section in line:
+                parts[section] = i
+
+    return helplines, parts
+
+
+def function_parts(subdir='./'):
+    """
+    Parse the gsw m-files in a given subdirectory.
+
+    Returns a list of parts: function base name, arguments,
+    inputs, and the help lines with a section index dictionary.
+    """
+
+    d = os.path.join(mfiledir, subdir)
+    mfilelist = glob.glob(os.path.join(d, '*.m'))
+    partslist = []
+    for fpath in mfilelist:
+        base = os.path.basename(fpath)[:-2]
+        if not base.startswith('gsw_') or base == 'gsw_check_functions':
+            continue
+        lines = open(fpath).readlines()
+        topline = lines[0].strip()
+        if not topline.startswith('function'):
+            log.warn("path %s, topline is\n%s", fpath, topline)
+            continue
+
+        parts = funcline_parts(base, topline)
+
+        parts.append(helptext_parts(lines))
+
+        partslist.append(parts)
+
+    return partslist
+
+
+def arguments(partslist):
+    args = set()
+    for entry in partslist:
+        args.update(entry[1])
+
+    arglist = list(args)
+    arglist.sort()
+    return arglist
+
+
+def arglists(partslist):
+    args = set()
+    for entry in partslist:
+        args.update([', '.join(entry[1])])
+
+    arglist = list(args)
+    arglist.sort()
+    return arglist
+
+
+def funclist_by_arg(partslist):
+    out = dict()
+    for entry in partslist:
+        if entry[1] not in out:
+            out[entry[1]] = []
+        out[entry[1]].append(entry[0])
+    return out
+
+
+def help_chunk(helptuple, sect):
+    lines, secdict = helptuple
+    sections = secdict.keys()
+    ind = secdict.values()
+    try:
+        i0 = sections.index(sect)
+    except ValueError:
+        return []   # or None?
+    # Assuming the sections are always in the expected order, this will
+    # work; otherwise we would have to look for the nearest section index
+    # after the one found.
+    return lines[ind[i0]:ind[i0 + 1]]
+
+
+def funcs_with_descriptions(partslist):
+    fdlist = [(p[0], help_chunk(p[3], 'DESCRIPTION:')) for p in partslist]
+    return OrderedDict(fdlist)
diff --git a/gsw/test/test_check_values.py b/gsw/test/test_check_values.py
new file mode 100644
index 0000000..564eaaf
--- /dev/null
+++ b/gsw/test/test_check_values.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+
+"""Unit tests using the check values from the version 3 documentation,
+http://www.teos-10.org/pubs/gsw/html/gsw_contents.html."""
+
+import sys
+import unittest
+import numpy as np
+import numpy.testing
+
+import gsw
+
+# Standard values for arguments from
+# http://www.teos-10.org/pubs/gsw/html/gsw_contents.html
+C = [34.5487, 34.7275, 34.8605, 34.6810, 34.5680, 34.5600]
+t = [28.7856, 28.4329, 22.8103, 10.2600,  6.8863,  4.4036]
+p = [10, 50, 125, 250, 600, 1000]
+
+# Salinities
+#SP = [34.5487, 34.7275, 34.8605, 34.6810, 34.5680, 34.5600]
+#SA = [34.7118, 34.8915, 35.0256, 34.8472, 34.7366, 34.7324]
+#Sstar = [34.7115, 34.8912, 35.0247, 34.8436, 34.7291, 34.7197]
+
+# Temperatures
+#t = [28.7856, 28.4329, 22.8103, 10.2600,  6.8863,  4.4036]
+#pt = [28.7832, 28.4209, 22.7850, 10.2305,  6.8292,  4.3245]
+#CT = [28.8099, 28.4392, 22.7862, 10.2262,  6.8272,  4.3236]
+#t48 = [29, 28, 23, 10, 7, 4]
+#t68 = [29, 28, 23, 10, 7, 4]
+
+# Other
+#p = [10, 50, 125, 250, 600, 1000]
+#z = [10, 50, 125, 250, 600, 1000]
+#rho = [1021.839, 1022.262, 1024.426, 1027.792, 1029.839, 1032.002]
+#entropy = [400.3892, 395.4378, 319.8668, 146.7910,  98.6471,  62.7919]
+#lon = 188
+#lat = 4
+
+
+class Test_standard(unittest.TestCase):
+#class Test_standard(numpy.testing.TestCase):
+
+    # ----------------------
+    # practical_salinity.py
+    # ----------------------
+
+    def test_SP_from_C(self):
+        """Practical Salinity from Conductivity"""
+        output = gsw.SP_from_C(C, t, p)
+        check_values = np.array((20.009869599086951,
+                                 20.265511864874270,
+                                 22.981513062527689,
+                                 31.204503263727982,
+                                 34.032315787432829,
+                                 36.400308494388170))
+        numpy.testing.assert_array_equal(output, check_values)
+
+# -----------------------------------------------
+if __name__ == '__main__':
+    # Verbose output.
+    suite = unittest.TestLoader().loadTestsFromTestCase(Test_standard)
+    a = unittest.TextTestRunner(verbosity=2).run(suite)
+    if a.errors or a.failures:
+        sys.exit(1)
+    #unittest.main()
+    #numpy.testing.test()
diff --git a/gsw/test/test_octave.py b/gsw/test/test_octave.py
new file mode 100644
index 0000000..442996a
--- /dev/null
+++ b/gsw/test/test_octave.py
@@ -0,0 +1,208 @@
+# -*- coding: utf-8 -*-
+#
+# test_octave.py
+#
+# purpose:  Quick "compare test" with octave results.
+# author:   Filipe P. A. Fernandes
+# e-mail:   ocefpaf at gmail
+# web:      http://ocefpaf.tiddlyspot.com/
+# created:  13-Jun-2013
+# modified: Tue 02 Jul 2013 07:45:17 PM BRT
+#
+# obs:  This is different from `test_check_values.py`, that tests
+# against the results in the docs, `test_octave.py` uses same input values to
+# run both python and Matlab versions (using Octave).
+#
+# This is not a thorough test, just an "ad hoc" test to compare when a new
+# Matlab version is released.
+#
+
+import os
+import sys
+from collections import OrderedDict
+
+import numpy as np
+
+from oct2py import octave
+from oct2py._utils import Oct2PyError
+
+import gsw
+
+try:
+    path = sys.argv[1]
+except IndexError:
+    path = "./matlab_gsw_v3_03"
+
+
+# We have to supply a fake superiorfloat function for octave.
+# We are writing it in the local directory, which is not a nice
+# thing to do; maybe this can be improved later.
+
+_sfloat = """function out = superiorfloat(varargin)
+out = 'double';
+"""
+open('superiorfloat.m', 'wt').write(_sfloat)
+
+
+if not os.path.exists(path):
+    raise ValueError("matlab gsw path %s not found" % path)
+
+_ = octave.addpath(octave.genpath(path))
+_ = octave.addpath('./')
+
+
+def compare_results(name, function, args):
+    args = [values.get(arg) for arg in args]
+    print(name)
+
+    try:  # Python.
+        res = function(*args)
+    except:
+        print('%s: python runtime error' % name)
+        raise
+        return 'no_python'
+
+    nout = 1
+    if isinstance(res, tuple):
+        nout = len(res)
+        res = res[0]
+
+    try:  # Octave.
+        val = octave.call('gsw_%s' % name, *args, verbose=True, nout=nout)
+        if nout > 1:
+            val = val[0]
+    except Oct2PyError:
+        print('%s: Octave runtime error' % name)
+        print("python:\n%s" % res)
+        return 'no_octave'
+
+    try:
+        val = val.flatten()
+        perfect = (val == res).all()
+    except:
+        print('%s: Comparison failed' % name)
+        print("octave:\n%s" % val)
+        print("python:\n%s" % res)
+        return 'no_comparison'
+    if np.allclose(val, res, rtol=1e-15, atol=0):
+        print('%s: Passed' % name)
+        return 'passed'
+    else:
+        print('%s: Failed' % name)
+        print("octave:\n%s" % val)
+        print("python:\n%s" % res)
+        return 'failed'
+    print('')
+
+values = dict(C=np.array([34.5487, 34.7275, 34.8605, 34.6810, 34.568, 34.56]),
+              t=np.array([28.7856, 28.4329, 22.8103, 10.2600, 6.8863, 4.4036]),
+              p=np.array([10., 50., 125., 250., 600., 1000.]),
+              SP=np.array([34.5487, 34.7275, 34.8605, 34.6810, 34.5680,
+                           34.5600]),
+              SA=np.array([34.7118, 34.8915, 35.0256, 34.8472, 34.7366,
+                           34.7324]),
+              CT=np.array([28.7856, 28.4329, 22.8103, 10.2600, 6.8863,
+                           4.4036]),
+              rho=np.array([1021.8484, 1022.2647, 1024.4207, 1027.7841,
+                            1029.8287, 1031.9916]),
+              ps=0, pt=0, pp=0,
+              lat=np.array([4., 4., 4., 4., 4., 4.]),
+              lon=np.array([188., 188., 188., 188., 188., 188.]),
+              pt0=np.array([28.8099, 28.4392, 22.7862, 10.2262, 6.8272,
+                            4.3236]),
+              spycnl=np.array([21.8482, 22.2647, 24.4207, 27.7841, 29.8287,
+                               31.9916]),
+              A='gn',  # or s2 for sigma2; but then spycnl would need to change
+              # Also, the matlab code is incorrect for the s2 case.
+              p_i=np.array([500.0, 600.0, 700.0]),
+              # Baltic.
+              SAb=np.array([6.6699, 6.7738, 6.9130, 7.3661, 7.5862, 10.3895]),
+              SPb=np.array([6.5683, 6.6719, 6.8108, 7.2629, 7.4825, 10.2796]),
+              latb=np.array([59., 59., 59., 59., 59., 59.]),
+              lonb=np.array([20., 20., 20., 20., 20., 20.])
+              )
+# Functions.
+library = OrderedDict({
+    # library.py
+    'deltaSA_atlas': (gsw.library.deltaSA_atlas, ('p', 'lon', 'lat')),
+    'enthalpy_SSO_0_p': (gsw.library.enthalpy_SSO_0_p, ('p')),
+    'entropy_part': (gsw.library.entropy_part, ('SA', 't', 'p')),
+    'entropy_part_zerop': (gsw.library.entropy_part_zerop, ('SA', 'pt0')),
+    'Fdelta': (gsw.library.Fdelta, ('p', 'lon', 'lat')),
+    'gibbs': (gsw.library.gibbs, ('ps', 'pt', 'pp', 'SA', 't', 'p')),
+    'gibbs_pt0_pt0': (gsw.library.gibbs_pt0_pt0, ('SA', 'pt0')),
+    'Hill_ratio_at_SP2': (gsw.library.Hill_ratio_at_SP2, ('t')),
+    'infunnel': (gsw.library.infunnel, ('SA', 'CT', 'p')),
+    # FIXME: There is a problem with the argument handling in interp_SA_CT.
+    'interp_ref_cast': (gsw.library.interp_ref_cast, ('spycnl', 'A')),
+    'interp_SA_CT': (gsw.library.interp_SA_CT, ('SA', 'CT', 'p', 'p_i')),
+    'SAAR': (gsw.library.SAAR, ('p', 'lon', 'lat')),
+    'SA_from_SP_Baltic': (gsw.library.SA_from_SP_Baltic, ('SPb', 'lonb',
+                                                          'latb')),
+    'specvol_SSO_0_p': (gsw.library.specvol_SSO_0_p, ('p')),
+    'SP_from_SA_Baltic': (gsw.library.SP_from_SA_Baltic, ('SAb', 'lonb',
+                                                          'latb')),
+    # thermodynamics_from_t.py
+    #'adiabatic_lapse_rate_from_t': (gsw.adiabatic_lapse_rate_from_t,
+                                    #('SA', 't', 'p')),
+    'alpha_wrt_CT_t_exact': (gsw.alpha_wrt_CT_t_exact, ('SA', 't', 'p')),
+    'alpha_wrt_pt_t_exact': (gsw.alpha_wrt_pt_t_exact, ('SA', 't', 'p')),
+    'alpha_wrt_t_exact': (gsw.alpha_wrt_t_exact, ('SA', 't', 'p')),
+    'beta_const_CT_t_exact': (gsw.beta_const_CT_t_exact, ('SA', 't', 'p')),
+    'beta_const_pt_t_exact': (gsw.beta_const_pt_t_exact, ('SA', 't', 'p')),
+    'beta_const_t_exact': (gsw.beta_const_t_exact, ('SA', 't', 'p')),
+    'chem_potential_relative_t_exact': (gsw.chem_potential_relative_t_exact,
+                                        ('SA', 't', 'p')),
+    'chem_potential_salt_t_exact': (gsw.chem_potential_salt_t_exact,
+                                    ('SA', 't', 'p')),
+    'chem_potential_water_t_exact': (gsw.chem_potential_water_t_exact,
+                                     ('SA', 't', 'p')),
+    'cp_t_exact': (gsw.cp_t_exact, ('SA', 't', 'p')),
+    #'deltaSA_from_rho_t_exact': (gsw.deltaSA_from_rho_t_exact,
+                                 #('rho', 'SP', 't', 'p')),
+    'dynamic_enthalpy_t_exact': (gsw.dynamic_enthalpy_t_exact,
+                                 ('SA', 't', 'p')),
+    'enthalpy_t_exact': (gsw.enthalpy_t_exact, ('SA', 't', 'p')),
+    'entropy_t_exact': (gsw.entropy_t_exact, ('SA', 't', 'p')),
+    'Helmholtz_energy_t_exact': (gsw.Helmholtz_energy_t_exact,
+                                 ('SA', 't', 'p')),
+    'internal_energy_t_exact': (gsw.internal_energy_t_exact, ('SA', 't', 'p')),
+    'isochoric_heat_cap_t_exact': (gsw.isochoric_heat_cap_t_exact,
+                                   ('SA', 't', 'p')),
+    'kappa_const_t_exact': (gsw.kappa_const_t_exact, ('SA', 't', 'p')),
+    'kappa_t_exact': (gsw.kappa_t_exact, ('SA', 't', 'p')),
+    'osmotic_coefficient_t_exact': (gsw.osmotic_coefficient_t_exact,
+                                    ('SA', 't', 'p')),
+    'osmotic_pressure_t_exact': (gsw.osmotic_pressure_t_exact,
+                                 ('SA', 't', 'pw')),
+    'pot_rho_t_exact': (gsw.pot_rho_t_exact, ('SA', 't', 'p', 'p_ref')),
+    'rho_t_exact': (gsw.rho_t_exact, ('SA', 't', 'p')),
+    'SA_from_rho_t_exact': (gsw.SA_from_rho_t_exact, ('rho', 't', 'p')),
+    #'SA_from_rho_t': (gsw.SA_from_rho_t, ('rho', 't', 'p')),
+    'sigma0_pt0_exact': (gsw.sigma0_pt0_exact, ('SA', 'pt0')),
+    'sound_speed_t_exact': (gsw.sound_speed_t_exact, ('SA', 't', 'p')),
+    'specvol_anom_t_exact': (gsw.specvol_anom_t_exact, ('SA', 't', 'p')),
+    'specvol_t_exact': (gsw.specvol_t_exact, ('SA', 't', 'p')),
+    't_from_rho_exact': (gsw.t_from_rho_exact, ('rho', 'SA', 'p')),
+    't_maxdensity_exact': (gsw.t_maxdensity_exact, ('SA', 'p')),
+    # absolute_salinity_sstar_ct.py
+    'SA_from_SP': (gsw.SA_from_SP, ('SP', 'p', 'lon', 'lat'))})
+
+
+if __name__ == '__main__':
+    outcomes = ['passed', 'no_octave', 'no_python', 'failed', 'no_comparison']
+    results = dict([(k, list()) for k in outcomes])
+
+    for name, (function, args) in library.iteritems():
+        ret = compare_results(name=name, function=function, args=args)
+        results[ret].append(name)
+
+    #os.remove('superiorfloat.m')
+
+    print('\nSummary:')
+    print('passed:\n  %s' % '\n  '.join(results['passed']))
+    print('octave call failed:\n  %s' % '\n  '.join(results['no_octave']))
+    print('python call failed:\n  %s' % '\n  '.join(results['no_python']))
+    print('results did not match:\n  %s' % '\n  '.join(results['failed']))
+    print('comparison failed:\n  %s' % '\n  '.join(results['no_comparison']))
+    print('')
diff --git a/gsw/test/test_profiles.py b/gsw/test/test_profiles.py
new file mode 100644
index 0000000..62acae9
--- /dev/null
+++ b/gsw/test/test_profiles.py
@@ -0,0 +1,339 @@
+# -*- coding: utf-8 -*-
+
+"""Unit check for standard profiles for the Gibbs Sea Water python package."""
+
+# Auto generates and perform a set of test methods like:
+#
+#    def test_funct(self):
+#        out = gsw.func(arg1_chck_cast, arg2_chck_cast, ...)
+#        maxdiff = np.nanmax(abs(out - cv.func)
+#        self.assertTrue(maxdiff < cv.func_ca)
+#
+# cv is a Bunch instance with all the check values from
+# the profile-file
+# The func, args are taken from the main dictionary below
+# giving a alphabetical table of all functions and their arguments
+#
+# Extra aliasing attributes are added to cv if the naming
+# convention is broken, if the targets or the attributes
+# in the check file has "wrong" names
+#
+
+
+# Bjørn Ådlandsvik <bjorn at imr.no>
+# 2011-03-03
+
+import os
+import unittest
+import functools  # Requires python 2.5.
+import numpy as np
+
+import gsw
+from gsw.utilities import Bunch
+
+
+# Read data file with check value profiles.
+datadir = os.path.join(os.path.dirname(gsw.utilities.__file__), 'data')
+cv = Bunch(np.load(os.path.join(datadir, 'gsw_cv_v3_0.npz')))
+cf = Bunch(np.load(os.path.join(datadir, 'gsw_cf.npz')))
+
+# Main dictionary of functions with arguments. Could perhaps be auto-generated.
+function_arguments = dict(
+    # absolute_salinity_sstar_ct.py
+    SA_from_SP=('SP', 'p', 'long', 'lat'),  # uses SAAR
+    #Sstar_from_SP  TODO
+    CT_from_t=('SA', 't', 'p'),
+    #
+    # thermodynamics_from_t.py
+    rho_t_exact=('SA', 't', 'p'),
+    pot_rho_t_exact=('SA', 't', 'p', 'pr'),
+    sigma0_pt0_exact=('SA', 'pt0'),
+    alpha_wrt_CT_t_exact=('SA', 't', 'p'),
+    alpha_wrt_pt_t_exact=('SA', 't', 'p'),
+    alpha_wrt_t_exact=('SA', 't', 'p'),
+    beta_const_CT_t_exact=('SA', 't', 'p'),
+    beta_const_pt_t_exact=('SA', 't', 'p'),
+    beta_const_t_exact=('SA', 't', 'p'),
+    specvol_t_exact=('SA', 't', 'p'),
+    specvol_anom_t_exact=('SA', 't', 'p'),
+    sound_speed_t_exact=('SA', 't', 'p'),
+    kappa_t_exact=('SA', 't', 'p'),
+    kappa_const_t_exact=('SA', 't', 'p'),
+    internal_energy_t_exact=('SA', 't', 'p'),
+    enthalpy_t_exact=('SA', 't', 'p'),
+    dynamic_enthalpy_t_exact=('SA', 't', 'p'),
+    SA_from_rho_t_exact=('rho', 't', 'p'),
+    #t_from_rho_exact=('rho', 'SA', 'p'),
+    t_maxdensity_exact=('SA', 'p'),
+    #entropy_t_exact=('SA', 't', 'p'),             # Not in V3.03
+    cp_t_exact=('SA', 't', 'p'),
+    isochoric_heat_cap_t_exact=('SA', 't', 'p'),
+    chem_potential_relative_t_exact=('SA', 't', 'p'),
+    chem_potential_water_t_exact=('SA', 't', 'p'),
+    chem_potential_salt_t_exact=('SA', 't', 'p'),
+    Helmholtz_energy_t_exact=('SA', 't', 'p'),
+    # adiabatic_lapse_rate_t_exact=('SA', 't', 'p'),  # Not in V3.03
+    osmotic_coefficient_t_exact=('SA', 't', 'p'),
+    osmotic_pressure_t_exact=('SA', 't', 'p'),
+    #
+    # conversion.py
+    #deltaSA_from_SP  TODO
+    #SA_Sstar_from_SP  TODO
+    SR_from_SP=('SP',),
+    SP_from_SR=('SR',),
+    #SP_from_SA=('SA', 'p', 'long', 'lat'),  TODO
+    #Sstar_from_SA=('SA', 'p', 'long', 'lat'),  TODO
+    #SA_from_Sstar=('Sstar', 'p', 'long', 'lat'), TODO
+    #SP_from_Sstar=('Sstar', 'p', 'long', 'lat'),  TODO
+    pt_from_CT=('SA', 'CT'),
+    t_from_CT=('SA', 'CT', 'p'),
+    CT_from_pt=('SA', 'pt'),
+    pot_enthalpy_from_pt=('SA', 'pt'),
+    pt0_from_t=('SA', 't', 'p'),
+    pt_from_t=('SA', 't', 'p', 'pr'),
+    t90_from_t48=('t',),
+    t90_from_t68=('t',),
+    z_from_p=('p', 'lat'),
+    p_from_z=('z', 'lat'),
+    depth_from_z=('z'),
+    z_from_depth=('depth',),
+    Abs_Pressure_from_p=('p',),
+    p_from_Abs_Pressure=('Abs_Pressure_from_p',),
+    entropy_from_CT=('SA', 'CT'),
+    CT_from_entropy=('SA', 'entropy'),
+    entropy_from_pt=('SA', 'pt'),
+    pt_from_entropy=('SA', 'entropy'),
+    molality_from_SA=('SA',),
+    ionic_strength_from_SA=('SA',),
+    #
+    # density_enthalpy_48_ct.py
+    #rho_CT  TODO
+    #alpha_CT  TODO
+    #beta_CT  TODO
+    #rho_alpha_beta_CT  TODO
+    #specvol_CT  TODO
+    #specvol_anom_CT  TODO
+    #sigma0_CT  TODO
+    #sigma1_CT  TODO
+    #sigma2_CT  TODO
+    #sigma3_CT  TODO
+    #sigma4_CT  TODO
+    #sound_speed_CT  TODO
+    #internal_energy_CT  TODO
+    #enthalpy_CT  TODO
+    #enthalpy_diff_CT  TODO
+    #dynamic_enthalpy_CT  TODO
+    #SA_from_rho_CT  TODO
+    #CT_from_rho  TODO
+    #CT_maxdensity TODO
+    #
+    # density_enthalpy_48.py NOTE: None are tested on Matlab.
+    rho=('SA', 'CT', 'p'),
+    alpha=('SA', 'CT', 'p'),
+    beta=('SA', 'CT', 'p'),
+    rho_alpha_beta=('SA', 'CT', 'p'),
+    specvol=('SA', 'CT', 'p'),
+    specvol_anom=('SA', 'CT', 'p'),
+    sigma0=('SA', 'CT'),
+    sigma1=('SA', 'CT'),
+    sigma2=('SA', 'CT'),
+    sigma3=('SA', 'CT'),
+    sigma4=('SA', 'CT'),
+    sound_speed=('SA', 'CT', 'p'),
+    internal_energy=('SA', 'CT', 'p'),
+    enthalpy=('SA', 'CT', 'p'),
+    enthalpy_diff=('SA', 'CT', 'p_shallow', 'p_deep'),
+    dynamic_enthalpy=('SA', 'CT', 'p'),
+    SA_from_rho=('rho_cf', 'CT', 'p'),
+    #
+    # density_enthalpy_ct_exact.py
+    rho_CT_exact=('SA', 'CT', 'p'),
+    alpha_CT_exact=('SA', 'CT', 'p'),
+    beta_CT_exact=('SA', 'CT', 'p'),
+    rho_alpha_beta_CT_exact=('SA', 'CT', 'p'),
+    specvol_CT_exact=('SA', 'CT', 'p'),
+    specvol_anom_CT_exact=('SA', 'CT', 'p'),
+    sigma0_CT_exact=('SA', 'CT'),
+    sigma1_CT_exact=('SA', 'CT'),
+    sigma2_CT_exact=('SA', 'CT'),
+    sigma3_CT_exact=('SA', 'CT'),
+    sigma4_CT_exact=('SA', 'CT'),
+    sound_speed_CT_exact=('SA', 'CT', 'p'),
+    internal_energy_CT_exact=('SA', 'CT', 'p'),
+    enthalpy_CT_exact=('SA', 'CT', 'p'),
+    enthalpy_diff_CT_exact=('SA', 'CT', 'p_shallow', 'p_deep'),
+    dynamic_enthalpy_CT_exact=('SA', 'CT', 'p'),
+    SA_from_rho_CT_exact=('rho', 'CT', 'p'),
+    # FIXME: NameError: 't_from_rho_exact' not defined
+    #CT_from_rho_exact=('rho', 'SA', 'p'),
+    CT_maxdensity_exact=('SA', 'p'),
+    #
+    # derivatives.py
+    #CT_first_derivatives=('SA', 'pt'),  FIXME: out should tuple.
+    #CT_second_derivatives=('SA', 'pt'),  FIXME: out should tuple.
+    #enthalpy_first_derivatives=('SA', 'CT', 'p'),  FIXME: out should tuple.
+    #enthalpy_second_derivatives=('SA', 'CT', 'p'),  FIXME: out should tuple.
+    #entropy_first_derivatives=('SA', 'CT'),  FIXME: out should tuple.
+    #entropy_second_derivatives=('SA', 'CT'),  FIXME: out should tuple.
+    #pt_first_derivatives=('SA', 'CT'),  FIXME: out should tuple.
+    #pt_second_derivatives=('SA', 'CT'),  FIXME: out should tuple.
+    #
+    # earth.py
+    f=('lat',),
+    grav=('lat', 'p'),
+    distance=('long', 'lat', 'p'),
+    #
+    # freezing.py
+    # NOTE: The matlab test does not use saturation_fraction=1 which is the
+    # default!  It uses saturation_fraction=0.
+    CT_freezing=('SA', 'p', 'sat0'),
+    t_freezing=('SA', 'p', 'sat0'),
+    brineSA_CT=('CT_freezing', 'p', 'sat05'),
+    brineSA_t=('t_freezing', 'p', 'sat05'),
+    #
+    # geostrophic.py
+    #geostrophic_velocity  TODO
+    #
+    # geostrophic_48.py
+    #geo_strf_dyn_height  TODO
+    #geo_strf_dyn_height_pc  TODO
+    #geo_strf_isopycnal  TODO
+    #geof_str_isopycnal_pc  TODO
+    #geo_strf_Montgomery  TODO
+    #geo_strf_Cunningham  TODO
+    #
+    # isobaric.py
+    #latentheat_melting  TODO
+    #latentheat_evap_CT  TODO
+    #latentheat_evap_t=('SA', 't'),
+    #
+    # library.py
+    #gibbs
+    #SAAR=('p', 'long', 'lat'),          #  not directly tested on Matlab
+    Fdelta=('p', 'long', 'lat'),
+    deltaSA_atlas=('p', 'long', 'lat'),
+    #SA_from_SP_Baltic=('SP', 'long', 'lat'),  NOTE: Not tested on Matlab.
+    #SP_from_SA_Baltic=('SA', 'long', 'lat'),  NOTE: Not tested on Matlab.
+    #infunnel=('SA', 'CT', 'p'),  NOTE: Not tested on Matlab.
+    #entropy_part=('SA', 'CT', 'p'),  NOTE: Not tested on Matlab.
+    #entropy_part_zerop=('SA', 'pt0'),  NOTE: Not tested on Matlab.
+    #interp_ref_cast=('spycnl', 'gn'),  NOTE: Not tested on Matlab.
+    #interp_SA_CT=('SA', 'CT', 'p', 'p_i'),  NOTE: Not tested on Matlab.
+    #gibbs_pt0_pt0=('SA', 'pt0'),  NOTE: Not tested on Matlab.
+    #specvol_SSO_0_p=('p'),  NOTE: Not tested on Matlab.
+    #enthalpy_SSO_0_p=('p',),  FIXME: No enthalpy_SSO_0_p.
+    #Hill_ratio_at_SP2= ('t'),  FIXME: No Hill_ratio_at_SP2.
+    #
+    #neutral_nonlinear_48.py
+    #cabbeling,  TODO
+    #thermobaric,  TODO
+    #isopycnal_slope_ratio,  TODO
+    #isopycnal_vs_ntp_CT_ratio,  TODO
+    #ntp_pt_vs_CT_ratio  TODO
+    #
+    # practical_salinity.py
+    SP_from_C=('C', 't', 'p'),
+    C_from_SP=('SP', 't', 'p'),
+    SP_from_R=('R_cf', 't', 'p'),
+    R_from_SP=('SP', 't', 'p'),
+    SP_salinometer=('Rt', 't'),
+    #SP_from_SK=('SK',),  NOTE: Not tested on Matlab.
+    #SK_from_SP=('SP',),  NOTE: Not tested on Matlab.
+    #
+    # steric.py
+    #steric_height=TODO
+    #
+    # water_column_48.py
+    Nsquared=('SA', 'CT', 'p', 'lat'),
+    Turner_Rsubrho=('SA', 'CT', 'p'),
+    IPV_vs_fNsquared_ratio=('SA', 'CT', 'p'))
+
+
+# Make aliases for some values to be used as arguments
+cv.entropy_chck_cast = cv.entropy_from_CT
+cv.Abs_Pressure_from_p_chck_cast = cv.Abs_Pressure_from_p
+cv.depth_chck_cast = cv.depth_from_z
+cv.C_chck_cast = cv.C_from_SP
+cv.pt_chck_cast = cv.pt_from_t
+cv.z_chck_cast = cv.z_from_p
+cv.SR_chck_cast = cv.SR_from_SP
+cv.pr_chck_cast = cv.pr
+cv.p_shallow_chck_cast = cv.p_chck_cast_shallow
+cv.p_deep_chck_cast = cv.p_chck_cast_deep
+cv.rho_chck_cast = cv.rho_CT_exact
+cv.rho_CTrab_exact_ca = cv.rho_CT_exact_rab_ca
+cv.CT_freezing_chck_cast = cv.CT_freezing
+cv.t_freezing_chck_cast = cv.t_freezing
+cv.sat0_chck_cast = 0
+cv.sat05_chck_cast = 0.5
+
+# Aliases from computed values.
+cv.R_cf_chck_cast = cf.R
+cv.rho_cf_chck_cast = cf.rho
+cv.pt0_chck_cast = cf.pt0_from_t
+
+# Functions and targets which does not follow the naming convention.
+not_match = {
+    'CT_first_derivatives': 'CT_SA',
+    'CT_second_derivatives': 'CT_SA_SA',
+    'enthalpy_first_derivatives': 'h_SA',
+    'enthalpy_second_derivatives': 'h_SA_SA',
+    'entropy_first_derivatives': 'eta_SA',
+    'entropy_second_derivatives': 'eta_SA_SA',
+    'pt_first_derivatives': 'pt_SA',
+    'pt_second_derivatives': 'pt_SA_SA',
+    'Turner_Rsubrho': 'Tu',
+    'IPV_vs_fNsquared_ratio': 'IPVfN2',
+    'Nsquared': 'n2',
+    #'chem_potential_relative_t_exact': 'chem_potential_t_exact',
+    'rho_alpha_beta_CT_exact': 'rho_CTrab_exact',
+    'rho_alpha_beta': 'rho_rab'}
+
+# Add target aliases to cv.
+for f in not_match:
+    setattr(cv, f, getattr(cv, not_match[f]))
+    setattr(cv, f + '_ca', getattr(cv, not_match[f] + '_ca'))
+
+
+# Generic test method.
+def generic_test(self, func=None, argnames=None):
+    """Generic test function, to be specialized by functools.partial."""
+    # Transform argument names to name convention in cv dataset.
+    args = [getattr(cv, a + '_chck_cast') for a in argnames]
+    # Perform the function call
+    out = getattr(gsw, func)(*args)
+    # FIXME: Testing just the first output!
+    # Check that the maximal error is less than the given tolerance
+    if isinstance(out, tuple):
+        out = out[0]
+        #print("""%s returns a tuple.""" % func)
+    target = getattr(cv, func)
+    maxdiff = np.nanmax(abs(out - target))
+    maxallowed = getattr(cv, func + '_ca')
+    try:
+        self.assertTrue(maxdiff < maxallowed)
+    except AssertionError as e:
+        print(out)
+        print(target)
+        raise AssertionError("Error in %s %s, maxdiff is %s vs %s allowed" %
+                             (func, e.args, maxdiff, maxallowed))
+
+
+# Dictionary of functions with corresponding test methods.
+function_test = {}
+for f in function_arguments:
+    function_test[f] = functools.partial(generic_test, func=f,
+                                         argnames=function_arguments[f])
+
+
+# Auto-generated TestCase.
+class Test_profiles(unittest.TestCase):
+
+    for f in function_test:
+        method_def = ("test_" + f +
+                      " = lambda self: function_test['" + f + "'](self)")
+        exec(method_def)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/gsw/test/test_tuples.py b/gsw/test/test_tuples.py
new file mode 100644
index 0000000..3bfe3e6
--- /dev/null
+++ b/gsw/test/test_tuples.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+
+"""Unit check for standard profiles for the Gibbs Sea Water python package."""
+
+import os
+import sys
+import unittest
+import functools  # Requires python 2.5.
+import numpy as np
+
+import gsw
+from gsw.utilities import Bunch
+
+
+# Read data file with check value profiles
+datadir = os.path.join(os.path.dirname(gsw.utilities.__file__), 'data')
+fname = 'gsw_cv_v3_0.npz'
+cv = Bunch(np.load(os.path.join(datadir, fname)))
+cf = Bunch(np.load(os.path.join(datadir, 'gsw_cf.npz')))
+
+# derivatives.py
+#CT_first_derivatives=('SA', 'pt'),  # NOTE: TI, BUG
+#CT_second_derivatives=('SA', 'pt'),  # NOTE: TI FIXME BUG
+#enthalpy_first_derivatives=('SA', 'CT', 'p'), FIXME name match
+#enthalpy_second_derivatives=('SA', 'CT', 'p'), FIXME name match
+#entropy_first_derivatives=('SA', 'CT'),  #NOTE: TI FIXME name match
+#entropy_second_derivatives=('SA', 'pt'),  #NOTE: TI FIXME name match
+#pt_first_derivatives':,  #NOTE: TI FIXME name match
+#pt_second_derivatives= #NOTE: TI FIXME name match
+
+# Make aliases for some values to be used as arguments
+cv.entropy_chck_cast = cv.entropy_from_CT
+cv.Abs_Pressure_from_p_chck_cast = cv.Abs_Pressure_from_p
+cv.depth_chck_cast = cv.depth_from_z
+cv.C_chck_cast = cv.C_from_SP
+cv.pt_chck_cast = cv.pt_from_t
+cv.z_chck_cast = cv.z_from_p
+cv.SR_chck_cast = cv.SR_from_SP
+cv.pr_chck_cast = cv.pr
+cv.p_shallow_chck_cast = cv.p_chck_cast_shallow
+cv.p_deep_chck_cast = cv.p_chck_cast_deep
+cv.rho_chck_cast = cv.rho_CT_exact
+cv.R_cf_chck_cast = cf.R
+cv.rho_cf_chck_cast = cf.rho
+
+
+def generic_test(self, func=None, argnames=None):
+    """Generic test function, to be specialized by functools.partial"""
+    # Transform argument names to name convention in cv dataset
+    args = [getattr(cv, a + '_chck_cast') for a in argnames]
+    # Perform the function call
+    out = getattr(gsw, func)(*args)
+    # FIXME: Testing just the first output!
+    # TODO: Create the tuples and compare all together.
+    # Check that the maximal error is less than the given tolerance
+    if isinstance(out, tuple):
+        out = out[0]
+    maxdiff = np.nanmax(abs(out - getattr(cv, func)))
+    try:
+        self.assertTrue(maxdiff < getattr(cv, func + '_ca'))
+    except AssertionError, e:
+        raise AssertionError("Error in %s %s" % (func, e.args))
+
+
+# Dictionary of functions with corresponding test methods
+function_test = {}
+for f in function_arguments:
+    function_test[f] = functools.partial(generic_test,
+                                         argnames=function_arguments[f],
+                                         func=f)
+
+
+# Auto-generated TestCase.
+class Test_profiles(unittest.TestCase):
+
+    for f in function_test:
+        method_def = ("test_%s = lambda self: function_test['%s'](self)" %
+                      (f, f))
+        #print method_def
+        exec(method_def)
+
+
+if __name__ == '__main__':
+    # A more verbose output
+    suite = unittest.TestLoader().loadTestsFromTestCase(Test_profiles)
+    a = unittest.TextTestRunner(verbosity=2).run(suite)
+    if a.errors or a.failures:
+        sys.exit(256)
+    #unittest.main()
+
+gsw_cf.CT_SA, gsw_cf.CT_pt = gsw.CT_first_derivatives(gsw_cv.SA_chck_cast,
+                                                      gsw_cf.pt)
+gsw_cf.ICT_first_deriv = np.where(np.abs(gsw_cv.CT_SA - gsw_cf.CT_SA) >=
+                                  gsw_cv.CT_SA_ca |
+                                  (gsw_cv.CT_pt - gsw_cf.CT_pt) >=
+                                  gsw_cv.CT_pt_ca)
+if gsw_cf.ICT_first_deriv:
+    print(2, 'gsw_CT_first_derivatives:   Failed\n')
+    gsw_cf.gsw_chks = 0
diff --git a/gsw/utilities/__init__.py b/gsw/utilities/__init__.py
new file mode 100644
index 0000000..c1de93c
--- /dev/null
+++ b/gsw/utilities/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+from .utilities import (Bunch, match_args_return, read_data, strip_mask,
+                        loadmatbunch)
diff --git a/gsw/utilities/data/gsw_cf.npz b/gsw/utilities/data/gsw_cf.npz
new file mode 100644
index 0000000..f387803
Binary files /dev/null and b/gsw/utilities/data/gsw_cf.npz differ
diff --git a/gsw/utilities/data/gsw_cv_v3_0.npz b/gsw/utilities/data/gsw_cv_v3_0.npz
new file mode 100644
index 0000000..7668c3e
Binary files /dev/null and b/gsw/utilities/data/gsw_cv_v3_0.npz differ
diff --git a/gsw/utilities/data/gsw_data_v3_0.npz b/gsw/utilities/data/gsw_data_v3_0.npz
new file mode 100644
index 0000000..b963c5b
Binary files /dev/null and b/gsw/utilities/data/gsw_data_v3_0.npz differ
diff --git a/gsw/utilities/data/gsw_demo_data_v3_0.npz b/gsw/utilities/data/gsw_demo_data_v3_0.npz
new file mode 100644
index 0000000..ea4ae9c
Binary files /dev/null and b/gsw/utilities/data/gsw_demo_data_v3_0.npz differ
diff --git a/gsw/utilities/list_npz.py b/gsw/utilities/list_npz.py
new file mode 100644
index 0000000..da5ed08
--- /dev/null
+++ b/gsw/utilities/list_npz.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+"""
+List to stdout the contents of an npz file used in testing.
+
+The filename is the sole command-line argument.
+"""
+
+import sys
+import numpy as np
+
+fname = sys.argv[1]
+
+dat = np.load(fname)
+keys = dat.keys()
+keys.sort()
+klens = [len(str(k)) for k in keys]
+klen = max(klens)
+
+str_fmt = "{0!s:<{klen}} : {1!s:>10}  {2!s:>12}\n"
+
+slist = [str_fmt.format(k, dat[k].dtype, dat[k].shape, klen=klen)
+         for k in keys]
+
+print ''.join(slist)
+
+
diff --git a/gsw/utilities/mat2npz.py b/gsw/utilities/mat2npz.py
new file mode 100644
index 0000000..5e47576
--- /dev/null
+++ b/gsw/utilities/mat2npz.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# mat2npz.py
+#
+# purpose:  Convert matlab file from TEOS-10 group to a npz file
+# author:   Filipe P. A. Fernandes
+# e-mail:   ocefpaf at gmail
+# web:      http://ocefpaf.tiddlyspot.com/
+# created:  06-Jun-2011
+# modified: Mon 16 Sep 2013 01:40:54 PM BRT
+#
+# obs:
+#
+
+import numpy as np
+
+from gsw.utilities import loadmatbunch
+
+data_ver = 'v3_0'
+gsw_data = loadmatbunch('gsw_data_%s.mat' % data_ver, masked=False)
+
+print('Data version number: %s' % gsw_data.version_number)
+print('Data version date: %s' % gsw_data.version_date)
+
+# Delta SA Atlas.
+ref_table = dict()
+for k in gsw_data:
+    if k == u'gsw_cv' or k == u'#refs#' or k == 'gsw_demo_data':
+        pass
+    else:
+        ref_table[k] = gsw_data[k]
+np.savez("data/gsw_data_%s" % data_ver, **ref_table)
+
+# Save demo data values gsw_demo_data in a separate file.
+gsw_demo_data = gsw_data['gsw_demo_data']
+
+np.savez("data/gsw_demo_data_%s" % data_ver, **gsw_data['gsw_demo_data'])
+
+# Save compare values `gsw_cv` in a separate file.
+cv_vars = gsw_data['gsw_cv']
+
+np.savez("data/gsw_cv_%s" % data_ver, **cv_vars)
+
+# NOTE: The matfile gsw_cf.mat contains the results from
+# `gsw_check_functions.m.` and is used later for tests.  Remember to save it as
+# MatlabTM '-v6' otherwise will have to use hdf5 instead of loadmat to read it.
+if True:
+    gsw_cf = loadmatbunch('gsw_cf.mat', masked=False)
+    np.savez("data/gsw_cf", **gsw_cf)
diff --git a/gsw/utilities/utilities.py b/gsw/utilities/utilities.py
new file mode 100644
index 0000000..6688095
--- /dev/null
+++ b/gsw/utilities/utilities.py
@@ -0,0 +1,333 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import division
+
+import os
+from functools import wraps
+
+import numpy as np
+from scipy.io import loadmat
+
+__all__ = ['Bunch',
+           'Cache_npz',
+           'match_args_return',
+           'read_data',
+           'strip_mask']
+
+
+# Based on Robert Kern's Bunch.
+class Bunch(dict):
+    """
+    A dictionary that also provides access via attributes.
+
+    Additional methods update_values and update_None provide
+    control over whether new keys are added to the dictionary
+    when updating, and whether an attempt to add a new key is
+    ignored or raises a KeyError.
+
+    The Bunch also prints differently than a normal
+    dictionary, using str() instead of repr() for its
+    keys and values, and in key-sorted order.  The printing
+    format can be customized by subclassing with a different
+    str_ftm class attribute.  Do not assign directly to this
+    class attribute, because that would substitute an instance
+    attribute which would then become part of the Bunch, and
+    would be reported as such by the keys() method.
+
+    To output a string representation with
+    a particular format, without subclassing, use the
+    formatted() method.
+    """
+
+    str_fmt = "{0!s:<{klen}} : {1!s:>{vlen}}\n"
+
+    def __init__(self, *args, **kwargs):
+        """
+        *args* can be dictionaries, bunches, or sequences of
+        key,value tuples.  *kwargs* can be used to initialize
+        or add key, value pairs.
+        """
+        dict.__init__(self)
+        self.__dict__ = self
+        for arg in args:
+            self.update(arg)
+        self.update(kwargs)
+
+    def __str__(self):
+        return self.formatted()
+
+    def formatted(self, fmt=None):
+        """
+        Return a string with keys and/or values.
+
+        *fmt* is a format string as used in the str.format() method.
+
+        The str.format() method is called with key, value as positional
+        arguments, and klen, vlen as kwargs.  The latter are the maxima
+        of the string lengths for the keys and values, respectively,
+        up to respective maxima of 20 and 40.
+        """
+        if fmt is None:
+            fmt = self.str_fmt
+        klens = [len(str(k)) for k in self.keys()]
+        vlens = [len(str(v)) for v in self.values()]
+        klen = min(20, max(klens))
+        vlen = min(40, max(vlens))
+        items = self.items()
+        items.sort()
+        slist = [fmt.format(k, v, klen=klen, vlen=vlen) for k, v in items]
+        return ''.join(slist)
+
+    def update_values(self, *args, **kw):
+        """
+        arguments are dictionary-like; if present, they act as
+        additional sources of kwargs, with the actual kwargs
+        taking precedence.
+
+        One reserved optional kwarg is "strict".  If present and
+        True, then any attempt to update with keys that are not
+        already in the Bunch instance will raise a KeyError.
+        """
+        strict = kw.pop("strict", False)
+        newkw = dict()
+        for d in args:
+            newkw.update(d)
+        newkw.update(kw)
+        self._check_strict(strict, newkw)
+        dsub = dict([(k, v) for (k, v) in newkw.items() if k in self])
+        self.update(dsub)
+
+    def update_None(self, *args, **kw):
+        """
+        Similar to update_values, except that an existing value
+        will be updated only if it is None.
+        """
+        strict = kw.pop("strict", False)
+        newkw = dict()
+        for d in args:
+            newkw.update(d)
+        newkw.update(kw)
+        self._check_strict(strict, newkw)
+        dsub = dict([(k, v) for (k, v) in newkw.items() if k in self and
+                     self[k] is None])
+        self.update(dsub)
+
+    def _check_strict(self, strict, kw):
+        if strict:
+            bad = set(kw.keys()) - set(self.keys())
+            if bad:
+                bk = list(bad)
+                bk.sort()
+                ek = self.keys()
+                ek.sort()
+                raise KeyError(
+                    "Update keys %s don't match existing keys %s" % (bk, ek))
+
+
+class Cache_npz(object):
+    def __init__(self):
+        self._cache = dict()
+        self._default_path = os.path.join(os.path.dirname(__file__), 'data')
+
+    def __call__(self, fname, datadir=None):
+        if datadir is None:
+            datadir = self._default_path
+        fpath = os.path.join(datadir, fname)
+        try:
+            return self._cache[fpath]
+        except KeyError:
+            pass
+        d = np.load(fpath)
+        ret = Bunch(d)
+        self._cache[fpath] = ret
+        return ret
+
+_npz_cache = Cache_npz()
+
+
+def repair_npzfile_with_objects(infile, outfile):
+    """
+    Read an npz file written based on scipy.io.loadmat,
+    and write out a new npz file in which arrays have been
+    extracted from object arrays.
+
+    This might be needed only during the development process.
+    It is motivated by the need to fix gsw_cf.npz so that
+    the special object array handling in to_masked is not needed
+    for the tests.
+    """
+    dat = np.load(infile)
+    out = dict()
+    for k, v in dat.iteritems():
+        if v.dtype.kind == 'O':
+            v = v.item()
+        out[k] = v
+    np.savez(outfile, **out)
+
+
+def to_masked(arg):
+    r"""
+    Ensure an argument is a floating-point masked array.
+
+    This is a helper for match_args_return.
+    """
+    if not np.iterable(arg):
+        arg = [arg]
+    try:
+        arg = np.ma.array(arg, copy=False, dtype=float)
+    except ValueError:
+        # We might not want to keep this here.  It handles the
+        # case where reading a matfile with scipy has yielded
+        # an object array containing a single object, which is
+        # the array one actually wants.
+        if arg.dtype.kind == 'O':
+            arg = np.ma.array(arg.item(), copy=False, dtype=float)
+        else:
+            raise
+    return np.ma.masked_invalid(arg)
+
+
+def match_args_return(f):
+    """
+    Decorator for most functions that operate on profile data.
+    """
+    @wraps(f)
+    def wrapper(*args, **kw):
+        p = kw.get('p', None)
+        if p is not None:
+            args = list(args)
+            args.append(p)
+
+        isarray = np.any([hasattr(a, '__iter__') for a in args])
+        ismasked = np.any([np.ma.isMaskedArray(a) for a in args])
+
+        def fixup(ret):
+            if not ismasked:
+                ret = np.ma.filled(ret, np.nan)
+            if not isarray:
+                ret = ret[0]
+            return ret
+
+        newargs = [to_masked(a) for a in args]
+        if p is not None:
+            kw['p'] = newargs.pop()
+
+        ret = f(*newargs, **kw)
+
+        if isinstance(ret, tuple):
+            retlist = [fixup(arg) for arg in ret]
+            ret = tuple(retlist)
+        else:
+            ret = fixup(ret)
+        return ret
+    wrapper.__wrapped__ = f
+    return wrapper
+
+
+def read_data(fname, datadir=None):
+    """
+    Read variables from a numpy '.npz' file into a minimal class providing
+    attribute access.  A cache is used to avoid re-reading the same file.
+    """
+    return _npz_cache(fname, datadir=datadir)
+
+
+def strip_mask(*args):
+    """
+    Process the standard arguments for efficient calculation.
+
+    Return unmasked arguments, plus a mask.
+
+    The first argument, SA, is handled specially so that it can be
+
+    This could be absorbed into a decorator, but it would
+    require redefining functions to take the additional
+    mask argument or kwarg.
+    """
+    mask = np.ma.getmaskarray(args[-1])
+    SA = args[0]
+    if SA.shape:
+        SA = np.ma.asarray(SA)
+        SA[SA < 0] = np.ma.masked
+        for a in args[:-1]:
+            mask = np.ma.mask_or(mask, np.ma.getmask(a))
+        newargs = [SA.filled(0)]
+    elif SA < 0:
+        SA = 0
+        for a in args[1:-1]:
+            mask = np.ma.mask_or(mask, np.ma.getmask(a))
+        newargs = [SA]
+    newargs.extend([np.ma.filled(a, 0) for a in args[1:]])
+    newargs.append(mask)
+    return newargs
+
+
+def _unicode(arr):
+    r"""
+    loadmat seems to be mishandling strings when there is a difference
+    in byte order between the machine that wrote the file and the one
+    that is reading the file.  The result is, e.g.,
+
+        u'\U31000000\U34000000'  instead of u'14'
+
+    """
+    try:
+        return unicode(arr)
+    except UnicodeEncodeError:
+        dt = arr.dtype.newbyteorder('S')
+        return unicode(arr.view(dt))
+
+
+def crunch(arr, masked=True):
+    arr = arr.squeeze()
+    if arr.ndim == 0:
+        kind = arr.dtype.kind
+        if kind == 'f':
+            return float(arr)
+        if kind in 'ui':
+            return int(arr)
+        if kind == 'U':
+            try:
+                return _unicode(arr)
+            except UnicodeDecodeError:
+                return "Could not decode."
+        if kind == 'S':
+            return str(arr)
+        if kind == 'O':
+            return arr
+        return arr  # Warn?  Other kinds need to be handled?
+    if masked and arr.dtype.kind == 'f':  # Check for complex also.
+        arrm = np.ma.masked_invalid(arr)
+        if arrm.count() < arrm.size:
+            arr = arrm
+        else:
+            arr = np.array(arr)  # Copy to force a read.
+    else:
+        arr = np.array(arr)
+    return arr
+
+
+def structured_to_bunch(arr, masked=True):
+    if arr.dtype.kind == 'V' and arr.shape == (1, 1):
+        b = Bunch()
+        x = arr[0, 0]
+        for name in x.dtype.names:
+            b[name] = structured_to_bunch(x[name], masked=masked)
+        return b
+    return crunch(arr, masked=masked)
+
+
+def loadmatbunch(fname, masked=True):
+    """
+    Wrapper for loadmat that dereferences (1,1) object arrays,
+    converts floating point arrays to masked arrays, and uses
+    nested Bunch objects in place of the MatlabTM structures.
+    """
+    out = Bunch()
+    fobj = open(fname, 'rb')
+    xx = loadmat(fobj)
+    keys = [k for k in xx.keys() if not k.startswith("__")]
+    for k in keys:
+        out[k] = structured_to_bunch(xx[k], masked=masked)
+    fobj.close()
+    return out
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..861a9f5
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..dbd5bcd
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from __future__ import absolute_import
+
+import io
+import re
+from setuptools import setup
+
+
+def read(*filenames, **kwargs):
+    encoding = kwargs.get('encoding', 'utf-8')
+    sep = kwargs.get('sep', '\n')
+    buf = []
+    for filename in filenames:
+        with io.open(filename, encoding=encoding) as f:
+            buf.append(f.read())
+    return sep.join(buf)
+
+
+VERSIONFILE = "gsw/__init__.py"
+verstrline = open(VERSIONFILE, "rt").read()
+VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"
+mo = re.search(VSRE, verstrline, re.M)
+if mo:
+    verstr = mo.group(1)
+else:
+    raise RuntimeError("Unable to find version string in %s." % (VERSIONFILE,))
+
+email = "ocefpaf at gmail.com"
+maintainer = "Filipe Fernandes"
+authors = ['Eric Firing', u'Bjørn Ådlandsvik', 'Filipe Fernandes']
+
+install_requires = ['numpy', 'nose']
+
+LICENSE = read('LICENSE.txt')
+long_description = read('README.txt', 'CHANGES.txt')
+
+config = dict(name='gsw',
+              version=verstr,
+              packages=['gsw', 'gsw/gibbs', 'gsw/utilities', 'gsw/test'],
+              package_data={'gsw': ['utilities/data/*.npz']},
+              test_suite='tests',
+              use_2to3=True,
+              license=LICENSE,
+              long_description=long_description,
+              classifiers=['Development Status :: 4 - Beta',
+                           'Environment :: Console',
+                           'Intended Audience :: Science/Research',
+                           'Intended Audience :: Developers',
+                           'Intended Audience :: Education',
+                           'License :: OSI Approved :: MIT License',
+                           'Operating System :: OS Independent',
+                           'Programming Language :: Python',
+                           'Topic :: Education',
+                           'Topic :: Scientific/Engineering',
+                           ],
+              description='Gibbs SeaWater Oceanographic Package of TEOS-10',
+              author=authors,
+              author_email=email,
+              maintainer=maintainer,
+              maintainer_email=email,
+              url='http://pypi.python.org/pypi/seawater/',
+              download_url='https://pypi.python.org/pypi/gsw/',
+              platforms='any',
+              keywords=['oceanography', 'seawater', 'TEOS-10', 'gibbs'],
+              install_requires=install_requires)
+
+setup(**config)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/gsw.git



More information about the debian-science-commits mailing list