# bmi_era5
[](https://zenodo.org/doi/10.5281/zenodo.10368878)
[](https://bmi-era5.readthedocs.io/en/latest/?badge=latest)
[](https://github.com/gantian127/bmi_era5/blob/master/LICENSE.txt)
**Please note: Starting with release v0.2.0, the New CDS platform is now supported.**
bmi_era5 package is an implementation of the Basic Model Interface ([BMI](https://bmi-spec.readthedocs.io/en/latest/))
for the [ERA5](https://confluence.ecmwf.int/display/CKB/ERA5) dataset.
This package uses the [CDS API](https://cds.climate.copernicus.eu/how-to-api) to download
the ERA5 dataset and wraps the dataset with BMI for data control and query.
It currently supports 3-dimensional ERA5
datasets defined with dimensions such as valid_time (or date), latitude, and longitude.
This package is not implemented for people to use but is the key element to convert the ERA5 dataset into
a data component ([pymt_era5](https://pymt-era5.readthedocs.io/)) for
the [PyMT](https://pymt.readthedocs.io/en/latest/?badge=latest) modeling framework developed
by Community Surface Dynamics Modeling System ([CSDMS](https://csdms.colorado.edu/wiki/Main_Page)).
If you have any suggestion to improve the current function, please create a GitHub issue
[here](https://github.com/gantian127/bmi_era5/issues).
### Install package
#### Stable Release
The bmi_era5 package and its dependencies can be installed with pip
```
$ pip install bmi_era5
```
or conda
```
$ conda install -c conda-forge bmi_era5
```
#### From Source
After downloading the source code, run the following command from top-level folder
to install bmi_era5.
```
$ pip install -e .
```
### Quick Start
Below shows how to use two methods to download the ERA5 datasets.
You can learn more details from the [tutorial notebook](https://github.com/gantian127/bmi_era5/blob/master/notebooks/bmi_era5.ipynb).
To run this notebook, please go to the [CSDMS EKT Lab](https://csdms.colorado.edu/wiki/Lab-0018) and follow the instruction in the "Lab notes" section.
#### Example 1: use CDS API to download the ERA5 data
```python
import cdsapi
import xarray
import matplotlib.pyplot as plt
c = cdsapi.Client()
c.retrieve(
"reanalysis-era5-single-levels",
{
"product_type": "reanalysis",
"format": "netcdf",
"variable": ["2m_temperature", "total_precipitation"],
"year": "2021",
"month": "01",
"day": "01",
"time": ["00:00", "01:00", "02:00"],
"area": [41, -109, 36, -102],
"grid": [0.25, 0.25],
},
"download.nc",
)
# load netCDF data
dataset = xarray.open_dataset("download.nc")
# select 2 meter temperature on 2021-01-01 at 00:00
air_temp = dataset.t2m.isel(valid_time=0)
# plot data
air_temp.plot(figsize=(9, 5))
plt.title("2 metre temperature in Colorado on Jan 1st, 2021 at 00:00")
```

#### Example 2: use BmiEra5 class to download the ERA5 data (Demonstration of how to use BMI)
```python
from bmi_era5 import BmiEra5
import numpy as np
import matplotlib.pyplot as plt
data_comp = BmiEra5()
data_comp.initialize("config_file.yaml")
# get variable info
for var_name in data_comp.get_output_var_names():
var_unit = data_comp.get_var_units(var_name)
var_location = data_comp.get_var_location(var_name)
var_type = data_comp.get_var_type(var_name)
var_grid = data_comp.get_var_grid(var_name)
var_itemsize = data_comp.get_var_itemsize(var_name)
var_nbytes = data_comp.get_var_nbytes(var_name)
print(f"{var_name=}")
print(f"{var_unit=}")
print(f"{var_location=}")
print(f"{var_type=}")
print(f"{var_grid=}")
print(f"{var_itemsize=}")
print(f"{var_nbytes=}")
# get time info
start_time = data_comp.get_start_time()
end_time = data_comp.get_end_time()
time_step = data_comp.get_time_step()
time_unit = data_comp.get_time_units()
time_steps = int((end_time - start_time) / time_step) + 1
print(f"{start_time=}")
print(f"{end_time=}")
print(f"{time_step=}")
print(f"{time_unit=}")
print(f"{time_steps=}")
# get variable grid info
grid_rank = data_comp.get_grid_rank(var_grid)
grid_size = data_comp.get_grid_size(var_grid)
grid_shape = np.empty(grid_rank, int)
data_comp.get_grid_shape(var_grid, grid_shape)
grid_spacing = np.empty(grid_rank)
data_comp.get_grid_spacing(var_grid, grid_spacing)
grid_origin = np.empty(grid_rank)
data_comp.get_grid_origin(var_grid, grid_origin)
print(f"{grid_rank=}")
print(f"{grid_size=}")
print(f"{grid_shape=}")
print(f"{grid_spacing=}")
print(f"{grid_origin=}")
# get variable data
data = np.empty(grid_size, var_type)
data_comp.get_value("2 metre temperature", data)
data_2D = data.reshape(grid_shape)
# get X, Y extent for plot
min_y, min_x = grid_origin
max_y = min_y + grid_spacing[0] * (grid_shape[0] - 1)
max_x = min_x + grid_spacing[1] * (grid_shape[1] - 1)
dy = grid_spacing[0] / 2
dx = grid_spacing[1] / 2
extent = [min_x - dx, max_x + dx, min_y - dy, max_y + dy]
# plot data
fig, ax = plt.subplots(1, 1, figsize=(9, 5))
im = ax.imshow(data_2D, extent=extent)
cbar = fig.colorbar(im)
cbar.set_label("2 metre temperature [K]")
plt.xlabel("longitude [degree_east]")
plt.ylabel("latitude [degree_north]")
plt.title("2 metre temperature in Colorado on Jan 1st, 2021 at 00:00")
# finalize the data component
data_comp.finalize()
```

Raw data
{
"_id": null,
"home_page": null,
"name": "bmi-era5",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "Tian Gan <jamy127@foxmail.com>",
"keywords": "BMI, Basic Model Interface, ERA5",
"author": null,
"author_email": "Tian Gan <jamy127@foxmail.com>",
"download_url": "https://files.pythonhosted.org/packages/03/af/626ed761092d7d95f638b88310d7c2222d0ba928c461056ffa2442fdc23b/bmi_era5-0.2.0.tar.gz",
"platform": null,
"description": "# bmi_era5\n[](https://zenodo.org/doi/10.5281/zenodo.10368878)\n[](https://bmi-era5.readthedocs.io/en/latest/?badge=latest)\n[](https://github.com/gantian127/bmi_era5/blob/master/LICENSE.txt)\n\n**Please note: Starting with release v0.2.0, the New CDS platform is now supported.**\n\nbmi_era5 package is an implementation of the Basic Model Interface ([BMI](https://bmi-spec.readthedocs.io/en/latest/))\nfor the [ERA5](https://confluence.ecmwf.int/display/CKB/ERA5) dataset.\nThis package uses the [CDS API](https://cds.climate.copernicus.eu/how-to-api) to download\nthe ERA5 dataset and wraps the dataset with BMI for data control and query.\nIt currently supports 3-dimensional ERA5\ndatasets defined with dimensions such as valid_time (or date), latitude, and longitude.\n\nThis package is not implemented for people to use but is the key element to convert the ERA5 dataset into\na data component ([pymt_era5](https://pymt-era5.readthedocs.io/)) for\nthe [PyMT](https://pymt.readthedocs.io/en/latest/?badge=latest) modeling framework developed\nby Community Surface Dynamics Modeling System ([CSDMS](https://csdms.colorado.edu/wiki/Main_Page)).\n\nIf you have any suggestion to improve the current function, please create a GitHub issue\n[here](https://github.com/gantian127/bmi_era5/issues).\n\n\n### Install package\n\n#### Stable Release\n\nThe bmi_era5 package and its dependencies can be installed with pip\n```\n$ pip install bmi_era5\n```\n\nor conda\n```\n$ conda install -c conda-forge bmi_era5\n```\n\n#### From Source\n\nAfter downloading the source code, run the following command from top-level folder\nto install bmi_era5.\n```\n$ pip install -e .\n```\n\n### Quick Start\nBelow shows how to use two methods to download the ERA5 datasets.\n\nYou can learn more details from the [tutorial notebook](https://github.com/gantian127/bmi_era5/blob/master/notebooks/bmi_era5.ipynb).\nTo run this notebook, please go to the [CSDMS EKT Lab](https://csdms.colorado.edu/wiki/Lab-0018) and follow the instruction in the \"Lab notes\" section.\n\n#### Example 1: use CDS API to download the ERA5 data\n\n```python\nimport cdsapi\nimport xarray\nimport matplotlib.pyplot as plt\n\nc = cdsapi.Client()\n\nc.retrieve(\n \"reanalysis-era5-single-levels\",\n {\n \"product_type\": \"reanalysis\",\n \"format\": \"netcdf\",\n \"variable\": [\"2m_temperature\", \"total_precipitation\"],\n \"year\": \"2021\",\n \"month\": \"01\",\n \"day\": \"01\",\n \"time\": [\"00:00\", \"01:00\", \"02:00\"],\n \"area\": [41, -109, 36, -102],\n \"grid\": [0.25, 0.25],\n },\n \"download.nc\",\n)\n\n# load netCDF data\ndataset = xarray.open_dataset(\"download.nc\")\n\n# select 2 meter temperature on 2021-01-01 at 00:00\nair_temp = dataset.t2m.isel(valid_time=0)\n\n# plot data\nair_temp.plot(figsize=(9, 5))\nplt.title(\"2 metre temperature in Colorado on Jan 1st, 2021 at 00:00\")\n```\n\n\n\n#### Example 2: use BmiEra5 class to download the ERA5 data (Demonstration of how to use BMI)\n\n```python\nfrom bmi_era5 import BmiEra5\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndata_comp = BmiEra5()\ndata_comp.initialize(\"config_file.yaml\")\n\n# get variable info\nfor var_name in data_comp.get_output_var_names():\n var_unit = data_comp.get_var_units(var_name)\n var_location = data_comp.get_var_location(var_name)\n var_type = data_comp.get_var_type(var_name)\n var_grid = data_comp.get_var_grid(var_name)\n var_itemsize = data_comp.get_var_itemsize(var_name)\n var_nbytes = data_comp.get_var_nbytes(var_name)\n\n print(f\"{var_name=}\")\n print(f\"{var_unit=}\")\n print(f\"{var_location=}\")\n print(f\"{var_type=}\")\n print(f\"{var_grid=}\")\n print(f\"{var_itemsize=}\")\n print(f\"{var_nbytes=}\")\n\n# get time info\nstart_time = data_comp.get_start_time()\nend_time = data_comp.get_end_time()\ntime_step = data_comp.get_time_step()\ntime_unit = data_comp.get_time_units()\ntime_steps = int((end_time - start_time) / time_step) + 1\n\nprint(f\"{start_time=}\")\nprint(f\"{end_time=}\")\nprint(f\"{time_step=}\")\nprint(f\"{time_unit=}\")\nprint(f\"{time_steps=}\")\n\n# get variable grid info\ngrid_rank = data_comp.get_grid_rank(var_grid)\ngrid_size = data_comp.get_grid_size(var_grid)\n\ngrid_shape = np.empty(grid_rank, int)\ndata_comp.get_grid_shape(var_grid, grid_shape)\n\ngrid_spacing = np.empty(grid_rank)\ndata_comp.get_grid_spacing(var_grid, grid_spacing)\n\ngrid_origin = np.empty(grid_rank)\ndata_comp.get_grid_origin(var_grid, grid_origin)\n\nprint(f\"{grid_rank=}\")\nprint(f\"{grid_size=}\")\nprint(f\"{grid_shape=}\")\nprint(f\"{grid_spacing=}\")\nprint(f\"{grid_origin=}\")\n\n# get variable data\ndata = np.empty(grid_size, var_type)\ndata_comp.get_value(\"2 metre temperature\", data)\ndata_2D = data.reshape(grid_shape)\n\n# get X, Y extent for plot\nmin_y, min_x = grid_origin\nmax_y = min_y + grid_spacing[0] * (grid_shape[0] - 1)\nmax_x = min_x + grid_spacing[1] * (grid_shape[1] - 1)\ndy = grid_spacing[0] / 2\ndx = grid_spacing[1] / 2\nextent = [min_x - dx, max_x + dx, min_y - dy, max_y + dy]\n\n# plot data\nfig, ax = plt.subplots(1, 1, figsize=(9, 5))\nim = ax.imshow(data_2D, extent=extent)\ncbar = fig.colorbar(im)\ncbar.set_label(\"2 metre temperature [K]\")\nplt.xlabel(\"longitude [degree_east]\")\nplt.ylabel(\"latitude [degree_north]\")\nplt.title(\"2 metre temperature in Colorado on Jan 1st, 2021 at 00:00\")\n\n# finalize the data component\ndata_comp.finalize()\n```\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "BMI implementation for ERA5 data https://confluence.ecmwf.int/display/CKB/ERA5",
"version": "0.2.0",
"project_urls": {
"documentation": "https://github.com/gantian127/bmi_era5",
"homepage": "https://github.com/gantian127/bmi_era5",
"repository": "https://github.com/gantian127/bmi_era5"
},
"split_keywords": [
"bmi",
" basic model interface",
" era5"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "03af626ed761092d7d95f638b88310d7c2222d0ba928c461056ffa2442fdc23b",
"md5": "32d1cb914c6c7692f7bf2e4ee46af8e9",
"sha256": "644b0d7f0906ddc70f1e74d63e543f4c9d244593ebd3974d31815386b1eee5cf"
},
"downloads": -1,
"filename": "bmi_era5-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "32d1cb914c6c7692f7bf2e4ee46af8e9",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 13636,
"upload_time": "2024-10-30T19:06:19",
"upload_time_iso_8601": "2024-10-30T19:06:19.748825Z",
"url": "https://files.pythonhosted.org/packages/03/af/626ed761092d7d95f638b88310d7c2222d0ba928c461056ffa2442fdc23b/bmi_era5-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-30 19:06:19",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "gantian127",
"github_project": "bmi_era5",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "bmipy",
"specs": []
},
{
"name": "cdsapi",
"specs": [
[
">=",
"0.7.2"
]
]
},
{
"name": "cftime",
"specs": []
},
{
"name": "netcdf4",
"specs": []
},
{
"name": "numpy",
"specs": []
},
{
"name": "pyyaml",
"specs": []
},
{
"name": "requests",
"specs": []
},
{
"name": "xarray",
"specs": []
}
],
"lcname": "bmi-era5"
}