Skip to content

Commit

Permalink
Improve wording of Sec_05_RegionExtraction.ipynb
Browse files Browse the repository at this point in the history
  • Loading branch information
BHFock committed Mar 31, 2023
1 parent 0a8e16b commit b61ed6b
Showing 1 changed file with 81 additions and 95 deletions.
176 changes: 81 additions & 95 deletions notebooks/Sec_05_RegionExtraction.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,90 +7,83 @@
"source": [
"# Section 5: Extracting a region from mesh-based data\n",
"\n",
"This process is considerably more involved than with \"structured\" data like UM.\n",
"This section demonstrates regional extraction from a global mesh. This process is considerably more involved than with \"structured\" data like UM. For instance, UM data has data and coordinates with X and Y dimensions, corresponding to cell indices in the model arrays, and longitudes and latitudes of cells on the globe. Therefore, we can slice out a rectangular range of X and Y indices, e.g. my_datacube[..., 10:40, 4:77], and the result is some contiguous region of the globe within a defined range of latitude and longitude. The unstructured mesh does not visit locations on the globe in any particular, simple regular pattern. So crucially, a slice of data from the (now 1-D) arrays is not a contiguous geographical region as a contiguous region of the data is generally not contained in a contiguous range of data indices. See the [diagram](./LFRic_mesh.svg) from Section 02 showing numbering of nodes and faces around an LFRic cubesphere corner.\n",
"\n",
"For instance, UM data has data and coordinates with X and Y dimensions, corresponding to cell indices in the model arrays, and longitudes and latitudes of cells on the globe. \n",
"Therefore, we can slice out a rectangular range of X and Y indices, e.g. `my_datacube[..., 10:40, 4:77]` and the result is some contiguous region of the globe within a defined range of latitude+longitude.\n",
"GeoVista supports the needed geographical calculations to extract mesh data within a required region. Here's an example of how to extract the mesh falling within a defined lat-lon region. As with the plotting example, there are no Iris utility functions for this, so user code is currently required to mediate between the Iris and Geovista/PyVista worlds.\n",
"\n",
"However, the unstructured mesh does not visit locations on the globe in any particular, simple regular pattern. So crucially, a slice of data from the (now 1-D) arrays is not a contiguous geographical region. And conversely a contiguous region of the data is generally not contained in a contiguous range of data indices. \n",
"***For a demonstration of that:*** see the previous diagram showing numbering of nodes+faces around an LFRic cubesphere corner, [here](./LFRic_mesh.svg).\n",
"\n",
"---\n",
"\n",
"So, we must use geographical calculations to extract mesh data within a required region. \n",
"Since this is a geographical concept, Geovista provides support for it. \n",
"This is also a good match since, with larger data this can become quite compute-intensive:\n",
"Processing via VTK should be performant and scalable, and can benefit from GPU acceleration.\n",
"\n",
"Here's an example of how to extract the mesh falling within a defined lat-lon region ... \n",
"**NOTE: as with the plotting example, there are no Iris utility functions for this, so a fair amount of user code is currently required to mediate between the Iris and Geovista/PyVista worlds.**"
"## Load unstructured data and create Polydata object\n"
]
},
{
"cell_type": "markdown",
"id": "3a175eb0-8956-4754-ac89-f554250afd7f",
"metadata": {},
"source": [
"---\n",
"\n",
"**First, import the utility function `lfric_rh_datacube` from `testdata_fetching`, and call it to get a global LFRic test cube.**"
"Firts load some global LFRic data with the utility function `lfric_rh_datacube` from `testdata_fetching`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0d189559-f75e-4872-a4bb-6509393c4394",
"metadata": {},
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from testdata_fetching import lfric_rh_singletime_2d\n",
"lfric_rh = lfric_rh_singletime_2d()\n",
"lfric_rh"
"#lfric_rh"
]
},
{
"cell_type": "markdown",
"id": "fe96bfb8-1dda-43ef-83bc-8e06c360e6bd",
"metadata": {},
"source": [
"**Create a Polydata object from this.** \n",
"Use the routine `pv_from_lfric_cube` from the package `pv_conversions`, which we used in the plotting section."
"As in the plotting [Section 03](./Sec_03_Plotting.ipynb) we create a Polydata object from the cube using the routine `pv_from_lfric_cube` from the package [pv_conversions](pv_conversions.py): "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "db0280ff-3ebd-42c9-a9eb-8f9c8117eeee",
"metadata": {
"lines_to_next_cell": 2
"lines_to_next_cell": 2,
"tags": []
},
"outputs": [],
"source": [
"from pv_conversions import pv_from_lfric_cube\n",
"pv_global_rh = pv_from_lfric_cube(lfric_rh)"
"pv_global_rh = pv_from_lfric_cube(lfric_rh)\n",
"#pv_global_rh"
]
},
{
"cell_type": "markdown",
"id": "d9ee71c7-e3cc-4479-aea9-2972c0424bd5",
"id": "d913e13d-6e3b-4608-a3e3-8e605fe2b797",
"metadata": {},
"source": [
"## Create a 'BBox' tool to extract over a desired region."
"Uncommenting `lfric_rh` and `pv_global_rh` in the cells above allows you to print the loaded and converted data. "
]
},
{
"cell_type": "markdown",
"id": "9b3b61bc-d827-4faf-93ee-637a020cd496",
"id": "d9ee71c7-e3cc-4479-aea9-2972c0424bd5",
"metadata": {},
"source": [
"**Import the class `BBox` from `geovista.geodesic`, and make one...** "
"## Enclose PolyData object in Bounding Box\n",
"\n",
"Next import the needed GeoVista class `BBox` (short name for \"Bounding Box\"):"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2e7b1bd1-f126-4900-a8bc-a56e4c98dca6",
"metadata": {},
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from geovista.geodesic import BBox"
Expand All @@ -101,9 +94,7 @@
"id": "01602100-f556-475a-a470-f7459a04371a",
"metadata": {},
"source": [
"Note: the name here is short for \"Bounding Box\".\n",
"\n",
"**Use the notebook \"?\" command to display the function signature of its constructor: `?BBox.__init__`**"
"You can use the notebook \"?\" command to display the function signature of its constructor"
]
},
{
Expand All @@ -121,130 +112,125 @@
"id": "96e6e603-94c0-48c8-85d2-0f397bca9010",
"metadata": {},
"source": [
"---\n",
"\n",
"**Create a BBox to specify a bounding rectangle in lat-lon space.** \n",
"Give it `lons` and `lats` arguments which specify the points of a bounding rectangle,\n",
"in lat-lon space, from 0..70 in longitude and -24..+45 in latitude. \n",
"( *Note:* do ***not*** supply a duplicate 'end' point -- a closed loop is automatically generated. )"
"Give the function `BBox` the arguments `lons` and `lats` which specify the points of a bounding rectangle:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "22f13977-864b-4c49-be0d-5d6e158bbd9e",
"metadata": {},
"id": "e1e70deb-6840-4a92-b40e-d5e9608bd07c",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"bbox = BBox(lons=[0, 70, 70, 0], lats=[-25, -25, 45, 45])"
"lon_min = -15\n",
"lon_max = 55\n",
"lat_min = -5\n",
"lat_max = 35\n",
"\n",
"bbox = BBox(lons=[lon_min, lon_max, lon_max, lon_min], lats=[lat_min, lat_min, lat_max, lat_max])"
]
},
{
"cell_type": "markdown",
"id": "32c47cdb-477d-4f0c-87e1-2f7c960163b3",
"metadata": {},
"source": [
"---\n",
"\n",
"## Apply the BBox to data\n",
"Operate on the global mesh data, by passing it to the `BBox.enclosed` method.** \n",
"And show the resulting object printout."
"To apply the BBox to data we pass the PolyData object to the `enclosed` method of the Bounding Box: "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f7dfaa88-43d6-4f4e-8f40-ce4ff4a594d4",
"metadata": {},
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# 'Apply' the region to the PolyData object.\n",
"pv_regional_rh = bbox.enclosed(pv_global_rh)\n",
"pv_regional_rh"
"#print(pv_regional_rh)"
]
},
{
"cell_type": "markdown",
"id": "75c46a22-6b43-433c-bf00-505214b46760",
"metadata": {
"tags": []
},
"source": [
"Uncomment the last line to print the enclsoed PolyData object `pv_regional_rh`. Compared to the global PolyData object `pv_global_rh` it has a smaller number of cells."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "af23f91c-e501-4dec-bdd6-17e8e4bf10b3",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"print(pv_global_rh)"
]
},
{
"cell_type": "markdown",
"id": "0ad463e2-f480-44fd-b3f5-9e325e039c1a",
"metadata": {},
"source": [
"You can see that this new (regional) PolyData has fewer cells than the original (global) one.\n",
"\n",
"---\n",
"### Plot extracted region\n",
"\n",
"### Plot this to see what it looks like.\n",
"Note: in this case, it will be very useful to add coastlines for reference.\n",
"Use the techniques from [Sec#2 Plotting - Additional features](./Sec_03_Plotting.ipynb#Additional-features)."
"We are now plotting the extracted region and are adding coastlines (see [Sec_02 Plotting - Additional features](./Sec_03_Plotting.ipynb#Additional-features)) for reference:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6661ad89-859e-4fc0-a56a-461abef6b4bb",
"metadata": {},
"id": "5338d0e5-68fd-4c3e-a1dc-dfe8d7c0ce2c",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"lon_min = -15\n",
"lon_max = 55\n",
"lat_min = -5\n",
"lat_max = 35\n",
"\n",
"\n",
"bbox = BBox(lons=[lon_min, lon_max, lon_max, lon_min], \n",
" lats=[lat_min, lat_min, lat_max, lat_max])\n",
"\n",
"pv_regional_rh = bbox.enclosed(pv_global_rh) \n",
"\n",
"from geovista import GeoPlotter\n",
"plotter = GeoPlotter()\n",
"plotter.add_mesh(pv_regional_rh)\n",
"plotter.add_coastlines()\n",
"plotter.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ac098bbe-7773-43cb-916f-e17134775989",
"metadata": {},
"outputs": [],
"source": [
"# Additional : static plot for notebook review\n",
"plotter.show(jupyter_backend='static')"
]
},
{
"cell_type": "markdown",
"id": "89030e96-2e30-40c7-bb97-ccf0af044d94",
"metadata": {},
"source": [
"---\n",
"## Get an Iris cube for an extracted region.\n",
"\n",
"While GeoVista provides the efficient tools for mesh region extraction, it and Iris know nothing about one another. \n",
"So, to calculate a regionally-extracted _Iris cube_, GeoVista can do the hard work of determining the subset of cells required, but you must then \"reconstruct\" an Iris cube from that information.\n",
"\n",
"For now, at least, there are no ready-made tools for this (in either Iris or Geovista). \n",
"\n",
"However, the operation is possible, and may be instructive. \n",
"So, for those interested, there is an extra notebook [\"MeshCube_Extraction.ipynb\"](./MeshCube_Extraction.ipynb), showing how this is done.\n"
"While GeoVista provides the efficient tools for mesh region extraction, it and Iris know nothing about one another. So, to calculate a regionally-extracted Iris cube, GeoVista can do the hard work of determining the subset of cells required, but you must then reconstruct an Iris cube from that information. For now, at least, there are no ready-made tools for this (in either Iris or Geovista). However, the operation is possible, and may be instructive. So, for those interested, there is an extra notebook [\"MeshCube_Extraction.ipynb\"](./MeshCube_Extraction.ipynb), showing how this is done.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bc933dc1-267f-4705-a6c9-07ca320f2f1d",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"id": "30699778-28fe-45be-aae4-04967916c36c",
"metadata": {},
"source": [
"## Next notebook\n",
"## Next notebooks\n",
"\n",
"This is the end of the standard tutorial content. \n",
"There is also some more detailed bonus content which you might be interested in: [see list here](./Mesh_Tutorial_Intro.ipynb#bonus_and_additional_material)"
"This is the end of the standard tutorial content. There is also some more detailed [bonus content](./Mesh_Tutorial_Intro.ipynb#bonus_and_additional_material) which you might be interested in."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ba321b78-3c05-424a-9476-1b7714abe39b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down

0 comments on commit b61ed6b

Please sign in to comment.