Skip to content

Commit 1a9b0f8

Browse files
authored
Add material about escape hatches (#333)
* reword * escape hatches and a exercise * replace `xr.ufuncs.log` with `np.log` * add tags
1 parent 4231740 commit 1a9b0f8

File tree

1 file changed

+80
-7
lines changed

1 file changed

+80
-7
lines changed

intermediate/hierarchical_computation.ipynb

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,26 +137,28 @@
137137
"source": [
138138
"## Applying functions designed for `Dataset` with `map_over_datasets`\n",
139139
"\n",
140-
"What if we wanted to convert the data to log-space? For a `Dataset` or `DataArray`, we could just use {py:func}`xarray.ufuncs.log`, but that does not support `DataTree` objects, yet:"
140+
"What if we wanted to apply a element-wise function, for example to convert the data to log-space? For a `DataArray` we could just use {py:func}`numpy.log`, but this is not supported for `DataTree` objects:"
141141
]
142142
},
143143
{
144144
"cell_type": "code",
145145
"execution_count": null,
146146
"id": "12",
147-
"metadata": {},
147+
"metadata": {
148+
"tags": [
149+
"raises-exception"
150+
]
151+
},
148152
"outputs": [],
149153
"source": [
150-
"xr.ufuncs.log(tree)"
154+
"np.log(tree)"
151155
]
152156
},
153157
{
154158
"cell_type": "markdown",
155159
"id": "13",
156160
"metadata": {},
157161
"source": [
158-
"Note how the result is a empty `Dataset`?\n",
159-
"\n",
160162
"To map a function to all nodes, we can use {py:func}`xarray.map_over_datasets` and {py:meth}`xarray.DataTree.map_over_datasets`: "
161163
]
162164
},
@@ -203,8 +205,7 @@
203205
"id": "18",
204206
"metadata": {
205207
"tags": [
206-
"raises-exception",
207-
"hide-output"
208+
"raises-exception"
208209
]
209210
},
210211
"outputs": [],
@@ -235,6 +236,78 @@
235236
"\n",
236237
"tree.map_over_datasets(demean)"
237238
]
239+
},
240+
{
241+
"cell_type": "markdown",
242+
"id": "21",
243+
"metadata": {},
244+
"source": [
245+
"## Escape hatches\n",
246+
"\n",
247+
"For some more complex operations, it might make sense to work on {py:class}`xarray.Dataset` or {py:class}`xarray.DataArray` objects and reassemble the tree afterwards.\n",
248+
"\n",
249+
"Let's look at a new dataset:"
250+
]
251+
},
252+
{
253+
"cell_type": "code",
254+
"execution_count": null,
255+
"id": "22",
256+
"metadata": {},
257+
"outputs": [],
258+
"source": [
259+
"precipitation = xr.tutorial.open_datatree(\"precipitation.nc4\").load()\n",
260+
"precipitation"
261+
]
262+
},
263+
{
264+
"cell_type": "markdown",
265+
"id": "23",
266+
"metadata": {},
267+
"source": [
268+
"Suppose we wanted to interpolate the observed precipitation to the modelled precipitation. We could use `map_over_datasets` for this, but we can also have a bit more control:"
269+
]
270+
},
271+
{
272+
"cell_type": "code",
273+
"execution_count": null,
274+
"id": "24",
275+
"metadata": {},
276+
"outputs": [],
277+
"source": [
278+
"interpolated = xr.DataTree.from_dict(\n",
279+
" {\n",
280+
" \"/\": precipitation.ds,\n",
281+
" \"/observed\": precipitation[\"/observed\"].ds.interp(\n",
282+
" lat=precipitation[\"/reanalysis/lat\"],\n",
283+
" lon=precipitation[\"/reanalysis/lon\"],\n",
284+
" ),\n",
285+
" \"/reanalysis\": precipitation[\"/reanalysis\"],\n",
286+
" }\n",
287+
")\n",
288+
"interpolated"
289+
]
290+
},
291+
{
292+
"cell_type": "markdown",
293+
"id": "25",
294+
"metadata": {},
295+
"source": [
296+
"::::{admonition} Exercise\n",
297+
":class: tip\n",
298+
"Compute the difference between total observed and modelled precipitation, and plot the result.\n",
299+
"\n",
300+
":::{admonition} Solution\n",
301+
":class: dropdown\n",
302+
"\n",
303+
"```python\n",
304+
"total = precipitation.sum(dim=[\"lon\", \"lat\"])\n",
305+
"difference = total[\"/observed/precipitation\"] - total[\"/reanalysis/precipitation\"]\n",
306+
"difference.plot()\n",
307+
"```\n",
308+
":::\n",
309+
"::::\n"
310+
]
238311
}
239312
],
240313
"metadata": {

0 commit comments

Comments
 (0)