diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..7818bef --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# See https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically/keeping-your-actions-up-to-date-with-dependabot + +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + labels: + - "Bot" + groups: + github-actions: + patterns: + - '*' diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..e309d6a --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,49 @@ + +name: Documentation + +on: + pull_request: + push: + branches: + - main + release: + types: + - published + +jobs: + build-docs: + runs-on: ubuntu-latest + + steps: + - name: checkout + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + with: + fetch-depth: 0 + + - name: Setup Micromamba + uses: mamba-org/setup-micromamba@422500192359a097648154e8db4e39bdb6c6eed7 #v1 + with: + environment-name: TEST + init-shell: bash + create-args: >- + python=3 --file requirements.txt --file requirements-dev.txt --channel conda-forge + + - name: Install erddapy + shell: bash -l {0} + run: | + python -m pip install -e . --no-deps --force-reinstall + + - name: Build documentation + shell: bash -l {0} + run: > + set -e + && pushd docs + && make clean html linkcheck + && popd + + - name: Deploy + if: success() && github.event_name == 'release' + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e #v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: docs/_build/html diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..79b0178 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,36 @@ +name: Full Tests + +on: + pull_request: + push: + branches: [main] + +jobs: + run: + runs-on: ${{ matrix.os }} + strategy: + matrix: + python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] + os: [windows-latest, ubuntu-latest, macos-latest] + fail-fast: false + + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4 + + - name: Setup Micromamba Python ${{ matrix.python-version }} + uses: mamba-org/setup-micromamba@422500192359a097648154e8db4e39bdb6c6eed7 #v1 + with: + environment-name: TEST + init-shell: bash + create-args: >- + python=${{ matrix.python-version }} --file requirements.txt --file requirements-dev.txt --channel conda-forge + + - name: Install seawater + shell: bash -l {0} + run: | + python -m pip install -e . --no-deps --force-reinstall + + - name: Full Tests + shell: bash -l {0} + run: | + python -m pytest -rxs --doctest-modules --pyargs seawater diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7621d11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build/ +docs/_build/ +python-test.txt +seawater.egg-info/ +seawater/_version.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..33a2368 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,61 @@ +exclude: seawater/test/seawater_v3_3/ + +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: trailing-whitespace + - id: check-ast + - id: debug-statements + - id: end-of-file-fixer + - id: check-docstring-first + - id: check-added-large-files + exclude_types: [yaml] + - id: requirements-txt-fixer + - id: file-contents-sorter + files: requirements-dev.txt + +- repo: https://github.com/keewis/blackdoc + rev: v0.3.9 + hooks: + - id: blackdoc + +- repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + exclude: > + (?x)^( + .*\.yaml + )$ + args: + - --ignore-words-list=pres,delt,arry + +- repo: https://github.com/asottile/add-trailing-comma + rev: v3.1.0 + hooks: + - id: add-trailing-comma + +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.6 + hooks: + - id: ruff + args: ["--fix", "--show-fixes"] + - id: ruff-format + + +- repo: https://github.com/tox-dev/pyproject-fmt + rev: 2.1.3 + hooks: + - id: pyproject-fmt + +ci: + autofix_commit_msg: | + [pre-commit.ci] auto fixes from pre-commit.com hooks + + for more information, see https://pre-commit.ci + autofix_prs: false + autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate' + autoupdate_schedule: monthly + skip: [] + submodules: false diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 697e44c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: python - -env: - #- CONDA="python=2.7" - - CONDA="python=3.4" - -before_install: - - sudo apt-add-repository -y ppa:picaso/octave - - sudo apt-get update -qq - - sudo apt-get install -qq octave liboctave-dev - - wget http://bit.ly/miniconda -O miniconda.sh - - bash miniconda.sh -b -p $HOME/miniconda - - export PATH="$HOME/miniconda/bin:$PATH" - - conda update --yes conda - - travis_retry conda create --yes -n test $CONDA --file requirements.txt - - source activate test - - travis_retry conda install --yes pip - - travis_retry pip install -r requirements-dev.txt - -script: - - python setup.py test diff --git a/MANIFEST.in b/MANIFEST.in index b447ad7..662a49a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,19 @@ -include README.rst -include LICENSE.txt -include CHANGES.txt +include *.txt +include README.md +include pyproject.toml include LICENSE.CSIRO -include seawater/*.py + +graft seawater + +prune .github +prune *.egg-info +prune docs +prune seawater/tests + +exclude .coveragerc +exclude ruff.toml +exclude .gitignore +exclude .isort.cfg +exclude .pre-commit-config.yaml +exclude *.yml +exclude seawater/_version.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..b7b5bad --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# python-seawater + +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.11395.svg)](https://doi.org/10.5281/zenodo.11395) +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/seawater) +[![Tests](https://github.com/pyoceans/python-seawater/actions/workflows/tests.yml/badge.svg)](https://github.com/pyoceans/python-seawater/actions/workflows/tests.yml) +![PyPI - License](https://img.shields.io/pypi/l/seawater) + +[![No Maintenance Intended](https://unmaintained.tech/badge.svg)](http://unmaintained.tech/) + +This is a Python re-write of the CSIRO seawater toolbox +([SEAWATER-3.3](https://www.cmar.csiro.au/datacentre/ext_docs/seawater.html)) +for calculating the properties of sea water. The package uses the +formulas from Unesco's joint panel on oceanographic tables and +standards, UNESCO 1981 and UNESCO 1983 (EOS-80). + +The EOS-80 library is considered now obsolete; it is provided here for +compatibility with old scripts, and to allow a smooth transition to the +new [TEOS-10](https://www.teos-10.org/). + +## Warning + +The Python version default output unit for sw.dist is *km* instead of +*nm*. + +Here we assume pressure as the first dimension, i.e. M pressure by N +positions (See the table below). The Matlab version does some guessing +at this that we simply ignore to avoid confusions. + + | **P** | **S** | **T** | + |------:|:-------:|:-------:| + | 10 | 34.5487 | 28.7856 | + | 50 | 34.7275 | 28.4329 | + | 125 | 34.8605 | 22.8103 | + | 250 | 34.6810 | 10.2600 | + | 600 | 34.5680 | 6.8863 | + | 1000 | 34.5600 | 4.4036 | + +The current version was tested against the Matlab seawater v3.3 +reproducing all functions and results from that release. + +More information at +[http://pythonhosted.org/seawater](http://pythonhosted.org/seawater). diff --git a/README.rst b/README.rst deleted file mode 100644 index 9a6356d..0000000 --- a/README.rst +++ /dev/null @@ -1,64 +0,0 @@ -python-seawater -=============== - - -.. image:: https://zenodo.org/badge/doi/10.5281/zenodo.11395.png - :target: http://dx.doi.org/10.5281/zenodo.11395 - :alt: DOI -.. image:: http://img.shields.io/pypi/v/seawater.svg?style=flat - :target: https://pypi.python.org/pypi/seawater - :alt: Version_status -.. image:: http://img.shields.io/pypi/dm/seawater.svg?style=flat - :target: https://pypi.python.org/pypi/seawater - :alt: Downloads -.. image:: http://img.shields.io/travis/pyoceans/python-seawater/master.svg?style=flat - :target: https://travis-ci.org/pyoceans/python-seawater - :alt: Build_status -.. image:: http://img.shields.io/badge/license-MIT-blue.svg?style=flat - :target: https://github.com/pyoceans/python-seawater/blob/master/LICENSE.txt - :alt: license -.. image:: http://bottlepy.org/docs/dev/_static/Gittip.png - :target: https://gratipay.com/~ocefpaf/ - :alt: Gittip - - -This is a Python re-write of the CSIRO seawater toolbox -(`SEAWATER-3.3 `__) -for calculating the properties of sea water. The package uses the -formulas from Unesco's joint panel on oceanographic tables and -standards, UNESCO 1981 and UNESCO 1983 (EOS-80). - -The EOS-80 library is considered now obsolete; it is provided here for -compatibility with old scripts, and to allow a smooth transition to the -new `TEOS-10 `__. - -Warning -------- - -The Python version default output unit for sw.dist is 'km' instead of -'nm'. - -Here we assume pressure as the first dimension, i.e. M pressure by N -positions (See the table below). The MatlabTM version does some guessing -at this that we simply ignore to avoid confusions. - -+---------+-----------+-----------+ -| **P** | **S** | **T** | -+=========+===========+===========+ -| 10 | 34.5487 | 28.7856 | -+---------+-----------+-----------+ -| 50 | 34.7275 | 28.4329 | -+---------+-----------+-----------+ -| 125 | 34.8605 | 22.8103 | -+---------+-----------+-----------+ -| 250 | 34.6810 | 10.2600 | -+---------+-----------+-----------+ -| 600 | 34.5680 | 6.8863 | -+---------+-----------+-----------+ -| 1000 | 34.5600 | 4.4036 | -+---------+-----------+-----------+ - -The current version was tested against the MatlabTM seawater v3.3 reproducing -all functions and results from that release. - -More information at http://pythonhosted.org/seawater diff --git a/docs/conf.py b/docs/conf.py index e36b9ec..eee85b6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # seawater documentation build configuration file, created by # sphinx-quickstart on Tue Aug 10 16:47:25 2010. @@ -11,39 +10,44 @@ # 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('.')) +# 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', - 'sphinx.ext.doctest', - 'matplotlib.sphinxext.only_directives', - 'numpydoc'] +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.mathjax", + "sphinx.ext.doctest", + "matplotlib.sphinxext.plot_directive", + "numpydoc", +] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8' +# source_encoding = 'utf-8' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'seawater' -copyright = u'2010, Filipe Fernandes' +import datetime + +year = datetime.datetime.now(tz=datetime.timezone.utc).date().year + +project = "seawater" +copyright = f"2010-{year}, 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 @@ -51,151 +55,152 @@ # # The short X.Y version. from seawater import __version__ -version = ''.join(str(d) for d in __version__[:2]) + +version = __version__ # The full version, including alpha/beta/rc tags. -release = ''.join(str(d) for d in __version__) +release = __version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. -#unused_docs = [] +# unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. -exclude_trees = ['_build'] +exclude_trees = ["_build"] # The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# 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 +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# 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 = 'sphinxdoc' +html_theme = "sphinxdoc" # 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 = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# 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 +# 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'] +# html_favicon = None # 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' +# 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 +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_use_modindex = True -html_domain_indices = ['py-modindex'] +# html_use_modindex = True +html_domain_indices = ["py-modindex"] # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' +# html_file_suffix = '' # Output file base name for HTML help builder. -htmlhelp_basename = 'seawaterdoc' +htmlhelp_basename = "seawaterdoc" # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' +# latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' +# 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', 'seawater.tex', u'seawater Documentation', - u'Filipe Fernandes', 'manual'), + ( + "index", + "seawater.tex", + "seawater Documentation", + "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 +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # Additional stuff for the LaTeX preamble. -#latex_preamble = '' +# latex_preamble = '' # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_use_modindex = True +# latex_use_modindex = True diff --git a/docs/index.rst b/docs/index.rst index 9ef5007..28eadf1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,58 +1,4 @@ -.. 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. - -python-seawater -=============== - -.. image:: https://badge.fury.io/py/seawater.png - :target: http://badge.fury.io/py/seawater -.. image:: https://api.travis-ci.org/pyoceans/python-seawater.png?branch=master - :target: https://travis-ci.org/pyoceans/python-seawater -.. image:: https://zenodo.org/badge/doi/10.5281/zenodo.11395.png - :target: http://dx.doi.org/10.5281/zenodo.11395 -.. image:: http://bottlepy.org/docs/dev/_static/Gittip.png - :target: https://www.gittip.com/ocefpaf/ - -This is a Python re-write of the CSIRO seawater toolbox -(`SEAWATER-3.3 `__) -for calculating the properties of sea water. The package uses the -formulas from Unesco's joint panel on oceanographic tables and -standards, UNESCO 1981 and UNESCO 1983 (EOS-80). - -The EOS-80 library is considered now obsolete; it is provided here for -compatibility with old scripts, and to allow a smooth transition to the -new `TEOS-10 `__. - -Warning -------- - -The Python version default output unit for sw.dist is 'km' instead of -'nm'. - -Here we assume pressure as the first dimension, i.e. M pressure by N -positions (See the table below). The MatlabTM version does some guessing -at this that we simply ignore to avoid confusions. - -+---------+-----------+-----------+ -| **P** | **S** | **T** | -+=========+===========+===========+ -| 10 | 34.5487 | 28.7856 | -+---------+-----------+-----------+ -| 50 | 34.7275 | 28.4329 | -+---------+-----------+-----------+ -| 125 | 34.8605 | 22.8103 | -+---------+-----------+-----------+ -| 250 | 34.6810 | 10.2600 | -+---------+-----------+-----------+ -| 600 | 34.5680 | 6.8863 | -+---------+-----------+-----------+ -| 1000 | 34.5600 | 4.4036 | -+---------+-----------+-----------+ - -The current version was tested against the MatlabTM seawater v3.3 reproducing -all functions and results from that release. +readme_link Documentation ============= diff --git a/docs/readme_link.md b/docs/readme_link.md new file mode 100644 index 0000000..451beda --- /dev/null +++ b/docs/readme_link.md @@ -0,0 +1,2 @@ +```{include} ../README.md +``` diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..72cce39 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,57 @@ +[build-system] +build-backend = "setuptools.build_meta" +requires = [ + "setuptools>=42", + "setuptools-scm", + "wheel", +] + +[project] +name = "seawater" +description = "Seawater Library for Python" +readme = "README.md" +license = { file = "LICENSE.txt" } +maintainers = [ + { name = "Filipe Fernandes", email = "ocefpaf+seawater@gmail.com" }, +] +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dynamic = [ + "dependencies", + "version", +] +urls.documentation = "https://pyoceans.github.io/python-seawater" +urls.homepage = "https://pypi.org/project/seawater/" +urls.repository = "https://github.com/pyoceans/python-seawater" + +[tool.setuptools] +packages = [ + "seawater", +] +# include-package-data = true + +[tool.setuptools.dynamic] +dependencies = { file = [ + "requirements.txt", +] } + +[tool.setuptools_scm] +write_to = "seawater/_version.py" +write_to_template = "__version__ = '{version}'" +tag_regex = "^(?Pv)?(?P[^\\+]+)(?P.*)?$" + +[tool.check-manifest] +ignore = [ + "*.yml", + "docs", + "docs/*", + "seawater/tests", + "seawater/tests/*", +] diff --git a/requirements-dev.txt b/requirements-dev.txt index 941ffb7..93f882d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,5 @@ -coveralls -nose +matplotlib +numpydoc oct2py +pytest +sphinx diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..4dd06af --- /dev/null +++ b/ruff.toml @@ -0,0 +1,76 @@ +line-length = 90 + +lint.select = ["ALL"] + +lint.ignore = [ + "ANN001", # Missing type annotation for function argument + "ANN002", # Missing type annotation for `*arys` + "ANN101", # Missing type annotation for `self` in method + "ANN201", # Missing return type annotation for public function + "ANN202", # Missing return type annotation for private function + "D100", # Missing docstring in public module + "D101", # Missing docstring in public class + "D102", # Missing docstring in public method + "D203", # 1 blank line required before class docstring + "D205", # 1 blank line required between summary line and description + "D213", # incompatible. Ignoring `multi-line-summary-second-line` + "D400", # First line should end with a period + "D401", # First line of docstring should be in imperative mood + "D415", # First line should end with a period, question mark, or exclamation point + "D417", # Missing argument descriptions in the docstring + "ERA001", # Found commented-out code + "N802", # Function name `test_satAr` should be lowercase + "N803", # Argument name should be lowercase + "N806", # Variable should be lowercase + "N816", # Variable `db2Pascal` in global scope should not be mixedCase + "PLR2004", # Magic value used in comparison + "TRY003", # Avoid specifying long messages outside the exception class + "UP031", # Use format specifiers instead of percent format +] + +[lint.extend-per-file-ignores] +"docs/conf.py" = [ + "A001", # builtin-variable-shadowing + "D100", # Missing docstring in public module + "E402", # Module level import not at top of file + "E501", # Line too long + "ERA001", # Found commented-out code + "ERA001", # Found commented-out code + "EXE001", # Shebang is present but file is not executable + "INP001" # File `docs/conf.py` is part of an implicit namespace package. Add an `__init__.py`. +] +"test_*.py" = [ + "ANN001", # Missing type annotation for function argument + "ANN201", # Missing return type annotation for public function + "ANN202", # Missing return type annotation for private function + "INP001", # File is part of an implicit namespace package + "PD901", # Avoid using the generic variable name `df` for DataFrames + "S101", # Use of assert detected +] +"sw_test.py" = [ + "INP001", # File `seawater/test/sw_test.py` is part of an implicit namespace package. Add an `__init__.py`. + "C901", # `test` is too complex (20 > 10) + "PLR0912", # Too many branches (19 > 12) + "PLR0915", # Too many statements (242 > 50) + "SIM115", # Use context handler for opening files + "PTH123", # `open()` should be replaced by `Path.open()` + "TD002", # Missing author in TODO; try: `# TODO(): ...` or `# TODO @: ...` + "TD003", # Missing issue link on the line following this TODO + "FIX002", # Line contains TODO, consider resolving the issue +] +# nbqa-ruff acts on converted .py so we cannot glob .ipynb :-/ +# https://github.com/nbQA-dev/nbQA/issues/823 +"notebooks/*" = [ + "ANN001", # Missing type annotation for function argument + "ANN201", # Missing return type annotation for public function + "B018", # Found useless expression. Either assign it to a variable or remove it + "D100", # Missing docstring in public module + "D103", # Missing docstring in public function + "E402", # Module level import not at top of file + "FBT003", # Boolean positional value in function call + "INP001", # File is part of an implicit namespace package + "PD901", # Avoid using the generic variable name `df` for DataFrames + "T201", # `print` found" +] +[lint.pycodestyle] +max-doc-length = 180 diff --git a/seawater/__init__.py b/seawater/__init__.py index 27ec543..2ba910a 100644 --- a/seawater/__init__.py +++ b/seawater/__init__.py @@ -1,9 +1,64 @@ -from __future__ import division, absolute_import +"""Seawater: EOS-80 equation of state.""" -__version__ = '3.3.4' +try: + from ._version import __version__ +except ImportError: + __version__ = "unknown" -from .geostrophic import bfrq, svan, gpan, gvel +from .eos80 import ( + adtg, + alpha, + aonb, + beta, + cp, + dens, + dens0, + dpth, + fp, + g, + pden, + pres, + ptmp, + salt, + svel, + temp, +) from .extras import dist, f, satAr, satN2, satO2, swvel -from .library import cndr, salds, salrp, salrt, seck, sals, smow -from .eos80 import (adtg, alpha, aonb, beta, dpth, g, salt, fp, svel, - pres, dens0, dens, pden, cp, ptmp, temp) +from .geostrophic import bfrq, gpan, gvel, svan +from .library import cndr, salds, salrp, salrt, sals, seck, smow + +__all__ = [ + "adtg", + "alpha", + "aonb", + "beta", + "bfrq", + "cndr", + "cp", + "dens", + "dens0", + "dist", + "dpth", + "f", + "fp", + "g", + "gpan", + "gvel", + "pden", + "pres", + "ptmp", + "salds", + "salrp", + "salrt", + "sals", + "salt", + "satAr", + "satN2", + "satO2", + "seck", + "smow", + "svan", + "svel", + "swvel", + "temp", +] diff --git a/seawater/constants.py b/seawater/constants.py index b3b51b1..0639d90 100644 --- a/seawater/constants.py +++ b/seawater/constants.py @@ -1,12 +1,8 @@ -""" -Constants +"""Constants. ========= """ -from __future__ import division, absolute_import - - from numpy import pi # dbar to pascal. @@ -19,16 +15,16 @@ gdef = 9.8 # 1 nm = 1.8520 km -DEG2NM, NM2KM = 60., 1.8520 +DEG2NM, NM2KM = 60.0, 1.8520 # Sidereal day = 23.9344696 hours. OMEGA = 7.292e-5 # 7.292115e-5 # Mean radius of earth [m] A.E. Gill. -earth_radius = 6371000. +earth_radius = 6371000.0 # Angle conversions. -deg2rad, rad2deg = pi / 180.0, 180.0 / pi +deg2rad, rad2deg = pi / 180.0, 180.0 / pi # Conductivity at S=35 psu , T=15 C [ITPS 68] and P=0 dbar. c3515 = 42.914 diff --git a/seawater/eos80.py b/seawater/eos80.py index 9012f10..9bd6f2a 100644 --- a/seawater/eos80.py +++ b/seawater/eos80.py @@ -1,35 +1,30 @@ -# -*- coding: utf-8 -*- - - -from __future__ import division, absolute_import - import numpy as np from .constants import deg2rad, earth_radius -from .library import T90conv, T68conv, salrt, salrp, sals, seck, smow - - -__all__ = ['adtg', - 'alpha', - 'aonb', - 'beta', - 'dpth', - 'g', - 'salt', - 'fp', - 'svel', - 'pres', - 'dens0', - 'dens', - 'pden', - 'cp', - 'ptmp', - 'temp'] +from .library import T68conv, T90conv, salrp, salrt, sals, seck, smow + +__all__ = [ + "adtg", + "alpha", + "aonb", + "beta", + "dpth", + "g", + "salt", + "fp", + "svel", + "pres", + "dens0", + "dens", + "pden", + "cp", + "ptmp", + "temp", +] def adtg(s, t, p): - """ - Calculates adiabatic temperature gradient as per UNESCO 1983 routines. + """Calculates adiabatic temperature gradient as per UNESCO 1983 routines. Parameters ---------- @@ -50,35 +45,41 @@ def adtg(s, t, p): >>> # Data from UNESCO 1983 p45. >>> import seawater as sw >>> from seawater.library import T90conv - >>> t = T90conv([[ 0, 0, 0, 0, 0, 0], - ... [10, 10, 10, 10, 10, 10], - ... [20, 20, 20, 20, 20, 20], - ... [30, 30, 30, 30, 30, 30], - ... [40, 40, 40, 40, 40, 40]]) - >>> s = [[25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35]] + >>> t = T90conv( + ... [ + ... [0, 0, 0, 0, 0, 0], + ... [10, 10, 10, 10, 10, 10], + ... [20, 20, 20, 20, 20, 20], + ... [30, 30, 30, 30, 30, 30], + ... [40, 40, 40, 40, 40, 40], + ... ] + ... ) + >>> s = [ + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... ] >>> p = [0, 5000, 10000, 0, 5000, 10000] >>> sw.adtg(s, t, p) - array([[ 1.68710000e-05, 1.04700000e-04, 1.69426000e-04, - 3.58030000e-05, 1.17956500e-04, 1.77007000e-04], - [ 1.00194580e-04, 1.60959050e-04, 2.06874170e-04, - 1.14887280e-04, 1.71364200e-04, 2.12991770e-04], - [ 1.73819840e-04, 2.13534000e-04, 2.44483760e-04, - 1.84273240e-04, 2.21087800e-04, 2.49137960e-04], - [ 2.41720460e-04, 2.64764100e-04, 2.82959590e-04, - 2.47934560e-04, 2.69466550e-04, 2.86150390e-04], - [ 3.07870120e-04, 3.16988600e-04, 3.23006480e-04, - 3.09844920e-04, 3.18839700e-04, 3.24733880e-04]]) + array([[1.6871000e-05, 1.0470000e-04, 1.6942600e-04, 3.5803000e-05, + 1.1795650e-04, 1.7700700e-04], + [1.0019458e-04, 1.6095905e-04, 2.0687417e-04, 1.1488728e-04, + 1.7136420e-04, 2.1299177e-04], + [1.7381984e-04, 2.1353400e-04, 2.4448376e-04, 1.8427324e-04, + 2.2108780e-04, 2.4913796e-04], + [2.4172046e-04, 2.6476410e-04, 2.8295959e-04, 2.4793456e-04, + 2.6946655e-04, 2.8615039e-04], + [3.0787012e-04, 3.1698860e-04, 3.2300648e-04, 3.0984492e-04, + 3.1883970e-04, 3.2473388e-04]]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] Bryden, H. 1973. New Polynomials for thermal expansion, adiabatic temperature gradient and potential temperature of sea water. Deep-Sea @@ -94,16 +95,21 @@ def adtg(s, t, p): c = [1.8741e-8, -6.7795e-10, 8.733e-12, -5.4481e-14] d = [-1.1351e-10, 2.7759e-12] e = [-4.6206e-13, 1.8676e-14, -2.1687e-16] - return (a[0] + (a[1] + (a[2] + a[3] * T68) * T68) * T68 + - (b[0] + b[1] * T68) * (s - 35) + - ((c[0] + (c[1] + (c[2] + c[3] * T68) * T68) * T68) + - (d[0] + d[1] * T68) * (s - 35)) * p + - (e[0] + (e[1] + e[2] * T68) * T68) * p * p) - - -def alpha(s, t, p, pt=False): - """ - Calculate the thermal expansion coefficient. + return ( + a[0] + + (a[1] + (a[2] + a[3] * T68) * T68) * T68 + + (b[0] + b[1] * T68) * (s - 35) + + ( + (c[0] + (c[1] + (c[2] + c[3] * T68) * T68) * T68) + + (d[0] + d[1] * T68) * (s - 35) + ) + * p + + (e[0] + (e[1] + e[2] * T68) * T68) * p * p + ) + + +def alpha(s, t, p, *, pt=False): + r"""Calculate the thermal expansion coefficient. Parameters ---------- @@ -136,12 +142,11 @@ def alpha(s, t, p, pt=False): """ s, t, p, pt = list(map(np.asanyarray, (s, t, p, pt))) - return aonb(s, t, p, pt) * beta(s, t, p, pt) + return aonb(s, t, p, pt=pt) * beta(s, t, p, pt=pt) -def aonb(s, t, p, pt=False): - """ - Calculate :math:`\\alpha/\\beta`. +def aonb(s, t, p, *, pt=False): + r"""Calculate :math:`\\alpha/\\beta`. Parameters ---------- @@ -173,18 +178,24 @@ def aonb(s, t, p, pt=False): 17, 1950-1964. doi: 10.1175/1520-0485(1987)017<1950:NS>2.0.CO;2 """ - # Ensure we use ptmp in calculations. s, t, p, pt = list(map(np.asanyarray, (s, t, p, pt))) if not pt: t = ptmp(s, t, p, 0) # Now we have ptmp. - p = np.float_(p) + p = np.float64(p) t = T68conv(t) - c1 = np.array([-0.255019e-7, 0.298357e-5, -0.203814e-3, - 0.170907e-1, 0.665157e-1]) + c1 = np.array( + [ + -0.255019e-7, + 0.298357e-5, + -0.203814e-3, + 0.170907e-1, + 0.665157e-1, + ], + ) c2 = np.array([-0.846960e-4, 0.378110e-2]) c2a = np.array([-0.251520e-11, -0.164759e-6, 0.0]) c3 = -0.678662e-5 @@ -194,15 +205,18 @@ def aonb(s, t, p, pt=False): # Now calculate the thermal expansion saline contraction ratio aonb. sm35 = s - 35.0 - return (np.polyval(c1, t) + sm35 * - (np.polyval(c2, t) + np.polyval(c2a, p)) + - sm35 ** 2 * c3 + p * np.polyval(c4, t) + - c5 * (p ** 2) * (t ** 2) + c6 * p ** 3) - - -def beta(s, t, p, pt=False): - """ - Calculate the saline contraction coefficient :math:`\\beta` as defined + return ( + np.polyval(c1, t) + + sm35 * (np.polyval(c2, t) + np.polyval(c2a, p)) + + sm35**2 * c3 + + p * np.polyval(c4, t) + + c5 * (p**2) * (t**2) + + c6 * p**3 + ) + + +def beta(s, t, p, *, pt=False): + r"""Calculate the saline contraction coefficient :math:`\\beta` as defined by T.J. McDougall. Parameters @@ -227,7 +241,7 @@ def beta(s, t, p, pt=False): >>> import seawater as sw >>> s, t, p = 40, 10, 4000 >>> sw.beta(s, t, p, pt=True) - 0.00072087661741618932 + 0.0007208766174161893 References ---------- @@ -235,7 +249,6 @@ def beta(s, t, p, pt=False): 17, 1950-1964. doi: 10.1175/1520-0485(1987)017<1950:NS>2.0.CO;2 """ - s, t, p, pt = list(map(np.asanyarray, (s, t, p, pt))) # Ensure we use ptmp in calculations @@ -254,15 +267,18 @@ def beta(s, t, p, pt=False): # Now calculate the thermal expansion saline contraction ratio adb sm35 = s - 35 - return (np.polyval(c1, t) + sm35 * - (np.polyval(c2, t) + np.polyval(c3, p)) + - c4 * (sm35 ** 2) + p * np.polyval(c5, t) + - (p ** 2) * np.polyval(c6, t) + c7 * (p ** 3)) + return ( + np.polyval(c1, t) + + sm35 * (np.polyval(c2, t) + np.polyval(c3, p)) + + c4 * (sm35**2) + + p * np.polyval(c5, t) + + (p**2) * np.polyval(c6, t) + + c7 * (p**3) + ) def cp(s, t, p): - """ - Heat Capacity of Sea Water using UNESCO 1983 polynomial. + """Heat Capacity of Sea Water using UNESCO 1983 polynomial. Parameters ---------- @@ -283,41 +299,46 @@ def cp(s, t, p): >>> # Data from Pond and Pickard Intro. Dyn. Oceanography 2nd ed. 1986. >>> import seawater as sw >>> from seawater.library import T90conv - >>> t = T90conv([[0, 0, 0, 0, 0, 0], - ... [10, 10, 10, 10, 10, 10], - ... [20, 20, 20, 20, 20, 20], - ... [30, 30, 30, 30, 30, 30], - ... [40, 40, 40, 40, 40, 40]]) - >>> s = [[25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35]] + >>> t = T90conv( + ... [ + ... [0, 0, 0, 0, 0, 0], + ... [10, 10, 10, 10, 10, 10], + ... [20, 20, 20, 20, 20, 20], + ... [30, 30, 30, 30, 30, 30], + ... [40, 40, 40, 40, 40, 40], + ... ] + ... ) + >>> s = [ + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... ] >>> p = [0, 5000, 10000, 0, 5000, 10000] >>> sw.cp(s, t, p) - array([[ 4048.4405375 , 3896.25585 , 3807.7330375 , 3986.53309476, - 3849.26094605, 3769.11791286], - [ 4041.8276691 , 3919.5550066 , 3842.3111366 , 3986.34061786, - 3874.72665865, 3804.415624 ], - [ 4044.8438591 , 3938.5978466 , 3866.7400391 , 3993.85441786, - 3894.99294519, 3828.29059113], - [ 4049.0984351 , 3952.0375476 , 3882.9855526 , 4000.68382238, - 3909.24271128, 3844.32151784], - [ 4051.2244911 , 3966.1132036 , 3905.9162711 , 4003.46192541, - 3923.89463092, 3868.28959814]]) + array([[4048.4405375 , 3896.25585 , 3807.7330375 , 3986.53309476, + 3849.26094605, 3769.11791286], + [4041.8276691 , 3919.5550066 , 3842.3111366 , 3986.34061786, + 3874.72665865, 3804.415624 ], + [4044.8438591 , 3938.5978466 , 3866.7400391 , 3993.85441786, + 3894.99294519, 3828.29059113], + [4049.0984351 , 3952.0375476 , 3882.9855526 , 4000.68382238, + 3909.24271128, 3844.32151784], + [4051.2244911 , 3966.1132036 , 3905.9162711 , 4003.46192541, + 3923.89463092, 3868.28959814]]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ - s, t, p = list(map(np.asanyarray, (s, t, p))) - p = p / 10. # To convert [db] to [bar] as used in UNESCO routines. + p = p / 10.0 # To convert [db] to [bar] as used in UNESCO routines. T68 = T68conv(t) # Eqn. 26 p.32. @@ -325,19 +346,26 @@ def cp(s, t, p): b = (0.1770383, -4.07718e-3, 5.148e-5) c = (4217.4, -3.720283, 0.1412855, -2.654387e-3, 2.093236e-5) - Cpst0 = ((((c[4] * T68 + c[3]) * T68 + c[2]) * T68 + c[1]) * T68 + c[0] + - (a[0] + a[1] * T68 + a[2] * T68 ** 2) * s + - (b[0] + b[1] * T68 + b[2] * T68 ** 2) * s * s ** 0.5) + Cpst0 = ( + (((c[4] * T68 + c[3]) * T68 + c[2]) * T68 + c[1]) * T68 + + c[0] + + (a[0] + a[1] * T68 + a[2] * T68**2) * s + + (b[0] + b[1] * T68 + b[2] * T68**2) * s * s**0.5 + ) # Eqn. 28 p.33. a = (-4.9592e-1, 1.45747e-2, -3.13885e-4, 2.0357e-6, 1.7168e-8) b = (2.4931e-4, -1.08645e-5, 2.87533e-7, -4.0027e-9, 2.2956e-11) c = (-5.422e-8, 2.6380e-9, -6.5637e-11, 6.136e-13) - del_Cp0t0 = ((((((c[3] * T68 + c[2]) * T68 + c[1]) * T68 + c[0]) * p + - ((((b[4] * T68 + b[3]) * T68 + b[2]) * T68 + b[1]) * - T68 + b[0])) * p + ((((a[4] * T68 + a[3]) * T68 + a[2]) * - T68 + a[1]) * T68 + a[0])) * p) + del_Cp0t0 = ( + ( + (((c[3] * T68 + c[2]) * T68 + c[1]) * T68 + c[0]) * p + + ((((b[4] * T68 + b[3]) * T68 + b[2]) * T68 + b[1]) * T68 + b[0]) + ) + * p + + ((((a[4] * T68 + a[3]) * T68 + a[2]) * T68 + a[1]) * T68 + a[0]) + ) * p # Eqn 29 p.34. d = (4.9247e-3, -1.28315e-4, 9.802e-7, 2.5941e-8, -2.9179e-10) @@ -347,21 +375,23 @@ def cp(s, t, p): h = (5.540e-10, -1.7682e-11, 3.513e-13) j1 = -1.4300e-12 - S3_2 = s * s ** 0.5 + S3_2 = s * s**0.5 - del_Cpstp = ((((((d[4] * T68 + d[3]) * T68 + d[2]) * T68 + d[1]) * - T68 + d[0]) * s + ((e[2] * T68 + e[1]) * T68 + e[0]) * - S3_2) * p + - ((((f[3] * T68 + f[2]) * T68 + f[1]) * T68 + f[0]) * s + - g0 * S3_2) * p ** 2 + (((h[2] * T68 + h[1]) * T68 + h[0]) * - s + j1 * T68 * S3_2) * p ** 3) + del_Cpstp = ( + ( + ((((d[4] * T68 + d[3]) * T68 + d[2]) * T68 + d[1]) * T68 + d[0]) * s + + ((e[2] * T68 + e[1]) * T68 + e[0]) * S3_2 + ) + * p + + ((((f[3] * T68 + f[2]) * T68 + f[1]) * T68 + f[0]) * s + g0 * S3_2) * p**2 + + (((h[2] * T68 + h[1]) * T68 + h[0]) * s + j1 * T68 * S3_2) * p**3 + ) return Cpst0 + del_Cp0t0 + del_Cpstp def dens0(s, t): - """ - Density of Sea Water at atmospheric pressure. + """Density of Sea Water at atmospheric pressure. Parameters ---------- @@ -384,22 +414,21 @@ def dens0(s, t): >>> s = [0, 0, 0, 0, 35, 35, 35, 35] >>> t = T90conv([0, 0, 30, 30, 0, 0, 30, 30]) >>> sw.dens0(s, t) - array([ 999.842594 , 999.842594 , 995.65113374, 995.65113374, - 1028.10633141, 1028.10633141, 1021.72863949, 1021.72863949]) + array([ 999.842594 , 999.842594 , 995.65113374, 995.65113374, + 1028.10633141, 1028.10633141, 1021.72863949, 1021.72863949]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] Millero, F.J. and Poisson, A. International one-atmosphere equation of state of seawater. Deep-Sea Res. 1981. Vol28A(6) pp625-629. doi:10.1016/0198-0149(81)90122-9 """ - s, t = list(map(np.asanyarray, (s, t))) T68 = T68conv(t) @@ -408,14 +437,16 @@ def dens0(s, t): b = (8.24493e-1, -4.0899e-3, 7.6438e-5, -8.2467e-7, 5.3875e-9) c = (-5.72466e-3, 1.0227e-4, -1.6546e-6) d = 4.8314e-4 - return (smow(t) + (b[0] + (b[1] + (b[2] + (b[3] + b[4] * T68) * T68) * - T68) * T68) * s + (c[0] + (c[1] + c[2] * T68) * T68) * s * - s ** 0.5 + d * s ** 2) + return ( + smow(t) + + (b[0] + (b[1] + (b[2] + (b[3] + b[4] * T68) * T68) * T68) * T68) * s + + (c[0] + (c[1] + c[2] * T68) * T68) * s * s**0.5 + + d * s**2 + ) def dens(s, t, p): - """ - Density of Sea Water using UNESCO 1983 (EOS 80) polynomial. + """Density of Sea Water using UNESCO 1983 (EOS 80) polynomial. Parameters ---------- @@ -440,34 +471,32 @@ def dens(s, t, p): >>> t = T90conv([0, 0, 30, 30, 0, 0, 30, 30]) >>> p = [0, 10000, 0, 10000, 0, 10000, 0, 10000] >>> sw.dens(s, t, p) - array([ 999.842594 , 1045.33710972, 995.65113374, 1036.03148891, - 1028.10633141, 1070.95838408, 1021.72863949, 1060.55058771]) + array([ 999.842594 , 1045.33710972, 995.65113374, 1036.03148891, + 1028.10633141, 1070.95838408, 1021.72863949, 1060.55058771]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] Millero, F.J., Chen, C.T., Bradshaw, A., and Schleicher, K. A new high pressure equation of state for seawater. Deap-Sea Research., 1980, Vol27A, pp255-264. doi:10.1016/0198-0149(80)90016-3 """ - s, t, p = list(map(np.asanyarray, (s, t, p))) # UNESCO 1983. Eqn..7 p.15. densP0 = dens0(s, t) K = seck(s, t, p) - p = p / 10. # Convert from db to atm pressure units. + p = p / 10.0 # Convert from db to atm pressure units. return densP0 / (1 - p / K) def dpth(p, lat): - """ - Calculates depth in meters from pressure in dbars. + """Calculates depth in meters from pressure in dbars. Parameters ---------- @@ -486,20 +515,22 @@ def dpth(p, lat): >>> # UNESCO 1983 data p30. >>> import seawater as sw >>> lat = [0, 30, 45, 90] - >>> p = [[ 500, 500, 500, 500], - ... [ 5000, 5000, 5000, 5000], - ... [10000, 10000, 10000, 10000]] + >>> p = [ + ... [500, 500, 500, 500], + ... [5000, 5000, 5000, 5000], + ... [10000, 10000, 10000, 10000], + ... ] >>> sw.dpth(p, lat) - array([[ 496.65299239, 495.99772917, 495.3427354 , 494.03357499], - [ 4915.04099112, 4908.55954332, 4902.08075214, 4889.13132561], - [ 9725.47087508, 9712.6530721 , 9699.84050403, 9674.23144056]]) + array([[ 496.65299239, 495.99772917, 495.3427354 , 494.03357499], + [4915.04099112, 4908.55954332, 4902.08075214, 4889.13132561], + [9725.47087508, 9712.6530721 , 9699.84050403, 9674.23144056]]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ p, lat = list(map(np.asanyarray, (p, lat))) @@ -512,15 +543,13 @@ def dpth(p, lat): X = np.sin(lat * deg2rad) X = X * X - bot_line = (9.780318 * (1.0 + (5.2788e-3 + 2.36e-5 * X) * X) + - gam_dash * 0.5 * p) + bot_line = 9.780318 * (1.0 + (5.2788e-3 + 2.36e-5 * X) * X) + gam_dash * 0.5 * p top_line = (((c[3] * p + c[2]) * p + c[1]) * p + c[0]) * p return top_line / bot_line def fp(s, p): - """ - Freezing point of Sea Water using UNESCO 1983 polynomial. + """Freezing point of Sea Water using UNESCO 1983 polynomial. Parameters ---------- @@ -538,10 +567,8 @@ def fp(s, p): -------- >>> # UNESCO DATA p.30. >>> import seawater as sw - >>> s = [[5, 10, 15, 20, 25, 30, 35, 40], - ... [5, 10, 15, 20, 25, 30, 35, 40]] - >>> p = [[ 0, 0, 0, 0, 0, 0, 0, 0], - ... [500, 500, 500, 500, 500, 500, 500, 500]] + >>> s = [[5, 10, 15, 20, 25, 30, 35, 40], [5, 10, 15, 20, 25, 30, 35, 40]] + >>> p = [[0, 0, 0, 0, 0, 0, 0, 0], [500, 500, 500, 500, 500, 500, 500, 500]] >>> sw.fp(s, p) array([[-0.27369757, -0.54232831, -0.81142026, -1.0829461 , -1.35804594, -1.63748903, -1.9218401 , -2.2115367 ], @@ -553,22 +580,20 @@ def fp(s, p): .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ - s, p = list(map(np.asanyarray, (s, p))) # NOTE: P = P/10 # to convert db to Bar as used in UNESCO routines. # Eqn p.29. a = [-0.0575, 1.710523e-3, -2.154996e-4] b = -7.53e-4 - return T90conv(a[0] * s + a[1] * s * s ** 0.5 + a[2] * s ** 2 + b * p) + return T90conv(a[0] * s + a[1] * s * s**0.5 + a[2] * s**2 + b * p) def g(lat, z=0): - """ - Calculates acceleration due to gravity as function of latitude. + """Calculates acceleration due to gravity as function of latitude. Parameters ---------- @@ -587,20 +612,19 @@ def g(lat, z=0): -------- >>> import seawater as sw >>> sw.g(45, z=0) - 9.8061898752053995 + 9.8061898752054 References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] A.E. Gill 1982. p.54 Eqn. 3.7.15 "Atmosphere-Ocean Dynamics" Academic Press: New York. ISBN: 0-12-283522-0 """ - lat, z = list(map(np.asanyarray, (lat, z))) # Eqn p27. UNESCO 1983. @@ -612,8 +636,7 @@ def g(lat, z=0): def pden(s, t, p, pr=0): - """ - Calculates potential density of water mass relative to the specified + r"""Calculates potential density of water mass relative to the specified reference pressure by pden = dens(S, ptmp, PR). Parameters @@ -641,14 +664,14 @@ def pden(s, t, p, pr=0): >>> t = T90conv([0, 0, 30, 30, 0, 0, 30, 30]) >>> p = [0, 10000, 0, 10000, 0, 10000, 0, 10000] >>> sw.pden(s, t, p) - array([ 999.842594 , 999.79523994, 995.65113374, 996.36115932, - 1028.10633141, 1028.15738545, 1021.72863949, 1022.59634627]) + array([ 999.842594 , 999.79523994, 995.65113374, 996.36115932, + 1028.10633141, 1028.15738545, 1021.72863949, 1022.59634627]) :math:`\\sigma_{4}` (at 4000 db) >>> sw.pden(s, t, p, 4000) - 1000 - array([ 19.2895493 , 19.33422519, 12.43271053, 13.27563816, - 46.30976432, 46.48818851, 37.76150878, 38.74500757]) + array([19.2895493 , 19.33422519, 12.43271053, 13.27563816, 46.30976432, + 46.48818851, 37.76150878, 38.74500757]) References ---------- @@ -656,7 +679,6 @@ def pden(s, t, p, pr=0): Academic Press: New York. ISBN: 0-12-283522-0 """ - s, t, p, pr = list(map(np.asanyarray, (s, t, p, pr))) pt = ptmp(s, t, p, pr) @@ -664,8 +686,7 @@ def pden(s, t, p, pr=0): def pres(depth, lat): - """ - Calculates pressure in dbars from depth in meters. + """Calculates pressure in dbars from depth in meters. Parameters ---------- @@ -683,8 +704,8 @@ def pres(depth, lat): -------- >>> import seawater as sw >>> depth, lat = 7321.45, 30 - >>> sw.pres(depth,lat) - 7500.0065130118019 + >>> sw.pres(depth, lat) + 7500.006513011802 References ---------- @@ -696,13 +717,12 @@ def pres(depth, lat): depth, lat = list(map(np.asanyarray, (depth, lat))) X = np.sin(np.abs(lat * deg2rad)) - C1 = 5.92e-3 + X ** 2 * 5.25e-3 + C1 = 5.92e-3 + X**2 * 5.25e-3 return ((1 - C1) - (((1 - C1) ** 2) - (8.84e-6 * depth)) ** 0.5) / 4.42e-6 def ptmp(s, t, p, pr=0): - """ - Calculates potential temperature as per UNESCO 1983 report. + """Calculates potential temperature as per UNESCO 1983 report. Parameters ---------- @@ -724,42 +744,47 @@ def ptmp(s, t, p, pr=0): -------- >>> import seawater as sw >>> from seawater.library import T90conv, T68conv - >>> t = T90conv([[0, 0, 0, 0, 0, 0], - ... [10, 10, 10, 10, 10, 10], - ... [20, 20, 20, 20, 20, 20], - ... [30, 30, 30, 30, 30, 30], - ... [40, 40, 40, 40, 40, 40]]) - >>> s = [[25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35], - ... [25, 25, 25, 35, 35, 35]] + >>> t = T90conv( + ... [ + ... [0, 0, 0, 0, 0, 0], + ... [10, 10, 10, 10, 10, 10], + ... [20, 20, 20, 20, 20, 20], + ... [30, 30, 30, 30, 30, 30], + ... [40, 40, 40, 40, 40, 40], + ... ] + ... ) + >>> s = [ + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... ] >>> p = [0, 5000, 10000, 0, 5000, 10000] >>> T68conv(sw.ptmp(s, t, p, pr=0)) - array([[ 0. , -0.30614418, -0.96669485, 0. , - -0.3855565 , -1.09741136], - [ 10. , 9.35306331, 8.46840949, 10. , - 9.29063461, 8.36425752], - [ 20. , 19.04376281, 17.94265 , 20. , - 18.99845171, 17.86536441], - [ 30. , 28.75124632, 27.43529911, 30. , - 28.72313484, 27.38506197], - [ 40. , 38.46068173, 36.92544552, 40. , - 38.44979906, 36.90231661]]) + array([[ 0. , -0.30614418, -0.96669485, 0. , -0.3855565 , + -1.09741136], + [10. , 9.35306331, 8.46840949, 10. , 9.29063461, + 8.36425752], + [20. , 19.04376281, 17.94265 , 20. , 18.99845171, + 17.86536441], + [30. , 28.75124632, 27.43529911, 30. , 28.72313484, + 27.38506197], + [40. , 38.46068173, 36.92544552, 40. , 38.44979906, + 36.90231661]]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] Bryden, H. 1973. New Polynomials for thermal expansion, adiabatic temperature gradient and potential temperature of sea water. Deep-Sea Res. Vol20,401-408. doi:10.1016/0011-7471(73)90063-6 """ - s, t, p, pr = list(map(np.asanyarray, (s, t, p, pr))) # Theta1. @@ -770,13 +795,13 @@ def ptmp(s, t, p, pr=0): # Theta2. del_th = del_P * adtg(s, T90conv(th), p + 0.5 * del_P) - th = th + (1 - 1 / 2 ** 0.5) * (del_th - q) - q = (2 - 2 ** 0.5) * del_th + (-2 + 3 / 2 ** 0.5) * q + th = th + (1 - 1 / 2**0.5) * (del_th - q) + q = (2 - 2**0.5) * del_th + (-2 + 3 / 2**0.5) * q # Theta3. del_th = del_P * adtg(s, T90conv(th), p + 0.5 * del_P) - th = th + (1 + 1 / 2 ** 0.5) * (del_th - q) - q = (2 + 2 ** 0.5) * del_th + (-2 - 3 / 2 ** 0.5) * q + th = th + (1 + 1 / 2**0.5) * (del_th - q) + q = (2 + 2**0.5) * del_th + (-2 - 3 / 2**0.5) * q # Theta4. del_th = del_P * adtg(s, T90conv(th), p + del_P) @@ -784,8 +809,7 @@ def ptmp(s, t, p, pr=0): def salt(r, t, p): - """ - Calculates Salinity from conductivity ratio. UNESCO 1983 polynomial. + r"""Calculates Salinity from conductivity ratio. UNESCO 1983 polynomial. Parameters ---------- @@ -810,14 +834,14 @@ def salt(r, t, p): >>> t = T90conv([15, 20, 5]) >>> p = [0, 2000, 1500] >>> sw.salt(r, t, p) - array([ 34.99999992, 37.24562765, 27.99534693]) + array([34.99999992, 37.24562765, 27.99534693]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ r, t, p = list(map(np.asanyarray, (r, t, p))) @@ -829,8 +853,7 @@ def salt(r, t, p): def svel(s, t, p): - """ - Sound Velocity in sea water using UNESCO 1983 polynomial. + """Sound Velocity in sea water using UNESCO 1983 polynomial. Parameters ---------- @@ -852,35 +875,41 @@ def svel(s, t, p): >>> import seawater as sw >>> from seawater.library import T90conv - >>> t = T90conv([[ 0, 0, 0, 0, 0, 0], - ... [ 10, 10, 10, 10, 10, 10], - ... [ 20, 20, 20, 20, 20, 20], - ... [ 30, 30, 30, 30, 30, 30], - ... [ 40, 40, 40, 40, 40, 40]]) - >>> s = [[ 25, 25, 25, 35, 35, 35], - ... [ 25, 25, 25, 35, 35, 35], - ... [ 25, 25, 25, 35, 35, 35], - ... [ 25, 25, 25, 35, 35, 35], - ... [ 25, 25, 25, 35, 35, 35]] - >>> p = [ 0, 5000, 10000, 0, 5000, 10000] + >>> t = T90conv( + ... [ + ... [0, 0, 0, 0, 0, 0], + ... [10, 10, 10, 10, 10, 10], + ... [20, 20, 20, 20, 20, 20], + ... [30, 30, 30, 30, 30, 30], + ... [40, 40, 40, 40, 40, 40], + ... ] + ... ) + >>> s = [ + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... [25, 25, 25, 35, 35, 35], + ... ] + >>> p = [0, 5000, 10000, 0, 5000, 10000] >>> sw.svel(s, t, p) - array([[ 1435.789875 , 1520.358725 , 1610.4074 , 1449.13882813, - 1533.96863705, 1623.15007097], - [ 1477.68316464, 1561.30635914, 1647.39267114, 1489.82233602, - 1573.40946928, 1658.99115504], - [ 1510.31388348, 1593.59671798, 1676.80967748, 1521.4619731 , - 1604.4762822 , 1687.18305631], - [ 1535.21434752, 1618.95631952, 1700.60547902, 1545.59485539, - 1628.97322783, 1710.06294277], - [ 1553.44506636, 1638.02522336, 1719.15088536, 1563.20925247, - 1647.29949576, 1727.83176404]]) + array([[1435.789875 , 1520.358725 , 1610.4074 , 1449.13882813, + 1533.96863705, 1623.15007097], + [1477.68316464, 1561.30635914, 1647.39267114, 1489.82233602, + 1573.40946928, 1658.99115504], + [1510.31388348, 1593.59671798, 1676.80967748, 1521.4619731 , + 1604.4762822 , 1687.18305631], + [1535.21434752, 1618.95631952, 1700.60547902, 1545.59485539, + 1628.97322783, 1710.06294277], + [1553.44506636, 1638.02522336, 1719.15088536, 1563.20925247, + 1647.29949576, 1727.83176404]]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ s, t, p = list(map(np.asanyarray, (s, t, p))) @@ -890,31 +919,69 @@ def svel(s, t, p): T68 = T68conv(t) # Eqn 34 p.46. - c00, c01, c02, c03, c04, c05 = (1402.388, 5.03711, -5.80852e-2, 3.3420e-4, - -1.47800e-6, 3.1464e-9) - c10, c11, c12, c13, c14 = (0.153563, 6.8982e-4, -8.1788e-6, 1.3621e-7, - -6.1185e-10) - c20, c21, c22, c23, c24 = (3.1260e-5, -1.7107e-6, 2.5974e-8, -2.5335e-10, - 1.0405e-12) + c00, c01, c02, c03, c04, c05 = ( + 1402.388, + 5.03711, + -5.80852e-2, + 3.3420e-4, + -1.47800e-6, + 3.1464e-9, + ) + c10, c11, c12, c13, c14 = ( + 0.153563, + 6.8982e-4, + -8.1788e-6, + 1.3621e-7, + -6.1185e-10, + ) + c20, c21, c22, c23, c24 = ( + 3.1260e-5, + -1.7107e-6, + 2.5974e-8, + -2.5335e-10, + 1.0405e-12, + ) c30, c31, c32 = (-9.7729e-9, 3.8504e-10, -2.3643e-12) - Cw = (((((c32 * T68 + c31) * T68 + c30) * p + - ((((c24 * T68 + c23) * T68 + c22) * T68 + c21) * T68 + c20)) * p + - ((((c14 * T68 + c13) * T68 + c12) * T68 + c11) * T68 + c10)) * - p + ((((c05 * T68 + c04) * T68 + c03) * T68 + c02) * T68 + c01) * - T68 + c00) + Cw = ( + ( + ( + ((c32 * T68 + c31) * T68 + c30) * p + + ((((c24 * T68 + c23) * T68 + c22) * T68 + c21) * T68 + c20) + ) + * p + + ((((c14 * T68 + c13) * T68 + c12) * T68 + c11) * T68 + c10) + ) + * p + + ((((c05 * T68 + c04) * T68 + c03) * T68 + c02) * T68 + c01) * T68 + + c00 + ) # Eqn. 35. p.47 a00, a01, a02, a03, a04 = (1.389, -1.262e-2, 7.164e-5, 2.006e-6, -3.21e-8) - a10, a11, a12, a13, a14 = (9.4742e-5, -1.2580e-5, -6.4885e-8, 1.0507e-8, - -2.0122e-10) + a10, a11, a12, a13, a14 = ( + 9.4742e-5, + -1.2580e-5, + -6.4885e-8, + 1.0507e-8, + -2.0122e-10, + ) a20, a21, a22, a23 = (-3.9064e-7, 9.1041e-9, -1.6002e-10, 7.988e-12) a30, a31, a32 = (1.100e-10, 6.649e-12, -3.389e-13) - A = (((((a32 * T68 + a31) * T68 + a30) * p + - (((a23 * T68 + a22) * T68 + a21) * T68 + a20)) * p + - ((((a14 * T68 + a13) * T68 + a12) * T68 + a11) * T68 + a10)) * p + - (((a04 * T68 + a03) * T68 + a02) * T68 + a01) * T68 + a00) + A = ( + ( + ( + ((a32 * T68 + a31) * T68 + a30) * p + + (((a23 * T68 + a22) * T68 + a21) * T68 + a20) + ) + * p + + ((((a14 * T68 + a13) * T68 + a12) * T68 + a11) * T68 + a10) + ) + * p + + (((a04 * T68 + a03) * T68 + a02) * T68 + a01) * T68 + + a00 + ) # Eqn 36 p.47. b00, b01, b10, b11 = -1.922e-2, -4.42e-5, 7.3637e-5, 1.7945e-7 @@ -925,12 +992,11 @@ def svel(s, t, p): D = d00 + d10 * p # Eqn 33 p.46. - return Cw + A * s + B * s * s ** 0.5 + D * s ** 2 + return Cw + A * s + B * s * s**0.5 + D * s**2 def temp(s, pt, p, pr=0): - """ - Calculates temperature from potential temperature at the reference + """Calculates temperature from potential temperature at the reference pressure PR and in situ pressure P. Parameters @@ -961,7 +1027,7 @@ def temp(s, pt, p, pr=0): .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] Bryden, H. 1973. New Polynomials for thermal expansion, adiabatic temperature gradient and potential temperature of sea water. Deep-Sea diff --git a/seawater/extras.py b/seawater/extras.py index e86bb64..f0902da 100644 --- a/seawater/extras.py +++ b/seawater/extras.py @@ -1,23 +1,20 @@ -# -*- coding: utf-8 -*- - - -from __future__ import division, absolute_import - import numpy as np + +from .constants import DEG2NM, NM2KM, OMEGA, Kelvin, deg2rad, gdef, rad2deg from .library import T68conv -from .constants import OMEGA, DEG2NM, NM2KM, Kelvin, deg2rad, rad2deg, gdef -__all__ = ['dist', - 'f', - 'satAr', - 'satN2', - 'satO2', - 'swvel'] +__all__ = [ + "dist", + "f", + "satAr", + "satN2", + "satO2", + "swvel", +] -def dist(lat, lon, units='km'): - """ - Calculate distance between two positions on globe using the "Plane +def dist(lat, lon, units="km"): + """Calculate distance between two positions on globe using the "Plane Sailing" method. Also uses simple geometry to calculate the bearing of the path between position pairs. @@ -42,18 +39,18 @@ def dist(lat, lon, units='km'): -------- >>> import seawater as sw >>> sw.dist(0, [-179, 180]) - (array([ 111.12]), array([ 180.])) + (array([111.12]), array([180.])) >>> lon = [35, 35] >>> lat = [41, 40] >>> sw.dist(lat, lon) - (array([ 111.12]), array([-90.])) + (array([111.12]), array([-90.])) >>> # Create a distance vector. - >>> lon = np.arange(30,40,1) + >>> lon = np.arange(30, 40, 1) >>> lat = 35 - >>> np.cumsum(np.append(0, sw.dist(lat, lon, units='km')[0])) - array([ 0. , 91.02417516, 182.04835032, 273.07252548, - 364.09670065, 455.12087581, 546.14505097, 637.16922613, - 728.19340129, 819.21757645]) + >>> np.cumsum(np.append(0, sw.dist(lat, lon, units="km")[0])) + array([ 0. , 91.02417516, 182.04835032, 273.07252548, + 364.09670065, 455.12087581, 546.14505097, 637.16922613, + 728.19340129, 819.21757645]) References ---------- @@ -61,7 +58,6 @@ def dist(lat, lon, units='km'): by Dr. P. Gormley. The Australian Antarctic Division. """ - lon, lat = list(map(np.asanyarray, (lon, lat))) lon, lat = np.broadcast_arrays(lon, lat) @@ -70,16 +66,17 @@ def dist(lat, lon, units='km'): ind = np.arange(0, npositions - 1, 1) # Index to first of position pairs. dlon = np.diff(lon, axis=0) - if np.any(np.abs(dlon) > 180): - flag = abs(dlon) > 180 - dlon[flag] = -np.sign(dlon[flag]) * (360 - np.abs(dlon[flag])) + lon180, lon360 = 180, 360 + if np.any(np.abs(dlon) > lon180): + flag = abs(dlon) > lon180 + dlon[flag] = -np.sign(dlon[flag]) * (lon360 - np.abs(dlon[flag])) latrad = np.abs(lat * deg2rad) dep = np.cos((latrad[ind + 1] + latrad[ind]) / 2) * dlon dlat = np.diff(lat, axis=0) - dist = DEG2NM * (dlat ** 2 + dep ** 2) ** 0.5 + dist = DEG2NM * (dlat**2 + dep**2) ** 0.5 - if units == 'km': + if units == "km": dist = dist * NM2KM # Calculate angle to x axis. @@ -88,8 +85,7 @@ def dist(lat, lon, units='km'): def f(lat): - """ - Calculates the Coriolis factor :math:`f` defined by: + r"""Calculates the Coriolis factor :math:`f` defined by: .. math:: f = 2 \\Omega \\sin(lat) @@ -136,8 +132,7 @@ def f(lat): def satAr(s, t): - """ - Solubility (saturation) of Argon (Ar) in sea water. + """Solubility (saturation) of Argon (Ar) in sea water. Parameters ---------- @@ -156,13 +151,13 @@ def satAr(s, t): >>> # Data from Weiss 1970. >>> import seawater as sw >>> from seawater.library import T90conv - >>> t = T90conv([[ -1, -1], [ 10, 10], [ 20, 20], [ 40, 40]]) - >>> s = [[ 20, 40], [ 20, 40], [ 20, 40], [ 20, 40]] + >>> t = T90conv([[-1, -1], [10, 10], [20, 20], [40, 40]]) + >>> s = [[20, 40], [20, 40], [20, 40], [20, 40]] >>> sw.satAr(s, t) - array([[ 0.4455784 , 0.38766011], - [ 0.33970659, 0.29887756], - [ 0.27660227, 0.24566428], - [ 0.19861429, 0.17937698]]) + array([[0.4455784 , 0.38766011], + [0.33970659, 0.29887756], + [0.27660227, 0.24566428], + [0.19861429, 0.17937698]]) References ---------- @@ -171,7 +166,6 @@ def satAr(s, t): doi:10.1016/0011-7471(70)90037-9 """ - s, t = list(map(np.asanyarray, (s, t))) # Convert T to Kelvin. @@ -182,15 +176,19 @@ def satAr(s, t): b = [-0.034474, 0.014934, -0.0017729] # Eqn (4) of Weiss 1970. - lnC = (a[0] + a[1] * (100 / t) + a[2] * np.log(t / 100) + a[3] * - (t / 100) + s * (b[0] + b[1] * (t / 100) + b[2] * ((t / 100) ** 2))) + lnC = ( + a[0] + + a[1] * (100 / t) + + a[2] * np.log(t / 100) + + a[3] * (t / 100) + + s * (b[0] + b[1] * (t / 100) + b[2] * ((t / 100) ** 2)) + ) return np.exp(lnC) def satN2(s, t): - """ - Solubility (saturation) of Nitrogen (N2) in sea water. + """Solubility (saturation) of Nitrogen (N2) in sea water. Parameters ---------- @@ -209,14 +207,13 @@ def satN2(s, t): >>> # Data from Weiss 1970. >>> import seawater as sw >>> from seawater.library import T90conv - >>> t = T90conv([[ -1, -1], [ 10, 10], [ 20, 20], [ 40, 40]]) - >>> s = [[ 20, 40], [ 20, 40], [ 20, 40], [ 20, 40]] + >>> t = T90conv([[-1, -1], [10, 10], [20, 20], [40, 40]]) + >>> s = [[20, 40], [20, 40], [20, 40], [20, 40]] >>> sw.satN2(s, t) - array([[ 16.27952432, 14.00784526], - [ 12.64036196, 11.01277257], - [ 10.46892822, 9.21126859], - [ 7.78163876, 6.95395099]]) - + array([[16.27952432, 14.00784526], + [12.64036196, 11.01277257], + [10.46892822, 9.21126859], + [ 7.78163876, 6.95395099]]) References ---------- @@ -225,7 +222,6 @@ def satN2(s, t): doi:10.1016/0011-7471(70)90037-9 """ - s, t = list(map(np.asanyarray, (s, t))) # Convert T to Kelvin. @@ -236,15 +232,19 @@ def satN2(s, t): b = (-0.049781, 0.025018, -0.0034861) # Eqn (4) of Weiss 1970. - lnC = (a[0] + a[1] * (100 / t) + a[2] * np.log(t / 100) + a[3] * - (t / 100) + s * (b[0] + b[1] * (t / 100) + b[2] * ((t / 100) ** 2))) + lnC = ( + a[0] + + a[1] * (100 / t) + + a[2] * np.log(t / 100) + + a[3] * (t / 100) + + s * (b[0] + b[1] * (t / 100) + b[2] * ((t / 100) ** 2)) + ) return np.exp(lnC) def satO2(s, t): - """ - Solubility (saturation) of Oxygen (O2) in sea water. + """Solubility (saturation) of Oxygen (O2) in sea water. Parameters ---------- @@ -263,13 +263,13 @@ def satO2(s, t): >>> # Data from Weiss 1970. >>> import seawater as sw >>> from seawater.library import T90conv - >>> t = T90conv([[ -1, -1], [ 10, 10], [ 20, 20], [ 40, 40]]) - >>> s = [[ 20, 40], [ 20, 40], [ 20, 40], [ 20, 40]] + >>> t = T90conv([[-1, -1], [10, 10], [20, 20], [40, 40]]) + >>> s = [[20, 40], [20, 40], [20, 40], [20, 40]] >>> sw.satO2(s, t) - array([[ 9.162056 , 7.98404249], - [ 6.95007741, 6.12101928], - [ 5.64401453, 5.01531004], - [ 4.0495115 , 3.65575811]]) + array([[9.162056 , 7.98404249], + [6.95007741, 6.12101928], + [5.64401453, 5.01531004], + [4.0495115 , 3.65575811]]) References ---------- @@ -278,7 +278,6 @@ def satO2(s, t): doi:10.1016/0011-7471(70)90037-9 """ - s, t = list(map(np.asanyarray, (s, t))) # Convert T to Kelvin. @@ -289,15 +288,19 @@ def satO2(s, t): b = (-0.033096, 0.014259, -0.0017000) # Eqn (4) of Weiss 1970. - lnC = (a[0] + a[1] * (100 / t) + a[2] * np.log(t / 100) + a[3] * - (t / 100) + s * (b[0] + b[1] * (t / 100) + b[2] * ((t / 100) ** 2))) + lnC = ( + a[0] + + a[1] * (100 / t) + + a[2] * np.log(t / 100) + + a[3] * (t / 100) + + s * (b[0] + b[1] * (t / 100) + b[2] * ((t / 100) ** 2)) + ) return np.exp(lnC) def swvel(length, depth): - """ - Calculates surface wave velocity. + """Calculates surface wave velocity. length : array_like wave length @@ -313,7 +316,7 @@ def swvel(length, depth): -------- >>> import seawater as sw >>> sw.swvel(10, 100) - 3.9493270848342941 + 3.949327084834294 """ length, depth = list(map(np.asanyarray, (length, depth))) diff --git a/seawater/geostrophic.py b/seawater/geostrophic.py index 23c81df..371f850 100644 --- a/seawater/geostrophic.py +++ b/seawater/geostrophic.py @@ -1,24 +1,20 @@ -# -*- coding: utf-8 -*- - - -from __future__ import division, absolute_import - import numpy as np +from .constants import db2Pascal, gdef +from .eos80 import dens, dpth, g, pden from .extras import dist, f from .library import atleast_2d -from .eos80 import dens, dpth, g, pden -from .constants import db2Pascal, gdef -__all__ = ['bfrq', - 'svan', - 'gpan', - 'gvel'] +__all__ = [ + "bfrq", + "svan", + "gpan", + "gvel", +] def bfrq(s, t, p, lat=None): - """ - Calculates Brünt-Väisälä Frequency squared (N :sup:`2`) at the mid + r"""Calculates Brünt-Väisälä Frequency squared (N :sup:`2`) at the mid depths from the equation: .. math:: @@ -54,14 +50,14 @@ def bfrq(s, t, p, lat=None): Examples -------- >>> import seawater as sw - >>> s = [[0, 0, 0], [15, 15, 15], [30, 30, 30],[35,35,35]] - >>> t = [[15]*3]*4 + >>> s = [[0, 0, 0], [15, 15, 15], [30, 30, 30], [35, 35, 35]] + >>> t = [[15] * 3] * 4 >>> p = [[0], [250], [500], [1000]] - >>> lat = [30,32,35] + >>> lat = [30, 32, 35] >>> sw.bfrq(s, t, p, lat)[0] - array([[ 4.51543648e-04, 4.51690708e-04, 4.51920753e-04], - [ 4.45598092e-04, 4.45743207e-04, 4.45970207e-04], - [ 7.40996788e-05, 7.41238078e-05, 7.41615525e-05]]) + array([[4.51543648e-04, 4.51690708e-04, 4.51920753e-04], + [4.45598092e-04, 4.45743207e-04, 4.45970207e-04], + [7.40996788e-05, 7.41238078e-05, 7.41615525e-05]]) References ---------- @@ -74,28 +70,27 @@ def bfrq(s, t, p, lat=None): doi: 10.1175/1520-0426(1995)012<0381:MAOHPT>2.0.CO;2 """ - s, t, p = list(map(np.asanyarray, (s, t, p))) s, t, p = np.broadcast_arrays(s, t, p) s, t, p = list(map(atleast_2d, (s, t, p))) if lat is None: - z, cor, grav = p, np.NaN, np.ones(p.shape) * gdef + z, cor, grav = p, np.nan, np.ones(p.shape) * gdef else: lat = np.asanyarray(lat) z = dpth(p, lat) grav = g(lat, -z) # -z because `grav` expects height as argument. cor = f(lat) - p_ave = (p[0:-1, ...] + p[1:, ...]) / 2. + p_ave = (p[0:-1, ...] + p[1:, ...]) / 2.0 pden_up = pden(s[0:-1, ...], t[0:-1, ...], p[0:-1, ...], p_ave) pden_lo = pden(s[1:, ...], t[1:, ...], p[1:, ...], p_ave) - mid_pden = (pden_up + pden_lo) / 2. + mid_pden = (pden_up + pden_lo) / 2.0 dif_pden = pden_up - pden_lo - mid_g = (grav[0:-1, ...] + grav[1:, ...]) / 2. + mid_g = (grav[0:-1, ...] + grav[1:, ...]) / 2.0 dif_z = np.diff(z, axis=0) @@ -107,8 +102,7 @@ def bfrq(s, t, p, lat=None): def svan(s, t, p=0): - """ - Specific Volume Anomaly calculated as + """Specific Volume Anomaly calculated as svan = 1 / dens(s, t, p) - 1 / dens(35, 0, p). Note that it is often quoted in literature as 1e8 * units. @@ -133,20 +127,20 @@ def svan(s, t, p=0): >>> import seawater as sw >>> from seawater.library import T90conv >>> s = [[0, 1, 2], [15, 16, 17], [30, 31, 32], [35, 35, 35]] - >>> t = T90conv([[15]*3]*4) + >>> t = T90conv([[15] * 3] * 4) >>> p = [[0], [250], [500], [1000]] >>> sw.svan(s, t, p) - array([[ 2.82371949e-05, 2.74626498e-05, 2.66921126e-05], - [ 1.68453274e-05, 1.60993333e-05, 1.53543515e-05], - [ 5.80768118e-06, 5.07784980e-06, 4.34876387e-06], - [ 2.30490099e-06, 2.30490099e-06, 2.30490099e-06]]) + array([[2.82371949e-05, 2.74626498e-05, 2.66921126e-05], + [1.68453274e-05, 1.60993333e-05, 1.53543515e-05], + [5.80768118e-06, 5.07784980e-06, 4.34876387e-06], + [2.30490099e-06, 2.30490099e-06, 2.30490099e-06]]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] S. Pond & G.Pickard 2nd Edition 1986 Introductory Dynamical Oceanography Pergamon Press Sydney. ISBN 0-08-028728-X @@ -157,8 +151,7 @@ def svan(s, t, p=0): def gpan(s, t, p): - """ - Geopotential Anomaly calculated as the integral of svan from the + """Geopotential Anomaly calculated as the integral of svan from the the sea surface to the bottom. THUS RELATIVE TO SEA SURFACE. Adapted method from Pond and Pickard (p76) to calculate gpan relative to @@ -187,14 +180,14 @@ def gpan(s, t, p): -------- >>> # Data from Unesco Tech. Paper in Marine Sci. No. 44, p22. >>> import seawater as sw - >>> s = [[0, 1, 2], [15, 16, 17], [30, 31, 32], [35,35,35]] - >>> t = [[15]*3]*4 + >>> s = [[0, 1, 2], [15, 16, 17], [30, 31, 32], [35, 35, 35]] + >>> t = [[15] * 3] * 4 >>> p = [[0], [250], [500], [1000]] >>> sw.gpan(s, t, p) - array([[ 0. , 0. , 0. ], - [ 56.35465209, 54.45399428, 52.55961152], - [ 84.67266947, 80.92724333, 77.19028933], - [ 104.95799186, 99.38799979, 93.82834339]]) + array([[ 0. , 0. , 0. ], + [ 56.35465209, 54.45399428, 52.55961152], + [ 84.67266947, 80.92724333, 77.19028933], + [104.95799186, 99.38799979, 93.82834339]]) References ---------- @@ -202,7 +195,6 @@ def gpan(s, t, p): Oceanography Pergamon Press Sydney. ISBN 0-08-028728-X """ - s, t, p = list(map(np.asanyarray, (s, t, p))) s, t, p = np.broadcast_arrays(s, t, p) s, t, p = list(map(atleast_2d, (s, t, p))) @@ -210,7 +202,7 @@ def gpan(s, t, p): svn = svan(s, t, p) # NOTE: Assumes that pressure is the first dimension! - mean_svan = (svn[1:, ...] + svn[0:-1, ...]) / 2. + mean_svan = (svn[1:, ...] + svn[0:-1, ...]) / 2.0 top = svn[0, ...] * p[0, ...] * db2Pascal bottom = (mean_svan * np.diff(p, axis=0)) * db2Pascal ga = np.concatenate((top[None, ...], bottom), axis=0) @@ -218,8 +210,7 @@ def gpan(s, t, p): def gvel(ga, lat, lon): - """ - Calculates geostrophic velocity given the geopotential anomaly and + """Calculates geostrophic velocity given the geopotential anomaly and position of each station. Parameters @@ -243,21 +234,33 @@ def gvel(ga, lat, lon): >>> import seawater as sw >>> lon = np.array([-30, -30, -30, -30, -30]) >>> lat = np.linspace(-22, -21, 5) - >>> t = np.array([[0, 0, 0, 0, 0], - ... [10, 10, 10, 10, 10], - ... [20, 20, 20, 20, 20], - ... [30, 30, 30, 30, 30], - ... [40, 40, 40, 40, 40]]) - >>> s = np.array([[25, 25, 25, 35, 35], - ... [25, 25, 25, 35, 35], - ... [25, 25, 25, 35, 35], - ... [25, 25, 25, 35, 35], - ... [25, 25, 25, 35, 35]]) - >>> p = np.array([[0, 5000, 10000, 0, 5000], - ... [0, 5000, 10000, 0, 5000], - ... [0, 5000, 10000, 0, 5000], - ... [0, 5000, 10000, 0, 5000], - ... [0, 5000, 10000, 0, 5000]]) + >>> t = np.array( + ... [ + ... [0, 0, 0, 0, 0], + ... [10, 10, 10, 10, 10], + ... [20, 20, 20, 20, 20], + ... [30, 30, 30, 30, 30], + ... [40, 40, 40, 40, 40], + ... ] + ... ) + >>> s = np.array( + ... [ + ... [25, 25, 25, 35, 35], + ... [25, 25, 25, 35, 35], + ... [25, 25, 25, 35, 35], + ... [25, 25, 25, 35, 35], + ... [25, 25, 25, 35, 35], + ... ] + ... ) + >>> p = np.array( + ... [ + ... [0, 5000, 10000, 0, 5000], + ... [0, 5000, 10000, 0, 5000], + ... [0, 5000, 10000, 0, 5000], + ... [0, 5000, 10000, 0, 5000], + ... [0, 5000, 10000, 0, 5000], + ... ] + ... ) >>> ga = sw.gpan(s, t, p) >>> sw.gvel(ga, lat, lon) array([[ 231.74785186, 197.54291221, -436.64938045, 0. ], @@ -272,8 +275,7 @@ def gvel(ga, lat, lon): Oceanography Pergamon Press Sydney. ISBN 0-08-028728-X """ - ga, lon, lat = list(map(np.asanyarray, (ga, lon, lat))) - distm = dist(lat, lon, units='km')[0] * 1e3 + distm = dist(lat, lon, units="km")[0] * 1e3 lf = f((lat[0:-1] + lat[1:]) / 2) * distm return -np.diff(ga, axis=1) / lf diff --git a/seawater/library.py b/seawater/library.py index 0a5f0ab..4e0f18f 100644 --- a/seawater/library.py +++ b/seawater/library.py @@ -1,20 +1,16 @@ -# -*- coding: utf-8 -*- - - -from __future__ import division, absolute_import - import numpy as np - -__all__ = ['cndr', - 'salds', - 'salrp', - 'salrt', - 'seck', - 'sals', - 'smow', - 'T68conv', - 'T90conv'] +__all__ = [ + "cndr", + "salds", + "salrp", + "salrt", + "seck", + "sals", + "smow", + "T68conv", + "T90conv", +] # Constants. @@ -27,8 +23,7 @@ def cndr(s, t, p): - """ - Calculates conductivity ratio. + """Calculates conductivity ratio. Parameters ---------- @@ -52,15 +47,15 @@ def cndr(s, t, p): >>> p = [0, 0, 1000, 1000, 0, 0] >>> s = [25, 25, 25, 25, 40, 40] >>> sw.cndr(s, t, p) - array([ 0.49800825, 0.65499015, 0.50624434, 0.66297496, 1.00007311, - 1.52996697]) + array([0.49800825, 0.65499015, 0.50624434, 0.66297496, 1.00007311, + 1.52996697]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.UNESCO.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ s, t, p = list(map(np.asanyarray, (s, t, p))) @@ -76,8 +71,7 @@ def cndr(s, t, p): SInc = sals(Rx_loop * Rx_loop, T) # S Increment (guess) from Rx. iloop = 0 while True: - # FIXME: I believe that T / 1.00024 isn't correct here. But I'm - # reproducing seawater up to its bugs! + # NOTE: I believe that T / 1.00024 isn't correct here. Rx_loop = Rx_loop + (S - SInc) / salds(Rx_loop, T / 1.00024 - 15) SInc = sals(Rx_loop * Rx_loop, T) iloop += 1 @@ -93,24 +87,22 @@ def cndr(s, t, p): # Once Rt found, corresponding to each (s,t) evaluate r. # Eqn(4) p.8 UNESCO 1983. - 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) + 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) # Eqn(6) p.9 UNESCO 1983. - Rt = Rx ** 2 + Rt = Rx**2 rt = salrt(t) # Rtrt = rt * Rt # NOTE: unused in the code, but present in the original. D = B - A * rt * Rt E = rt * Rt * A * (B + C) - r = np.sqrt(np.abs(D ** 2 + 4 * E)) - D - r = 0.5 * r / A - return r + r = np.sqrt(np.abs(D**2 + 4 * E)) - D + return 0.5 * r / A def salds(rtx, delt): - """ - Calculates Salinity differential (:math:`\\frac{dS}{d(\\sqrt{Rt})}`) at + r"""Calculates Salinity differential (:math:`\\frac{dS}{d(\\sqrt{Rt})}`) at constant temperature. Parameters @@ -131,33 +123,30 @@ def salds(rtx, delt): >>> import numpy as np >>> import seawater as sw >>> delt = T90conv([15, 20, 5]) - 15 - >>> rtx = np.array([ 1, 1.0568875, 0.81705885]) ** 0.5 + >>> rtx = np.array([1, 1.0568875, 0.81705885]) ** 0.5 >>> sw.salds(rtx, delt) - array([ 78.31921607, 81.5689307 , 68.19023687]) + array([78.31921607, 81.5689307 , 68.19023687]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.UNESCO.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ rtx, delt = list(map(np.asanyarray, (rtx, delt))) - ds = (a[1] + - (2 * a[2] + (3 * a[3] + (4 * a[4] + 5 * a[5] * rtx) * rtx) * rtx) * - rtx + (delt / (1 + k * delt)) * - (b[1] + - (2 * b[2] + (3 * b[3] + (4 * b[4] + 5 * b[5] * rtx) * rtx) * rtx) * - rtx)) - - return ds + return ( + a[1] + + (2 * a[2] + (3 * a[3] + (4 * a[4] + 5 * a[5] * rtx) * rtx) * rtx) * rtx + + (delt / (1 + k * delt)) + * (b[1] + (2 * b[2] + (3 * b[3] + (4 * b[4] + 5 * b[5] * rtx) * rtx) * rtx) * rtx) + ) def salrp(r, t, p): - """ - Equation for Rp used in calculating salinity. UNESCO 1983 polynomial. + r"""Equation for Rp used in calculating salinity. UNESCO 1983 polynomial. .. math:: Rp(S,T,P) = \\frac{C(S,T,P)}{C(S,T,0)} @@ -184,14 +173,14 @@ def salrp(r, t, p): >>> t = T90conv([15, 20, 5]) >>> p = [0, 2000, 1500] >>> sw.salrp(r, t, p) - array([ 1. , 1.01694294, 1.02048638]) + array([1. , 1.01694294, 1.02048638]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ r, t, p = list(map(np.asanyarray, (r, t, p))) @@ -199,15 +188,13 @@ def salrp(r, t, p): # Eqn(4) p.8 UNESCO. T68 = T68conv(t) - 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)) - - return rp + return 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 + ) def salrt(t): - """ - Equation for rt used in calculating salinity. UNESCO 1983 polynomial. + r"""Equation for rt used in calculating salinity. UNESCO 1983 polynomial. .. math:: rt(t) = \\frac{C(35,t,0)}{C(35,15(\\textrm{IPTS-68}), 0)} @@ -229,14 +216,14 @@ def salrt(t): >>> import seawater as sw >>> t = T90conv([15, 20, 5]) >>> sw.salrt(t) - array([ 1. , 1.11649272, 0.77956585]) + array([1. , 1.11649272, 0.77956585]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ t = np.asanyarray(t) @@ -246,8 +233,7 @@ def salrt(t): def seck(s, t, p=0): - """ - Secant Bulk Modulus (K) of Sea Water using Equation of state 1980. + """Secant Bulk Modulus (K) of Sea Water using Equation of state 1980. UNESCO polynomial implementation. Parameters @@ -272,15 +258,15 @@ def seck(s, t, p=0): >>> t = T90conv([0, 0, 30, 30, 0, 0, 30, 30]) >>> p = [0, 10000, 0, 10000, 0, 10000, 0, 10000] >>> sw.seck(s, t, p) - array([ 19652.21 , 22977.2115 , 22336.0044572 , 25656.8196222 , - 21582.27006823, 24991.99729129, 23924.21823158, 27318.32472464]) + array([19652.21 , 22977.2115 , 22336.0044572 , 25656.8196222 , + 21582.27006823, 24991.99729129, 23924.21823158, 27318.32472464]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] Millero, F.J. and Poisson, A. International one-atmosphere equation of state of seawater. Deep-Sea Res. 1981. Vol28A(6) pp625-629. @@ -310,21 +296,27 @@ def seck(s, t, p=0): # Sea water terms of secant bulk modulus at atmos. pressure. j0 = 1.91075e-4 i = [2.2838e-3, -1.0981e-5, -1.6078e-6] - A = AW + (i[0] + (i[1] + i[2] * T68) * T68 + j0 * s ** 0.5) * s + A = AW + (i[0] + (i[1] + i[2] * T68) * T68 + j0 * s**0.5) * s m = [-9.9348e-7, 2.0816e-8, 9.1697e-10] B = BW + (m[0] + (m[1] + m[2] * T68) * T68) * s # Eqn 18. f = [54.6746, -0.603459, 1.09987e-2, -6.1670e-5] g = [7.944e-2, 1.6483e-2, -5.3009e-4] - K0 = (KW + (f[0] + (f[1] + (f[2] + f[3] * T68) * T68) * T68 + - (g[0] + (g[1] + g[2] * T68) * T68) * s ** 0.5) * s) # Eqn 16. + K0 = ( + KW + + ( + f[0] + + (f[1] + (f[2] + f[3] * T68) * T68) * T68 + + (g[0] + (g[1] + g[2] * T68) * T68) * s**0.5 + ) + * s + ) # Eqn 16. return K0 + (A + B * p) * p # Eqn 15. def sals(rt, t): - """ - Salinity of sea water as a function of Rt and T. UNESCO 1983 polynomial. + r"""Salinity of sea water as a function of Rt and T. UNESCO 1983 polynomial. Parameters ---------- @@ -345,14 +337,14 @@ def sals(rt, t): >>> t = T90conv([15, 20, 5]) >>> rt = [1, 1.0568875, 0.81705885] >>> sw.sals(rt, t) - array([ 35. , 37.24562718, 27.99534701]) + array([35. , 37.24562718, 27.99534701]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.UNESCO.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng """ rt, t = list(map(np.asanyarray, (rt, t))) @@ -361,19 +353,17 @@ def sals(rt, t): del_T68 = T68conv(t) - 15 Rtx = (rt) ** 0.5 - del_S = ((del_T68 / (1 + k * del_T68)) * - (b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * - Rtx) * Rtx) * Rtx) * Rtx)) - s = a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * - Rtx) * Rtx) * Rtx) * Rtx + del_S = (del_T68 / (1 + k * del_T68)) * ( + b[0] + (b[1] + (b[2] + (b[3] + (b[4] + b[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx + ) + s = a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * Rtx) * Rtx) * Rtx) * Rtx) * Rtx s += del_S return s def smow(t): - """ - Density of Standard Mean Ocean Water (Pure Water) using EOS 1980. + """Density of Standard Mean Ocean Water (Pure Water) using EOS 1980. Parameters ---------- @@ -391,15 +381,15 @@ def smow(t): >>> import seawater as sw >>> t = T90conv([0, 0, 30, 30, 0, 0, 30, 30]) >>> sw.smow(t) - array([ 999.842594 , 999.842594 , 995.65113374, 995.65113374, - 999.842594 , 999.842594 , 995.65113374, 995.65113374]) + array([999.842594 , 999.842594 , 995.65113374, 995.65113374, + 999.842594 , 999.842594 , 995.65113374, 995.65113374]) References ---------- .. [1] Fofonoff, P. and Millard, R.C. Jr UNESCO 1983. Algorithms for computation of fundamental properties of seawater. UNESCO Tech. Pap. in Mar. Sci., No. 44, 53 pp. Eqn.(31) p.39. - http://unesdoc.unesco.org/images/0005/000598/059832eb.pdf + https://unesdoc.unesco.org/ark:/48223/pf0000059832_eng .. [2] Millero, F.J. and Poisson, A. International one-atmosphere equation of state of seawater. Deep-Sea Res. 1981. Vol28A(6) pp625-629. @@ -408,17 +398,21 @@ def smow(t): """ t = np.asanyarray(t) - a = (999.842594, 6.793952e-2, -9.095290e-3, 1.001685e-4, -1.120083e-6, - 6.536332e-9) + a = ( + 999.842594, + 6.793952e-2, + -9.095290e-3, + 1.001685e-4, + -1.120083e-6, + 6.536332e-9, + ) T68 = T68conv(t) - return (a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * T68) * T68) * T68) * - T68) * T68) + return a[0] + (a[1] + (a[2] + (a[3] + (a[4] + a[5] * T68) * T68) * T68) * T68) * T68 def T68conv(T90): - """ - Convert ITS-90 temperature to IPTS-68 + """Convert ITS-90 temperature to IPTS-68. :math:`T68 = T90 * 1.00024` @@ -456,9 +450,8 @@ def T68conv(T90): return T90 * 1.00024 -def T90conv(t, t_type='T68'): - """ - Convert IPTS-68 or IPTS-48 to temperature to ITS-90. +def T90conv(t, t_type="T68"): + """Convert IPTS-68 or IPTS-48 to temperature to ITS-90. T48 apply to all data collected prior to 31/12/1967. T68 apply to all data collected between 01/10/1968 and 31/12/1989. @@ -491,8 +484,8 @@ def T90conv(t, t_type='T68'): -------- >>> T90conv(20.004799999999999) 20.0 - >>> T90conv(20., t_type='T48') - 19.988162840918179 + >>> T90conv(20.0, t_type="T48") + 19.98816284091818 References ---------- @@ -500,44 +493,35 @@ def T90conv(t, t_type='T68'): ITS-90. WOCE Newsletter, No. 10, WOCE International Project Office, Southampton, United Kingdom, 10. - .. [2] International Temperature Scales of 1948, 1968 and 1990, an ICES - note, available from http://www.ices.dk/ocean/procedures/its.htm - """ t = np.asanyarray(t) - if t_type == 'T68': + if t_type == "T68": T90 = t / 1.00024 - elif t_type == 'T48': + elif t_type == "T48": T90 = (t - 4.4e-6 * t * (100 - t)) / 1.00024 else: - raise NameError("Unrecognized temperature type. Try 'T68'' or 'T48'") + msg = "Unrecognized temperature type. Try 'T68'' or 'T48'" + raise NameError(msg) return T90 def atleast_2d(*arys): - """ - Same as numpy atleast_2d, but with the single dimension last, instead of + """Same as numpy atleast_2d, but with the single dimension last, instead of first. """ res = [] for ary in arys: - ary = np.asanyarray(ary) - if len(ary.shape) == 0: - result = ary.reshape(1, 1) - elif len(ary.shape) == 1: - result = ary[:, np.newaxis] + arry = np.asanyarray(ary) + if len(arry.shape) == 0: + result = arry.reshape(1, 1) + elif len(arry.shape) == 1: + result = arry[:, np.newaxis] else: - result = ary + result = arry res.append(result) if len(res) == 1: return res[0] - else: - return res - - -if __name__ == '__main__': - import doctest - doctest.testmod() + return res diff --git a/seawater/test/sw_test.py b/seawater/test/sw_test.py deleted file mode 100644 index a1cb333..0000000 --- a/seawater/test/sw_test.py +++ /dev/null @@ -1,480 +0,0 @@ -from __future__ import division, absolute_import - -import sys -from platform import uname -from time import asctime, localtime - -import numpy as np -import seawater as sw - - -def test(fileout='python-test.txt'): - """ - Copy of the Matlab test. - - """ - f = open(fileout, 'w') - asterisks = '*' * 76 - - f.write(asterisks) - f.write('\n TEST REPORT ') - f.write('\n') - f.write('\n SEA WATER LIBRARY %s' % sw.__version__) - f.write('\n') - # Show some info about this Python. - f.write('\npython version: %s' % sys.version) - f.write('\n on %s computer %s' % (uname()[0], uname()[-1])) - f.write('\n') - f.write('\n') - f.write(asctime(localtime())) - f.write('\n') - f.write('\n') - - # Test main module ptmp. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: ptmp') - f.write('\n** and SUB-MODULE: adtg') - f.write('\n%s' % asterisks) - f.write('\n') - f.write('\n') - - # Test 1 - data from Unesco 1983 p45. - T = np.array([[0, 0, 0, 0, 0, 0], - [10, 10, 10, 10, 10, 10], - [20, 20, 20, 20, 20, 20], - [30, 30, 30, 30, 30, 30], - [40, 40, 40, 40, 40, 40]]) - - T = T / 1.00024 - - S = np.array([[25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35]]) - - P = np.array([[0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000]]) - - Pr = np.array([0, 0, 0, 0, 0, 0]) - - UN_ptmp = np.array([[0, -0.3061, -0.9667, 0, -0.3856, -1.0974], - [10, 9.3531, 8.4684, 10, 9.2906, 8.3643], - [20, 19.0438, 17.9426, 20, 18.9985, 17.8654], - [30, 28.7512, 27.4353, 30, 28.7231, 27.3851], - [40, 38.4607, 36.9254, 40, 38.4498, 36.9023]]) - - PT = sw.ptmp(S, T, P, Pr) * 1.00024 - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from UNESCO 1983 ') - f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p45)') - f.write('\n%s' % asterisks) - f.write('\n') - - m, n = S.shape # TODO: so many loops there must be a better way. - for icol in range(0, n): - f.write('\n Sal Temp Press PTMP ptmp') - f.write('\n (psu) (C) (db) (C) (C)\n') - result = np.vstack((S[:, icol], T[:, icol], P[:, icol], - UN_ptmp[:, icol], PT[:, icol])) - for iline in range(0, m): - f.write(" %4.0f %4.0f %5.0f %8.4f %11.5f\n" % - tuple(result[:, iline])) - - # Test main module svan. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: svan') - f.write('\n** and SUB-MODULE: dens dens0 smow seck pden ptmp') - f.write('\n%s' % asterisks) - - # Test data FROM: Unesco Tech. Paper in Marine Sci. No. 44, p22. - s = np.array([0, 0, 0, 0, 35, 35, 35, 35]) - p = np.array([0, 10000, 0, 10000, 0, 10000, 0, 10000]) - t = np.array([0, 0, 30, 30, 0, 0, 30, 30]) / 1.00024 - - UN_svan = np.array([2749.54, 2288.61, 3170.58, 3147.85, - 0.0, 0.00, 607.14, 916.34]) - - SVAN = sw.svan(s, t, p) - - # DISPLAY RESULTS - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\n') - f.write('\nComparison of accepted values from UNESCO 1983') - f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p22)') - f.write('\n%s' % asterisks) - f.write('\n') - f.write('\n Sal Temp Press SVAN svan') - f.write('\n (psu) (C) (db) (1e-8*m3/kg) (1e-8*m3/kg)\n') - result = np.vstack([s, t, p, UN_svan, 1e+8 * SVAN]) - for iline in range(0, len(SVAN)): - f.write(" %4.0f %4.0f %5.0f %11.2f %11.3f\n" % - tuple(result[:, iline])) - - # Test main module salt. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: salt') - f.write('\n** and SUB-MODULE: salrt salrp sals') - f.write('\n%s' % asterisks) - f.write('\n') - - # Test 1 - data from Unesco 1983 p9. - R = np.array([1, 1.2, 0.65]) # cndr = R. - T = np.array([15, 20, 5]) / 1.00024 - P = np.array([0, 2000, 1500]) - # Rt = np.array([ 1, 1.0568875, 0.81705885]) - UN_S = np.array([35, 37.245628, 27.995347]) - - S = sw.salt(R, T, P) - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from UNESCO 1983 ') - f.write('\n(Unesco Tech. Paper in Marine Sci. No. 44, p9)') - f.write('\n%s' % asterisks) - f.write('\n') - - f.write('\n Temp Press R S salt') - f.write('\n (C) (db) (no units) (psu) (psu)\n') - table = np.vstack([T, P, R, UN_S, S]) - m, n = table.shape - for iline in range(0, n): - f.write(" %4.0f %4.0f %8.2f %11.6f %14.7f\n" % - tuple(table[:, iline])) - - # Test main module cndr. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: cndr') - f.write('\n** and SUB-MODULE: salds') - f.write('\n%s' % asterisks) - - # Test 1 - data from Unesco 1983 p9. - T = np.array([0, 10, 0, 10, 10, 30]) / 1.00024 - P = np.array([0, 0, 1000, 1000, 0, 0]) - S = np.array([25, 25, 25, 25, 40, 40]) - UN_R = np.array([0.498088, 0.654990, 0.506244, 0.662975, 1.000073, - 1.529967]) - R = sw.cndr(S, T, P) - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from UNESCO 1983 ') - f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p14)') - f.write('\n%s' % asterisks) - f.write('\n') - f.write('\n') - - f.write('\n Temp Press S cndr cndr') - f.write('\n (C) (db) (psu) (no units) (no units)\n') - table = np.vstack([T, P, S, UN_R, R]) - m, n = table.shape - for iline in range(0, n): - f.write(" %4.0f %4.0f %8.6f %11.6f %14.8f\n" % - tuple(table[:, iline])) - - # Test main module depth. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: depth') - f.write('\n%s' % asterisks) - - # Test data - matrix "pressure", vector "lat" Unesco 1983 data p30. - lat = np.array([0, 30, 45, 90]) - P = np.array([[500, 500, 500, 500], - [5000, 5000, 5000, 5000], - [10000, 10000, 10000, 10000]]) - - UN_dpth = np.array([[496.65, 496.00, 495.34, 494.03], - [4915.04, 4908.56, 4902.08, 4889.13], - [9725.47, 9712.65, 9699.84, 9674.23]]) - - dpth = sw.dpth(P, lat) - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from Unesco 1983 ') - f.write('\n(Unesco Tech. Paper in Marine Sci. No. 44, p28)') - f.write('\n%s' % asterisks) - f.write('\n') - - f.write('\n') - for irow in range(0, 3): - f.write('\n Lat Press DPTH dpth') - f.write('\n (degree) (db) (meter) (meter)\n') - table = np.vstack([lat, P[irow, :], UN_dpth[irow, :], dpth[irow, :]]) - m, n = table.shape - for iline in range(0, n): - f.write(" %6.3f %6.0f %8.2f %8.3f\n" % - tuple(table[:, iline])) - - # Test main module fp. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: fp') - f.write('\n%s' % asterisks) - - # Test 1 - UNESCO data p.30. - S = np.array([[5, 10, 15, 20, 25, 30, 35, 40], - [5, 10, 15, 20, 25, 30, 35, 40]]) - - P = np.array([[0, 0, 0, 0, 0, 0, 0, 0], - [500, 500, 500, 500, 500, 500, 500, 500]]) - - UN_fp = np.array([[-0.274, -0.542, -0.812, -1.083, -1.358, -1.638, -1.922, - -2.212], [-0.650, -0.919, -1.188, -1.460, -1.735, - -2.014, -2.299, -2.589]]) - - FP = sw.fp(S, P) - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from UNESCO 1983 ') - f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p30)') - f.write('\n%s' % asterisks) - f.write('\n') - - f.write('\n') - for irow in range(0, 2): - f.write('\n Sal Press fp fp') - f.write('\n (psu) (db) (C) (C)\n') - table = np.vstack([S[irow, :], P[irow, :], UN_fp[irow, :], - FP[irow, :]]) - m, n = table.shape - for iline in range(0, n): - f.write(" %4.0f %5.0f %8.3f %11.4f\n" % - tuple(table[:, iline])) - - # Test main module cp. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: cp') - f.write('\n%s' % asterisks) - - # Test 1. - # Data from Pond and Pickard Intro. Dynamical Oceanography 2nd ed. 1986 - T = np.array([[0, 0, 0, 0, 0, 0], - [10, 10, 10, 10, 10, 10], - [20, 20, 20, 20, 20, 20], - [30, 30, 30, 30, 30, 30], - [40, 40, 40, 40, 40, 40]]) / 1.00024 - - S = np.array([[25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35]]) - - P = np.array([[0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000]]) - - UN_cp = np.array([[4048.4, 3896.3, 3807.7, 3986.5, 3849.3, 3769.1], - [4041.8, 3919.6, 3842.3, 3986.3, 3874.7, 3804.4], - [4044.8, 3938.6, 3866.7, 3993.9, 3895.0, 3828.3], - [4049.1, 3952.0, 3883.0, 4000.7, 3909.2, 3844.3], - [4051.2, 3966.1, 3905.9, 4003.5, 3923.9, 3868.3]]) - - CP = sw.cp(S, T, P) - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from UNESCO 1983 ') - f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p37)') - f.write('\n%s' % asterisks) - f.write('\n') - - m, n = S.shape - f.write('\n') - for icol in range(0, n): - f.write('\n Sal Temp Press Cp cp') - f.write('\n (psu) (C) (db) (J/kg.C) (J/kg.C)\n') - result = np.vstack([S[:, icol], T[:, icol], P[:, icol], - UN_cp[:, icol], CP[:, icol]]) - for iline in range(0, m): - f.write(" %4.0f %4.0f %5.0f %8.1f %11.2f\n" % - tuple(result[:, iline])) - - # Test main module svel. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: svel') - f.write('\n%s' % asterisks) - - # Test 1. - # Data from Pond and Pickard Intro. Dynamical Oceanography 2nd ed. 1986 - T = np.array([[0, 0, 0, 0, 0, 0], - [10, 10, 10, 10, 10, 10], - [20, 20, 20, 20, 20, 20], - [30, 30, 30, 30, 30, 30], - [40, 40, 40, 40, 40, 40]]) / 1.00024 - - S = np.array([[25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35], - [25, 25, 25, 35, 35, 35]]) - - P = np.array([[0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000], - [0, 5000, 10000, 0, 5000, 10000]]) - - UN_svel = np.array([[1435.8, 1520.4, 1610.4, 1449.1, 1534.0, 1623.2], - [1477.7, 1561.3, 1647.4, 1489.8, 1573.4, 1659.0], - [1510.3, 1593.6, 1676.8, 1521.5, 1604.5, 1687.2], - [1535.2, 1619.0, 1700.6, 1545.6, 1629.0, 1710.1], - [1553.4, 1638.0, 1719.2, 1563.2, 1647.3, 1727.8]]) - - SVEL = sw.svel(S, T, P) - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from UNESCO 1983 ') - f.write('\n (Unesco Tech. Paper in Marine Sci. No. 44, p50)') - f.write('\n%s' % asterisks) - f.write('\n') - - m, n = SVEL.shape - f.write('\n') - for icol in range(0, n): - f.write('\n Sal Temp Press SVEL svel') - f.write('\n (psu) (C) (db) (m/s) (m/s)\n') - - result = np.vstack([S[:, icol], T[:, icol], P[:, icol], - UN_svel[:, icol], SVEL[:, icol]]) - for iline in range(0, m): - f.write(" %4.0f %4.0f %5.0f %8.1f %11.3f\n" % - tuple(result[:, iline])) - - # Test submodules alpha beta aonb. - f.write('\n%s' % asterisks) - f.write('\n** and SUB-MODULE: alpha beta aonb') - f.write('\n%s' % asterisks) - - # Data from McDougall 1987. - s = 40 - PT = 10 - p = 4000 - beta_lit = 0.72088e-03 - aonb_lit = 0.34763 - alpha_lit = aonb_lit * beta_lit - - BETA = sw.beta(s, PT, p, pt=True) - ALPHA = sw.alpha(s, PT, p, pt=True) - AONB = sw.aonb(s, PT, p, pt=True) - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from MCDOUGALL 1987 ') - f.write('\n%s' % asterisks) - f.write('\n') - f.write('\n') - - f.write('\n Sal Temp Press BETA beta') - f.write('\n (psu) (C) (db) (psu^-1) (psu^-1)\n') - table = np.hstack([s, PT, p, beta_lit, BETA]) - f.write(" %4.0f %4.0f %5.0f %11.4e %11.5e\n" % - tuple(table)) - - f.write('\n Sal Temp Press AONB aonb') - f.write('\n (psu) (C) (db) (psu C^-1) (psu C^-1)\n') - table = np.hstack([s, PT, p, aonb_lit, AONB]) - f.write(" %4.0f %4.0f %5.0f %8.5f %11.6f\n" % - tuple(table)) - - f.write('\n Sal Temp Press ALPHA alpha') - f.write('\n (psu) (C) (db) (psu^-1) (psu^-1)\n') - table = np.hstack([s, PT, p, alpha_lit, ALPHA]) - f.write(" %4.0f %4.0f %5.0f %11.4e %11.4e\n" % - tuple(table)) - - # Test main moduleS satO2 satN2 satAr. - f.write('\n%s' % asterisks) - f.write('\n** TESTING MODULE: satO2 satN2 satAr') - f.write('\n%s' % asterisks) - f.write('\n') - - # Data from Weiss 1970. - T = np.array([[-1, -1], - [10, 10], - [20, 20], - [40, 40]]) / 1.00024 - - S = np.array([[20, 40], - [20, 40], - [20, 40], - [20, 40]]) - - lit_O2 = np.array([[9.162, 7.984], - [6.950, 6.121], - [5.644, 5.015], - [4.050, 3.656]]) - - lit_N2 = np.array([[16.28, 14.01], - [12.64, 11.01], - [10.47, 9.21], - [7.78, 6.95]]) - - lit_Ar = np.array([[0.4456, 0.3877], - [0.3397, 0.2989], - [0.2766, 0.2457], - [0.1986, 0.1794]]) - - O2 = sw.satO2(S, T) - N2 = sw.satN2(S, T) - Ar = sw.satAr(S, T) - - # Display results. - f.write('\n') - f.write('\n%s' % asterisks) - f.write('\nComparison of accepted values from Weiss, R.F. 1979 ') - f.write('\n"The solubility of nitrogen, oxygen and argon in water') - f.write('\n and seawater." Deep-Sea Research., 1970, Vol 17, pp721-735.') - f.write('\n%s' % asterisks) - f.write('\n') - - m, n = S.shape - f.write('\n') - for icol in range(0, n): - f.write('\n Sal Temp O2 satO2') - f.write('\n (psu) (C) (ml/l) (ml/l)\n') - result = np.vstack([S[:, icol], T[:, icol], - lit_O2[:, icol], O2[:, icol]]) - for iline in range(0, m): - f.write(" %4.0f %4.0f %8.2f %9.3f\n" % - tuple(result[:, iline])) - - for icol in range(0, n): - f.write('\n Sal Temp N2 satN2') - f.write('\n (psu) (C) (ml/l) (ml/l)\n') - result = np.vstack([S[:, icol], T[:, icol], - lit_N2[:, icol], N2[:, icol]]) - for iline in range(0, m): - f.write(" %4.0f %4.0f %8.2f %9.3f\n" % - tuple(result[:, iline])) - - for icol in range(0, n): - f.write('\n Sal Temp Ar satAr') - f.write('\n (psu) (C) (ml/l) (ml/l)\n') - result = np.vstack([S[:, icol], T[:, icol], - lit_Ar[:, icol], Ar[:, icol]]) - for iline in range(0, m): - f.write(" %4.0f %4.0f %8.4f %9.4f\n" % - tuple(result[:, iline])) - - -if __name__ == '__main__': - test() diff --git a/seawater/test/test_input_shapes.py b/seawater/test/test_input_shapes.py deleted file mode 100644 index fe591d5..0000000 --- a/seawater/test/test_input_shapes.py +++ /dev/null @@ -1,45 +0,0 @@ -from __future__ import division, absolute_import - -import os -import unittest - -import numpy as np -import seawater as sw - -rootpath = os.path.dirname(__file__) -fname = os.path.join(rootpath, 'data', 'shapes.npz') - - -class InputShapes(unittest.TestCase): - def setUp(self): - with np.load(fname) as shapes: - self.cp = shapes['cp'] - self.lon = shapes['lon'] - self.lat = shapes['lat'] - self.dens = shapes['dens'] - self.depth = shapes['depth'] - self.s_mean = shapes['s_mean'] - self.t_mean = shapes['t_mean'] - self.pt_mean = shapes['pt_mean'] - self.steric_height = shapes['steric_height'] - - def tearDown(self): - unittest.TestCase.tearDown(self) - - def test_1D(self): - steric_height_new = sw.gpan(self.s_mean[:, 0, 0], self.t_mean[:, 0, 0], - self.depth) - np.testing.assert_array_almost_equal(self.steric_height[:, 0, 0], - steric_height_new) - - def test_2D(self): - steric_height_new = sw.gpan(self.s_mean[..., 1], self.t_mean[..., 1], - self.depth[..., None]) - np.testing.assert_array_almost_equal(self.steric_height[..., 1], - steric_height_new) - - def test_3D(self): - steric_height_new = sw.gpan(self.s_mean, self.t_mean, - self.depth[..., None, None]) - np.testing.assert_array_almost_equal(self.steric_height, - steric_height_new) diff --git a/seawater/test/test_result_comparison.py b/seawater/test/test_result_comparison.py deleted file mode 100644 index 073d5e6..0000000 --- a/seawater/test/test_result_comparison.py +++ /dev/null @@ -1,358 +0,0 @@ -from __future__ import division, absolute_import - -import os -import unittest - -import numpy as np -import seawater as sw -from oct2py import Oct2Py -from seawater.constants import c3515 -from seawater.library import T90conv, T68conv, atleast_2d - -rootpath = os.path.dirname(__file__) -octave = Oct2Py(timeout=3) -path = os.path.join(rootpath, 'seawater_v3_3') -_ = octave.addpath(octave.genpath(path)) - - -functions = dict({'adtg': octave.sw_adtg, - 'alpha': octave.sw_alpha, - 'aonb': octave.sw_aonb, - 'beta': octave.sw_beta, - 'bfrq': octave.sw_bfrq, - 'c3515': octave.sw_c3515, - 'cndr': octave.sw_cndr, - 'cp': octave.sw_cp, - 'dens0': octave.sw_dens0, - 'dens': octave.sw_dens, - 'dist': octave.sw_dist, - 'dpth': octave.sw_dpth, - 'f': octave.sw_f, - 'fp': octave.sw_fp, - 'g': octave.sw_g, - 'gpan': octave.sw_gpan, - 'gvel': octave.sw_gvel, - 'pden': octave.sw_pden, - 'pres': octave.sw_pres, - 'ptmp': octave.sw_ptmp, - 'salds': octave.sw_salds, - 'salrp': octave.sw_salrp, - 'salrpP': octave.sw_salrp, - 'salrt': octave.sw_salrt, - 'sals': octave.sw_sals, - 'salt': octave.sw_salt, - 'satAr': octave.sw_satAr, - 'satN2': octave.sw_satN2, - 'satO2': octave.sw_satO2, - 'seck': octave.sw_seck, - 'smow': octave.sw_smow, - 'svan': octave.sw_svan, - 'svel': octave.sw_svel, - 'swvel': octave.sw_swvel, - 'temp': octave.sw_temp, - 'test': octave.sw_test}) - - -def compare_results(name, function, args, values): - args = [values.get(arg) for arg in args] - res = function(*args) # Python call. - # FIXME: Test only the first output when multiple outputs are present. - if isinstance(res, tuple): - res = res[0] - val = functions[name](*args) # Octave call. - val, res = val.squeeze(), res.squeeze() - np.testing.assert_allclose(val, res) - - -class OctaveResultComparison(unittest.TestCase): - def setUp(self): - kw = dict(comments='#', skiprows=6, delimiter=',') - station_61 = 'Endeavor_Cruise-88_Station-61.csv' - station_64 = 'Endeavor_Cruise-88_Station-64.csv' - st61 = np.loadtxt(os.path.join(rootpath, 'data', station_61), **kw) - st64 = np.loadtxt(os.path.join(rootpath, 'data', station_64), **kw) - - latst = 36. + 40.03 / 60., 37. + 39.93 / 60. - lonst = -(70. + 59.59 / 60.), -71. - Sal = np.c_[st61[:, 2], st64[:, 2]] - Temp = np.c_[st61[:, 1], st64[:, 1]] - Pres = np.c_[st61[:, 0], st61[:, 0]] - Gpan = sw.gpan(Sal, Temp, Pres) - - self.values = dict(r=np.array([56.4125, 56.3161, 50.6703, 38.1345, - 35.0565, 32.9865]) / c3515, - s=np.array([34.5487, 34.7275, 34.8605, 34.6810, - 34.5680, 34.5600]), - t=np.array([28.7856, 28.4329, 22.8103, 10.2600, - 6.8863, 4.4036]), - p=np.array([10., 50., 125., 250., 600., 1000.]), - pref=np.array([0.0]), - pt=np.array([28.8099, 28.4392, 22.7862, 10.2262, - 6.8272, 4.3236]), - rtx=np.array([0.99353194]), - delt=np.array([13.7856]), - rt=np.array([1.32968079, 1.32094651, 1.18368907, - 0.89332541, 0.81977076, 0.76703445]), - units='km', - lon=np.array([-30.] * 6), - lat=np.linspace(-22., -21., 6.), - length=np.array([100.] * 6), - latst=latst, lonst=lonst, Sal=Sal, Temp=Temp, - Pres=Pres, Gpan=Gpan - ) - - def tearDown(self): - unittest.TestCase.tearDown(self) - - # `library.py` - def test_cndr(self): - name = 'cndr' - function, args = (sw.cndr, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_salds(self): - name = 'salds' - function, args = (sw.salds, ('rtx', 'delt')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_salrp(self): - name = 'salrp' - function, args = (sw.salrp, ('r', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_salrt(self): - name = 'salrt' - function, args = (sw.salrt, ('t',)) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_seck(self): - name = 'seck' - function, args = (sw.seck, ('s', 't', 'pref')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_sals(self): - name = 'sals' - function, args = (sw.sals, ('rt', 't')) - compare_results(name=name, function=function, args=args, - values=self.values) - - # `extras.py` - def test_dist(self): - name = 'dist' - function, args = (sw.dist, ('lat', 'lon', 'units')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_f(self): - name = 'f' - function, args = (sw.f, ('lat',)) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_satAr(self): - name = 'satAr' - function, args = (sw.satAr, ('s', 't')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_satN2(self): - name = 'satN2' - function, args = (sw.satN2, ('s', 't')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_satO2(self): - name = 'satO2' - function, args = (sw.satO2, ('s', 't')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_swvel(self): - name = 'swvel' - function, args = (sw.swvel, ('length', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - # `eos80.py` - def test_adtg(self): - name = 'adtg' - function, args = (sw.adtg, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_alpha(self): - name = 'alpha' - function, args = (sw.alpha, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_aonb(self): - name = 'aonb' - function, args = (sw.aonb, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_beta(self): - name = 'beta' - function, args = (sw.beta, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_bfrq1d(self): - name = 'bfrq' - function, args = (sw.bfrq, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_dpth(self): - name = 'dpth' - function, args = (sw.dpth, ('p', 'lat')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_g(self): - name = 'g' - function, args = (sw.g, ('lat',)) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_salt(self): - name = 'salt' - function, args = (sw.salt, ('r', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_fp(self): - name = 'fp' - function, args = (sw.fp, ('s', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_svel(self): - name = 'svel' - function, args = (sw.svel, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_pres(self): - name = 'pres' - function, args = (sw.pres, ('p', 'lat')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_dens0(self): - name = 'dens0' - function, args = (sw.dens0, ('s', 't')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_smow(self): - name = 'smow' - function, args = (sw.smow, ('t')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_dens(self): - name = 'dens' - function, args = (sw.dens, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_pden(self): - name = 'pden' - function, args = (sw.pden, ('s', 't', 'p', 'pref')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_cp(self): - name = 'cp' - function, args = (sw.cp, ('s', 't', 'p')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_ptmp(self): - name = 'ptmp' - function, args = (sw.ptmp, ('s', 't', 'p', 'pref')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_temp(self): - name = 'temp' - function, args = (sw.temp, ('s', 'pt', 'p', 'pref')) - compare_results(name=name, function=function, args=args, - values=self.values) - - # `geostrophic.py` - def test_svan(self): - name = 'svan' - function, args = (sw.svan, ('s', 't', 'pref')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_bfrq(self): - name = 'bfrq' - function, args = (sw.bfrq, ('Sal', 'Temp', 'Pres')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_gpan(self): - name = 'gpan' - function, args = (sw.gpan, ('Sal', 'Temp', 'Pres')) - compare_results(name=name, function=function, args=args, - values=self.values) - - def test_gvel(self): - name = 'gvel' - function, args = (sw.gvel, ('Gpan', 'latst', 'lonst')) - compare_results(name=name, function=function, args=args, - values=self.values) - - -class TConv(unittest.TestCase): - def setUp(self): - self.temp = np.arange(-4., 45.) - - def tearDown(self): - unittest.TestCase.tearDown(self) - - def test_roundtrip(self): - T68 = T68conv(self.temp) - T90 = T90conv(T68, t_type='T68') - np.testing.assert_array_almost_equal(T90, self.temp) - - def test_raise(self): - with self.assertRaises(NameError): - T90conv(self.temp, t_type='T10') - - -class Arrays(unittest.TestCase): - def setUp(self): - self.res = np.array([[1], - [2], - [3]]) - - def tearDown(self): - unittest.TestCase.tearDown(self) - - def test_atleast_0d(self): - np.testing.assert_equal(atleast_2d(1), - np.array([[1]])) - - def test_atleast_1d(self): - np.testing.assert_equal(atleast_2d([1, 2, 3]), - self.res) - - def test_atleast_2d(self): - np.testing.assert_equal(atleast_2d([[1], [2], [3]]), - self.res) - - atleast_2d([[1], [2], [3]]) - - -if __name__ == '__main__': - unittest.main() diff --git a/seawater/test/data/Endeavor_Cruise-88_Station-61-64-gvel.csv b/seawater/tests/data/Endeavor_Cruise-88_Station-61-64-gvel.csv similarity index 100% rename from seawater/test/data/Endeavor_Cruise-88_Station-61-64-gvel.csv rename to seawater/tests/data/Endeavor_Cruise-88_Station-61-64-gvel.csv diff --git a/seawater/test/data/Endeavor_Cruise-88_Station-61.csv b/seawater/tests/data/Endeavor_Cruise-88_Station-61.csv similarity index 100% rename from seawater/test/data/Endeavor_Cruise-88_Station-61.csv rename to seawater/tests/data/Endeavor_Cruise-88_Station-61.csv diff --git a/seawater/test/data/Endeavor_Cruise-88_Station-64.csv b/seawater/tests/data/Endeavor_Cruise-88_Station-64.csv similarity index 100% rename from seawater/test/data/Endeavor_Cruise-88_Station-64.csv rename to seawater/tests/data/Endeavor_Cruise-88_Station-64.csv diff --git a/seawater/test/data/shapes.npz b/seawater/tests/data/shapes.npz similarity index 100% rename from seawater/test/data/shapes.npz rename to seawater/tests/data/shapes.npz diff --git a/seawater/test/matlab_test.txt b/seawater/tests/matlab_test.txt similarity index 95% rename from seawater/test/matlab_test.txt rename to seawater/tests/matlab_test.txt index b9aabbd..0e37ece 100644 --- a/seawater/test/matlab_test.txt +++ b/seawater/tests/matlab_test.txt @@ -1,26 +1,26 @@ *********************** - TEST REPORT - - SEA WATER LIBRARY - + TEST REPORT + + SEA WATER LIBRARY + SEAWATER Version 3.3 - + Matlab Version 8.1.0.604 (R2013a) - + 04-Aug-2013 *********************** - + ************************************* ** TESTING MODULE: sw_ptmp ** and SUB-MODULE: sw_adtg.m ************************************* - + ******************************************************** -Comparison of accepted values from UNESCO 1983 +Comparison of accepted values from UNESCO 1983 (Unesco Tech. Paper in Marine Sci. No. 44, p45) with computed results from sw_ptmp on GLNXA64 computer ******************************************************** - + Sal Temp Press PTMP sw_ptmp (psu) (C) (db) (C) (C) 25 0 0 0.0000 0.00000 @@ -28,7 +28,7 @@ with computed results from sw_ptmp on GLNXA64 computer 25 20 0 20.0000 20.00000 25 30 0 30.0000 30.00000 25 40 0 40.0000 40.00000 - + Sal Temp Press PTMP sw_ptmp (psu) (C) (db) (C) (C) 25 0 5000 -0.3061 -0.30614 @@ -36,7 +36,7 @@ with computed results from sw_ptmp on GLNXA64 computer 25 20 5000 19.0438 19.04376 25 30 5000 28.7512 28.75125 25 40 5000 38.4607 38.46068 - + Sal Temp Press PTMP sw_ptmp (psu) (C) (db) (C) (C) 25 0 10000 -0.9667 -0.96669 @@ -44,7 +44,7 @@ with computed results from sw_ptmp on GLNXA64 computer 25 20 10000 17.9426 17.94265 25 30 10000 27.4353 27.43530 25 40 10000 36.9254 36.92545 - + Sal Temp Press PTMP sw_ptmp (psu) (C) (db) (C) (C) 35 0 0 0.0000 0.00000 @@ -52,7 +52,7 @@ with computed results from sw_ptmp on GLNXA64 computer 35 20 0 20.0000 20.00000 35 30 0 30.0000 30.00000 35 40 0 40.0000 40.00000 - + Sal Temp Press PTMP sw_ptmp (psu) (C) (db) (C) (C) 35 0 5000 -0.3856 -0.38556 @@ -60,7 +60,7 @@ with computed results from sw_ptmp on GLNXA64 computer 35 20 5000 18.9985 18.99845 35 30 5000 28.7231 28.72313 35 40 5000 38.4498 38.44980 - + Sal Temp Press PTMP sw_ptmp (psu) (C) (db) (C) (C) 35 0 10000 -1.0974 -1.09741 @@ -68,18 +68,18 @@ with computed results from sw_ptmp on GLNXA64 computer 35 20 10000 17.8654 17.86536 35 30 10000 27.3851 27.38506 35 40 10000 36.9023 36.90232 - + ************************************************************************ ** TESTING MODULE: sw_svan.m ** and SUB-MODULE: sw_dens.m sw_dens0.m sw_smow.m sw_seck.m sw_pden.m sw_ptmp.m ************************************************************************ - + ******************************************************** Comparison of accepted values from UNESCO 1983 (Unesco Tech. Paper in Marine Sci. No. 44, p22) with computed results from sw_svan.m on GLNXA64 computer ******************************************************** - + Sal Temp Press SVAN sw_svan (psu) (C) (db) (1e-8*m3/kg) (1e-8*m3/kg) 0 0 0 2749.54 2749.539 @@ -90,85 +90,85 @@ with computed results from sw_svan.m on GLNXA64 computer 35 0 10000 0.00 0.000 35 30 0 607.14 607.142 35 30 10000 916.34 916.336 - + ************************************************************************ ** TESTING MODULE: sw_salt.m ** and SUB-MODULE: sw_salrt.m sw_salrp.m sw_sals.m ************************************************************************ - + ******************************************************** -Comparison of accepted values from UNESCO 1983 +Comparison of accepted values from UNESCO 1983 (Unesco Tech. Paper in Marine Sci. No. 44, p9) with computed results from sw_salt.m on GLNXA64 computer ******************************************************** - + Temp Press R S sw_salt - (C) (db) (no units) (psu) (psu) + (C) (db) (no units) (psu) (psu) 15 0 1.00 35.000000 34.9999999 20 2000 1.20 37.245628 37.2456276 5 1500 0.65 27.995347 27.9953469 - + ************************************************************************ ** TESTING MODULE: sw_cndr.m ** and SUB-MODULE: sw_salds.m ************************************************************************ - + ******************************************************** -Comparison of accepted values from UNESCO 1983 +Comparison of accepted values from UNESCO 1983 (Unesco Tech. Paper in Marine Sci. No. 44, p14) with computed results from sw_cndr.m on GLNXA64 computer ******************************************************** - + Temp Press S cndr sw_cndr - (C) (db) (psu) (no units) (no units) + (C) (db) (psu) (no units) (no units) 0 0 25.000000 0.498088 0.49800825 10 0 25.000000 0.654990 0.65499015 0 1000 25.000000 0.506244 0.50624434 10 1000 25.000000 0.662975 0.66297496 10 0 40.000000 1.000073 1.00007311 30 0 40.000000 1.529967 1.52996697 - + ************************************************************************ ** TESTING MODULE: sw_dpth.m ************************************************************************ - + ******************************************************** -Comparison of accepted values from Unesco 1983 +Comparison of accepted values from Unesco 1983 (Unesco Tech. Paper in Marine Sci. No. 44, p28) with computed results from sw_dpth.m on GLNXA64 computer ******************************************************** - + Lat Press DPTH sw_dpth (degree) (db) (meter) (meter) 0.000 500 496.65 496.653 30.000 500 496.00 495.998 45.000 500 495.34 495.343 90.000 500 494.03 494.034 - + Lat Press DPTH sw_dpth (degree) (db) (meter) (meter) 0.000 5000 4915.04 4915.041 30.000 5000 4908.56 4908.560 45.000 5000 4902.08 4902.081 90.000 5000 4889.13 4889.131 - + Lat Press DPTH sw_dpth (degree) (db) (meter) (meter) 0.000 10000 9725.47 9725.471 30.000 10000 9712.65 9712.653 45.000 10000 9699.84 9699.841 90.000 10000 9674.23 9674.231 - + ************************************************************************ ** TESTING MODULE: sw_fp.m ************************************************************************ - + ******************************************************** -Comparison of accepted values from UNESCO 1983 +Comparison of accepted values from UNESCO 1983 (Unesco Tech. Paper in Marine Sci. No. 44, p30) with computed results from sw_fp.m on GLNXA64 computer ******************************************************** - + Sal Press fp sw_fp (psu) (db) (C) (C) 5 0 -0.274 -0.2737 @@ -179,7 +179,7 @@ with computed results from sw_fp.m on GLNXA64 computer 30 0 -1.638 -1.6375 35 0 -1.922 -1.9218 40 0 -2.212 -2.2115 - + Sal Press fp sw_fp (psu) (db) (C) (C) 5 500 -0.650 -0.6501 @@ -190,17 +190,17 @@ with computed results from sw_fp.m on GLNXA64 computer 30 500 -2.014 -2.0139 35 500 -2.299 -2.2982 40 500 -2.589 -2.5879 - + ************************************************************************ ** TESTING MODULE: sw_cp.m ************************************************************************ - + ******************************************************** -Comparison of accepted values from UNESCO 1983 +Comparison of accepted values from UNESCO 1983 (Unesco Tech. Paper in Marine Sci. No. 44, p37) with computed results from sw_cp.m on GLNXA64 computer ******************************************************** - + Sal Temp Press Cp sw_cp (psu) (C) (db) (J/kg.C) (J/kg.C) 25 0 0 4048.4 4048.44 @@ -208,7 +208,7 @@ with computed results from sw_cp.m on GLNXA64 computer 25 20 0 4044.8 4044.84 25 30 0 4049.1 4049.10 25 40 0 4051.2 4051.22 - + Sal Temp Press Cp sw_cp (psu) (C) (db) (J/kg.C) (J/kg.C) 25 0 5000 3896.3 3896.26 @@ -216,7 +216,7 @@ with computed results from sw_cp.m on GLNXA64 computer 25 20 5000 3938.6 3938.60 25 30 5000 3952.0 3952.04 25 40 5000 3966.1 3966.11 - + Sal Temp Press Cp sw_cp (psu) (C) (db) (J/kg.C) (J/kg.C) 25 0 10000 3807.7 3807.73 @@ -224,7 +224,7 @@ with computed results from sw_cp.m on GLNXA64 computer 25 20 10000 3866.7 3866.74 25 30 10000 3883.0 3882.99 25 40 10000 3905.9 3905.92 - + Sal Temp Press Cp sw_cp (psu) (C) (db) (J/kg.C) (J/kg.C) 35 0 0 3986.5 3986.53 @@ -232,7 +232,7 @@ with computed results from sw_cp.m on GLNXA64 computer 35 20 0 3993.9 3993.85 35 30 0 4000.7 4000.68 35 40 0 4003.5 4003.46 - + Sal Temp Press Cp sw_cp (psu) (C) (db) (J/kg.C) (J/kg.C) 35 0 5000 3849.3 3849.26 @@ -240,7 +240,7 @@ with computed results from sw_cp.m on GLNXA64 computer 35 20 5000 3895.0 3894.99 35 30 5000 3909.2 3909.24 35 40 5000 3923.9 3923.89 - + Sal Temp Press Cp sw_cp (psu) (C) (db) (J/kg.C) (J/kg.C) 35 0 10000 3769.1 3769.12 @@ -248,17 +248,17 @@ with computed results from sw_cp.m on GLNXA64 computer 35 20 10000 3828.3 3828.29 35 30 10000 3844.3 3844.32 35 40 10000 3868.3 3868.29 - + ************************************************************************ ** TESTING MODULE: sw_svel.m ************************************************************************ - + ******************************************************** -Comparison of accepted values from UNESCO 1983 +Comparison of accepted values from UNESCO 1983 (Unesco Tech. Paper in Marine Sci. No. 44, p50) with computed results from sw_svel.m on GLNXA64 computer ******************************************************** - + Sal Temp Press SVEL sw_svel (psu) (C) (db) (m/s) (m/s) 25 0 0 1435.8 1435.790 @@ -266,7 +266,7 @@ with computed results from sw_svel.m on GLNXA64 computer 25 20 0 1510.3 1510.314 25 30 0 1535.2 1535.214 25 40 0 1553.4 1553.445 - + Sal Temp Press SVEL sw_svel (psu) (C) (db) (m/s) (m/s) 25 0 5000 1520.4 1520.359 @@ -274,7 +274,7 @@ with computed results from sw_svel.m on GLNXA64 computer 25 20 5000 1593.6 1593.597 25 30 5000 1619.0 1618.956 25 40 5000 1638.0 1638.025 - + Sal Temp Press SVEL sw_svel (psu) (C) (db) (m/s) (m/s) 25 0 10000 1610.4 1610.407 @@ -282,7 +282,7 @@ with computed results from sw_svel.m on GLNXA64 computer 25 20 10000 1676.8 1676.810 25 30 10000 1700.6 1700.605 25 40 10000 1719.2 1719.151 - + Sal Temp Press SVEL sw_svel (psu) (C) (db) (m/s) (m/s) 35 0 0 1449.1 1449.139 @@ -290,7 +290,7 @@ with computed results from sw_svel.m on GLNXA64 computer 35 20 0 1521.5 1521.462 35 30 0 1545.6 1545.595 35 40 0 1563.2 1563.209 - + Sal Temp Press SVEL sw_svel (psu) (C) (db) (m/s) (m/s) 35 0 5000 1534.0 1533.969 @@ -298,7 +298,7 @@ with computed results from sw_svel.m on GLNXA64 computer 35 20 5000 1604.5 1604.476 35 30 5000 1629.0 1628.973 35 40 5000 1647.3 1647.299 - + Sal Temp Press SVEL sw_svel (psu) (C) (db) (m/s) (m/s) 35 0 10000 1623.2 1623.150 @@ -306,75 +306,75 @@ with computed results from sw_svel.m on GLNXA64 computer 35 20 10000 1687.2 1687.183 35 30 10000 1710.1 1710.063 35 40 10000 1727.8 1727.832 - + ********************************************************************** ** TESTING MODULE: sw_alpha.m sw_beta.m sw_aonb.m ********************************************************************** - + ******************************************************** -Comparison of accepted values from MCDOUGALL 1987 +Comparison of accepted values from MCDOUGALL 1987 with computed results on GLNXA64 computer ******************************************************** - + Sal Temp Press BETA sw_beta (psu) (C) (db) (psu^-1) (psu^-1) 40 10 4000 7.2088e-04 7.20877e-04 - + Sal Temp Press AONB sw_aonb (psu) (C) (db) (psu C^-1) (psu C^-1) 40 10 4000 0.34763 0.347651 - + Sal Temp Press ALPHA sw_alpha (psu) (C) (db) (psu^-1) (psu^-1) 40 10 4000 2.5060e-04 2.5061e-04 - + ************************************* ** TESTING MODULE: sw_satO2 sw_satN2 sw_satAr ** and SUB-MODULE: sw_alpha.m sw_beta.m sw_aonb.m ************************************* - + ******************************************************** -Comparison of accepted values from Weiss, R.F. 1979 +Comparison of accepted values from Weiss, R.F. 1979 "The solubility of nitrogen, oxygen and argon in water and seawater." Deap-Sea Research., 1970, Vol 17, pp721-735. with computed results from sw_satO2 sw_satN2 sw_satAr on GLNXA64 computer ******************************************************** - + Sal Temp O2 sw_satO2 (psu) (C) (ml/l) (ml/l) 20 -1 9.16 9.162 20 10 6.95 6.950 20 20 5.64 5.644 20 40 4.05 4.050 - + Sal Temp O2 sw_satO2 (psu) (C) (ml/l) (ml/l) 40 -1 7.98 7.984 40 10 6.12 6.121 40 20 5.01 5.015 40 40 3.66 3.656 - + Sal Temp N2 sw_satN2 (psu) (C) (ml/l) (ml/l) 20 -1 16.28 16.280 20 10 12.64 12.640 20 20 10.47 10.469 20 40 7.78 7.782 - + Sal Temp N2 sw_satN2 (psu) (C) (ml/l) (ml/l) 40 -1 14.01 14.008 40 10 11.01 11.013 40 20 9.21 9.211 40 40 6.95 6.954 - + Sal Temp Ar sw_satAr (psu) (C) (ml/l) (ml/l) 20 -1 0.4456 0.4456 20 10 0.3397 0.3397 20 20 0.2766 0.2766 20 40 0.1986 0.1986 - + Sal Temp Ar sw_satAr (psu) (C) (ml/l) (ml/l) 40 -1 0.3877 0.3877 diff --git a/seawater/test/seawater_v3_3/Contents.m b/seawater/tests/seawater_v3_3/Contents.m similarity index 100% rename from seawater/test/seawater_v3_3/Contents.m rename to seawater/tests/seawater_v3_3/Contents.m diff --git a/seawater/test/seawater_v3_3/sw_adtg.m b/seawater/tests/seawater_v3_3/sw_adtg.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_adtg.m rename to seawater/tests/seawater_v3_3/sw_adtg.m diff --git a/seawater/test/seawater_v3_3/sw_alpha.m b/seawater/tests/seawater_v3_3/sw_alpha.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_alpha.m rename to seawater/tests/seawater_v3_3/sw_alpha.m diff --git a/seawater/test/seawater_v3_3/sw_aonb.m b/seawater/tests/seawater_v3_3/sw_aonb.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_aonb.m rename to seawater/tests/seawater_v3_3/sw_aonb.m diff --git a/seawater/test/seawater_v3_3/sw_beta.m b/seawater/tests/seawater_v3_3/sw_beta.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_beta.m rename to seawater/tests/seawater_v3_3/sw_beta.m diff --git a/seawater/test/seawater_v3_3/sw_bfrq.m b/seawater/tests/seawater_v3_3/sw_bfrq.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_bfrq.m rename to seawater/tests/seawater_v3_3/sw_bfrq.m diff --git a/seawater/test/seawater_v3_3/sw_c3515.m b/seawater/tests/seawater_v3_3/sw_c3515.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_c3515.m rename to seawater/tests/seawater_v3_3/sw_c3515.m diff --git a/seawater/test/seawater_v3_3/sw_cndr.m b/seawater/tests/seawater_v3_3/sw_cndr.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_cndr.m rename to seawater/tests/seawater_v3_3/sw_cndr.m diff --git a/seawater/test/seawater_v3_3/sw_copy.m b/seawater/tests/seawater_v3_3/sw_copy.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_copy.m rename to seawater/tests/seawater_v3_3/sw_copy.m diff --git a/seawater/test/seawater_v3_3/sw_cp.m b/seawater/tests/seawater_v3_3/sw_cp.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_cp.m rename to seawater/tests/seawater_v3_3/sw_cp.m diff --git a/seawater/test/seawater_v3_3/sw_dens.m b/seawater/tests/seawater_v3_3/sw_dens.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_dens.m rename to seawater/tests/seawater_v3_3/sw_dens.m diff --git a/seawater/test/seawater_v3_3/sw_dens0.m b/seawater/tests/seawater_v3_3/sw_dens0.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_dens0.m rename to seawater/tests/seawater_v3_3/sw_dens0.m diff --git a/seawater/test/seawater_v3_3/sw_dist.m b/seawater/tests/seawater_v3_3/sw_dist.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_dist.m rename to seawater/tests/seawater_v3_3/sw_dist.m diff --git a/seawater/test/seawater_v3_3/sw_dpth.m b/seawater/tests/seawater_v3_3/sw_dpth.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_dpth.m rename to seawater/tests/seawater_v3_3/sw_dpth.m diff --git a/seawater/test/seawater_v3_3/sw_f.m b/seawater/tests/seawater_v3_3/sw_f.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_f.m rename to seawater/tests/seawater_v3_3/sw_f.m diff --git a/seawater/test/seawater_v3_3/sw_fp.m b/seawater/tests/seawater_v3_3/sw_fp.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_fp.m rename to seawater/tests/seawater_v3_3/sw_fp.m diff --git a/seawater/test/seawater_v3_3/sw_g.m b/seawater/tests/seawater_v3_3/sw_g.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_g.m rename to seawater/tests/seawater_v3_3/sw_g.m diff --git a/seawater/test/seawater_v3_3/sw_gpan.m b/seawater/tests/seawater_v3_3/sw_gpan.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_gpan.m rename to seawater/tests/seawater_v3_3/sw_gpan.m diff --git a/seawater/test/seawater_v3_3/sw_gvel.m b/seawater/tests/seawater_v3_3/sw_gvel.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_gvel.m rename to seawater/tests/seawater_v3_3/sw_gvel.m diff --git a/seawater/test/seawater_v3_3/sw_info.m b/seawater/tests/seawater_v3_3/sw_info.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_info.m rename to seawater/tests/seawater_v3_3/sw_info.m diff --git a/seawater/test/seawater_v3_3/sw_new.m b/seawater/tests/seawater_v3_3/sw_new.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_new.m rename to seawater/tests/seawater_v3_3/sw_new.m diff --git a/seawater/test/seawater_v3_3/sw_pden.m b/seawater/tests/seawater_v3_3/sw_pden.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_pden.m rename to seawater/tests/seawater_v3_3/sw_pden.m diff --git a/seawater/test/seawater_v3_3/sw_pres.m b/seawater/tests/seawater_v3_3/sw_pres.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_pres.m rename to seawater/tests/seawater_v3_3/sw_pres.m diff --git a/seawater/test/seawater_v3_3/sw_ptmp.m b/seawater/tests/seawater_v3_3/sw_ptmp.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_ptmp.m rename to seawater/tests/seawater_v3_3/sw_ptmp.m diff --git a/seawater/test/seawater_v3_3/sw_salds.m b/seawater/tests/seawater_v3_3/sw_salds.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_salds.m rename to seawater/tests/seawater_v3_3/sw_salds.m diff --git a/seawater/test/seawater_v3_3/sw_salrp.m b/seawater/tests/seawater_v3_3/sw_salrp.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_salrp.m rename to seawater/tests/seawater_v3_3/sw_salrp.m diff --git a/seawater/test/seawater_v3_3/sw_salrt.m b/seawater/tests/seawater_v3_3/sw_salrt.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_salrt.m rename to seawater/tests/seawater_v3_3/sw_salrt.m diff --git a/seawater/test/seawater_v3_3/sw_sals.m b/seawater/tests/seawater_v3_3/sw_sals.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_sals.m rename to seawater/tests/seawater_v3_3/sw_sals.m diff --git a/seawater/test/seawater_v3_3/sw_salt.m b/seawater/tests/seawater_v3_3/sw_salt.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_salt.m rename to seawater/tests/seawater_v3_3/sw_salt.m diff --git a/seawater/test/seawater_v3_3/sw_satAr.m b/seawater/tests/seawater_v3_3/sw_satAr.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_satAr.m rename to seawater/tests/seawater_v3_3/sw_satAr.m diff --git a/seawater/test/seawater_v3_3/sw_satN2.m b/seawater/tests/seawater_v3_3/sw_satN2.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_satN2.m rename to seawater/tests/seawater_v3_3/sw_satN2.m diff --git a/seawater/test/seawater_v3_3/sw_satO2.m b/seawater/tests/seawater_v3_3/sw_satO2.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_satO2.m rename to seawater/tests/seawater_v3_3/sw_satO2.m diff --git a/seawater/test/seawater_v3_3/sw_seck.m b/seawater/tests/seawater_v3_3/sw_seck.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_seck.m rename to seawater/tests/seawater_v3_3/sw_seck.m diff --git a/seawater/test/seawater_v3_3/sw_smow.m b/seawater/tests/seawater_v3_3/sw_smow.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_smow.m rename to seawater/tests/seawater_v3_3/sw_smow.m diff --git a/seawater/test/seawater_v3_3/sw_svan.m b/seawater/tests/seawater_v3_3/sw_svan.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_svan.m rename to seawater/tests/seawater_v3_3/sw_svan.m diff --git a/seawater/test/seawater_v3_3/sw_svel.m b/seawater/tests/seawater_v3_3/sw_svel.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_svel.m rename to seawater/tests/seawater_v3_3/sw_svel.m diff --git a/seawater/test/seawater_v3_3/sw_swvel.m b/seawater/tests/seawater_v3_3/sw_swvel.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_swvel.m rename to seawater/tests/seawater_v3_3/sw_swvel.m diff --git a/seawater/test/seawater_v3_3/sw_temp.m b/seawater/tests/seawater_v3_3/sw_temp.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_temp.m rename to seawater/tests/seawater_v3_3/sw_temp.m diff --git a/seawater/test/seawater_v3_3/sw_test.m b/seawater/tests/seawater_v3_3/sw_test.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_test.m rename to seawater/tests/seawater_v3_3/sw_test.m diff --git a/seawater/test/seawater_v3_3/sw_ver.m b/seawater/tests/seawater_v3_3/sw_ver.m similarity index 100% rename from seawater/test/seawater_v3_3/sw_ver.m rename to seawater/tests/seawater_v3_3/sw_ver.m diff --git a/seawater/tests/sw_test.py b/seawater/tests/sw_test.py new file mode 100644 index 0000000..d5587b9 --- /dev/null +++ b/seawater/tests/sw_test.py @@ -0,0 +1,667 @@ +import sys +from platform import uname +from time import asctime, localtime + +import numpy as np + +import seawater as sw + + +def test(fileout="python-test.txt"): + """Copy of the Matlab test.""" + f = open(fileout, "w") + asterisks = "*" * 76 + + f.write(asterisks) + f.write("\n TEST REPORT ") + f.write("\n") + f.write("\n SEA WATER LIBRARY %s" % sw.__version__) + f.write("\n") + # Show some info about this Python. + f.write("\npython version: %s" % sys.version) + f.write("\n on %s computer %s" % (uname()[0], uname()[-1])) + f.write("\n") + f.write("\n") + f.write(asctime(localtime())) + f.write("\n") + f.write("\n") + + # Test main module ptmp. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: ptmp") + f.write("\n** and SUB-MODULE: adtg") + f.write("\n%s" % asterisks) + f.write("\n") + f.write("\n") + + # Test 1 - data from Unesco 1983 p45. + T = np.array( + [ + [0, 0, 0, 0, 0, 0], + [10, 10, 10, 10, 10, 10], + [20, 20, 20, 20, 20, 20], + [30, 30, 30, 30, 30, 30], + [40, 40, 40, 40, 40, 40], + ], + ) + + T = T / 1.00024 + + S = np.array( + [ + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + ], + ) + + P = np.array( + [ + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + ], + ) + + Pr = np.array([0, 0, 0, 0, 0, 0]) + + UN_ptmp = np.array( + [ + [0, -0.3061, -0.9667, 0, -0.3856, -1.0974], + [10, 9.3531, 8.4684, 10, 9.2906, 8.3643], + [20, 19.0438, 17.9426, 20, 18.9985, 17.8654], + [30, 28.7512, 27.4353, 30, 28.7231, 27.3851], + [40, 38.4607, 36.9254, 40, 38.4498, 36.9023], + ], + ) + + PT = sw.ptmp(S, T, P, Pr) * 1.00024 + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from UNESCO 1983 ") + f.write("\n (Unesco Tech. Paper in Marine Sci. No. 44, p45)") + f.write("\n%s" % asterisks) + f.write("\n") + + m, n = S.shape # TODO: so many loops there must be a better way. + for icol in range(n): + f.write("\n Sal Temp Press PTMP ptmp") + f.write("\n (psu) (C) (db) (C) (C)\n") + result = np.vstack( + ( + S[:, icol], + T[:, icol], + P[:, icol], + UN_ptmp[:, icol], + PT[:, icol], + ), + ) + for iline in range(m): + f.write( + " %4.0f %4.0f %5.0f %8.4f %11.5f\n" % tuple(result[:, iline]), + ) + + # Test main module svan. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: svan") + f.write("\n** and SUB-MODULE: dens dens0 smow seck pden ptmp") + f.write("\n%s" % asterisks) + + # Test data FROM: Unesco Tech. Paper in Marine Sci. No. 44, p22. + s = np.array([0, 0, 0, 0, 35, 35, 35, 35]) + p = np.array([0, 10000, 0, 10000, 0, 10000, 0, 10000]) + t = np.array([0, 0, 30, 30, 0, 0, 30, 30]) / 1.00024 + + UN_svan = np.array( + [ + 2749.54, + 2288.61, + 3170.58, + 3147.85, + 0.0, + 0.00, + 607.14, + 916.34, + ], + ) + + SVAN = sw.svan(s, t, p) + + # DISPLAY RESULTS + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\n") + f.write("\nComparison of accepted values from UNESCO 1983") + f.write("\n (Unesco Tech. Paper in Marine Sci. No. 44, p22)") + f.write("\n%s" % asterisks) + f.write("\n") + f.write("\n Sal Temp Press SVAN svan") + f.write("\n (psu) (C) (db) (1e-8*m3/kg) (1e-8*m3/kg)\n") + result = np.vstack([s, t, p, UN_svan, 1e8 * SVAN]) + for iline in range(len(SVAN)): + f.write( + " %4.0f %4.0f %5.0f %11.2f %11.3f\n" % tuple(result[:, iline]), + ) + + # Test main module salt. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: salt") + f.write("\n** and SUB-MODULE: salrt salrp sals") + f.write("\n%s" % asterisks) + f.write("\n") + + # Test 1 - data from Unesco 1983 p9. + R = np.array([1, 1.2, 0.65]) # cndr = R. + T = np.array([15, 20, 5]) / 1.00024 + P = np.array([0, 2000, 1500]) + # Rt = np.array([ 1, 1.0568875, 0.81705885]) + UN_S = np.array([35, 37.245628, 27.995347]) + + S = sw.salt(R, T, P) + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from UNESCO 1983 ") + f.write("\n(Unesco Tech. Paper in Marine Sci. No. 44, p9)") + f.write("\n%s" % asterisks) + f.write("\n") + + f.write("\n Temp Press R S salt") + f.write("\n (C) (db) (no units) (psu) (psu)\n") + table = np.vstack([T, P, R, UN_S, S]) + m, n = table.shape + for iline in range(n): + f.write( + " %4.0f %4.0f %8.2f %11.6f %14.7f\n" % tuple(table[:, iline]), + ) + + # Test main module cndr. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: cndr") + f.write("\n** and SUB-MODULE: salds") + f.write("\n%s" % asterisks) + + # Test 1 - data from Unesco 1983 p9. + T = np.array([0, 10, 0, 10, 10, 30]) / 1.00024 + P = np.array([0, 0, 1000, 1000, 0, 0]) + S = np.array([25, 25, 25, 25, 40, 40]) + UN_R = np.array( + [ + 0.498088, + 0.654990, + 0.506244, + 0.662975, + 1.000073, + 1.529967, + ], + ) + R = sw.cndr(S, T, P) + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from UNESCO 1983 ") + f.write("\n (Unesco Tech. Paper in Marine Sci. No. 44, p14)") + f.write("\n%s" % asterisks) + f.write("\n") + f.write("\n") + + f.write("\n Temp Press S cndr cndr") + f.write("\n (C) (db) (psu) (no units) (no units)\n") + table = np.vstack([T, P, S, UN_R, R]) + m, n = table.shape + for iline in range(n): + f.write( + " %4.0f %4.0f %8.6f %11.6f %14.8f\n" % tuple(table[:, iline]), + ) + + # Test main module depth. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: depth") + f.write("\n%s" % asterisks) + + # Test data - matrix "pressure", vector "lat" Unesco 1983 data p30. + lat = np.array([0, 30, 45, 90]) + P = np.array( + [ + [500, 500, 500, 500], + [5000, 5000, 5000, 5000], + [10000, 10000, 10000, 10000], + ], + ) + + UN_dpth = np.array( + [ + [496.65, 496.00, 495.34, 494.03], + [4915.04, 4908.56, 4902.08, 4889.13], + [9725.47, 9712.65, 9699.84, 9674.23], + ], + ) + + dpth = sw.dpth(P, lat) + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from Unesco 1983 ") + f.write("\n(Unesco Tech. Paper in Marine Sci. No. 44, p28)") + f.write("\n%s" % asterisks) + f.write("\n") + + f.write("\n") + for irow in range(3): + f.write("\n Lat Press DPTH dpth") + f.write("\n (degree) (db) (meter) (meter)\n") + table = np.vstack([lat, P[irow, :], UN_dpth[irow, :], dpth[irow, :]]) + m, n = table.shape + for iline in range(n): + f.write( + " %6.3f %6.0f %8.2f %8.3f\n" % tuple(table[:, iline]), + ) + + # Test main module fp. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: fp") + f.write("\n%s" % asterisks) + + # Test 1 - UNESCO data p.30. + S = np.array( + [ + [5, 10, 15, 20, 25, 30, 35, 40], + [5, 10, 15, 20, 25, 30, 35, 40], + ], + ) + + P = np.array( + [ + [0, 0, 0, 0, 0, 0, 0, 0], + [500, 500, 500, 500, 500, 500, 500, 500], + ], + ) + + UN_fp = np.array( + [ + [ + -0.274, + -0.542, + -0.812, + -1.083, + -1.358, + -1.638, + -1.922, + -2.212, + ], + [ + -0.650, + -0.919, + -1.188, + -1.460, + -1.735, + -2.014, + -2.299, + -2.589, + ], + ], + ) + + FP = sw.fp(S, P) + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from UNESCO 1983 ") + f.write("\n (Unesco Tech. Paper in Marine Sci. No. 44, p30)") + f.write("\n%s" % asterisks) + f.write("\n") + + f.write("\n") + for irow in range(2): + f.write("\n Sal Press fp fp") + f.write("\n (psu) (db) (C) (C)\n") + table = np.vstack( + [ + S[irow, :], + P[irow, :], + UN_fp[irow, :], + FP[irow, :], + ], + ) + m, n = table.shape + for iline in range(n): + f.write( + " %4.0f %5.0f %8.3f %11.4f\n" % tuple(table[:, iline]), + ) + + # Test main module cp. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: cp") + f.write("\n%s" % asterisks) + + # Test 1. + # Data from Pond and Pickard Intro. Dynamical Oceanography 2nd ed. 1986 + T = ( + np.array( + [ + [0, 0, 0, 0, 0, 0], + [10, 10, 10, 10, 10, 10], + [20, 20, 20, 20, 20, 20], + [30, 30, 30, 30, 30, 30], + [40, 40, 40, 40, 40, 40], + ], + ) + / 1.00024 + ) + + S = np.array( + [ + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + ], + ) + + P = np.array( + [ + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + ], + ) + + UN_cp = np.array( + [ + [4048.4, 3896.3, 3807.7, 3986.5, 3849.3, 3769.1], + [4041.8, 3919.6, 3842.3, 3986.3, 3874.7, 3804.4], + [4044.8, 3938.6, 3866.7, 3993.9, 3895.0, 3828.3], + [4049.1, 3952.0, 3883.0, 4000.7, 3909.2, 3844.3], + [4051.2, 3966.1, 3905.9, 4003.5, 3923.9, 3868.3], + ], + ) + + CP = sw.cp(S, T, P) + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from UNESCO 1983 ") + f.write("\n (Unesco Tech. Paper in Marine Sci. No. 44, p37)") + f.write("\n%s" % asterisks) + f.write("\n") + + m, n = S.shape + f.write("\n") + for icol in range(n): + f.write("\n Sal Temp Press Cp cp") + f.write("\n (psu) (C) (db) (J/kg.C) (J/kg.C)\n") + result = np.vstack( + [ + S[:, icol], + T[:, icol], + P[:, icol], + UN_cp[:, icol], + CP[:, icol], + ], + ) + for iline in range(m): + f.write( + " %4.0f %4.0f %5.0f %8.1f %11.2f\n" % tuple(result[:, iline]), + ) + + # Test main module svel. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: svel") + f.write("\n%s" % asterisks) + + # Test 1. + # Data from Pond and Pickard Intro. Dynamical Oceanography 2nd ed. 1986 + T = ( + np.array( + [ + [0, 0, 0, 0, 0, 0], + [10, 10, 10, 10, 10, 10], + [20, 20, 20, 20, 20, 20], + [30, 30, 30, 30, 30, 30], + [40, 40, 40, 40, 40, 40], + ], + ) + / 1.00024 + ) + + S = np.array( + [ + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + [25, 25, 25, 35, 35, 35], + ], + ) + + P = np.array( + [ + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + [0, 5000, 10000, 0, 5000, 10000], + ], + ) + + UN_svel = np.array( + [ + [1435.8, 1520.4, 1610.4, 1449.1, 1534.0, 1623.2], + [1477.7, 1561.3, 1647.4, 1489.8, 1573.4, 1659.0], + [1510.3, 1593.6, 1676.8, 1521.5, 1604.5, 1687.2], + [1535.2, 1619.0, 1700.6, 1545.6, 1629.0, 1710.1], + [1553.4, 1638.0, 1719.2, 1563.2, 1647.3, 1727.8], + ], + ) + + SVEL = sw.svel(S, T, P) + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from UNESCO 1983 ") + f.write("\n (Unesco Tech. Paper in Marine Sci. No. 44, p50)") + f.write("\n%s" % asterisks) + f.write("\n") + + m, n = SVEL.shape + f.write("\n") + for icol in range(n): + f.write("\n Sal Temp Press SVEL svel") + f.write("\n (psu) (C) (db) (m/s) (m/s)\n") + + result = np.vstack( + [ + S[:, icol], + T[:, icol], + P[:, icol], + UN_svel[:, icol], + SVEL[:, icol], + ], + ) + for iline in range(m): + f.write( + " %4.0f %4.0f %5.0f %8.1f %11.3f\n" % tuple(result[:, iline]), + ) + + # Test submodules alpha beta aonb. + f.write("\n%s" % asterisks) + f.write("\n** and SUB-MODULE: alpha beta aonb") + f.write("\n%s" % asterisks) + + # Data from McDougall 1987. + s = 40 + PT = 10 + p = 4000 + beta_lit = 0.72088e-03 + aonb_lit = 0.34763 + alpha_lit = aonb_lit * beta_lit + + BETA = sw.beta(s, PT, p, pt=True) + ALPHA = sw.alpha(s, PT, p, pt=True) + AONB = sw.aonb(s, PT, p, pt=True) + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from MCDOUGALL 1987 ") + f.write("\n%s" % asterisks) + f.write("\n") + f.write("\n") + + f.write("\n Sal Temp Press BETA beta") + f.write("\n (psu) (C) (db) (psu^-1) (psu^-1)\n") + table = np.hstack([s, PT, p, beta_lit, BETA]) + f.write( + " %4.0f %4.0f %5.0f %11.4e %11.5e\n" % tuple(table), + ) + + f.write("\n Sal Temp Press AONB aonb") + f.write("\n (psu) (C) (db) (psu C^-1) (psu C^-1)\n") + table = np.hstack([s, PT, p, aonb_lit, AONB]) + f.write( + " %4.0f %4.0f %5.0f %8.5f %11.6f\n" % tuple(table), + ) + + f.write("\n Sal Temp Press ALPHA alpha") + f.write("\n (psu) (C) (db) (psu^-1) (psu^-1)\n") + table = np.hstack([s, PT, p, alpha_lit, ALPHA]) + f.write( + " %4.0f %4.0f %5.0f %11.4e %11.4e\n" % tuple(table), + ) + + # Test main moduleS satO2 satN2 satAr. + f.write("\n%s" % asterisks) + f.write("\n** TESTING MODULE: satO2 satN2 satAr") + f.write("\n%s" % asterisks) + f.write("\n") + + # Data from Weiss 1970. + T = ( + np.array( + [ + [-1, -1], + [10, 10], + [20, 20], + [40, 40], + ], + ) + / 1.00024 + ) + + S = np.array( + [ + [20, 40], + [20, 40], + [20, 40], + [20, 40], + ], + ) + + lit_O2 = np.array( + [ + [9.162, 7.984], + [6.950, 6.121], + [5.644, 5.015], + [4.050, 3.656], + ], + ) + + lit_N2 = np.array( + [ + [16.28, 14.01], + [12.64, 11.01], + [10.47, 9.21], + [7.78, 6.95], + ], + ) + + lit_Ar = np.array( + [ + [0.4456, 0.3877], + [0.3397, 0.2989], + [0.2766, 0.2457], + [0.1986, 0.1794], + ], + ) + + O2 = sw.satO2(S, T) + N2 = sw.satN2(S, T) + Ar = sw.satAr(S, T) + + # Display results. + f.write("\n") + f.write("\n%s" % asterisks) + f.write("\nComparison of accepted values from Weiss, R.F. 1979 ") + f.write('\n"The solubility of nitrogen, oxygen and argon in water') + f.write('\n and seawater." Deep-Sea Research., 1970, Vol 17, pp721-735.') + f.write("\n%s" % asterisks) + f.write("\n") + + m, n = S.shape + f.write("\n") + for icol in range(n): + f.write("\n Sal Temp O2 satO2") + f.write("\n (psu) (C) (ml/l) (ml/l)\n") + result = np.vstack( + [ + S[:, icol], + T[:, icol], + lit_O2[:, icol], + O2[:, icol], + ], + ) + for iline in range(m): + f.write( + " %4.0f %4.0f %8.2f %9.3f\n" % tuple(result[:, iline]), + ) + + for icol in range(n): + f.write("\n Sal Temp N2 satN2") + f.write("\n (psu) (C) (ml/l) (ml/l)\n") + result = np.vstack( + [ + S[:, icol], + T[:, icol], + lit_N2[:, icol], + N2[:, icol], + ], + ) + for iline in range(m): + f.write( + " %4.0f %4.0f %8.2f %9.3f\n" % tuple(result[:, iline]), + ) + + for icol in range(n): + f.write("\n Sal Temp Ar satAr") + f.write("\n (psu) (C) (ml/l) (ml/l)\n") + result = np.vstack( + [ + S[:, icol], + T[:, icol], + lit_Ar[:, icol], + Ar[:, icol], + ], + ) + for iline in range(m): + f.write( + " %4.0f %4.0f %8.4f %9.4f\n" % tuple(result[:, iline]), + ) + + +if __name__ == "__main__": + test() diff --git a/seawater/tests/test_input_shapes.py b/seawater/tests/test_input_shapes.py new file mode 100644 index 0000000..240d406 --- /dev/null +++ b/seawater/tests/test_input_shapes.py @@ -0,0 +1,59 @@ +import unittest +from pathlib import Path + +import numpy as np + +import seawater as sw + +rootpath = Path(__file__).parent +fname = rootpath.joinpath("data", "shapes.npz") + + +class InputShapes(unittest.TestCase): + def setUp(self): + with np.load(fname) as shapes: + self.cp = shapes["cp"] + self.lon = shapes["lon"] + self.lat = shapes["lat"] + self.dens = shapes["dens"] + self.depth = shapes["depth"] + self.s_mean = shapes["s_mean"] + self.t_mean = shapes["t_mean"] + self.pt_mean = shapes["pt_mean"] + self.steric_height = shapes["steric_height"] + + def tearDown(self): + unittest.TestCase.tearDown(self) + + def test_1D(self): + steric_height_new = sw.gpan( + self.s_mean[:, 0, 0], + self.t_mean[:, 0, 0], + self.depth, + ) + np.testing.assert_array_almost_equal( + self.steric_height[:, 0, 0], + steric_height_new, + ) + + def test_2D(self): + steric_height_new = sw.gpan( + self.s_mean[..., 1], + self.t_mean[..., 1], + self.depth[..., None], + ) + np.testing.assert_array_almost_equal( + self.steric_height[..., 1], + steric_height_new, + ) + + def test_3D(self): + steric_height_new = sw.gpan( + self.s_mean, + self.t_mean, + self.depth[..., None, None], + ) + np.testing.assert_array_almost_equal( + self.steric_height, + steric_height_new, + ) diff --git a/seawater/tests/test_result_comparison.py b/seawater/tests/test_result_comparison.py new file mode 100644 index 0000000..0712870 --- /dev/null +++ b/seawater/tests/test_result_comparison.py @@ -0,0 +1,554 @@ +import unittest +from pathlib import Path + +import numpy as np +import pytest +from oct2py import Oct2Py + +import seawater as sw +from seawater.constants import c3515 +from seawater.library import T68conv, T90conv, atleast_2d + +rootpath = Path(__file__).parent +octave = Oct2Py(timeout=3) +path = rootpath.joinpath("seawater_v3_3") +_ = octave.addpath(octave.genpath(str(path))) + + +functions = { + "adtg": octave.sw_adtg, + "alpha": octave.sw_alpha, + "aonb": octave.sw_aonb, + "beta": octave.sw_beta, + "bfrq": octave.sw_bfrq, + "c3515": octave.sw_c3515, + "cndr": octave.sw_cndr, + "cp": octave.sw_cp, + "dens0": octave.sw_dens0, + "dens": octave.sw_dens, + "dist": octave.sw_dist, + "dpth": octave.sw_dpth, + "f": octave.sw_f, + "fp": octave.sw_fp, + "g": octave.sw_g, + "gpan": octave.sw_gpan, + "gvel": octave.sw_gvel, + "pden": octave.sw_pden, + "pres": octave.sw_pres, + "ptmp": octave.sw_ptmp, + "salds": octave.sw_salds, + "salrp": octave.sw_salrp, + "salrpP": octave.sw_salrp, + "salrt": octave.sw_salrt, + "sals": octave.sw_sals, + "salt": octave.sw_salt, + "satAr": octave.sw_satAr, + "satN2": octave.sw_satN2, + "satO2": octave.sw_satO2, + "seck": octave.sw_seck, + "smow": octave.sw_smow, + "svan": octave.sw_svan, + "svel": octave.sw_svel, + "swvel": octave.sw_swvel, + "temp": octave.sw_temp, + "test": octave.sw_test, +} + + +def compare_results(name, function, args, values): + """Compare Python and Matlab results.""" + args = [values.get(arg) for arg in args] + res = function(*args) # Python call. + # NOTE: Test only the first output when multiple outputs are present. + if isinstance(res, tuple): + res = res[0] + val = functions[name](*args) # Octave call. + if isinstance(val, np.ndarray): + val, res = val.squeeze(), res.squeeze() + np.testing.assert_allclose(val, res) + + +class OctaveResultComparison(unittest.TestCase): + def setUp(self): + kw = {"comments": "#", "skiprows": 6, "delimiter": ","} + station_61 = "Endeavor_Cruise-88_Station-61.csv" + station_64 = "Endeavor_Cruise-88_Station-64.csv" + st61 = np.loadtxt(rootpath.joinpath("data", station_61), **kw) + st64 = np.loadtxt(rootpath.joinpath("data", station_64), **kw) + + latst = 36.0 + 40.03 / 60.0, 37.0 + 39.93 / 60.0 + lonst = -(70.0 + 59.59 / 60.0), -71.0 + Sal = np.c_[st61[:, 2], st64[:, 2]] + Temp = np.c_[st61[:, 1], st64[:, 1]] + Pres = np.c_[st61[:, 0], st61[:, 0]] + Gpan = sw.gpan(Sal, Temp, Pres) + + self.values = { + "r": np.array( + [ + 56.4125, + 56.3161, + 50.6703, + 38.1345, + 35.0565, + 32.9865, + ], + ) + / c3515, + "s": np.array( + [ + 34.5487, + 34.7275, + 34.8605, + 34.6810, + 34.5680, + 34.5600, + ], + ), + "t": np.array( + [ + 28.7856, + 28.4329, + 22.8103, + 10.2600, + 6.8863, + 4.4036, + ], + ), + "p": np.array([10.0, 50.0, 125.0, 250.0, 600.0, 1000.0]), + "pref": np.array([0.0]), + "pt": np.array( + [ + 28.8099, + 28.4392, + 22.7862, + 10.2262, + 6.8272, + 4.3236, + ], + ), + "rtx": np.array([0.99353194]), + "delt": np.array([13.7856]), + "rt": np.array( + [ + 1.32968079, + 1.32094651, + 1.18368907, + 0.89332541, + 0.81977076, + 0.76703445, + ], + ), + "units": "km", + "lon": np.array([-30.0] * 6), + "lat": np.linspace(-22, -21.0, 6), + "length": np.array([100.0] * 6), + "latst": np.array(latst), + "lonst": np.array(lonst), + "Sal": Sal, + "Temp": Temp, + "Pres": Pres, + "Gpan": Gpan, + } + + def tearDown(self): + unittest.TestCase.tearDown(self) + + # `library.py` + def test_cndr(self): + name = "cndr" + function, args = (sw.cndr, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_salds(self): + name = "salds" + function, args = (sw.salds, ("rtx", "delt")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_salrp(self): + name = "salrp" + function, args = (sw.salrp, ("r", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_salrt(self): + name = "salrt" + function, args = (sw.salrt, ("t",)) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_seck(self): + name = "seck" + function, args = (sw.seck, ("s", "t", "pref")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_sals(self): + name = "sals" + function, args = (sw.sals, ("rt", "t")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + # `extras.py` + def test_dist(self): + name = "dist" + function, args = (sw.dist, ("lat", "lon", "units")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_f(self): + name = "f" + function, args = (sw.f, ("lat",)) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_satAr(self): + name = "satAr" + function, args = (sw.satAr, ("s", "t")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_satN2(self): + name = "satN2" + function, args = (sw.satN2, ("s", "t")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_satO2(self): + name = "satO2" + function, args = (sw.satO2, ("s", "t")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_swvel(self): + name = "swvel" + function, args = (sw.swvel, ("length", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + # `eos80.py` + def test_adtg(self): + name = "adtg" + function, args = (sw.adtg, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_alpha(self): + name = "alpha" + function, args = (sw.alpha, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_aonb(self): + name = "aonb" + function, args = (sw.aonb, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_beta(self): + name = "beta" + function, args = (sw.beta, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_bfrq1d(self): + name = "bfrq" + function, args = (sw.bfrq, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_dpth(self): + name = "dpth" + function, args = (sw.dpth, ("p", "lat")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_g(self): + name = "g" + function, args = (sw.g, ("lat",)) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_salt(self): + name = "salt" + function, args = (sw.salt, ("r", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_fp(self): + name = "fp" + function, args = (sw.fp, ("s", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_svel(self): + name = "svel" + function, args = (sw.svel, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_pres(self): + name = "pres" + function, args = (sw.pres, ("p", "lat")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_dens0(self): + name = "dens0" + function, args = (sw.dens0, ("s", "t")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_smow(self): + name = "smow" + function, args = (sw.smow, ("t")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_dens(self): + name = "dens" + function, args = (sw.dens, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_pden(self): + name = "pden" + function, args = (sw.pden, ("s", "t", "p", "pref")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_cp(self): + name = "cp" + function, args = (sw.cp, ("s", "t", "p")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_ptmp(self): + name = "ptmp" + function, args = (sw.ptmp, ("s", "t", "p", "pref")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_temp(self): + name = "temp" + function, args = (sw.temp, ("s", "pt", "p", "pref")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + # `geostrophic.py` + def test_svan(self): + name = "svan" + function, args = (sw.svan, ("s", "t", "pref")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_bfrq(self): + name = "bfrq" + function, args = (sw.bfrq, ("Sal", "Temp", "Pres")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_gpan(self): + name = "gpan" + function, args = (sw.gpan, ("Sal", "Temp", "Pres")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + def test_gvel(self): + name = "gvel" + function, args = (sw.gvel, ("Gpan", "latst", "lonst")) + compare_results( + name=name, + function=function, + args=args, + values=self.values, + ) + + +class TConv(unittest.TestCase): + def setUp(self): + self.temp = np.arange(-4.0, 45.0) + + def tearDown(self): + unittest.TestCase.tearDown(self) + + def test_roundtrip(self): + T68 = T68conv(self.temp) + T90 = T90conv(T68, t_type="T68") + np.testing.assert_array_almost_equal(T90, self.temp) + + def test_raise(self): + with pytest.raises(NameError): + T90conv(self.temp, t_type="T10") + + +class Arrays(unittest.TestCase): + def setUp(self): + self.res = np.array( + [ + [1], + [2], + [3], + ], + ) + + def tearDown(self): + unittest.TestCase.tearDown(self) + + def test_atleast_0d(self): + np.testing.assert_equal( + atleast_2d(1), + np.array([[1]]), + ) + + def test_atleast_1d(self): + np.testing.assert_equal( + atleast_2d([1, 2, 3]), + self.res, + ) + + def test_atleast_2d(self): + np.testing.assert_equal( + atleast_2d([[1], [2], [3]]), + self.res, + ) + + atleast_2d([[1], [2], [3]]) + + +if __name__ == "__main__": + unittest.main() diff --git a/setup.py b/setup.py deleted file mode 100644 index 49e9ec0..0000000 --- a/setup.py +++ /dev/null @@ -1,78 +0,0 @@ -import os -import sys -from setuptools import setup -from setuptools.command.test import test as TestCommand - - -class PyTest(TestCommand): - def finalize_options(self): - TestCommand.finalize_options(self) - self.test_args = ['--verbose', '--doctest-modules', - '--ignore', 'setup.py'] - self.test_suite = True - - def run_tests(self): - import pytest - errno = pytest.main(self.test_args) - sys.exit(errno) - - -def extract_version(module='seawater'): - version = None - fdir = os.path.dirname(__file__) - fnme = os.path.join(fdir, module, '__init__.py') - with open(fnme) as fd: - for line in fd: - if (line.startswith('__version__')): - _, version = line.split('=') - # Remove quotation characters. - version = version.strip()[1:-1] - break - return version - - -rootpath = os.path.abspath(os.path.dirname(__file__)) - - -def read(*parts): - return open(os.path.join(rootpath, *parts), 'r').read() - - -long_description = '{}\n{}'.format(read('README.rst'), read('CHANGES.txt')) -LICENSE = read('LICENSE.txt') - -source = 'http://pypi.python.org/packages/source/s/seawater' - -setup(name='seawater', - version=extract_version(), - license=LICENSE, - long_description=long_description, - classifiers=['Programming Language :: Python', - 'Development Status :: 6 - Mature', - 'Environment :: Console', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: MIT License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Topic :: Scientific/Engineering', - ], - description='Seawater Library for Python', - author='Filipe Fernandes', - maintainer='Filipe Fernandes', - author_email='ocefpaf@gmail.com', - maintainer_email='ocefpaf@gmail.com', - url='https://github.com/pyoceans/python-seawater/', - download_url='https://pypi.python.org/pypi/seawater', - platforms='any', - keywords=['oceanography', 'seawater'], - install_requires=['numpy'], - tests_require=['pytest', 'scipy', 'oct2py'], - cmdclass=dict(test=PyTest), - packages=['seawater'], - include_package_data=True, - )