CF Conventions Module#
The cf module provides shared infrastructure for reading and writing
CF (Climate and Forecast) convention attributes. It is used by both the
structured NetCDF class and the unstructured UgridDataset class.
Key Capabilities#
- Variable classification: Detect coordinate, data, mesh topology,
and connectivity variables via
classify_variables() - CRS handling: Convert between CF
grid_mappingattributes and OGRSpatialReferenceviagrid_mapping_to_srs()/srs_to_grid_mapping() - Attribute writing: Write CF-compliant attributes to GDAL MDArrays and root groups
- Axis detection: Identify X/Y/Z/T axes from variable names, attributes, and units
- Convention parsing: Parse
Conventionsattribute strings (e.g.,"CF-1.8 UGRID-1.0") - Data masking: Apply
valid_range,valid_min,valid_maxmasks - Flag decoding: Decode CF
flag_values/flag_meanings
Capability map#
The cf module is a flat collection of helpers (no classes) shared by the structured NetCDF reader
and the unstructured UgridDataset. They group into five roles — classification, CRS translation,
convention parsing, attribute writing, and value decoding/validation:
flowchart TB
NC["NetCDF"] --> CF
UG["UgridDataset"] --> CF
subgraph CF["cf module"]
direction TB
CLS["classify_variables()<br/>data · coordinate · grid_mapping · bounds<br/>mesh_topology · connectivity · …"]
CRS["grid_mapping_to_srs() ⇄ srs_to_grid_mapping()"]
PAR["detect_axis() · parse_conventions()<br/>parse_cell_methods()"]
WR["write_attributes_to_md_array()<br/>write_global_attributes()<br/>build_coordinate_attrs()"]
DEC["apply_valid_range_mask() · decode_flags()<br/>validate_cf()"]
end
API Reference#
pyramids.netcdf.cf.classify_variables(variables, dimensions)
#
Classify each variable's CF role by cross-referencing attributes.
Must be called AFTER all variables are collected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variables
|
dict[str, Any]
|
Dict of |
required |
dimensions
|
dict[str, Any]
|
Dict of |
required |
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dict of |
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.grid_mapping_to_srs(grid_mapping_name, params)
#
Convert CF grid_mapping attributes to an OGR SpatialReference.
Tries crs_wkt first (fast path). Falls back to reconstructing
the SRS from individual CF parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grid_mapping_name
|
str
|
CF |
required |
params
|
dict[str, Any]
|
All attributes from the grid_mapping variable. |
required |
Returns:
| Type | Description |
|---|---|
SpatialReference
|
osr.SpatialReference: The reconstructed spatial reference. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the grid_mapping_name is not supported and
no |
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.srs_to_grid_mapping(srs)
#
Convert an OGR SpatialReference to CF grid_mapping name and params.
Returns the CF grid_mapping_name and a dict of CF projection
parameters (including crs_wkt for interoperability). For
geographic CRS (no projection), returns "latitude_longitude"
with only ellipsoid parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
srs
|
SpatialReference
|
An OGR SpatialReference object. |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, dict[str, Any]]
|
Tuple of |
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.write_attributes_to_md_array(md_arr, attrs)
#
Write a dict of attributes to a GDAL MDArray.
Handles str, bool, int, float, and list values. Silently skips attributes that can't be written (GDAL limitation). Bool values are stored as int32 (1/0) since NetCDF has no boolean type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
md_arr
|
MDArray
|
The GDAL MDArray to write attributes to. |
required |
attrs
|
dict[str, Any]
|
Dict of attribute names to values. |
required |
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.write_global_attributes(rg, attrs)
#
Write a dict of attributes to a GDAL root group.
Handles str, bool, int, float values. Bool values are stored as int32. Silently skips attributes that can't be written.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rg
|
Group
|
The GDAL root group to write attributes to. |
required |
attrs
|
dict[str, Any]
|
Dict of attribute names to values. |
required |
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.build_coordinate_attrs(dim_name, is_geographic=True)
#
Generate CF-compliant attributes for a coordinate variable.
Maps dimension names to the appropriate CF axis,
standard_name, long_name, and units attributes
based on whether the CRS is geographic or projected.
Dimension names are case-normalized (lowered) before
matching, so "X", "x", and "Lon" all match the
X-axis pattern.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dim_name
|
str
|
Dimension name (e.g. |
required |
is_geographic
|
bool | None
|
True if the CRS is geographic (lon/lat), False if
projected (easting/northing in metres), or |
True
|
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dict of CF attribute names to string values. Empty dict |
dict[str, str]
|
if the dimension name is not recognized. |
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.detect_axis(name, attrs, units=None)
#
Detect CF axis type from a variable's attributes.
Applies heuristics in priority order:
1. Explicit axis attribute ("X", "Y", "Z", "T")
2. standard_name lookup against CF conventions
3. Unit string matching (degrees_north -> Y, etc.)
4. Variable name pattern matching (lat -> Y, lon -> X)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Variable or dimension short name. |
required |
attrs
|
dict[str, Any]
|
Variable attribute dictionary. Attribute names are matched
case-insensitively ( |
required |
units
|
str | None
|
Unit string (separate from attrs for flexibility). |
None
|
Returns:
| Type | Description |
|---|---|
str | None
|
One of |
Examples:
- An explicit
axisattribute wins over everything else: - A
standard_nameis matched against the CF table: - A
unitsstring of the form<period> since <epoch>marks a time axis: - With no attributes, the variable name is matched by pattern:
- Attribute names are matched case-insensitively, so capitalized keys
(e.g.
Axis) still classify the coordinate: - An unrecognized name with no usable attributes returns
None:
Source code in src/pyramids/netcdf/cf.py
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | |
pyramids.netcdf.cf.parse_conventions(conventions_str)
#
Parse a Conventions global attribute string.
Logs a warning if the CF version is higher than the highest
tested version (1.11).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conventions_str
|
str | None
|
Space-separated conventions string, e.g.
|
required |
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
Dict of |
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.parse_cell_methods(cell_methods_str)
#
Parse a CF cell_methods attribute string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cell_methods_str
|
str
|
CF cell_methods string, e.g.
|
required |
Returns:
| Type | Description |
|---|---|
list[dict[str, str]]
|
List of dicts with keys |
list[dict[str, str]]
|
and optionally |
Examples:
- A single dimension and method:
- Several dimensions sharing one method are all captured:
- Independent entries, with a
wherequalifier:
Source code in src/pyramids/netcdf/cf.py
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 | |
pyramids.netcdf.cf.apply_valid_range_mask(arr, valid_min=None, valid_max=None, valid_range=None, fill_value=float('nan'))
#
Mask values outside the CF valid range.
Values below valid_min or above valid_max are replaced
with fill_value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arr
|
Any
|
Input numpy array. |
required |
valid_min
|
float | None
|
Minimum valid value. |
None
|
valid_max
|
float | None
|
Maximum valid value. |
None
|
valid_range
|
tuple | list | None
|
|
None
|
fill_value
|
float
|
Replacement value. Defaults to NaN. |
float('nan')
|
Returns:
| Type | Description |
|---|---|
Any
|
A copy of |
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.decode_flags(value, flag_values=None, flag_meanings=None, flag_masks=None)
#
Decode a CF flag value to human-readable label(s).
Supports three CF flag modes:
- Mutually exclusive (flag_values + flag_meanings): Returns the single meaning matching the value.
- Boolean / bit-field (flag_masks + flag_meanings): Returns a list of meanings for active bits.
- Combined (flag_masks + flag_values + flag_meanings):
Returns meanings where
(value & mask) == flag_value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
int
|
The integer flag value to decode. |
required |
flag_values
|
list | None
|
List of possible flag values (1:1 with meanings). |
None
|
flag_meanings
|
list[str] | None
|
List of human-readable meaning strings. |
None
|
flag_masks
|
list[int] | None
|
List of bit masks for boolean flags. |
None
|
Returns:
| Type | Description |
|---|---|
list[str]
|
list[str]: List of matching meaning strings. Returns |
list[str]
|
|
Source code in src/pyramids/netcdf/cf.py
pyramids.netcdf.cf.validate_cf(global_attrs, variables, dimensions)
#
Check for common CF compliance issues.
Returns a list of warning/error messages. An empty list means the dataset passes basic CF checks. This is NOT a full cfchecker replacement — it covers the most common issues.
Checks:
1. Conventions attribute present and contains "CF-"
2. Coordinate variables have units
3. Time coordinates have calendar
Limitation: Only checks dimension-coordinate variables (those
whose name matches a dimension). Auxiliary coordinates referenced
by the coordinates attribute on data variables are not
validated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
global_attrs
|
dict[str, Any]
|
Root-level attributes dict. |
required |
variables
|
dict[str, Any]
|
Dict of |
required |
dimensions
|
dict[str, Any]
|
Dict of |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of warning/error strings. Empty if compliant. |