reki
A data preparation tool for meteorological data in CEMC/CMA.
Load GRIB2 data using eccodes or cfgrib.
中文文档 (Chinese documentation): https://reki.readthedocs.io/
Installation
Install from pip:
pip install reki
or download the latest source code from GitHub and install using pip.
reki uses ecCodes to decode GRIB files
(which is needed by eccodes and cfgrib).
Please install ecCodes through conda or other package source.
Getting started
Local file lookup
The reki library includes built-in config files to locate data files in CMA-HPC2023-SC1 shared file system (/g3/COMMONDATA).
The codes below finds the GRIB2-ORIG file path for CMA-GFS:
>>> from reki.data_finder import find_local_file
>>> gfs_grib2_file_path = find_local_file(
... "cma_gfs_gmf/grib2/orig",
... start_time="2025081900",
... forecast_time="24h",
... )
>>> gfs_grib2_file_path
PosixPath('/g3/COMMONDATA/OPER/CEMC/GFS_GMF/Prod-grib/2025081900/ORIG/gmf.gra.2025081900024.grb2')
The find_local_file function supports additional parameters for more specific file selection.
For instance, using number to indicate ensemble member:
>>> geps_grib2_file_path = find_local_file(
... "cma_geps/grib2/orig",
... start_time="2025081900",
... forecast_time="24h",
... number=2,
... )
>>> geps_grib2_file_path
PosixPath('/g3/COMMONDATA/OPER/CEMC/GEPS/Prod-grib/2025081900/grib2/gef.gra.002.2025081900024.grb2')
reki also supports locating intermediate model output files. The example below find path of the 240-hour model-level binary data file for CMA-GFS:
>>> gfs_modelvar_file_path = find_local_file(
... "cma_gfs_gmf/bin/modelvar",
... start_time="2025081900",
... forecast_time="240h",
... )
>>> gfs_modelvar_file_path
PosixPath('/g3/COMMONDATA/OPER/CEMC/GFS_GMF/Fcst-long/2025081900/modelvar2025081900_240')
Built-in configuration files are located in the reki/data_finder/conf directory.
Reading GRIB2 files
Basic method
Use eccodes to retrieve a field from a GRIB2 file and return an xarray.DataArray object.
This example loads the 850 hPa temperature field from a CMA-GFS GRIB2-ORIG data:
>>> from reki.format.grib.eccodes import load_field_from_file
>>> field = load_field_from_file(
... gfs_grib2_file_path,
... parameter="t",
... level_type="pl",
... level=850,
... )
>>> field
<xarray.DataArray 't' (latitude: 1440, longitude: 2880)> Size: 33MB
array([[270.49505859, 270.50505859, 270.50505859, ..., 270.49505859,
270.49505859, 270.49505859],
[270.69505859, 270.70505859, 270.71505859, ..., 270.70505859,
270.70505859, 270.69505859],
[270.84505859, 270.85505859, 270.85505859, ..., 270.84505859,
270.84505859, 270.84505859],
...,
[247.60505859, 247.58505859, 247.74505859, ..., 247.62505859,
247.63505859, 247.61505859],
[247.26505859, 247.26505859, 247.25505859, ..., 247.25505859,
247.25505859, 247.25505859],
[246.84505859, 246.84505859, 246.84505859, ..., 246.85505859,
246.84505859, 246.84505859]], shape=(1440, 2880))
Coordinates:
time datetime64[ns] 8B 2025-08-19
step timedelta64[ns] 8B 1 days
valid_time datetime64[ns] 8B 2025-08-20
pl float64 8B 850.0
* latitude (latitude) float64 12kB 89.94 89.81 89.69 ... -89.81 -89.94
* longitude (longitude) float64 23kB 0.0 0.125 0.25 ... 359.6 359.8 359.9
Attributes: (12/17)
GRIB_edition: 2
GRIB_centre: babj
GRIB_subCentre: 0
GRIB_tablesVersion: 4
GRIB_localTablesVersion: 0
GRIB_dataType: fc
... ...
GRIB_stepType: instant
GRIB_stepUnits: 1
GRIB_stepRange: 24
GRIB_endStep:int: 24
GRIB_count: 109
long_name: discipline=0 parmcat=0 parm=0
Quick plotting:
>>> (field - 273.15).plot()
Level Type
Load variables from model-level data.
The example below loads the u-component at model level 10 (ml) from CMA-GFS model-level GRIB2 data:
>>> gfs_model_grib2_file_path = find_local_file(
... "cma_gfs_gmf/grib2/modelvar",
... start_time="2025081900",
... forecast_time="24h",
... )
>>> gfs_model_grib2_file_path
PosixPath('/g3/COMMONDATA/OPER/CEMC/GFS_GMF/Prod-grib/2025081900/MODELVAR/modelvar2025081900024.grb2')
>>> field = load_field_from_file(
... gfs_model_grib2_file_path,
... parameter="u",
... level_type="ml",
... level=10,
... )
>>> field
<xarray.DataArray 'u' (latitude: 1440, longitude: 2880)> Size: 33MB
array([[ 9.09106934, 9.09106934, 9.10106934, ..., 9.09106934,
9.09106934, 9.09106934],
[ 8.00106934, 8.00106934, 8.00106934, ..., 8.01106934,
8.01106934, 8.01106934],
[ 7.97106934, 7.96106934, 7.96106934, ..., 7.97106934,
7.97106934, 7.97106934],
...,
[11.00106934, 10.99106934, 10.98106934, ..., 11.04106934,
11.03106934, 11.01106934],
[11.73106934, 11.72106934, 11.71106934, ..., 11.77106934,
11.75106934, 11.74106934],
[14.21106934, 14.20106934, 14.19106934, ..., 14.24106934,
14.23106934, 14.22106934]], shape=(1440, 2880))
Coordinates:
time datetime64[ns] 8B 2025-08-19
step timedelta64[ns] 8B 1 days
valid_time datetime64[ns] 8B 2025-08-20
ml int64 8B 10
* latitude (latitude) float64 12kB 89.94 89.81 89.69 ... -89.81 -89.94
* longitude (longitude) float64 23kB 0.0 0.125 0.25 ... 359.6 359.8 359.9
Attributes: (12/17)
GRIB_edition: 2
GRIB_centre: babj
GRIB_subCentre: 0
GRIB_tablesVersion: 4
GRIB_localTablesVersion: 0
GRIB_dataType: fc
... ...
GRIB_stepType: instant
GRIB_stepUnits: 1
GRIB_stepRange: 24
GRIB_endStep:int: 24
GRIB_count: 187
long_name: discipline=0 parmcat=2 parm=2
More filtering options
The load_field_from_file function also supports passing GRIB key parameters directly via a dictionary.
The example below loads the radar reflectivity field at 850 hPa:
>>> field = load_field_from_file(
... gfs_grib2_file_path,
... parameter={
... "discipline": 0,
... "parameterCategory": 16,
... "parameterNumber": 225,
... },
... level_type="pl",
... level=850,
... )
>>> field
<xarray.DataArray '0_16_225' (latitude: 1440, longitude: 2880)> Size: 33MB
array([[-7.12, -7.17, -7.24, ..., -7.03, -7.04, -7.06],
[-7.71, -7.64, -7.65, ..., -7.82, -7.8 , -7.78],
[-6.03, -6.07, -6.08, ..., -6.07, -6.08, -6.08],
...,
[ 1.52, 1.37, 1.18, ..., 1.59, 1.22, 1.23],
[ 0.65, 0.68, 1.31, ..., 0.65, 0.67, 0.69],
[-0.22, -0.2 , -0.21, ..., -0.25, -0.24, -0.24]],
shape=(1440, 2880))
Coordinates:
time datetime64[ns] 8B 2025-08-19
step timedelta64[ns] 8B 1 days
valid_time datetime64[ns] 8B 2025-08-20
pl float64 8B 850.0
* latitude (latitude) float64 12kB 89.94 89.81 89.69 ... -89.81 -89.94
* longitude (longitude) float64 23kB 0.0 0.125 0.25 ... 359.6 359.8 359.9
Attributes: (12/17)
GRIB_edition: 2
GRIB_centre: babj
GRIB_subCentre: 0
GRIB_tablesVersion: 4
GRIB_localTablesVersion: 1
GRIB_dataType: fc
... ...
GRIB_stepType: instant
GRIB_stepUnits: 1
GRIB_stepRange: 24
GRIB_endStep:int: 24
GRIB_count: 790
long_name: discipline=0 parmcat=16 parm=225
ecCodes interface
reki supports returning the raw GRIB message via the ecCodes Python API. For instance, loading the 850 hPa geopotential height field:
>>> from reki.format.grib.eccodes import load_message_from_file
>>> message = load_message_from_file(
... gfs_grib2_file_path,
... parameter="gh",
... level_type="pl",
... level=850,
... )
>>> message
94257262686816
>>> import eccodes
>>> values = eccodes.codes_get_double_array(message, "values")
>>> ni = eccodes.codes_get_long(message, "Ni")
>>> nj = eccodes.codes_get_long(message, "Nj")
>>> values.reshape(nj, ni)
array([[1425.48203125, 1425.48203125, 1425.48203125, ..., 1425.48203125,
1425.48203125, 1425.48203125],
[1428.68203125, 1428.68203125, 1428.68203125, ..., 1428.68203125,
1428.68203125, 1428.68203125],
[1431.18203125, 1431.18203125, 1431.18203125, ..., 1431.18203125,
1431.18203125, 1431.18203125],
...,
[1311.18203125, 1311.28203125, 1310.38203125, ..., 1311.08203125,
1311.08203125, 1311.08203125],
[1311.88203125, 1311.78203125, 1311.88203125, ..., 1311.88203125,
1311.88203125, 1311.88203125],
[1313.38203125, 1313.38203125, 1313.38203125, ..., 1313.28203125,
1313.38203125, 1313.38203125]], shape=(1440, 2880))
Finally, release the GRIB message object:
>>> eccodes.codes_release(message)
Examples
See cemc-oper/data-notebook project for more examples.
LICENSE
Copyright © 2020-2026, developers at CMA Earth System Modeling And Prediction Centre.
reki is licensed under Apache License, Version 2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file reki-2026.7.0.tar.gz.
File metadata
- Download URL: reki-2026.7.0.tar.gz
- Upload date:
- Size: 114.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5233480613ce5fb635d517e08babf290793e7af7c4084be4489206c925c247d6
|
|
| MD5 |
ab9d29ad7485960aa0d9fb83773844ea
|
|
| BLAKE2b-256 |
c27cdfc4d16dbf4c03bd2fad39ab38dc4941ca06b33ef8d15d54eb098831eac9
|
File details
Details for the file reki-2026.7.0-py3-none-any.whl.
File metadata
- Download URL: reki-2026.7.0-py3-none-any.whl
- Upload date:
- Size: 91.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a4a92af1326b890e11b87c4e6f77bf73ae20df76fb01bf97801cc17042f690cc
|
|
| MD5 |
906fe2ec0e412146ef326e73465efa1d
|
|
| BLAKE2b-256 |
9e785a3f77592b20c808bea837aeb01ab50a02eca9adaeb3f977717146bbdaed
|