Field overview

A Field represents a single horizontal slice of a geophysical quantity at a particular time and vertical level. It bundles together the data values and a set of replaceable metadata components, each responsible for a distinct aspect of the metadata:

Attribute

What it describes

field.parameter

Physical quantity: variable name, units, CF names

field.time

Temporal coordinate: base datetime, forecast step, valid datetime

field.vertical

Vertical coordinate: level value, level type

field.geography

Horizontal grid: lat/lon arrays, bounding box, projection

field.ensemble

Ensemble member identifier

field.proc

Post-processing operations (e.g. accumulation). Experimental.

All component keys are also accessible through the generic py:meth:`~earthkit.data.core.field.Field.get` interface.

Load data

[1]:
import earthkit.data as ekd
[2]:
ds = ekd.from_source("sample", "test.grib")
ds
[2]:
GRIB file

path/var/folders/93/w0p869rx17q98wxk83gn9ys40000gn/T/tmp7di2ty1r/url-3d2bc4976d3b9f59146160e41a1ba98175e42d42e500f37b9d97e62e3bbe41fd.grib
size1 KiB
typesfieldlist, pandas, xarray, numpy, array
[3]:
f = ds.to_fieldlist()[0]
f
[3]:
Field
number_of_values209
array_typendarray
array_dtypefloat64
variable2t
standard_nameunknown
long_name2 metre temperature
unitskelvin
valid_datetime2020-05-13 12:00:00
base_datetime2020-05-13 12:00:00
step0:00:00
level0
layerNone
level_typesurface
member0
grid_spec{'area': [73, -27, 33, 45], 'grid': [4, 4]}
grid_typeregular_ll
shape(11, 19)
area(73.0, -27.0, 33.0, 45.0)

Parameter component

The Parameter component describes the physical quantity the field represents.

[4]:
print(f.parameter.variable())  # short variable name
print(f.parameter.units())  # native units
print(f.parameter.standard_name())  # CF standard name
print(f.parameter.long_name())  # human-readable description

# Same information via the generic get() interface
print(f.get("parameter.variable"))
print(f.get("parameter.units"))
2t
kelvin
unknown
2 metre temperature
2t
kelvin

Time component

The Time component describes the temporal coordinate: base datetime, forecast step, and valid datetime.

[5]:
print(f.time.base_datetime())  # analysis/reference time
print(f.time.step())  # forecast step as timedelta
print(f.time.valid_datetime())  # base_datetime + step

# Same information via get()
print(f.get("time.base_datetime"))
print(f.get("time.step"))
2020-05-13 12:00:00
0:00:00
2020-05-13 12:00:00
2020-05-13 12:00:00
0:00:00

Vertical component

The Vertical component describes where in the atmosphere, ocean, or land the field is defined.

[6]:
print(f.vertical.level())  # level value in native units
print(f.vertical.level_type())  # e.g. "surface", "pressure", "hybrid"
print(f.vertical.units())  # units of the level value
print(f.vertical.positive())  # "up" or "down"

# Same information via get()
print(f.get("vertical.level"))
print(f.get("vertical.level_type"))
0
surface
dimensionless
None
0
surface

Geography component

The Geography component describes the horizontal grid: shape, bounding box, projection, and coordinates.

[7]:
print(f.geography.shape())  # grid dimensions
print(f.geography.area())  # bounding box (north, west, south, east)
print(f.geography.grid_type())  # e.g. "regular_ll", "reduced_gg"

# Retrieve all lat/lon coordinates for every grid point
lat, lon = f.geography.latlons()
print(lat.shape, lon.shape)

# Same information via get()
print(f.get("geography.shape"))
print(f.get("geography.area"))
(11, 19)
(73.0, -27.0, 33.0, 45.0)
regular_ll
(11, 19) (11, 19)
(11, 19)
(73.0, -27.0, 33.0, 45.0)

Data values

The values returns a copy of the underlying flat 1-D array. Use to_numpy() to get an array shaped to the grid.

[8]:
v = f.values  # flat 1-D copy
print(v.shape, v.dtype)
print(f"min={v.min():.2f}  max={v.max():.2f}")

v2d = f.to_numpy()  # shaped to (Nj, Ni)
print(v2d.shape)
(209,) float64
min=262.78  max=315.46
(11, 19)

Modifying a field

All components are immutable. Use set() to derive a modified copy. The original field is never changed.

[9]:
# Change the forecast step
new_f = f.set({"time.step": 6})
print(f.time.step(), "->", new_f.time.step())

# Change the parameter variable and units
new_f2 = f.set({"parameter.variable": "msl", "parameter.units": "Pa"})
print(f.parameter.variable(), "->", new_f2.parameter.variable())

# Change the level
new_f3 = f.set({"vertical.level": 500, "vertical.level_type": "pressure"})
print(f.vertical.level(), "->", new_f3.vertical.level())

# Replace the data values (must match the grid shape)
new_values = f.values + 10.0
new_f4 = f.set({"values": new_values})
print(f"original mean={f.values.mean():.2f}  modified mean={new_f4.values.mean():.2f}")
0:00:00 -> 6:00:00
2t -> msl
0 -> 500
original mean=283.99  modified mean=293.99