-
Notifications
You must be signed in to change notification settings - Fork 76
Open
Description
Version of compliance checker running:
5.4.2
Describe the checker this affects:
CF checkers
Attach a minimal CDL or NetCDF file which is able to reproduce the issue
netcdf example_timeseries_cf_1_11 {
dimensions:
time = 24 ;
variables:
double air_temperature(time) ;
air_temperature:_FillValue = -9999. ;
air_temperature:standard_name = "air_temperature" ;
air_temperature:long_name = "Air temperature" ;
air_temperature:units = "K" ;
air_temperature:coordinates = "time lat lon" ;
int64 time(time) ;
time:long_name = "Time of measurement" ;
time:axis = "T" ;
time:units = "seconds since 1970-01-01" ;
time:calendar = "gregorian" ;
double lat ;
lat:_FillValue = NaN ;
lat:standard_name = "latitude" ;
lat:long_name = "Station latitude" ;
lat:units = "degrees_north" ;
lat:axis = "Y" ;
double lon ;
lon:_FillValue = NaN ;
lon:standard_name = "longitude" ;
lon:long_name = "Station longitude" ;
lon:units = "degrees_east" ;
lon:axis = "X" ;
string station ;
station:long_name = "Station Identifier" ;
// global attributes:
:title = "Example CF-1.11 Time Series Dataset" ;
:summary = "Synthetic single-station hourly air temperature time series for CF compliance checking." ;
:institution = "Example Organization" ;
:source = "Synthetic generation with xarray" ;
:history = "Created 2025-09-21T18:21:58.371791Z by xarray" ;
:references = "https://cfconventions.org/" ;
:Conventions = "CF-1.11" ;
:featureType = "timeSeries" ;
:geospatial_lat_min = 42. ;
:geospatial_lat_max = 42. ;
:geospatial_lon_min = -71. ;
:geospatial_lon_max = -71. ;
:time_coverage_start = "2025-01-01T00:00:00Z" ;
:time_coverage_end = "2025-01-01T23:00:00Z" ;
:coordinates = "station" ;
}
To Reproduce:
# Create a simple CF-1.11 compliant time series NetCDF file with xarray
import numpy as np
import pandas as pd
import xarray as xr
from datetime import datetime, timezone
# Configuration
n_time = 24 # 24 hourly samples
start_time = "2025-01-01"
station_id = "station01"
output_path = "example_timeseries_cf_1_11.nc"
# Create a time coordinate (naive UTC datetimes; CF assumes UTC if no timezone)
time = pd.date_range(start_time, periods=n_time, freq="H")
# Generate example data (air temperature in Kelvin)
rng = np.random.default_rng(seed=42)
air_temperature_K = 273.15 + 5 + 2 * np.sin(np.linspace(0, 2 * np.pi, n_time)) + rng.normal(0, 0.3, n_time)
# Build Dataset
# We model a single-station timeSeries feature: dimensions (time, station)
ds = xr.Dataset(
data_vars={
"air_temperature": ("time", air_temperature_K, {
"standard_name": "air_temperature",
"long_name": "Air temperature",
"units": "K",
"coordinates": "time lat lon",
})
},
coords={
"time": ("time", time, {
# "standard_name": "time",
"long_name": "Time of measurement",
"axis": "T"
}),
# Represent the station as scalar lat/lon coordinates (1D with length 1 is also acceptable)
"lat": ((), 42.0, { # scalar coordinate
"standard_name": "latitude",
"long_name": "Station latitude",
"units": "degrees_north",
"axis": "Y"
}),
"lon": ((), -71.0, {
"standard_name": "longitude",
"long_name": "Station longitude",
"units": "degrees_east",
"axis": "X"
}),
"station": ((), station_id, {"long_name": "Station Identifier"}),
},
attrs={
"title": "Example CF-1.11 Time Series Dataset",
"summary": "Synthetic single-station hourly air temperature time series for CF compliance checking.",
"institution": "Example Organization",
"source": "Synthetic generation with xarray",
"history": f"Created {datetime.utcnow().isoformat()}Z by xarray",
"references": "https://cfconventions.org/",
"Conventions": "CF-1.11",
"featureType": "timeSeries",
# ACDD geospatial + temporal summary (optional but useful)
"geospatial_lat_min": 42.0,
"geospatial_lat_max": 42.0,
"geospatial_lon_min": -71.0,
"geospatial_lon_max": -71.0,
"time_coverage_start": time[0].isoformat() + "Z",
"time_coverage_end": time[-1].isoformat() + "Z",
}
)
# Explicit encodings for CF-compliant time (numeric since epoch) & fill values if needed
encoding = {
"time": {"units": "seconds since 1970-01-01 00:00:00", "calendar": "gregorian"},
"air_temperature": {"_FillValue": -9999.0}
}
# Write NetCDF file
ds.to_netcdf(output_path, format="NETCDF4", encoding=encoding)
print(f"Wrote CF-1.12 example file: {output_path}")
print(ds)command
compliance-checker -t cf:1.11 example_timeseries_cf_1_11.nc
Describe the issue below:
The example above throws the following error:
Errors
--------------------------------------------------------------------------------
§5.1 Independent Latitude, Longitude, Vertical, and Time Axes
* Coordinate variable 'time' should have standard_name='time', found: 'None'
From my understanding of the CF convention regarding relative time axis, this should only be a warning, because
A reference time coordinate is identifiable from its units string alone.
it is only optional to provide a standard name for the time axis:
Optionally, the time coordinate may be indicated additionally by providing the standard_name attribute with an appropriate value, and/or the axis attribute with the value T.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels