xbudget 0.5.1__tar.gz → 0.6.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.
- xbudget-0.6.0/.github/ci.yml +50 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/PKG-INFO +1 -1
- {xbudget-0.5.1 → xbudget-0.6.0}/xbudget/collect.py +3 -1
- xbudget-0.6.0/xbudget/tests/test_nb.ipynb +750 -0
- xbudget-0.6.0/xbudget/tests/test_presets.py +16 -0
- xbudget-0.6.0/xbudget/tests/test_utilities.py +420 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/xbudget/version.py +1 -1
- {xbudget-0.5.1 → xbudget-0.6.0}/.github/workflows/publish-to-pypi.yml +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/.gitignore +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/LICENSE +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/README.md +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/ci/environment.yml +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/docs/environment.yml +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/pyproject.toml +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/xbudget/__init__.py +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/xbudget/conventions/MOM6.yaml +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/xbudget/conventions/MOM6_3Donly.yaml +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/xbudget/conventions/MOM6_drift.yaml +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/xbudget/conventions/MOM6_surface.yaml +0 -0
- {xbudget-0.5.1 → xbudget-0.6.0}/xbudget/presets.py +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
defaults:
|
|
16
|
+
run:
|
|
17
|
+
shell: bash -l {0}
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
python-version: ['3.12', '3.13', '3.14', '3.15']
|
|
22
|
+
|
|
23
|
+
steps:
|
|
24
|
+
- name: Cancel previous runs
|
|
25
|
+
uses: styfle/cancel-workflow-action@0.7.0
|
|
26
|
+
with:
|
|
27
|
+
access_token: ${{ github.token }}
|
|
28
|
+
- name: Checkout source
|
|
29
|
+
uses: actions/checkout@v2
|
|
30
|
+
|
|
31
|
+
- name: Conda setup
|
|
32
|
+
uses: conda-incubator/setup-miniconda@v2
|
|
33
|
+
with:
|
|
34
|
+
channels: conda-forge
|
|
35
|
+
mamba-version: '*'
|
|
36
|
+
python-version: ${{ matrix.python-version }}
|
|
37
|
+
activate-environment: test_env_xbudget
|
|
38
|
+
auto-activate-base: false
|
|
39
|
+
|
|
40
|
+
- name: Set up conda environment
|
|
41
|
+
run: |
|
|
42
|
+
mamba env update -f ci/environment.yml
|
|
43
|
+
python -m pip install -e .
|
|
44
|
+
- name: Conda list information
|
|
45
|
+
run: |
|
|
46
|
+
conda env list
|
|
47
|
+
conda list
|
|
48
|
+
- name: Test with pytest
|
|
49
|
+
run: |
|
|
50
|
+
pytest
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xbudget
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Helper functions and meta-data conventions for wrangling finite-volume ocean model budgets
|
|
5
5
|
Project-URL: Homepage, https://github.com/hdrake/xbudget
|
|
6
6
|
Project-URL: Bugs/Issues/Features, https://github.com/hdrake/xbudget/issues
|
|
@@ -219,13 +219,15 @@ def budget_fill_dict(data, xbudget_dict, namepath):
|
|
|
219
219
|
v_term_recursive = budget_fill_dict(data, v_term, f"{namepath}_{k}_{k_term}")
|
|
220
220
|
if v_term_recursive is not None:
|
|
221
221
|
op_list.append(v_term_recursive)
|
|
222
|
+
elif v_term.get("var") is not None and v_term.get("var") not in ds:
|
|
223
|
+
warnings.warn(f"Variable {v_term.get('var')} is missing from the dataset `ds`, so it is being skipped. To suppress this warning, remove {v_term.get('var')} from the `xbudget_dict`.", UserWarning)
|
|
222
224
|
elif isinstance(v_term, numbers.Number):
|
|
223
225
|
op_list.append(v_term)
|
|
224
226
|
elif isinstance(v_term, str):
|
|
225
227
|
if v_term in ds:
|
|
226
228
|
op_list.append(ds[v_term])
|
|
227
229
|
else:
|
|
228
|
-
warnings.warn(f"Variable {v_term} is missing from the dataset `ds`, so it is being skipped. To suppress this warning, remove {v_term} from the `xbudget_dict`.")
|
|
230
|
+
warnings.warn(f"Variable {v_term} is missing from the dataset `ds`, so it is being skipped. To suppress this warning, remove {v_term} from the `xbudget_dict`.", UserWarning)
|
|
229
231
|
if k=="product":
|
|
230
232
|
op_list.append(0.)
|
|
231
233
|
|
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "code",
|
|
5
|
+
"execution_count": 1,
|
|
6
|
+
"id": "55ae02be",
|
|
7
|
+
"metadata": {},
|
|
8
|
+
"outputs": [],
|
|
9
|
+
"source": [
|
|
10
|
+
"import xarray as xr\n",
|
|
11
|
+
"import xbudget\n",
|
|
12
|
+
"import numpy as np"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"cell_type": "code",
|
|
17
|
+
"execution_count": 2,
|
|
18
|
+
"id": "a6e6f2cb",
|
|
19
|
+
"metadata": {},
|
|
20
|
+
"outputs": [],
|
|
21
|
+
"source": [
|
|
22
|
+
"ds = xr.Dataset({\n",
|
|
23
|
+
" \"advective_tendency\": xr.DataArray(np.random.rand(3, 3), dims=(\"x\", \"y\")),\n",
|
|
24
|
+
"}, coords={\"x\":[0,1,2], \"y\":[0,1,2]})\n",
|
|
25
|
+
"\n",
|
|
26
|
+
"xbudget_dict = {\n",
|
|
27
|
+
" \"heat\": {\n",
|
|
28
|
+
" \"rhs\": {\n",
|
|
29
|
+
" \"sum\": {\n",
|
|
30
|
+
" \"advection\": {\"var\": \"advective_tendency\"},\n",
|
|
31
|
+
" \"var\": None,\n",
|
|
32
|
+
" },\n",
|
|
33
|
+
" \"var\": None,\n",
|
|
34
|
+
" }\n",
|
|
35
|
+
" }\n",
|
|
36
|
+
"}"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"cell_type": "code",
|
|
41
|
+
"execution_count": 4,
|
|
42
|
+
"id": "477544f4",
|
|
43
|
+
"metadata": {},
|
|
44
|
+
"outputs": [],
|
|
45
|
+
"source": [
|
|
46
|
+
"xbudget.collect_budgets(ds, xbudget_dict)"
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"cell_type": "code",
|
|
51
|
+
"execution_count": 8,
|
|
52
|
+
"id": "f8301230",
|
|
53
|
+
"metadata": {},
|
|
54
|
+
"outputs": [
|
|
55
|
+
{
|
|
56
|
+
"data": {
|
|
57
|
+
"text/html": [
|
|
58
|
+
"<div><svg style=\"position: absolute; width: 0; height: 0; overflow: hidden\">\n",
|
|
59
|
+
"<defs>\n",
|
|
60
|
+
"<symbol id=\"icon-database\" viewBox=\"0 0 32 32\">\n",
|
|
61
|
+
"<path d=\"M16 0c-8.837 0-16 2.239-16 5v4c0 2.761 7.163 5 16 5s16-2.239 16-5v-4c0-2.761-7.163-5-16-5z\"></path>\n",
|
|
62
|
+
"<path d=\"M16 17c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
|
|
63
|
+
"<path d=\"M16 26c-8.837 0-16-2.239-16-5v6c0 2.761 7.163 5 16 5s16-2.239 16-5v-6c0 2.761-7.163 5-16 5z\"></path>\n",
|
|
64
|
+
"</symbol>\n",
|
|
65
|
+
"<symbol id=\"icon-file-text2\" viewBox=\"0 0 32 32\">\n",
|
|
66
|
+
"<path d=\"M28.681 7.159c-0.694-0.947-1.662-2.053-2.724-3.116s-2.169-2.030-3.116-2.724c-1.612-1.182-2.393-1.319-2.841-1.319h-15.5c-1.378 0-2.5 1.121-2.5 2.5v27c0 1.378 1.122 2.5 2.5 2.5h23c1.378 0 2.5-1.122 2.5-2.5v-19.5c0-0.448-0.137-1.23-1.319-2.841zM24.543 5.457c0.959 0.959 1.712 1.825 2.268 2.543h-4.811v-4.811c0.718 0.556 1.584 1.309 2.543 2.268zM28 29.5c0 0.271-0.229 0.5-0.5 0.5h-23c-0.271 0-0.5-0.229-0.5-0.5v-27c0-0.271 0.229-0.5 0.5-0.5 0 0 15.499-0 15.5 0v7c0 0.552 0.448 1 1 1h7v19.5z\"></path>\n",
|
|
67
|
+
"<path d=\"M23 26h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
|
|
68
|
+
"<path d=\"M23 22h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
|
|
69
|
+
"<path d=\"M23 18h-14c-0.552 0-1-0.448-1-1s0.448-1 1-1h14c0.552 0 1 0.448 1 1s-0.448 1-1 1z\"></path>\n",
|
|
70
|
+
"</symbol>\n",
|
|
71
|
+
"</defs>\n",
|
|
72
|
+
"</svg>\n",
|
|
73
|
+
"<style>/* CSS stylesheet for displaying xarray objects in notebooks */\n",
|
|
74
|
+
"\n",
|
|
75
|
+
":root {\n",
|
|
76
|
+
" --xr-font-color0: var(\n",
|
|
77
|
+
" --jp-content-font-color0,\n",
|
|
78
|
+
" var(--pst-color-text-base rgba(0, 0, 0, 1))\n",
|
|
79
|
+
" );\n",
|
|
80
|
+
" --xr-font-color2: var(\n",
|
|
81
|
+
" --jp-content-font-color2,\n",
|
|
82
|
+
" var(--pst-color-text-base, rgba(0, 0, 0, 0.54))\n",
|
|
83
|
+
" );\n",
|
|
84
|
+
" --xr-font-color3: var(\n",
|
|
85
|
+
" --jp-content-font-color3,\n",
|
|
86
|
+
" var(--pst-color-text-base, rgba(0, 0, 0, 0.38))\n",
|
|
87
|
+
" );\n",
|
|
88
|
+
" --xr-border-color: var(\n",
|
|
89
|
+
" --jp-border-color2,\n",
|
|
90
|
+
" hsl(from var(--pst-color-on-background, white) h s calc(l - 10))\n",
|
|
91
|
+
" );\n",
|
|
92
|
+
" --xr-disabled-color: var(\n",
|
|
93
|
+
" --jp-layout-color3,\n",
|
|
94
|
+
" hsl(from var(--pst-color-on-background, white) h s calc(l - 40))\n",
|
|
95
|
+
" );\n",
|
|
96
|
+
" --xr-background-color: var(\n",
|
|
97
|
+
" --jp-layout-color0,\n",
|
|
98
|
+
" var(--pst-color-on-background, white)\n",
|
|
99
|
+
" );\n",
|
|
100
|
+
" --xr-background-color-row-even: var(\n",
|
|
101
|
+
" --jp-layout-color1,\n",
|
|
102
|
+
" hsl(from var(--pst-color-on-background, white) h s calc(l - 5))\n",
|
|
103
|
+
" );\n",
|
|
104
|
+
" --xr-background-color-row-odd: var(\n",
|
|
105
|
+
" --jp-layout-color2,\n",
|
|
106
|
+
" hsl(from var(--pst-color-on-background, white) h s calc(l - 15))\n",
|
|
107
|
+
" );\n",
|
|
108
|
+
"}\n",
|
|
109
|
+
"\n",
|
|
110
|
+
"html[theme=\"dark\"],\n",
|
|
111
|
+
"html[data-theme=\"dark\"],\n",
|
|
112
|
+
"body[data-theme=\"dark\"],\n",
|
|
113
|
+
"body.vscode-dark {\n",
|
|
114
|
+
" --xr-font-color0: var(\n",
|
|
115
|
+
" --jp-content-font-color0,\n",
|
|
116
|
+
" var(--pst-color-text-base, rgba(255, 255, 255, 1))\n",
|
|
117
|
+
" );\n",
|
|
118
|
+
" --xr-font-color2: var(\n",
|
|
119
|
+
" --jp-content-font-color2,\n",
|
|
120
|
+
" var(--pst-color-text-base, rgba(255, 255, 255, 0.54))\n",
|
|
121
|
+
" );\n",
|
|
122
|
+
" --xr-font-color3: var(\n",
|
|
123
|
+
" --jp-content-font-color3,\n",
|
|
124
|
+
" var(--pst-color-text-base, rgba(255, 255, 255, 0.38))\n",
|
|
125
|
+
" );\n",
|
|
126
|
+
" --xr-border-color: var(\n",
|
|
127
|
+
" --jp-border-color2,\n",
|
|
128
|
+
" hsl(from var(--pst-color-on-background, #111111) h s calc(l + 10))\n",
|
|
129
|
+
" );\n",
|
|
130
|
+
" --xr-disabled-color: var(\n",
|
|
131
|
+
" --jp-layout-color3,\n",
|
|
132
|
+
" hsl(from var(--pst-color-on-background, #111111) h s calc(l + 40))\n",
|
|
133
|
+
" );\n",
|
|
134
|
+
" --xr-background-color: var(\n",
|
|
135
|
+
" --jp-layout-color0,\n",
|
|
136
|
+
" var(--pst-color-on-background, #111111)\n",
|
|
137
|
+
" );\n",
|
|
138
|
+
" --xr-background-color-row-even: var(\n",
|
|
139
|
+
" --jp-layout-color1,\n",
|
|
140
|
+
" hsl(from var(--pst-color-on-background, #111111) h s calc(l + 5))\n",
|
|
141
|
+
" );\n",
|
|
142
|
+
" --xr-background-color-row-odd: var(\n",
|
|
143
|
+
" --jp-layout-color2,\n",
|
|
144
|
+
" hsl(from var(--pst-color-on-background, #111111) h s calc(l + 15))\n",
|
|
145
|
+
" );\n",
|
|
146
|
+
"}\n",
|
|
147
|
+
"\n",
|
|
148
|
+
".xr-wrap {\n",
|
|
149
|
+
" display: block !important;\n",
|
|
150
|
+
" min-width: 300px;\n",
|
|
151
|
+
" max-width: 700px;\n",
|
|
152
|
+
" line-height: 1.6;\n",
|
|
153
|
+
" padding-bottom: 4px;\n",
|
|
154
|
+
"}\n",
|
|
155
|
+
"\n",
|
|
156
|
+
".xr-text-repr-fallback {\n",
|
|
157
|
+
" /* fallback to plain text repr when CSS is not injected (untrusted notebook) */\n",
|
|
158
|
+
" display: none;\n",
|
|
159
|
+
"}\n",
|
|
160
|
+
"\n",
|
|
161
|
+
".xr-header {\n",
|
|
162
|
+
" padding-top: 6px;\n",
|
|
163
|
+
" padding-bottom: 6px;\n",
|
|
164
|
+
"}\n",
|
|
165
|
+
"\n",
|
|
166
|
+
".xr-header {\n",
|
|
167
|
+
" border-bottom: solid 1px var(--xr-border-color);\n",
|
|
168
|
+
" margin-bottom: 4px;\n",
|
|
169
|
+
"}\n",
|
|
170
|
+
"\n",
|
|
171
|
+
".xr-header > div,\n",
|
|
172
|
+
".xr-header > ul {\n",
|
|
173
|
+
" display: inline;\n",
|
|
174
|
+
" margin-top: 0;\n",
|
|
175
|
+
" margin-bottom: 0;\n",
|
|
176
|
+
"}\n",
|
|
177
|
+
"\n",
|
|
178
|
+
".xr-obj-type,\n",
|
|
179
|
+
".xr-obj-name {\n",
|
|
180
|
+
" margin-left: 2px;\n",
|
|
181
|
+
" margin-right: 10px;\n",
|
|
182
|
+
"}\n",
|
|
183
|
+
"\n",
|
|
184
|
+
".xr-obj-type,\n",
|
|
185
|
+
".xr-group-box-contents > label {\n",
|
|
186
|
+
" color: var(--xr-font-color2);\n",
|
|
187
|
+
" display: block;\n",
|
|
188
|
+
"}\n",
|
|
189
|
+
"\n",
|
|
190
|
+
".xr-sections {\n",
|
|
191
|
+
" padding-left: 0 !important;\n",
|
|
192
|
+
" display: grid;\n",
|
|
193
|
+
" grid-template-columns: 150px auto auto 1fr 0 20px 0 20px;\n",
|
|
194
|
+
" margin-block-start: 0;\n",
|
|
195
|
+
" margin-block-end: 0;\n",
|
|
196
|
+
"}\n",
|
|
197
|
+
"\n",
|
|
198
|
+
".xr-section-item {\n",
|
|
199
|
+
" display: contents;\n",
|
|
200
|
+
"}\n",
|
|
201
|
+
"\n",
|
|
202
|
+
".xr-section-item > input,\n",
|
|
203
|
+
".xr-group-box-contents > input,\n",
|
|
204
|
+
".xr-array-wrap > input {\n",
|
|
205
|
+
" display: block;\n",
|
|
206
|
+
" opacity: 0;\n",
|
|
207
|
+
" height: 0;\n",
|
|
208
|
+
" margin: 0;\n",
|
|
209
|
+
"}\n",
|
|
210
|
+
"\n",
|
|
211
|
+
".xr-section-item > input + label,\n",
|
|
212
|
+
".xr-var-item > input + label {\n",
|
|
213
|
+
" color: var(--xr-disabled-color);\n",
|
|
214
|
+
"}\n",
|
|
215
|
+
"\n",
|
|
216
|
+
".xr-section-item > input:enabled + label,\n",
|
|
217
|
+
".xr-var-item > input:enabled + label,\n",
|
|
218
|
+
".xr-array-wrap > input:enabled + label,\n",
|
|
219
|
+
".xr-group-box-contents > input:enabled + label {\n",
|
|
220
|
+
" cursor: pointer;\n",
|
|
221
|
+
" color: var(--xr-font-color2);\n",
|
|
222
|
+
"}\n",
|
|
223
|
+
"\n",
|
|
224
|
+
".xr-section-item > input:focus-visible + label,\n",
|
|
225
|
+
".xr-var-item > input:focus-visible + label,\n",
|
|
226
|
+
".xr-array-wrap > input:focus-visible + label,\n",
|
|
227
|
+
".xr-group-box-contents > input:focus-visible + label {\n",
|
|
228
|
+
" outline: auto;\n",
|
|
229
|
+
"}\n",
|
|
230
|
+
"\n",
|
|
231
|
+
".xr-section-item > input:enabled + label:hover,\n",
|
|
232
|
+
".xr-var-item > input:enabled + label:hover,\n",
|
|
233
|
+
".xr-array-wrap > input:enabled + label:hover,\n",
|
|
234
|
+
".xr-group-box-contents > input:enabled + label:hover {\n",
|
|
235
|
+
" color: var(--xr-font-color0);\n",
|
|
236
|
+
"}\n",
|
|
237
|
+
"\n",
|
|
238
|
+
".xr-section-summary {\n",
|
|
239
|
+
" grid-column: 1;\n",
|
|
240
|
+
" color: var(--xr-font-color2);\n",
|
|
241
|
+
" font-weight: 500;\n",
|
|
242
|
+
" white-space: nowrap;\n",
|
|
243
|
+
"}\n",
|
|
244
|
+
"\n",
|
|
245
|
+
".xr-section-summary > em {\n",
|
|
246
|
+
" font-weight: normal;\n",
|
|
247
|
+
"}\n",
|
|
248
|
+
"\n",
|
|
249
|
+
".xr-span-grid {\n",
|
|
250
|
+
" grid-column-end: -1;\n",
|
|
251
|
+
"}\n",
|
|
252
|
+
"\n",
|
|
253
|
+
".xr-section-summary > span {\n",
|
|
254
|
+
" display: inline-block;\n",
|
|
255
|
+
" padding-left: 0.3em;\n",
|
|
256
|
+
"}\n",
|
|
257
|
+
"\n",
|
|
258
|
+
".xr-group-box-contents > input:checked + label > span {\n",
|
|
259
|
+
" display: inline-block;\n",
|
|
260
|
+
" padding-left: 0.6em;\n",
|
|
261
|
+
"}\n",
|
|
262
|
+
"\n",
|
|
263
|
+
".xr-section-summary-in:disabled + label {\n",
|
|
264
|
+
" color: var(--xr-font-color2);\n",
|
|
265
|
+
"}\n",
|
|
266
|
+
"\n",
|
|
267
|
+
".xr-section-summary-in + label:before {\n",
|
|
268
|
+
" display: inline-block;\n",
|
|
269
|
+
" content: \"►\";\n",
|
|
270
|
+
" font-size: 11px;\n",
|
|
271
|
+
" width: 15px;\n",
|
|
272
|
+
" text-align: center;\n",
|
|
273
|
+
"}\n",
|
|
274
|
+
"\n",
|
|
275
|
+
".xr-section-summary-in:disabled + label:before {\n",
|
|
276
|
+
" color: var(--xr-disabled-color);\n",
|
|
277
|
+
"}\n",
|
|
278
|
+
"\n",
|
|
279
|
+
".xr-section-summary-in:checked + label:before {\n",
|
|
280
|
+
" content: \"▼\";\n",
|
|
281
|
+
"}\n",
|
|
282
|
+
"\n",
|
|
283
|
+
".xr-section-summary-in:checked + label > span {\n",
|
|
284
|
+
" display: none;\n",
|
|
285
|
+
"}\n",
|
|
286
|
+
"\n",
|
|
287
|
+
".xr-section-summary,\n",
|
|
288
|
+
".xr-section-inline-details,\n",
|
|
289
|
+
".xr-group-box-contents > label {\n",
|
|
290
|
+
" padding-top: 4px;\n",
|
|
291
|
+
"}\n",
|
|
292
|
+
"\n",
|
|
293
|
+
".xr-section-inline-details {\n",
|
|
294
|
+
" grid-column: 2 / -1;\n",
|
|
295
|
+
"}\n",
|
|
296
|
+
"\n",
|
|
297
|
+
".xr-section-details {\n",
|
|
298
|
+
" grid-column: 1 / -1;\n",
|
|
299
|
+
" margin-top: 4px;\n",
|
|
300
|
+
" margin-bottom: 5px;\n",
|
|
301
|
+
"}\n",
|
|
302
|
+
"\n",
|
|
303
|
+
".xr-section-summary-in ~ .xr-section-details {\n",
|
|
304
|
+
" display: none;\n",
|
|
305
|
+
"}\n",
|
|
306
|
+
"\n",
|
|
307
|
+
".xr-section-summary-in:checked ~ .xr-section-details {\n",
|
|
308
|
+
" display: contents;\n",
|
|
309
|
+
"}\n",
|
|
310
|
+
"\n",
|
|
311
|
+
".xr-children {\n",
|
|
312
|
+
" display: inline-grid;\n",
|
|
313
|
+
" grid-template-columns: 100%;\n",
|
|
314
|
+
" grid-column: 1 / -1;\n",
|
|
315
|
+
" padding-top: 4px;\n",
|
|
316
|
+
"}\n",
|
|
317
|
+
"\n",
|
|
318
|
+
".xr-group-box {\n",
|
|
319
|
+
" display: inline-grid;\n",
|
|
320
|
+
" grid-template-columns: 0px 30px auto;\n",
|
|
321
|
+
"}\n",
|
|
322
|
+
"\n",
|
|
323
|
+
".xr-group-box-vline {\n",
|
|
324
|
+
" grid-column-start: 1;\n",
|
|
325
|
+
" border-right: 0.2em solid;\n",
|
|
326
|
+
" border-color: var(--xr-border-color);\n",
|
|
327
|
+
" width: 0px;\n",
|
|
328
|
+
"}\n",
|
|
329
|
+
"\n",
|
|
330
|
+
".xr-group-box-hline {\n",
|
|
331
|
+
" grid-column-start: 2;\n",
|
|
332
|
+
" grid-row-start: 1;\n",
|
|
333
|
+
" height: 1em;\n",
|
|
334
|
+
" width: 26px;\n",
|
|
335
|
+
" border-bottom: 0.2em solid;\n",
|
|
336
|
+
" border-color: var(--xr-border-color);\n",
|
|
337
|
+
"}\n",
|
|
338
|
+
"\n",
|
|
339
|
+
".xr-group-box-contents {\n",
|
|
340
|
+
" grid-column-start: 3;\n",
|
|
341
|
+
" padding-bottom: 4px;\n",
|
|
342
|
+
"}\n",
|
|
343
|
+
"\n",
|
|
344
|
+
".xr-group-box-contents > label::before {\n",
|
|
345
|
+
" content: \"📂\";\n",
|
|
346
|
+
" padding-right: 0.3em;\n",
|
|
347
|
+
"}\n",
|
|
348
|
+
"\n",
|
|
349
|
+
".xr-group-box-contents > input:checked + label::before {\n",
|
|
350
|
+
" content: \"📁\";\n",
|
|
351
|
+
"}\n",
|
|
352
|
+
"\n",
|
|
353
|
+
".xr-group-box-contents > input:checked + label {\n",
|
|
354
|
+
" padding-bottom: 0px;\n",
|
|
355
|
+
"}\n",
|
|
356
|
+
"\n",
|
|
357
|
+
".xr-group-box-contents > input:checked ~ .xr-sections {\n",
|
|
358
|
+
" display: none;\n",
|
|
359
|
+
"}\n",
|
|
360
|
+
"\n",
|
|
361
|
+
".xr-group-box-contents > input + label > span {\n",
|
|
362
|
+
" display: none;\n",
|
|
363
|
+
"}\n",
|
|
364
|
+
"\n",
|
|
365
|
+
".xr-group-box-ellipsis {\n",
|
|
366
|
+
" font-size: 1.4em;\n",
|
|
367
|
+
" font-weight: 900;\n",
|
|
368
|
+
" color: var(--xr-font-color2);\n",
|
|
369
|
+
" letter-spacing: 0.15em;\n",
|
|
370
|
+
" cursor: default;\n",
|
|
371
|
+
"}\n",
|
|
372
|
+
"\n",
|
|
373
|
+
".xr-array-wrap {\n",
|
|
374
|
+
" grid-column: 1 / -1;\n",
|
|
375
|
+
" display: grid;\n",
|
|
376
|
+
" grid-template-columns: 20px auto;\n",
|
|
377
|
+
"}\n",
|
|
378
|
+
"\n",
|
|
379
|
+
".xr-array-wrap > label {\n",
|
|
380
|
+
" grid-column: 1;\n",
|
|
381
|
+
" vertical-align: top;\n",
|
|
382
|
+
"}\n",
|
|
383
|
+
"\n",
|
|
384
|
+
".xr-preview {\n",
|
|
385
|
+
" color: var(--xr-font-color3);\n",
|
|
386
|
+
"}\n",
|
|
387
|
+
"\n",
|
|
388
|
+
".xr-array-preview,\n",
|
|
389
|
+
".xr-array-data {\n",
|
|
390
|
+
" padding: 0 5px !important;\n",
|
|
391
|
+
" grid-column: 2;\n",
|
|
392
|
+
"}\n",
|
|
393
|
+
"\n",
|
|
394
|
+
".xr-array-data,\n",
|
|
395
|
+
".xr-array-in:checked ~ .xr-array-preview {\n",
|
|
396
|
+
" display: none;\n",
|
|
397
|
+
"}\n",
|
|
398
|
+
"\n",
|
|
399
|
+
".xr-array-in:checked ~ .xr-array-data,\n",
|
|
400
|
+
".xr-array-preview {\n",
|
|
401
|
+
" display: inline-block;\n",
|
|
402
|
+
"}\n",
|
|
403
|
+
"\n",
|
|
404
|
+
".xr-dim-list {\n",
|
|
405
|
+
" display: inline-block !important;\n",
|
|
406
|
+
" list-style: none;\n",
|
|
407
|
+
" padding: 0 !important;\n",
|
|
408
|
+
" margin: 0;\n",
|
|
409
|
+
"}\n",
|
|
410
|
+
"\n",
|
|
411
|
+
".xr-dim-list li {\n",
|
|
412
|
+
" display: inline-block;\n",
|
|
413
|
+
" padding: 0;\n",
|
|
414
|
+
" margin: 0;\n",
|
|
415
|
+
"}\n",
|
|
416
|
+
"\n",
|
|
417
|
+
".xr-dim-list:before {\n",
|
|
418
|
+
" content: \"(\";\n",
|
|
419
|
+
"}\n",
|
|
420
|
+
"\n",
|
|
421
|
+
".xr-dim-list:after {\n",
|
|
422
|
+
" content: \")\";\n",
|
|
423
|
+
"}\n",
|
|
424
|
+
"\n",
|
|
425
|
+
".xr-dim-list li:not(:last-child):after {\n",
|
|
426
|
+
" content: \",\";\n",
|
|
427
|
+
" padding-right: 5px;\n",
|
|
428
|
+
"}\n",
|
|
429
|
+
"\n",
|
|
430
|
+
".xr-has-index {\n",
|
|
431
|
+
" font-weight: bold;\n",
|
|
432
|
+
"}\n",
|
|
433
|
+
"\n",
|
|
434
|
+
".xr-var-list,\n",
|
|
435
|
+
".xr-var-item {\n",
|
|
436
|
+
" display: contents;\n",
|
|
437
|
+
"}\n",
|
|
438
|
+
"\n",
|
|
439
|
+
".xr-var-item > div,\n",
|
|
440
|
+
".xr-var-item label,\n",
|
|
441
|
+
".xr-var-item > .xr-var-name span {\n",
|
|
442
|
+
" background-color: var(--xr-background-color-row-even);\n",
|
|
443
|
+
" border-color: var(--xr-background-color-row-odd);\n",
|
|
444
|
+
" margin-bottom: 0;\n",
|
|
445
|
+
" padding-top: 2px;\n",
|
|
446
|
+
"}\n",
|
|
447
|
+
"\n",
|
|
448
|
+
".xr-var-item > .xr-var-name:hover span {\n",
|
|
449
|
+
" padding-right: 5px;\n",
|
|
450
|
+
"}\n",
|
|
451
|
+
"\n",
|
|
452
|
+
".xr-var-list > li:nth-child(odd) > div,\n",
|
|
453
|
+
".xr-var-list > li:nth-child(odd) > label,\n",
|
|
454
|
+
".xr-var-list > li:nth-child(odd) > .xr-var-name span {\n",
|
|
455
|
+
" background-color: var(--xr-background-color-row-odd);\n",
|
|
456
|
+
" border-color: var(--xr-background-color-row-even);\n",
|
|
457
|
+
"}\n",
|
|
458
|
+
"\n",
|
|
459
|
+
".xr-var-name {\n",
|
|
460
|
+
" grid-column: 1;\n",
|
|
461
|
+
"}\n",
|
|
462
|
+
"\n",
|
|
463
|
+
".xr-var-dims {\n",
|
|
464
|
+
" grid-column: 2;\n",
|
|
465
|
+
"}\n",
|
|
466
|
+
"\n",
|
|
467
|
+
".xr-var-dtype {\n",
|
|
468
|
+
" grid-column: 3;\n",
|
|
469
|
+
" text-align: right;\n",
|
|
470
|
+
" color: var(--xr-font-color2);\n",
|
|
471
|
+
"}\n",
|
|
472
|
+
"\n",
|
|
473
|
+
".xr-var-preview {\n",
|
|
474
|
+
" grid-column: 4;\n",
|
|
475
|
+
"}\n",
|
|
476
|
+
"\n",
|
|
477
|
+
".xr-index-preview {\n",
|
|
478
|
+
" grid-column: 2 / 5;\n",
|
|
479
|
+
" color: var(--xr-font-color2);\n",
|
|
480
|
+
"}\n",
|
|
481
|
+
"\n",
|
|
482
|
+
".xr-var-name,\n",
|
|
483
|
+
".xr-var-dims,\n",
|
|
484
|
+
".xr-var-dtype,\n",
|
|
485
|
+
".xr-preview,\n",
|
|
486
|
+
".xr-attrs dt {\n",
|
|
487
|
+
" white-space: nowrap;\n",
|
|
488
|
+
" overflow: hidden;\n",
|
|
489
|
+
" text-overflow: ellipsis;\n",
|
|
490
|
+
" padding-right: 10px;\n",
|
|
491
|
+
"}\n",
|
|
492
|
+
"\n",
|
|
493
|
+
".xr-var-name:hover,\n",
|
|
494
|
+
".xr-var-dims:hover,\n",
|
|
495
|
+
".xr-var-dtype:hover,\n",
|
|
496
|
+
".xr-attrs dt:hover {\n",
|
|
497
|
+
" overflow: visible;\n",
|
|
498
|
+
" width: auto;\n",
|
|
499
|
+
" z-index: 1;\n",
|
|
500
|
+
"}\n",
|
|
501
|
+
"\n",
|
|
502
|
+
".xr-var-attrs,\n",
|
|
503
|
+
".xr-var-data,\n",
|
|
504
|
+
".xr-index-data {\n",
|
|
505
|
+
" display: none;\n",
|
|
506
|
+
" border-top: 2px dotted var(--xr-background-color);\n",
|
|
507
|
+
" padding-bottom: 20px !important;\n",
|
|
508
|
+
" padding-top: 10px !important;\n",
|
|
509
|
+
"}\n",
|
|
510
|
+
"\n",
|
|
511
|
+
".xr-var-attrs-in + label,\n",
|
|
512
|
+
".xr-var-data-in + label,\n",
|
|
513
|
+
".xr-index-data-in + label {\n",
|
|
514
|
+
" padding: 0 1px;\n",
|
|
515
|
+
"}\n",
|
|
516
|
+
"\n",
|
|
517
|
+
".xr-var-attrs-in:checked ~ .xr-var-attrs,\n",
|
|
518
|
+
".xr-var-data-in:checked ~ .xr-var-data,\n",
|
|
519
|
+
".xr-index-data-in:checked ~ .xr-index-data {\n",
|
|
520
|
+
" display: block;\n",
|
|
521
|
+
"}\n",
|
|
522
|
+
"\n",
|
|
523
|
+
".xr-var-data > table {\n",
|
|
524
|
+
" float: right;\n",
|
|
525
|
+
"}\n",
|
|
526
|
+
"\n",
|
|
527
|
+
".xr-var-data > pre,\n",
|
|
528
|
+
".xr-index-data > pre,\n",
|
|
529
|
+
".xr-var-data > table > tbody > tr {\n",
|
|
530
|
+
" background-color: transparent !important;\n",
|
|
531
|
+
"}\n",
|
|
532
|
+
"\n",
|
|
533
|
+
".xr-var-name span,\n",
|
|
534
|
+
".xr-var-data,\n",
|
|
535
|
+
".xr-index-name div,\n",
|
|
536
|
+
".xr-index-data,\n",
|
|
537
|
+
".xr-attrs {\n",
|
|
538
|
+
" padding-left: 25px !important;\n",
|
|
539
|
+
"}\n",
|
|
540
|
+
"\n",
|
|
541
|
+
".xr-attrs,\n",
|
|
542
|
+
".xr-var-attrs,\n",
|
|
543
|
+
".xr-var-data,\n",
|
|
544
|
+
".xr-index-data {\n",
|
|
545
|
+
" grid-column: 1 / -1;\n",
|
|
546
|
+
"}\n",
|
|
547
|
+
"\n",
|
|
548
|
+
"dl.xr-attrs {\n",
|
|
549
|
+
" padding: 0;\n",
|
|
550
|
+
" margin: 0;\n",
|
|
551
|
+
" display: grid;\n",
|
|
552
|
+
" grid-template-columns: 125px auto;\n",
|
|
553
|
+
"}\n",
|
|
554
|
+
"\n",
|
|
555
|
+
".xr-attrs dt,\n",
|
|
556
|
+
".xr-attrs dd {\n",
|
|
557
|
+
" padding: 0;\n",
|
|
558
|
+
" margin: 0;\n",
|
|
559
|
+
" float: left;\n",
|
|
560
|
+
" padding-right: 10px;\n",
|
|
561
|
+
" width: auto;\n",
|
|
562
|
+
"}\n",
|
|
563
|
+
"\n",
|
|
564
|
+
".xr-attrs dt {\n",
|
|
565
|
+
" font-weight: normal;\n",
|
|
566
|
+
" grid-column: 1;\n",
|
|
567
|
+
"}\n",
|
|
568
|
+
"\n",
|
|
569
|
+
".xr-attrs dt:hover span {\n",
|
|
570
|
+
" display: inline-block;\n",
|
|
571
|
+
" background: var(--xr-background-color);\n",
|
|
572
|
+
" padding-right: 10px;\n",
|
|
573
|
+
"}\n",
|
|
574
|
+
"\n",
|
|
575
|
+
".xr-attrs dd {\n",
|
|
576
|
+
" grid-column: 2;\n",
|
|
577
|
+
" white-space: pre-wrap;\n",
|
|
578
|
+
" word-break: break-all;\n",
|
|
579
|
+
"}\n",
|
|
580
|
+
"\n",
|
|
581
|
+
".xr-icon-database,\n",
|
|
582
|
+
".xr-icon-file-text2,\n",
|
|
583
|
+
".xr-no-icon {\n",
|
|
584
|
+
" display: inline-block;\n",
|
|
585
|
+
" vertical-align: middle;\n",
|
|
586
|
+
" width: 1em;\n",
|
|
587
|
+
" height: 1.5em !important;\n",
|
|
588
|
+
" stroke-width: 0;\n",
|
|
589
|
+
" stroke: currentColor;\n",
|
|
590
|
+
" fill: currentColor;\n",
|
|
591
|
+
"}\n",
|
|
592
|
+
"\n",
|
|
593
|
+
".xr-var-attrs-in:checked + label > .xr-icon-file-text2,\n",
|
|
594
|
+
".xr-var-data-in:checked + label > .xr-icon-database,\n",
|
|
595
|
+
".xr-index-data-in:checked + label > .xr-icon-database {\n",
|
|
596
|
+
" color: var(--xr-font-color0);\n",
|
|
597
|
+
" filter: drop-shadow(1px 1px 5px var(--xr-font-color2));\n",
|
|
598
|
+
" stroke-width: 0.8px;\n",
|
|
599
|
+
"}\n",
|
|
600
|
+
"</style><pre class='xr-text-repr-fallback'><xarray.Dataset> Size: 336B\n",
|
|
601
|
+
"Dimensions: (x: 3, y: 3)\n",
|
|
602
|
+
"Coordinates:\n",
|
|
603
|
+
" * x (x) int64 24B 0 1 2\n",
|
|
604
|
+
" * y (y) int64 24B 0 1 2\n",
|
|
605
|
+
"Data variables:\n",
|
|
606
|
+
" advective_tendency (x, y) float64 72B 0.7948 0.6921 ... 0.5149 0.3452\n",
|
|
607
|
+
" heat_rhs_sum_advection (x, y) float64 72B 0.7948 0.6921 ... 0.5149 0.3452\n",
|
|
608
|
+
" heat_rhs_sum (x, y) float64 72B 0.7948 0.6921 ... 0.5149 0.3452\n",
|
|
609
|
+
" heat_rhs (x, y) float64 72B 0.7948 0.6921 ... 0.5149 0.3452</pre><div class='xr-wrap' style='display:none'><div class='xr-header'><div class='xr-obj-type'>xarray.Dataset</div></div><ul class='xr-sections'><li class='xr-section-item'><input id='section-87a6abab-94fb-482d-8d83-3f8c1854237f' class='xr-section-summary-in' type='checkbox' disabled /><label for='section-87a6abab-94fb-482d-8d83-3f8c1854237f' class='xr-section-summary'>Dimensions:</label><div class='xr-section-inline-details'><ul class='xr-dim-list'><li><span class='xr-has-index'>x</span>: 3</li><li><span class='xr-has-index'>y</span>: 3</li></ul></div></li><li class='xr-section-item'><input id='section-d798de27-798d-4a0e-900b-84e3279292d8' class='xr-section-summary-in' type='checkbox' checked /><label for='section-d798de27-798d-4a0e-900b-84e3279292d8' class='xr-section-summary' title='Expand/collapse section'>Coordinates: <span>(2)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>x</span></div><div class='xr-var-dims'>(x)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0 1 2</div><input id='attrs-b5e22c66-5fd4-4403-b11b-98e8d9079b11' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-b5e22c66-5fd4-4403-b11b-98e8d9079b11' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-25c11dfc-b33e-4c92-a7f1-cd6ed434055f' class='xr-var-data-in' type='checkbox'><label for='data-25c11dfc-b33e-4c92-a7f1-cd6ed434055f' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([0, 1, 2])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span class='xr-has-index'>y</span></div><div class='xr-var-dims'>(y)</div><div class='xr-var-dtype'>int64</div><div class='xr-var-preview xr-preview'>0 1 2</div><input id='attrs-59136841-91db-4af0-8f17-77ed518035f3' class='xr-var-attrs-in' type='checkbox' disabled><label for='attrs-59136841-91db-4af0-8f17-77ed518035f3' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-c9ca5a65-8f5d-4b81-85a9-b33a97cdfaf2' class='xr-var-data-in' type='checkbox'><label for='data-c9ca5a65-8f5d-4b81-85a9-b33a97cdfaf2' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'></dl></div><div class='xr-var-data'><pre>array([0, 1, 2])</pre></div></li></ul></div></li><li class='xr-section-item'><input id='section-755e0e0a-1a96-43f7-b8cb-45f7b7eb1200' class='xr-section-summary-in' type='checkbox' checked /><label for='section-755e0e0a-1a96-43f7-b8cb-45f7b7eb1200' class='xr-section-summary' title='Expand/collapse section'>Data variables: <span>(4)</span></label><div class='xr-section-inline-details'></div><div class='xr-section-details'><ul class='xr-var-list'><li class='xr-var-item'><div class='xr-var-name'><span>advective_tendency</span></div><div class='xr-var-dims'>(x, y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>0.7948 0.6921 ... 0.5149 0.3452</div><input id='attrs-6ba4f376-ae28-46a3-8f50-da8cabfc5603' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-6ba4f376-ae28-46a3-8f50-da8cabfc5603' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-02238e4a-bff0-42a0-af00-71efa72a9677' class='xr-var-data-in' type='checkbox'><label for='data-02238e4a-bff0-42a0-af00-71efa72a9677' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>provenance :</span></dt><dd>advective_tendency</dd></dl></div><div class='xr-var-data'><pre>array([[0.79478668, 0.69205428, 0.39855605],\n",
|
|
610
|
+
" [0.47887945, 0.08594403, 0.63197551],\n",
|
|
611
|
+
" [0.57136049, 0.51491147, 0.34519876]])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>heat_rhs_sum_advection</span></div><div class='xr-var-dims'>(x, y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>0.7948 0.6921 ... 0.5149 0.3452</div><input id='attrs-1e02a9a6-24fe-4d21-9263-8c94db722782' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-1e02a9a6-24fe-4d21-9263-8c94db722782' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-d1560fbc-8b31-4e11-aa30-5b5fb8a00cdc' class='xr-var-data-in' type='checkbox'><label for='data-d1560fbc-8b31-4e11-aa30-5b5fb8a00cdc' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>provenance :</span></dt><dd>advective_tendency</dd></dl></div><div class='xr-var-data'><pre>array([[0.79478668, 0.69205428, 0.39855605],\n",
|
|
612
|
+
" [0.47887945, 0.08594403, 0.63197551],\n",
|
|
613
|
+
" [0.57136049, 0.51491147, 0.34519876]])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>heat_rhs_sum</span></div><div class='xr-var-dims'>(x, y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>0.7948 0.6921 ... 0.5149 0.3452</div><input id='attrs-3f1cac9e-c9cc-493e-a65e-d151b2f50f72' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-3f1cac9e-c9cc-493e-a65e-d151b2f50f72' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-680cd05e-dcc0-43cf-8602-5e8243f1d3df' class='xr-var-data-in' type='checkbox'><label for='data-680cd05e-dcc0-43cf-8602-5e8243f1d3df' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>provenance :</span></dt><dd>['heat_rhs_sum_advection']</dd></dl></div><div class='xr-var-data'><pre>array([[0.79478668, 0.69205428, 0.39855605],\n",
|
|
614
|
+
" [0.47887945, 0.08594403, 0.63197551],\n",
|
|
615
|
+
" [0.57136049, 0.51491147, 0.34519876]])</pre></div></li><li class='xr-var-item'><div class='xr-var-name'><span>heat_rhs</span></div><div class='xr-var-dims'>(x, y)</div><div class='xr-var-dtype'>float64</div><div class='xr-var-preview xr-preview'>0.7948 0.6921 ... 0.5149 0.3452</div><input id='attrs-0deff6ac-7188-434c-afe9-6852aa2b9c89' class='xr-var-attrs-in' type='checkbox' ><label for='attrs-0deff6ac-7188-434c-afe9-6852aa2b9c89' title='Show/Hide attributes'><svg class='icon xr-icon-file-text2'><use xlink:href='#icon-file-text2'></use></svg></label><input id='data-020cdf83-3b99-42e6-aeef-97bc3cbefad8' class='xr-var-data-in' type='checkbox'><label for='data-020cdf83-3b99-42e6-aeef-97bc3cbefad8' title='Show/Hide data repr'><svg class='icon xr-icon-database'><use xlink:href='#icon-database'></use></svg></label><div class='xr-var-attrs'><dl class='xr-attrs'><dt><span>provenance :</span></dt><dd>heat_rhs_sum</dd></dl></div><div class='xr-var-data'><pre>array([[0.79478668, 0.69205428, 0.39855605],\n",
|
|
616
|
+
" [0.47887945, 0.08594403, 0.63197551],\n",
|
|
617
|
+
" [0.57136049, 0.51491147, 0.34519876]])</pre></div></li></ul></div></li></ul></div></div>"
|
|
618
|
+
],
|
|
619
|
+
"text/plain": [
|
|
620
|
+
"<xarray.Dataset> Size: 336B\n",
|
|
621
|
+
"Dimensions: (x: 3, y: 3)\n",
|
|
622
|
+
"Coordinates:\n",
|
|
623
|
+
" * x (x) int64 24B 0 1 2\n",
|
|
624
|
+
" * y (y) int64 24B 0 1 2\n",
|
|
625
|
+
"Data variables:\n",
|
|
626
|
+
" advective_tendency (x, y) float64 72B 0.7948 0.6921 ... 0.5149 0.3452\n",
|
|
627
|
+
" heat_rhs_sum_advection (x, y) float64 72B 0.7948 0.6921 ... 0.5149 0.3452\n",
|
|
628
|
+
" heat_rhs_sum (x, y) float64 72B 0.7948 0.6921 ... 0.5149 0.3452\n",
|
|
629
|
+
" heat_rhs (x, y) float64 72B 0.7948 0.6921 ... 0.5149 0.3452"
|
|
630
|
+
]
|
|
631
|
+
},
|
|
632
|
+
"execution_count": 8,
|
|
633
|
+
"metadata": {},
|
|
634
|
+
"output_type": "execute_result"
|
|
635
|
+
}
|
|
636
|
+
],
|
|
637
|
+
"source": [
|
|
638
|
+
"ds"
|
|
639
|
+
]
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
"cell_type": "code",
|
|
643
|
+
"execution_count": 9,
|
|
644
|
+
"id": "78cde311",
|
|
645
|
+
"metadata": {},
|
|
646
|
+
"outputs": [],
|
|
647
|
+
"source": [
|
|
648
|
+
"ds = xr.Dataset({\n",
|
|
649
|
+
" \"advection\": xr.DataArray(np.ones((3, 3)), dims=(\"x\", \"y\")),\n",
|
|
650
|
+
"}, coords={\"x\": [0, 1, 2], \"y\": [0, 1, 2]})\n",
|
|
651
|
+
"\n",
|
|
652
|
+
"xbudget_dict = {\n",
|
|
653
|
+
" \"var\": None,\n",
|
|
654
|
+
" \"sum\": {\n",
|
|
655
|
+
" \"advection\": {\"var\": \"advection\"},\n",
|
|
656
|
+
" \"missing_var\": {\"var\": \"missing_var\"},\n",
|
|
657
|
+
" \"var\": None,\n",
|
|
658
|
+
" }\n",
|
|
659
|
+
"}"
|
|
660
|
+
]
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
"cell_type": "code",
|
|
664
|
+
"execution_count": 10,
|
|
665
|
+
"id": "332313b7",
|
|
666
|
+
"metadata": {},
|
|
667
|
+
"outputs": [
|
|
668
|
+
{
|
|
669
|
+
"data": {
|
|
670
|
+
"text/plain": [
|
|
671
|
+
"{'var': None,\n",
|
|
672
|
+
" 'sum': {'advection': {'var': 'advection'},\n",
|
|
673
|
+
" 'missing_var': {'var': 'missing_var'},\n",
|
|
674
|
+
" 'var': None}}"
|
|
675
|
+
]
|
|
676
|
+
},
|
|
677
|
+
"execution_count": 10,
|
|
678
|
+
"metadata": {},
|
|
679
|
+
"output_type": "execute_result"
|
|
680
|
+
}
|
|
681
|
+
],
|
|
682
|
+
"source": [
|
|
683
|
+
"xbudget_dict"
|
|
684
|
+
]
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
"cell_type": "code",
|
|
688
|
+
"execution_count": 13,
|
|
689
|
+
"id": "ca8803c0",
|
|
690
|
+
"metadata": {},
|
|
691
|
+
"outputs": [],
|
|
692
|
+
"source": [
|
|
693
|
+
"xbudget.budget_fill_dict(ds, xbudget_dict, \"heat_rhs\");"
|
|
694
|
+
]
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"cell_type": "code",
|
|
698
|
+
"execution_count": 14,
|
|
699
|
+
"id": "13153e2e",
|
|
700
|
+
"metadata": {},
|
|
701
|
+
"outputs": [
|
|
702
|
+
{
|
|
703
|
+
"data": {
|
|
704
|
+
"text/plain": [
|
|
705
|
+
"{'var': 'heat_rhs',\n",
|
|
706
|
+
" 'sum': {'advection': {'var': 'advection'},\n",
|
|
707
|
+
" 'missing_var': {'var': 'missing_var'},\n",
|
|
708
|
+
" 'var': 'heat_rhs_sum'}}"
|
|
709
|
+
]
|
|
710
|
+
},
|
|
711
|
+
"execution_count": 14,
|
|
712
|
+
"metadata": {},
|
|
713
|
+
"output_type": "execute_result"
|
|
714
|
+
}
|
|
715
|
+
],
|
|
716
|
+
"source": [
|
|
717
|
+
"xbudget_dict"
|
|
718
|
+
]
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
"cell_type": "code",
|
|
722
|
+
"execution_count": null,
|
|
723
|
+
"id": "45a6dd62",
|
|
724
|
+
"metadata": {},
|
|
725
|
+
"outputs": [],
|
|
726
|
+
"source": []
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
"metadata": {
|
|
730
|
+
"kernelspec": {
|
|
731
|
+
"display_name": "docs_env_xbudget",
|
|
732
|
+
"language": "python",
|
|
733
|
+
"name": "python3"
|
|
734
|
+
},
|
|
735
|
+
"language_info": {
|
|
736
|
+
"codemirror_mode": {
|
|
737
|
+
"name": "ipython",
|
|
738
|
+
"version": 3
|
|
739
|
+
},
|
|
740
|
+
"file_extension": ".py",
|
|
741
|
+
"mimetype": "text/x-python",
|
|
742
|
+
"name": "python",
|
|
743
|
+
"nbconvert_exporter": "python",
|
|
744
|
+
"pygments_lexer": "ipython3",
|
|
745
|
+
"version": "3.12.0"
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
"nbformat": 4,
|
|
749
|
+
"nbformat_minor": 5
|
|
750
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from xbudget.presets import load_yaml
|
|
5
|
+
|
|
6
|
+
def test_load_all_convention_presets():
|
|
7
|
+
"""Test that all convention YAML files can be loaded successfully."""
|
|
8
|
+
conventions_dir = Path(__file__).parent.parent / "conventions"
|
|
9
|
+
yaml_files = sorted(conventions_dir.glob("*.yaml"))
|
|
10
|
+
|
|
11
|
+
assert len(yaml_files) > 0, "No YAML files found in conventions directory"
|
|
12
|
+
|
|
13
|
+
for yaml_file in yaml_files:
|
|
14
|
+
preset_dict = load_yaml(str(yaml_file))
|
|
15
|
+
assert isinstance(preset_dict, dict), f"Failed to load {yaml_file.name} as dictionary"
|
|
16
|
+
assert len(preset_dict) > 0, f"Loaded preset {yaml_file.name} is empty"
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import numpy as np
|
|
3
|
+
import xarray as xr
|
|
4
|
+
import copy
|
|
5
|
+
from xbudget.collect import (
|
|
6
|
+
aggregate,
|
|
7
|
+
disaggregate,
|
|
8
|
+
deep_search,
|
|
9
|
+
_deep_search,
|
|
10
|
+
collect_budgets,
|
|
11
|
+
budget_fill_dict,
|
|
12
|
+
get_vars,
|
|
13
|
+
_get_vars,
|
|
14
|
+
flatten,
|
|
15
|
+
flatten_lol,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestDisaggregate:
|
|
20
|
+
"""Test the disaggregate function"""
|
|
21
|
+
|
|
22
|
+
def test_disaggregate_basic(self):
|
|
23
|
+
"""Test basic disaggregation without decompose"""
|
|
24
|
+
b = {
|
|
25
|
+
"sum": {
|
|
26
|
+
"advection": {"var": "advective_tendency"},
|
|
27
|
+
"var": "heat_rhs_sum",
|
|
28
|
+
},
|
|
29
|
+
"var": "heat_rhs",
|
|
30
|
+
}
|
|
31
|
+
result = disaggregate(b)
|
|
32
|
+
assert result == {"advection": "advective_tendency"}
|
|
33
|
+
|
|
34
|
+
def test_disaggregate_with_decompose(self):
|
|
35
|
+
"""Test disaggregation with decompose parameter"""
|
|
36
|
+
b = {
|
|
37
|
+
"sum": {
|
|
38
|
+
"advection": {
|
|
39
|
+
"var": "advective_tendency",
|
|
40
|
+
"sum": {
|
|
41
|
+
"horizontal": {"var": "advective_tendency_h"},
|
|
42
|
+
"vertical": {"var": "advective_tendency_v"},
|
|
43
|
+
"var": "heat_rhs_sum_advection_sum",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
"var": "heat_rhs_sum",
|
|
47
|
+
},
|
|
48
|
+
"var": "heat_rhs",
|
|
49
|
+
}
|
|
50
|
+
result = disaggregate(b, decompose="advection")
|
|
51
|
+
assert result == {
|
|
52
|
+
"advection": {
|
|
53
|
+
"horizontal": "advective_tendency_h",
|
|
54
|
+
"vertical": "advective_tendency_v",
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
def test_disaggregate_no_sum(self):
|
|
59
|
+
"""Test disaggregation when no sum key exists"""
|
|
60
|
+
b = {"var": "some_variable"}
|
|
61
|
+
result = disaggregate(b)
|
|
62
|
+
assert result == {"var": "some_variable"}
|
|
63
|
+
|
|
64
|
+
def test_disaggregate_with_none_values(self):
|
|
65
|
+
"""Test disaggregation ignores None values"""
|
|
66
|
+
b = {
|
|
67
|
+
"sum": {
|
|
68
|
+
"advection": {"var": "advective_tendency"},
|
|
69
|
+
"diffusion": None,
|
|
70
|
+
"var": "heat_rhs_sum",
|
|
71
|
+
},
|
|
72
|
+
"var": "heat_rhs",
|
|
73
|
+
}
|
|
74
|
+
result = disaggregate(b)
|
|
75
|
+
assert "diffusion" not in result
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class TestDeepSearch:
|
|
79
|
+
"""Test the deep_search and _deep_search functions"""
|
|
80
|
+
|
|
81
|
+
def test_deep_search_simple_dict(self):
|
|
82
|
+
"""Test deep_search with simple nested dictionary"""
|
|
83
|
+
b = {"advection": "advective_tendency"}
|
|
84
|
+
result = deep_search(b)
|
|
85
|
+
assert result == {"advection": "advective_tendency"}
|
|
86
|
+
|
|
87
|
+
def test_deep_search_nested_dict(self):
|
|
88
|
+
"""Test deep_search with deeply nested dictionary"""
|
|
89
|
+
b = {
|
|
90
|
+
"advection": {
|
|
91
|
+
"horizontal": "advective_tendency_h",
|
|
92
|
+
"vertical": "advective_tendency_v",
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
result = deep_search(b)
|
|
96
|
+
assert result == {
|
|
97
|
+
"advection_horizontal": "advective_tendency_h",
|
|
98
|
+
"advection_vertical": "advective_tendency_v",
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
def test_deep_search_string_input(self):
|
|
102
|
+
"""Test deep_search with string input"""
|
|
103
|
+
result = deep_search("variable_name")
|
|
104
|
+
assert result == None
|
|
105
|
+
|
|
106
|
+
def test_deep_search_complex_nesting(self):
|
|
107
|
+
"""Test deep_search with complex nested structure"""
|
|
108
|
+
b = {
|
|
109
|
+
"heat": {
|
|
110
|
+
"rhs": {
|
|
111
|
+
"advection": {
|
|
112
|
+
"horizontal": "adv_h",
|
|
113
|
+
"vertical": "adv_v",
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
result = deep_search(b)
|
|
119
|
+
assert result == {
|
|
120
|
+
"heat_rhs_advection_horizontal": "adv_h",
|
|
121
|
+
"heat_rhs_advection_vertical": "adv_v",
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class TestAggregate:
|
|
126
|
+
"""Test the aggregate function"""
|
|
127
|
+
|
|
128
|
+
def test_aggregate_basic(self):
|
|
129
|
+
"""Test basic aggregation"""
|
|
130
|
+
xbudget_dict = {
|
|
131
|
+
"heat": {
|
|
132
|
+
"rhs": {
|
|
133
|
+
"sum": {
|
|
134
|
+
"advection": {"var": "advective_tendency"},
|
|
135
|
+
"var": "heat_rhs_sum",
|
|
136
|
+
},
|
|
137
|
+
"var": "heat_rhs",
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
result = aggregate(xbudget_dict)
|
|
142
|
+
assert result["heat"]["rhs"] == {"advection": "advective_tendency"}
|
|
143
|
+
|
|
144
|
+
def test_aggregate_with_decompose(self):
|
|
145
|
+
"""Test aggregation with decompose parameter"""
|
|
146
|
+
xbudget_dict = {
|
|
147
|
+
"heat": {
|
|
148
|
+
"rhs": {
|
|
149
|
+
"sum": {
|
|
150
|
+
"advection": {
|
|
151
|
+
"var": "advective_tendency",
|
|
152
|
+
"sum": {
|
|
153
|
+
"horizontal": {"var": "advective_tendency_h"},
|
|
154
|
+
"vertical": {"var": "advective_tendency_v"},
|
|
155
|
+
"var": "heat_rhs_sum_advection_sum",
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
"var": "heat_rhs_sum",
|
|
159
|
+
},
|
|
160
|
+
"var": "heat_rhs",
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
result = aggregate(xbudget_dict, decompose="advection")
|
|
165
|
+
assert "advection_horizontal" in result["heat"]["rhs"]
|
|
166
|
+
assert "advection_vertical" in result["heat"]["rhs"]
|
|
167
|
+
|
|
168
|
+
def test_aggregate_doesnt_modify_original(self):
|
|
169
|
+
"""Test that aggregate doesn't modify the original dictionary"""
|
|
170
|
+
xbudget_dict = {
|
|
171
|
+
"heat": {
|
|
172
|
+
"rhs": {
|
|
173
|
+
"sum": {
|
|
174
|
+
"advection": {"var": "advective_tendency"},
|
|
175
|
+
"var": "heat_rhs_sum",
|
|
176
|
+
},
|
|
177
|
+
"var": "heat_rhs",
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
original_copy = copy.deepcopy(xbudget_dict)
|
|
182
|
+
aggregate(xbudget_dict)
|
|
183
|
+
assert xbudget_dict == original_copy
|
|
184
|
+
|
|
185
|
+
def test_aggregate_with_both_lhs_rhs(self):
|
|
186
|
+
"""Test aggregation with both lhs and rhs"""
|
|
187
|
+
xbudget_dict = {
|
|
188
|
+
"heat": {
|
|
189
|
+
"lhs": {
|
|
190
|
+
"sum": {
|
|
191
|
+
"tendency": {"var": "tendency_var"},
|
|
192
|
+
"var": "heat_lhs_sum",
|
|
193
|
+
},
|
|
194
|
+
"var": "heat_lhs",
|
|
195
|
+
},
|
|
196
|
+
"rhs": {
|
|
197
|
+
"sum": {
|
|
198
|
+
"advection": {"var": "advective_tendency"},
|
|
199
|
+
"var": "heat_rhs_sum",
|
|
200
|
+
},
|
|
201
|
+
"var": "heat_rhs",
|
|
202
|
+
},
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
result = aggregate(xbudget_dict)
|
|
206
|
+
assert "tendency" in result["heat"]["lhs"]
|
|
207
|
+
assert "advection" in result["heat"]["rhs"]
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class TestGetVars:
|
|
211
|
+
"""Test the get_vars and _get_vars functions"""
|
|
212
|
+
|
|
213
|
+
def test_get_vars_simple(self):
|
|
214
|
+
"""Test get_vars with simple variable"""
|
|
215
|
+
xbudget_dict = {
|
|
216
|
+
"heat": {
|
|
217
|
+
"rhs": {
|
|
218
|
+
"sum": {
|
|
219
|
+
"advection": {"var": "advective_tendency"},
|
|
220
|
+
"var": "heat_rhs_sum",
|
|
221
|
+
},
|
|
222
|
+
"var": "heat_rhs",
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
result = get_vars(xbudget_dict, "advective_tendency")
|
|
227
|
+
assert result["var"] == "advective_tendency"
|
|
228
|
+
|
|
229
|
+
def test_get_vars_list_input(self):
|
|
230
|
+
"""Test get_vars with list of terms"""
|
|
231
|
+
xbudget_dict = {
|
|
232
|
+
"heat": {
|
|
233
|
+
"rhs": {
|
|
234
|
+
"sum": {
|
|
235
|
+
"advection": {"var": "advective_tendency"},
|
|
236
|
+
"diffusion": {"var": "diffusive_tendency"},
|
|
237
|
+
"var": "heat_rhs_sum",
|
|
238
|
+
},
|
|
239
|
+
"var": "heat_rhs",
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
result = get_vars(xbudget_dict, ["advective_tendency", "diffusive_tendency"])
|
|
244
|
+
assert isinstance(result, list)
|
|
245
|
+
assert len(result) == 2
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class TestFlatten:
|
|
249
|
+
"""Test the flatten and flatten_lol functions"""
|
|
250
|
+
|
|
251
|
+
def test_flatten_simple_list(self):
|
|
252
|
+
"""Test flatten with simple list"""
|
|
253
|
+
result = list(flatten([1, 2, 3]))
|
|
254
|
+
assert result == [1, 2, 3]
|
|
255
|
+
|
|
256
|
+
def test_flatten_nested_lists(self):
|
|
257
|
+
"""Test flatten with nested lists"""
|
|
258
|
+
result = list(flatten([1, [2, 3], 4]))
|
|
259
|
+
assert result == [1, 2, 3, 4]
|
|
260
|
+
|
|
261
|
+
def test_flatten_deeply_nested(self):
|
|
262
|
+
"""Test flatten with deeply nested lists"""
|
|
263
|
+
result = list(flatten([1, [2, [3, 4]], 5]))
|
|
264
|
+
assert result == [1, 2, 3, 4, 5]
|
|
265
|
+
|
|
266
|
+
def test_flatten_lol_simple(self):
|
|
267
|
+
"""Test flatten_lol with simple list of lists"""
|
|
268
|
+
result = flatten_lol([[1, 2], [3, 4]])
|
|
269
|
+
assert result == [1, 2, 3, 4]
|
|
270
|
+
|
|
271
|
+
def test_flatten_lol_mixed(self):
|
|
272
|
+
"""Test flatten_lol with mixed nesting"""
|
|
273
|
+
result = flatten_lol([[1, [2, 3]], [4, 5]])
|
|
274
|
+
assert result == [1, 2, 3, 4, 5]
|
|
275
|
+
|
|
276
|
+
def test_flatten_lol_empty(self):
|
|
277
|
+
"""Test flatten_lol with empty list"""
|
|
278
|
+
result = flatten_lol([])
|
|
279
|
+
assert result == []
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class TestCollectBudgets:
|
|
283
|
+
"""Test the collect_budgets function"""
|
|
284
|
+
|
|
285
|
+
def test_collect_budgets_basic(self):
|
|
286
|
+
"""Test basic budget collection"""
|
|
287
|
+
ds = xr.Dataset({
|
|
288
|
+
"forcing_diag": xr.DataArray(np.random.rand(3, 3), dims=("x", "y")),
|
|
289
|
+
}, coords={"x": [0, 1, 2], "y": [0, 1, 2]})
|
|
290
|
+
|
|
291
|
+
xbudget_dict = {
|
|
292
|
+
"heat": {
|
|
293
|
+
"rhs": {
|
|
294
|
+
"sum": {
|
|
295
|
+
"forcing": {"var": "forcing_diag"},
|
|
296
|
+
"var": None,
|
|
297
|
+
},
|
|
298
|
+
"var": None,
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
collect_budgets(ds, xbudget_dict)
|
|
304
|
+
assert "heat_rhs_sum_forcing" in ds
|
|
305
|
+
assert "heat_rhs_sum" in ds
|
|
306
|
+
assert "heat_rhs" in ds
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def test_collect_budgets_with_lhs_rhs(self):
|
|
310
|
+
"""Test budget collection with both lhs and rhs"""
|
|
311
|
+
ds = xr.Dataset({
|
|
312
|
+
"tendency_diag": xr.DataArray(np.random.rand(3, 3), dims=("x", "y")),
|
|
313
|
+
"forcing_diag": xr.DataArray(np.random.rand(3, 3), dims=("x", "y")),
|
|
314
|
+
}, coords={"x": [0, 1, 2], "y": [0, 1, 2]})
|
|
315
|
+
|
|
316
|
+
xbudget_dict = {
|
|
317
|
+
"heat": {
|
|
318
|
+
"lhs": {
|
|
319
|
+
"sum": {
|
|
320
|
+
"tendency": {"var": "tendency_diag"},
|
|
321
|
+
"var": None,
|
|
322
|
+
},
|
|
323
|
+
"var": None,
|
|
324
|
+
},
|
|
325
|
+
"rhs": {
|
|
326
|
+
"sum": {
|
|
327
|
+
"advection": {"var": "forcing_diag"},
|
|
328
|
+
"var": None,
|
|
329
|
+
},
|
|
330
|
+
"var": None,
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
collect_budgets(ds, xbudget_dict)
|
|
336
|
+
assert "heat_lhs" in ds
|
|
337
|
+
assert "heat_rhs" in ds
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
class TestBudgetFillDict:
|
|
341
|
+
"""Test the budget_fill_dict function"""
|
|
342
|
+
|
|
343
|
+
def test_budget_fill_dict_sum_operation(self):
|
|
344
|
+
"""Test budget_fill_dict with sum operation"""
|
|
345
|
+
ds = xr.Dataset({
|
|
346
|
+
"advection": xr.DataArray(np.ones((3, 3)), dims=("x", "y")),
|
|
347
|
+
"diffusion": xr.DataArray(np.ones((3, 3)), dims=("x", "y")),
|
|
348
|
+
}, coords={"x": [0, 1, 2], "y": [0, 1, 2]})
|
|
349
|
+
|
|
350
|
+
xbudget_dict = {
|
|
351
|
+
"var": None,
|
|
352
|
+
"sum": {
|
|
353
|
+
"advection": {"var": "advection"},
|
|
354
|
+
"diffusion": {"var": "diffusion"},
|
|
355
|
+
"var": None,
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
result = budget_fill_dict(ds, xbudget_dict, "heat_rhs")
|
|
360
|
+
assert result is not None
|
|
361
|
+
assert "heat_rhs_sum" in ds
|
|
362
|
+
|
|
363
|
+
def test_budget_fill_dict_product_operation(self):
|
|
364
|
+
"""Test budget_fill_dict with product operation"""
|
|
365
|
+
ds = xr.Dataset({
|
|
366
|
+
"coeff": xr.DataArray(2.0 * np.ones((3, 3)), dims=("x", "y")),
|
|
367
|
+
"var": xr.DataArray(3.0 * np.ones((3, 3)), dims=("x", "y")),
|
|
368
|
+
}, coords={"x": [0, 1, 2], "y": [0, 1, 2]})
|
|
369
|
+
|
|
370
|
+
xbudget_dict = {
|
|
371
|
+
"var": None,
|
|
372
|
+
"product": {
|
|
373
|
+
"coeff": {"var": "coeff"},
|
|
374
|
+
"var_part": {"var": "var"},
|
|
375
|
+
"var": None,
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
result = budget_fill_dict(ds, xbudget_dict, "heat_rhs")
|
|
380
|
+
assert result is not None
|
|
381
|
+
assert "heat_rhs_product" in ds
|
|
382
|
+
# Check that product is correct (2.0 * 3.0 = 6.0)
|
|
383
|
+
assert np.allclose(ds["heat_rhs_product"].values, 6.0)
|
|
384
|
+
|
|
385
|
+
def test_budget_fill_dict_missing_variable_warning(self):
|
|
386
|
+
"""Test that missing variables generate warnings"""
|
|
387
|
+
ds = xr.Dataset({
|
|
388
|
+
"advection": xr.DataArray(np.ones((3, 3)), dims=("x", "y")),
|
|
389
|
+
}, coords={"x": [0, 1, 2], "y": [0, 1, 2]})
|
|
390
|
+
|
|
391
|
+
xbudget_dict = {
|
|
392
|
+
"var": None,
|
|
393
|
+
"sum": {
|
|
394
|
+
"advection": {"var": "advection"},
|
|
395
|
+
"missing_var": {"var": "missing_var"},
|
|
396
|
+
"var": None,
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
with pytest.warns(UserWarning):
|
|
401
|
+
budget_fill_dict(ds, xbudget_dict, "heat_rhs")
|
|
402
|
+
|
|
403
|
+
def test_budget_fill_dict_numeric_values(self):
|
|
404
|
+
"""Test budget_fill_dict with numeric values"""
|
|
405
|
+
ds = xr.Dataset({
|
|
406
|
+
"var": xr.DataArray(np.ones((3, 3)), dims=("x", "y")),
|
|
407
|
+
}, coords={"x": [0, 1, 2], "y": [0, 1, 2]})
|
|
408
|
+
|
|
409
|
+
xbudget_dict = {
|
|
410
|
+
"var": None,
|
|
411
|
+
"product": {
|
|
412
|
+
"factor": 2.0,
|
|
413
|
+
"var_part": {"var": "var"},
|
|
414
|
+
"var": None,
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
result = budget_fill_dict(ds, xbudget_dict, "heat_rhs")
|
|
419
|
+
assert result is not None
|
|
420
|
+
assert np.allclose(ds["heat_rhs_product"].values, 2.0)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|