Skip to main content

reki

Maturity-Emerging GitHub Release PyPI - Version Documentation Status GitHub License GitHub Action Workflow Status

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 the latest release from pip:

pip install reki

or download the latest source code from GitHub and install using pip.

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 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 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

reki-2026.8.0.tar.gz (188.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

reki-2026.8.0-py3-none-any.whl (131.9 kB view details)

Uploaded Python 3

File details

Details for the file reki-2026.8.0.tar.gz.

File metadata

  • Download URL: reki-2026.8.0.tar.gz
  • Upload date:
  • Size: 188.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for reki-2026.8.0.tar.gz
Algorithm Hash digest
SHA256 a4e6eb8a52ac665dfdd990a156f46984a28ec9c92b4fc8d5f4994d6b59343cac
MD5 cbcc7c797ac1f0cf840061d2b805b9a1
BLAKE2b-256 2e645bdf65e20c1accb1c3fc00b585fe5f17d1a44e1ff0bf7f4666a0e8d9510d

See more details on using hashes here.

File details

Details for the file reki-2026.8.0-py3-none-any.whl.

File metadata

  • Download URL: reki-2026.8.0-py3-none-any.whl
  • Upload date:
  • Size: 131.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for reki-2026.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3f2fc99bc2240435b159d300538ed277748511f3495a874fe00e9f5a26895431
MD5 2b92abea0e259b95400e7da0367d2180
BLAKE2b-256 f4aa1a39ee0ec10e343740a58f03eb0d1a0135f7f96bc42908c47eae327f04f9

See more details on using hashes here.

Release history Release notifications | RSS feed

2026.8.1

2 files

This release

2026.8.0 This release

2 files

2026.7.0

2 files

2025.7.2

2 files

2025.7.1

2 files

2025.7.0

2 files

2024.10.0

2 files

2024.4.0

2 files

0.3.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page