Skip to content

Commit be3244e

Browse files
authored
Add API extending xgcm vertical regridding (#388)
1 parent c70827a commit be3244e

File tree

18 files changed

+3993
-219
lines changed

18 files changed

+3993
-219
lines changed

conda-env/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ dependencies:
2222
# Constrained because 0.6.3 breaks with import ESMF
2323
# Source: https://github.com/pangeo-data/xESMF/issues/212
2424
- xesmf >0.6.3
25+
- xgcm
2526
# Quality Assurance
2627
# ==================
2728
- types-python-dateutil

conda-env/dev.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ dependencies:
1919
- pandas=1.5.3
2020
- python-dateutil=2.8.2
2121
- xarray=2023.4.2
22+
- xgcm=0.8.0
2223
# ==================
2324
# Optional
2425
# ==================
@@ -35,6 +36,7 @@ dependencies:
3536
- nbsphinx=0.9.1
3637
- pandoc=3.1.1
3738
- ipython=8.11.0 # Required for nbsphinx syntax highlighting
39+
- gsw-xarray=0.3.0 # Required for vertical regridding example
3840
# ==================
3941
# Quality Assurance
4042
# ==================

conda-env/readthedocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies:
1818
- pandas=1.5.3
1919
- python-dateutil=2.8.2
2020
- xarray=2023.4.2
21+
- xgcm=0.8.0
2122
# ==================
2223
# Optional
2324
# ==================

docs/api.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ Classes
8888
xcdat.regridder.accessor.RegridderAccessor
8989
xcdat.regridder.regrid2.Regrid2Regridder
9090
xcdat.regridder.xesmf.XESMFRegridder
91+
xcdat.regridder.xgcm.XGCMRegridder
9192

9293
.. currentmodule:: xarray
9394

@@ -123,6 +124,7 @@ Methods
123124
Dataset.regridder.horizontal
124125
Dataset.regridder.horizontal_xesmf
125126
Dataset.regridder.horizontal_regrid2
127+
Dataset.regridder.vertical
126128

127129
.. _dsmeth_1:
128130

docs/examples/horizontal-regridding.ipynb renamed to docs/examples/regridding-horizontal.ipynb

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
{
22
"cells": [
33
{
4+
"attachments": {},
45
"cell_type": "markdown",
56
"id": "a31785d6-310c-4871-9ac6-064a7874945f",
67
"metadata": {
78
"tags": []
89
},
910
"source": [
1011
"# Horizontal Regridding\n",
12+
"\n",
1113
"Author: [Jason Boutte](https://github.com/jasonb5)\n",
1214
"\n",
1315
"Date: 08/24/22\n",
1416
"\n",
1517
"Related APIs:\n",
1618
"\n",
17-
"* [xarray.Dataset.regridder.horizontal](../generated/xarray.Dataset.regridder.horizontal.rst)\n",
19+
"- [xarray.Dataset.regridder.horizontal](../generated/xarray.Dataset.regridder.horizontal.rst)\n",
1820
"\n",
1921
"The data used in this example can be found through the [Earth System Grid Federation (ESGF) search portal](https://aims2.llnl.gov/search).\n",
2022
"\n",
2123
"## Overview\n",
24+
"\n",
2225
"We'll cover horizontal regridding using the `xESMF` and `Regrid2` tools as well as various methods supported by `xESMF`.\n",
2326
"\n",
24-
"It should be noted that `Regrid2` treats the grid cells as being flat."
27+
"It should be noted that `Regrid2` treats the grid cells as being flat.\n"
2528
]
2629
},
2730
{
@@ -39,14 +42,16 @@
3942
]
4043
},
4144
{
45+
"attachments": {},
4246
"cell_type": "markdown",
4347
"id": "7d904843-4079-4ebe-a3d0-ab439e8ce052",
4448
"metadata": {},
4549
"source": [
4650
"## 1. Open the Dataset\n",
51+
"\n",
4752
"We are using xarray's OPeNDAP support to read a netCDF4 dataset file directly from its source. The data is not loaded over the network until we perform operations on it (e.g., temperature unit adjustment).\n",
4853
"\n",
49-
"More information on the xarray's OPeNDAP support can be found [here](https://docs.xarray.dev/en/stable/user-guide/io.html#opendap)."
54+
"More information on the xarray's OPeNDAP support can be found [here](https://docs.xarray.dev/en/stable/user-guide/io.html#opendap).\n"
5055
]
5156
},
5257
{
@@ -640,25 +645,27 @@
640645
}
641646
],
642647
"source": [
643-
"filepath = 'http://aims3.llnl.gov/thredds/dodsC/css03_data/CMIP6/CMIP/CCCma/CanESM5/historical/r13i1p1f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r13i1p1f1_gn_185001-201412.nc'\n",
648+
"filepath = \"http://aims3.llnl.gov/thredds/dodsC/css03_data/CMIP6/CMIP/CCCma/CanESM5/historical/r13i1p1f1/Amon/tas/gn/v20190429/tas_Amon_CanESM5_historical_r13i1p1f1_gn_185001-201412.nc\"\n",
644649
"\n",
645650
"ds = xcdat.open_dataset(filepath)\n",
646651
"\n",
647652
"# Unit adjust (-273.15, K to C)\n",
648-
"ds['tas'] = ds['tas'] - 273.15\n",
653+
"ds[\"tas\"] = ds[\"tas\"] - 273.15\n",
649654
"\n",
650-
"ds"
655+
"ds\n"
651656
]
652657
},
653658
{
659+
"attachments": {},
654660
"cell_type": "markdown",
655661
"id": "1aa0dc89-d664-4721-8759-45065060a5b1",
656662
"metadata": {},
657663
"source": [
658664
"## 2. Create the output grid\n",
665+
"\n",
659666
"Related API: [xcdat.create_gaussian_grid()](../generated/xcdat.create_gaussian_grid.rst)\n",
660667
"\n",
661-
"In this example, we will generate a gaussian grid with 32 latitudes to regrid our input data to."
668+
"In this example, we will generate a gaussian grid with 32 latitudes to regrid our input data to.\n"
662669
]
663670
},
664671
{
@@ -685,24 +692,26 @@
685692
"\n",
686693
"fig, axes = plt.subplots(ncols=2, figsize=(16, 4))\n",
687694
"\n",
688-
"ds.regridder.grid.plot.scatter('lon', 'lat', s=0.01, ax=axes[0])\n",
689-
"axes[0].set_title('Input Grid')\n",
695+
"ds.regridder.grid.plot.scatter(\"lon\", \"lat\", s=0.01, ax=axes[0])\n",
696+
"axes[0].set_title(\"Input Grid\")\n",
690697
"\n",
691-
"output_grid.plot.scatter('lon', 'lat', s=0.1, ax=axes[1])\n",
692-
"axes[1].set_title('Output Grid')\n",
698+
"output_grid.plot.scatter(\"lon\", \"lat\", s=0.1, ax=axes[1])\n",
699+
"axes[1].set_title(\"Output Grid\")\n",
693700
"\n",
694-
"plt.tight_layout()"
701+
"plt.tight_layout()\n"
695702
]
696703
},
697704
{
705+
"attachments": {},
698706
"cell_type": "markdown",
699707
"id": "9d5fe21a-85ef-4737-95fd-0a0868e89579",
700708
"metadata": {},
701709
"source": [
702710
"## 3. Regrid the data\n",
711+
"\n",
703712
"Related API: [xarray.Dataset.regridder.horizontal()](../generated/xarray.Dataset.regridder.horizontal.rst)\n",
704713
"\n",
705-
"Here we will regrid the input data to the ouptut grid using the `xESMF` tool and the `bilinear` method."
714+
"Here we will regrid the input data to the ouptut grid using the `xESMF` tool and the `bilinear` method.\n"
706715
]
707716
},
708717
{
@@ -725,25 +734,27 @@
725734
}
726735
],
727736
"source": [
728-
"output = ds.regridder.horizontal('tas', output_grid, tool='xesmf', method='bilinear')\n",
737+
"output = ds.regridder.horizontal(\"tas\", output_grid, tool=\"xesmf\", method=\"bilinear\")\n",
729738
"\n",
730739
"fig, axes = plt.subplots(ncols=2, figsize=(16, 4))\n",
731740
"\n",
732741
"ds.tas.isel(time=0).plot(ax=axes[0])\n",
733-
"axes[0].set_title('Input data')\n",
742+
"axes[0].set_title(\"Input data\")\n",
734743
"\n",
735744
"output.tas.isel(time=0).plot(ax=axes[1])\n",
736-
"axes[1].set_title('Output data')\n",
745+
"axes[1].set_title(\"Output data\")\n",
737746
"\n",
738-
"plt.tight_layout()"
747+
"plt.tight_layout()\n"
739748
]
740749
},
741750
{
751+
"attachments": {},
742752
"cell_type": "markdown",
743753
"id": "4084129e-dd96-4d0d-ae01-4a66f897e4e5",
744754
"metadata": {},
745755
"source": [
746756
"## 4. Regridding algorithms\n",
757+
"\n",
747758
"Related API: [xarray.Dataset.regridder.horizontal()](../generated/xarray.Dataset.regridder.horizontal.rst)\n",
748759
"\n",
749760
"In this example, we will compare the different regridding methods supported by `xESMF`.\n",
@@ -752,11 +763,11 @@
752763
"\n",
753764
"Methods:\n",
754765
"\n",
755-
"* bilinear\n",
756-
"* conservative\n",
757-
"* nearest_s2d\n",
758-
"* nearest_d2s\n",
759-
"* patch"
766+
"- bilinear\n",
767+
"- conservative\n",
768+
"- nearest_s2d\n",
769+
"- nearest_d2s\n",
770+
"- patch\n"
760771
]
761772
},
762773
{
@@ -779,35 +790,37 @@
779790
}
780791
],
781792
"source": [
782-
"methods = ['bilinear', 'conservative', 'nearest_s2d', 'nearest_d2s', 'patch']\n",
793+
"methods = [\"bilinear\", \"conservative\", \"nearest_s2d\", \"nearest_d2s\", \"patch\"]\n",
783794
"\n",
784795
"fig, axes = plt.subplots(3, 2, figsize=(16, 12))\n",
785796
"\n",
786797
"axes = axes.flatten()\n",
787798
"\n",
788799
"for i, method in enumerate(methods):\n",
789-
" output = ds.regridder.horizontal('tas', output_grid, tool='xesmf', method=method)\n",
800+
" output = ds.regridder.horizontal(\"tas\", output_grid, tool=\"xesmf\", method=method)\n",
790801
"\n",
791802
" output.tas.isel(time=0).plot(ax=axes[i])\n",
792803
"\n",
793804
" axes[i].set_title(method)\n",
794805
"\n",
795806
"axes[-1].set_visible(False)\n",
796807
"\n",
797-
"plt.tight_layout()"
808+
"plt.tight_layout()\n"
798809
]
799810
},
800811
{
812+
"attachments": {},
801813
"cell_type": "markdown",
802814
"id": "92685e37-ed43-42c2-b9b3-8b4722075ebc",
803815
"metadata": {},
804816
"source": [
805817
"## 5. Masking\n",
818+
"\n",
806819
"Related API: [xarray.Dataset.regridder.horizontal()](../generated/xarray.Dataset.regridder.horizontal.rst)\n",
807820
"\n",
808821
"`xESMF` supports masking by simply adding a data variable with the id `mask`.\n",
809822
"\n",
810-
"See `xESMF` [documentation](https://pangeo-xesmf.readthedocs.io/en/latest/notebooks/Masking.html) for additonal details."
823+
"See `xESMF` [documentation](https://pangeo-xesmf.readthedocs.io/en/latest/notebooks/Masking.html) for additonal details.\n"
811824
]
812825
},
813826
{
@@ -830,32 +843,36 @@
830843
}
831844
],
832845
"source": [
833-
"ds['mask'] = xr.where(ds.tas.isel(time=0)<-10, 1, 0)\n",
846+
"ds[\"mask\"] = xr.where(ds.tas.isel(time=0) < -10, 1, 0)\n",
834847
"\n",
835-
"masked_output = ds.regridder.horizontal('tas', output_grid, tool='xesmf', method='bilinear')\n",
848+
"masked_output = ds.regridder.horizontal(\n",
849+
" \"tas\", output_grid, tool=\"xesmf\", method=\"bilinear\"\n",
850+
")\n",
836851
"\n",
837852
"fig, axes = plt.subplots(ncols=2, figsize=(18, 4))\n",
838853
"\n",
839-
"ds['mask'].plot(ax=axes[0], cmap='binary_r')\n",
840-
"axes[0].set_title('Mask')\n",
854+
"ds[\"mask\"].plot(ax=axes[0], cmap=\"binary_r\")\n",
855+
"axes[0].set_title(\"Mask\")\n",
841856
"\n",
842857
"masked_output.tas.isel(time=0).plot(ax=axes[1])\n",
843-
"axes[1].set_title('Masked output')\n",
858+
"axes[1].set_title(\"Masked output\")\n",
844859
"\n",
845-
"plt.tight_layout()"
860+
"plt.tight_layout()\n"
846861
]
847862
},
848863
{
864+
"attachments": {},
849865
"cell_type": "markdown",
850866
"id": "99daebe0-0b0d-4a88-988a-5e2d685de80d",
851867
"metadata": {},
852868
"source": [
853869
"## 6. Regridding using `regrid2`\n",
870+
"\n",
854871
"Related API: [xarray.Dataset.regridder.horizontal()](../generated/xarray.Dataset.regridder.horizontal.rst)\n",
855872
"\n",
856873
"`Regrid2` is a conservative regridder for rectilinear (lat/lon) grids originally from the `cdutil` package from `CDAT`.\n",
857874
"\n",
858-
"This regridder assumes constant latitude lines when generating weights."
875+
"This regridder assumes constant latitude lines when generating weights.\n"
859876
]
860877
},
861878
{
@@ -888,19 +905,19 @@
888905
}
889906
],
890907
"source": [
891-
"output = ds.regridder.horizontal('tas', output_grid, tool='regrid2')\n",
908+
"output = ds.regridder.horizontal(\"tas\", output_grid, tool=\"regrid2\")\n",
892909
"\n",
893910
"fig, axes = plt.subplots(ncols=2, figsize=(16, 4))\n",
894911
"\n",
895912
"ds.tas.isel(time=0).plot(ax=axes[0])\n",
896913
"\n",
897-
"output.tas.isel(time=0).plot(ax=axes[1])"
914+
"output.tas.isel(time=0).plot(ax=axes[1])\n"
898915
]
899916
}
900917
],
901918
"metadata": {
902919
"kernelspec": {
903-
"display_name": "Python 3.9.13 ('xcdat_dev')",
920+
"display_name": "Python 3 (ipykernel)",
904921
"language": "python",
905922
"name": "python3"
906923
},
@@ -914,7 +931,7 @@
914931
"name": "python",
915932
"nbconvert_exporter": "python",
916933
"pygments_lexer": "ipython3",
917-
"version": "3.9.13"
934+
"version": "3.10.8"
918935
},
919936
"vscode": {
920937
"interpreter": {

0 commit comments

Comments
 (0)