cf-xarray 0.10.11__tar.gz → 0.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.github/workflows/ci.yaml +2 -2
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.github/workflows/pypi.yaml +5 -5
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.github/workflows/testpypi-release.yaml +2 -2
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.pre-commit-config.yaml +2 -2
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/PKG-INFO +1 -1
- cf_xarray-0.11.0/cf_xarray/_version.py +1 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/accessor.py +5 -10
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/helpers.py +16 -17
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_accessor.py +50 -4
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray.egg-info/PKG-INFO +1 -1
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/index.rst +1 -1
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/uv.lock +265 -235
- cf_xarray-0.10.11/cf_xarray/_version.py +0 -1
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.binder/environment.yml +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.deepsource.toml +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.github/dependabot.yml +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.github/release.yml +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.github/workflows/parse_logs.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.github/workflows/upstream-dev-ci.yaml +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.gitignore +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.readthedocs.yml +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/.tributors +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/CITATION.cff +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/LICENSE +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/README.rst +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/__init__.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/coding.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/criteria.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/datasets.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/formatting.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/geometry.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/groupers.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/options.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/parametric.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/py.typed +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/scripts/make_doc.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/scripts/print_versions.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/sgrid.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/__init__.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/conftest.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_coding.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_geometry.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_groupers.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_helpers.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_options.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_parametric.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_scripts.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/tests/test_units.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/units.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray/utils.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray.egg-info/SOURCES.txt +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray.egg-info/dependency_links.txt +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray.egg-info/requires.txt +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/cf_xarray.egg-info/top_level.txt +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/codecov.yml +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/2D_bounds_averaged.png +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/2D_bounds_error.png +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/2D_bounds_nonunique.png +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/Makefile +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/_static/dataset-diagram-logo.tex +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/_static/full-logo.png +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/_static/logo.png +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/_static/logo.svg +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/_static/rich-repr-example.png +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/_static/style.css +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/api.rst +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/bounds.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/cartopy_rotated_pole.png +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/coding.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/conf.py +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/contributing.rst +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/coord_axes.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/custom-criteria.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/dsg.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/examples/introduction.ipynb +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/faq.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/flags.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/geometry.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/grid_mappings.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/howtouse.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/make.bat +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/parametricz.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/plotting.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/provenance.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/quickstart.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/roadmap.rst +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/selecting.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/sgrid_ugrid.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/units.md +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/doc/whats-new.rst +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/pyproject.toml +0 -0
- {cf_xarray-0.10.11 → cf_xarray-0.11.0}/setup.cfg +0 -0
|
@@ -58,7 +58,7 @@ jobs:
|
|
|
58
58
|
pytest -n auto --cov=./ --cov-report=xml
|
|
59
59
|
|
|
60
60
|
- name: Upload code coverage to Codecov
|
|
61
|
-
uses: codecov/codecov-action@
|
|
61
|
+
uses: codecov/codecov-action@v6.0.0
|
|
62
62
|
with:
|
|
63
63
|
file: ./coverage.xml
|
|
64
64
|
flags: unittests
|
|
@@ -98,7 +98,7 @@ jobs:
|
|
|
98
98
|
python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report cf_xarray/
|
|
99
99
|
|
|
100
100
|
- name: Upload mypy coverage to Codecov
|
|
101
|
-
uses: codecov/codecov-action@
|
|
101
|
+
uses: codecov/codecov-action@v6.0.0
|
|
102
102
|
with:
|
|
103
103
|
file: mypy_report/cobertura.xml
|
|
104
104
|
flags: mypy
|
|
@@ -41,7 +41,7 @@ jobs:
|
|
|
41
41
|
else
|
|
42
42
|
echo "✅ Looks good"
|
|
43
43
|
fi
|
|
44
|
-
- uses: actions/upload-artifact@
|
|
44
|
+
- uses: actions/upload-artifact@v7
|
|
45
45
|
with:
|
|
46
46
|
name: releases
|
|
47
47
|
path: dist
|
|
@@ -54,7 +54,7 @@ jobs:
|
|
|
54
54
|
name: Install Python
|
|
55
55
|
with:
|
|
56
56
|
python-version: "3.11"
|
|
57
|
-
- uses: actions/download-artifact@
|
|
57
|
+
- uses: actions/download-artifact@v8
|
|
58
58
|
with:
|
|
59
59
|
name: releases
|
|
60
60
|
path: dist
|
|
@@ -72,7 +72,7 @@ jobs:
|
|
|
72
72
|
|
|
73
73
|
- name: Publish package to TestPyPI
|
|
74
74
|
if: github.event_name == 'push'
|
|
75
|
-
uses: pypa/gh-action-pypi-publish@v1.
|
|
75
|
+
uses: pypa/gh-action-pypi-publish@v1.14.0
|
|
76
76
|
with:
|
|
77
77
|
password: ${{ secrets.TESTPYPI_TOKEN }}
|
|
78
78
|
repository_url: https://test.pypi.org/legacy/
|
|
@@ -91,11 +91,11 @@ jobs:
|
|
|
91
91
|
id-token: write
|
|
92
92
|
|
|
93
93
|
steps:
|
|
94
|
-
- uses: actions/download-artifact@
|
|
94
|
+
- uses: actions/download-artifact@v8
|
|
95
95
|
with:
|
|
96
96
|
name: releases
|
|
97
97
|
path: dist
|
|
98
98
|
- name: Publish package to PyPI
|
|
99
|
-
uses: pypa/gh-action-pypi-publish@v1.
|
|
99
|
+
uses: pypa/gh-action-pypi-publish@v1.14.0
|
|
100
100
|
with:
|
|
101
101
|
verbose: true
|
|
@@ -53,7 +53,7 @@ jobs:
|
|
|
53
53
|
echo "✅ Looks good"
|
|
54
54
|
fi
|
|
55
55
|
|
|
56
|
-
- uses: actions/upload-artifact@
|
|
56
|
+
- uses: actions/upload-artifact@v7
|
|
57
57
|
with:
|
|
58
58
|
name: releases
|
|
59
59
|
path: dist
|
|
@@ -66,7 +66,7 @@ jobs:
|
|
|
66
66
|
name: Install Python
|
|
67
67
|
with:
|
|
68
68
|
python-version: "3.11"
|
|
69
|
-
- uses: actions/download-artifact@
|
|
69
|
+
- uses: actions/download-artifact@v8
|
|
70
70
|
with:
|
|
71
71
|
name: releases
|
|
72
72
|
path: dist
|
|
@@ -10,7 +10,7 @@ repos:
|
|
|
10
10
|
|
|
11
11
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
12
12
|
# Ruff version.
|
|
13
|
-
rev: 'v0.
|
|
13
|
+
rev: 'v0.15.9'
|
|
14
14
|
hooks:
|
|
15
15
|
- id: ruff
|
|
16
16
|
args: ["--fix", "--show-fixes"]
|
|
@@ -55,7 +55,7 @@ repos:
|
|
|
55
55
|
- id: validate-cff
|
|
56
56
|
|
|
57
57
|
- repo: https://github.com/abravalheri/validate-pyproject
|
|
58
|
-
rev: v0.
|
|
58
|
+
rev: v0.25
|
|
59
59
|
hooks:
|
|
60
60
|
- id: validate-pyproject
|
|
61
61
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.11.0"
|
|
@@ -48,6 +48,11 @@ except ImportError:
|
|
|
48
48
|
Weighted,
|
|
49
49
|
)
|
|
50
50
|
|
|
51
|
+
try:
|
|
52
|
+
from regex import match as regex_match
|
|
53
|
+
except ImportError:
|
|
54
|
+
from re import match as regex_match # type: ignore[no-redef]
|
|
55
|
+
|
|
51
56
|
|
|
52
57
|
from . import parametric, sgrid
|
|
53
58
|
from .criteria import (
|
|
@@ -305,12 +310,6 @@ def _get_custom_criteria(
|
|
|
305
310
|
List[str]
|
|
306
311
|
Variable name(s) in parent xarray object that matches axis, coordinate, or custom ``key``
|
|
307
312
|
"""
|
|
308
|
-
|
|
309
|
-
try:
|
|
310
|
-
from regex import match as regex_match
|
|
311
|
-
except ImportError:
|
|
312
|
-
from re import match as regex_match # type: ignore[no-redef]
|
|
313
|
-
|
|
314
313
|
if criteria is None:
|
|
315
314
|
if not OPTIONS["custom_criteria"]:
|
|
316
315
|
return []
|
|
@@ -1814,10 +1813,6 @@ class CFAccessor:
|
|
|
1814
1813
|
for k, v in value.items()
|
|
1815
1814
|
)
|
|
1816
1815
|
)
|
|
1817
|
-
|
|
1818
|
-
elif value is Ellipsis:
|
|
1819
|
-
pass
|
|
1820
|
-
|
|
1821
1816
|
else:
|
|
1822
1817
|
# things like sum which have dim
|
|
1823
1818
|
newvalue = [
|
|
@@ -17,24 +17,23 @@ def _guess_bounds_1d(da, dim):
|
|
|
17
17
|
"""
|
|
18
18
|
if dim not in da.dims:
|
|
19
19
|
(dim,) = da.cf.axes[dim]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
upper = da
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
|
|
21
|
+
bound_position = 0.5
|
|
22
|
+
|
|
23
|
+
diff = da.diff(dim).pad({dim: (1, 1)}, mode="edge")
|
|
24
|
+
lower = da.copy(
|
|
25
|
+
deep=False,
|
|
26
|
+
data=da.data - bound_position * diff.isel({dim: slice(0, -1)}).data,
|
|
27
|
+
)
|
|
28
|
+
upper = da.copy(
|
|
29
|
+
deep=False,
|
|
30
|
+
data=da.data + bound_position * diff.isel({dim: slice(1, None)}).data,
|
|
31
|
+
)
|
|
32
|
+
return (
|
|
33
|
+
xr.concat([lower, upper], dim="bounds")
|
|
34
|
+
.transpose(..., "bounds")
|
|
35
|
+
.drop_attrs(deep=False)
|
|
33
36
|
)
|
|
34
|
-
result = xr.concat([first, bounds], dim=dim).transpose(..., "bounds")
|
|
35
|
-
if ADDED_INDEX:
|
|
36
|
-
result = result.drop_vars(dim)
|
|
37
|
-
return result.drop_attrs(deep=False)
|
|
38
37
|
|
|
39
38
|
|
|
40
39
|
def _guess_bounds_2d(da, dims):
|
|
@@ -3,6 +3,7 @@ import pickle
|
|
|
3
3
|
import warnings
|
|
4
4
|
from textwrap import dedent
|
|
5
5
|
|
|
6
|
+
import dask.array
|
|
6
7
|
import matplotlib as mpl
|
|
7
8
|
import numpy as np
|
|
8
9
|
import pandas as pd
|
|
@@ -839,6 +840,51 @@ def test_add_bounds(dims):
|
|
|
839
840
|
_check_unchanged(original, ds)
|
|
840
841
|
|
|
841
842
|
|
|
843
|
+
def test_add_bounds_preserves_array_type() -> None:
|
|
844
|
+
# Test that the array type of the bounds variable is the same as the original variable.
|
|
845
|
+
ds = airds
|
|
846
|
+
original = ds.copy(deep=True)
|
|
847
|
+
ds = ds.drop_indexes("lat").rename_dims(lat="x")
|
|
848
|
+
ds["lat"] = ds.lat.copy(data=dask.array.asarray(ds.lat.data))
|
|
849
|
+
added = ds.cf.add_bounds("lat")
|
|
850
|
+
|
|
851
|
+
assert isinstance(added.lat.data, dask.array.Array)
|
|
852
|
+
assert isinstance(added.lat_bounds.data, dask.array.Array)
|
|
853
|
+
|
|
854
|
+
assert isinstance(ds.lat.data, dask.array.Array)
|
|
855
|
+
_check_unchanged(original, ds)
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
def test_add_irregularly_spaced_bounds_do_not_overlap() -> None:
|
|
859
|
+
# Test that added bounds with irregular spacing do not overlap.
|
|
860
|
+
ds = airds
|
|
861
|
+
original = ds.copy(deep=True)
|
|
862
|
+
ds["time"] = ds["time"].copy(data=pd.date_range("2013-01", "2013-04", freq="MS"))
|
|
863
|
+
expected = xr.DataArray(
|
|
864
|
+
data=[
|
|
865
|
+
pd.to_datetime(t)
|
|
866
|
+
for t in [
|
|
867
|
+
["2012-12-16T12", "2013-01-16T12"],
|
|
868
|
+
["2013-01-16T12", "2013-02-15T00"],
|
|
869
|
+
["2013-02-15T00", "2013-03-16T12"],
|
|
870
|
+
["2013-03-16T12", "2013-04-16T12"],
|
|
871
|
+
]
|
|
872
|
+
],
|
|
873
|
+
dims=["time", "bounds"],
|
|
874
|
+
name="time_bounds",
|
|
875
|
+
coords={"time": ds.time.data},
|
|
876
|
+
)
|
|
877
|
+
added = ds.copy(deep=False)
|
|
878
|
+
added = added.cf.add_bounds("time")
|
|
879
|
+
|
|
880
|
+
name = "time_bounds"
|
|
881
|
+
assert name in added.coords
|
|
882
|
+
assert added["time"].attrs["bounds"] == name
|
|
883
|
+
assert_allclose(added[name].reset_coords(drop=True), expected)
|
|
884
|
+
|
|
885
|
+
_check_unchanged(original, ds)
|
|
886
|
+
|
|
887
|
+
|
|
842
888
|
def test_add_bounds_multiple() -> None:
|
|
843
889
|
# Test multiple dimensions
|
|
844
890
|
assert not {"x1_bounds", "x2_bounds"} <= set(multiple.variables)
|
|
@@ -853,7 +899,7 @@ def test_add_bounds_nd_variable() -> None:
|
|
|
853
899
|
|
|
854
900
|
# 2D
|
|
855
901
|
expected = (
|
|
856
|
-
vertices_to_bounds(
|
|
902
|
+
vertices_to_bounds(
|
|
857
903
|
xr.DataArray(
|
|
858
904
|
np.arange(0, 13, 3).reshape(5, 1) + np.arange(-2, 2).reshape(1, 4),
|
|
859
905
|
dims=("x", "y"),
|
|
@@ -861,7 +907,7 @@ def test_add_bounds_nd_variable() -> None:
|
|
|
861
907
|
out_dims=("bounds", "x", "y"),
|
|
862
908
|
)
|
|
863
909
|
.rename("z_bounds")
|
|
864
|
-
.assign_coords(**ds.coords)
|
|
910
|
+
.assign_coords(**ds.coords) # type: ignore[arg-type]
|
|
865
911
|
)
|
|
866
912
|
actual = ds.cf.add_bounds("z").z_bounds.reset_coords(drop=True)
|
|
867
913
|
xr.testing.assert_identical(actual, expected)
|
|
@@ -882,11 +928,11 @@ def test_add_bounds_nd_variable() -> None:
|
|
|
882
928
|
expected = (
|
|
883
929
|
xr.concat([ds.z - 1.5, ds.z + 1.5], dim="bounds")
|
|
884
930
|
.rename("z_bounds")
|
|
885
|
-
.transpose("bounds"
|
|
931
|
+
.transpose(..., "bounds")
|
|
886
932
|
)
|
|
887
933
|
|
|
888
934
|
actual = ds.cf.add_bounds("z", dim="x").z_bounds.reset_coords(drop=True)
|
|
889
|
-
xr.testing.assert_identical(expected
|
|
935
|
+
xr.testing.assert_identical(expected, actual)
|
|
890
936
|
|
|
891
937
|
# Requesting bounds on a non-variable dimension
|
|
892
938
|
with pytest.raises(ValueError, match="are dimensions with no index."):
|
|
@@ -35,7 +35,7 @@ or using ``conda``
|
|
|
35
35
|
examples/introduction
|
|
36
36
|
EarthCube 2021 demo <https://earthcube2021.github.io/ec21_book/notebooks/ec21_cherian_etal/DC_01_cf-xarray.html>
|
|
37
37
|
CESM ocean model demo <https://pop-tools.readthedocs.io/en/latest/examples/cesm-cmip-cf-xarray.html>
|
|
38
|
-
COSIMA ocean-sea ice model demo <https://cosima-recipes.readthedocs.io/en/latest/
|
|
38
|
+
COSIMA ocean-sea ice model demo <https://cosima-recipes.readthedocs.io/en/latest/01-Cooking-Lessons-101/02-Advanced/Model_Agnostic_Analysis.html>
|
|
39
39
|
|
|
40
40
|
.. toctree::
|
|
41
41
|
:maxdepth: 2
|