Creating cf.Field
objects¶
Note
For versions 3.x (Python 3) documentation, see https://ncas-cms.github.io/cf-python
A new field may be created by initializing a new cf.Field
instance
with properties and a data array:
Keyword | Description |
---|---|
attributes |
Provide the new field with non-CF attributes in a dictionary |
data |
Provide the new field with a data array in a cf.Data object |
flags |
Provide the new field with self-describing flag values in a
cf.Flags object |
properties |
Provide the new field with CF properties in a dictionary |
Other metadata items (coordinate, cell methods, etc.) are then provided with bespoke methods:
cf.Field.insert_aux |
Insert an auxiliary coordinate object into the field. |
cf.Field.insert_axis |
Insert a domain axis into the field. |
cf.Field.insert_cell_methods |
Insert one or more cell method objects into the field. |
cf.Field.insert_domain_anc |
Insert a domain ancillary object into the field. |
cf.Field.insert_data |
Insert a data array into the field. |
cf.Field.insert_dim |
Insert a dimension coordinate object into the field. |
cf.Field.insert_field_anc |
Insert a field ancillary object into the field. |
cf.Field.insert_measure |
Insert a cell measure object into the field. |
cf.Field.insert_ref |
Insert a coordinate reference object into the field. |
For example:
>>> coord
<CF DimensionCoordinate: time(12) days since 2003-12-1>
>>> f.insert_dim(coord)
Removing field components is done with the following methods:
cf.Field.remove_axis |
Remove and return a unique axis from the field. |
cf.Field.remove_axes |
Remove and return axes from the field. |
cf.Field.remove_data |
Remove and return the data array. |
cf.Field.remove_item |
Remove and return an item from the field. |
cf.Field.remove_items |
Remove and return items from the field. |
For example:
>>> f.remove_item('forecast_reference_time')
Examples¶
To improve readability, it is recommended that the construction of a field is done by first creating the components separately (data, coordinates, properties, etc.), and then combining them to make the field (as in example 3 and example 4), although this may not be necessary for very simple fields (as in example 1 and example 2).
Example 2¶
A field with just CF properties:
>>> f = cf.Field(properties={'standard_name': 'air_temperature',
... 'long_name': 'temperature of air'})
...
>>> print f
Field: air_temperature
----------------------
Example 3¶
A field with a simple domain. Note that in this example the data and
coordinates are generated using range
and numpy.arange
simply for the sake of having some numbers to play with. In practice
it is likely the values would have been read from a file in some
arbitrary format:
>>> import numpy
>>> data = cf.Data(numpy.arange(90.).reshape(10, 9), 'm s-1')
>>> properties = {'standard_name': 'eastward_wind'}
>>> dim0 = cf.DimensionCoordinate(data=cf.Data(range(10), 'degrees_north'),
... properties={'standard_name': 'latitude'})
>>> dim1 = cf.DimensionCoordinate(data=cf.Data(range(9), 'degrees_east'))
>>> dim1.standard_name = 'longitude'
>>> f = cf.Field(properties=properties)
>>> f.insert_dim(dim0)
>>> f.insert_dim(dim1)
>>> f.insert_data(data)
>>> print f
Field: eastward_wind
--------------------
Data : eastward_wind(latitude(10), longitude(9)) m s-1
Axes : latitude(10) = [0, ..., 9] degrees_north
: longitude(9) = [0, ..., 8] degrees_east
Adding an auxiliary coordinate to the “latitude” axis and a cell method may be done with the relevant methods (note that these coordinate values are just for illustration):
>>> aux = cf.AuxiliaryCoordinate(data=cf.Data(['alpha','beta','gamma','delta','epsilon',
... 'zeta','eta','theta','iota','kappa']))
>>> aux.long_name = 'extra'
>>> f.insert_aux(aux, axes=['dim0'])
>>> f.insert_cell_methods('latitude: point')
>>> f.long_name = 'wind'
>>> print f
Field: eastward_wind
--------------------
Data : eastward_wind(latitude(10), longitude(9)) m s-1
Cell methods : latitude: point
Axes : latitude(10) = [0, ..., 9] degrees_north
: longitude(9) = [0, ..., 8] degrees_east
Aux coords : long_name:extra(latitude(10)) = [alpha, ..., kappa]
Removing the auxiliary coordinate and the cell method that were just added is also done with a method and by simple deletion:
>>> f.remove_item({'long_name': 'extra'})
>>> del f.cell_methods
>>> print f
Field: eastward_wind
--------------------
Data : eastward_wind(latitude(10), longitude(9)) m s-1
Axes : latitude(10) = [0, ..., 9] degrees_north
: longitude(9) = [0, ..., 8] degrees_east
Example 4¶
A more complicated field is created by the following script. Note that
in this example the data and coordinates are generated using
numpy.arange
simply for the sake of having some numbers to play
with. In practice it is likely the values would have been read from a
file in some arbitrary format:
import numpy
import cf
#---------------------------------------------------------------------
# 1. CREATE the field's domain items
#---------------------------------------------------------------------
# Create a grid_latitude dimension coordinate
Y = cf.DimensionCoordinate(properties={'standard_name': 'grid_latitude'},
data=cf.Data(numpy.arange(10.), 'degrees'))
# Create a grid_longitude dimension coordinate
X = cf.DimensionCoordinate(data=cf.Data(numpy.arange(9.), 'degrees'))
X.standard_name = 'grid_longitude'
# Create a time dimension coordinate (with bounds)
bounds = cf.Bounds(data=cf.Data([0.5, 1.5],
cf.Units('days since 2000-1-1', calendar='noleap')))
T = cf.DimensionCoordinate(properties=dict(standard_name='time'),
data=cf.Data(1, cf.Units('days since 2000-1-1',
calendar='noleap')),
bounds=bounds)
# Create a longitude auxiliary coordinate
lat = cf.AuxiliaryCoordinate(data=cf.Data(numpy.arange(90).reshape(10, 9),
'degrees_north'))
lat.standard_name = 'latitude'
# Create a latitude auxiliary coordinate
lon = cf.AuxiliaryCoordinate(properties=dict(standard_name='longitude'),
data=cf.Data(numpy.arange(1, 91).reshape(9, 10),
'degrees_east'))
# Create a rotated_latitude_longitude grid mapping coordinate reference
grid_mapping = cf.CoordinateReference('rotated_latitude_longitude',
parameters={
'grid_north_pole_latitude': 38.0,
'grid_north_pole_longitude': 190.0})
#---------------------------------------------------------------------
# 3. Create the field
#---------------------------------------------------------------------
# Create CF properties
properties = {'standard_name': 'eastward_wind',
'long_name' : 'East Wind'}
# Create the field's data array
data = cf.Data(numpy.arange(90.).reshape(9, 10), 'm s-1')
# Finally, create the field
f = cf.Field(properties=properties)
f.insert_cell_methods('latitude: point')
f.insert_dim(T)
f.insert_dim(X)
f.insert_dim(Y)
f.insert_aux(lat)
f.insert_aux(lon)
f.insert_ref(grid_mapping)
f.insert_data(data)
print_f = str(f)
self.assertTrue(
print f
Running this script produces the following output:
The new field:
Field: eastward_wind
--------------------
Data : eastward_wind(grid_longitude(9), grid_latitude(10)) m s-1
Cell methods : latitude: point
Axes : time(1) = [2000-01-02T00:00:00Z] noleap
: grid_longitude(9) = [0.0, ..., 8.0] degrees
: grid_latitude(10) = [0.0, ..., 9.0] degrees
Aux coords : latitude(grid_latitude(10), grid_longitude(9)) = [[0, ..., 89]] degrees_north
: longitude(grid_longitude(9), grid_latitude(10)) = [[1, ..., 90]] degrees_east
Coord refs : rotated_latitude_longitude
Example 5¶
Example 4 would be slightly more complicated if
the grid_longitude
and grid_latitude
axes were to have the
same size. In this case the field needs be told which axes, and in
which order, are spanned by the two dimensional auxiliary coordinates
(latitude
and longitude
) and the field needs to know which
axes span the data array:
import numpy
import cf
import cf
import numpy
#---------------------------------------------------------------------
# 1. CREATE the field's domain items
#---------------------------------------------------------------------
# Create a grid_latitude dimension coordinate
Y = cf.DimensionCoordinate(properties={'standard_name': 'grid_latitude'},
data=cf.Data(numpy.arange(10.), 'degrees'))
# Create a grid_longitude dimension coordinate
X = cf.DimensionCoordinate(data=cf.Data(numpy.arange(10.), 'degrees'))
X.standard_name = 'grid_longitude'
# Create a time dimension coordinate (with bounds)
bounds = cf.Bounds(data=cf.Data([0.5, 1.5],
cf.Units('days since 2000-1-1', calendar='noleap')))
T = cf.DimensionCoordinate(properties=dict(standard_name='time'),
data=cf.Data(1, cf.Units('days since 2000-1-1',
calendar='noleap')),
bounds=bounds)
# Create a longitude auxiliary coordinate
lat = cf.AuxiliaryCoordinate(data=cf.Data(numpy.arange(100).reshape(10, 10),
'degrees_north'))
lat.standard_name = 'latitude'
# Create a latitude auxiliary coordinate
lon = cf.AuxiliaryCoordinate(properties=dict(standard_name='longitude'),
data=cf.Data(numpy.arange(1, 101).reshape(10, 10),
'degrees_east'))
# Create a rotated_latitude_longitude grid mapping coordinate reference
grid_mapping = cf.CoordinateReference('rotated_latitude_longitude',
parameters={
'grid_north_pole_latitude': 38.0,
'grid_north_pole_longitude': 190.0})
#---------------------------------------------------------------------
# 3. Create the field
#---------------------------------------------------------------------
# Create CF properties
properties = {'standard_name': 'eastward_wind',
'long_name' : 'Eastward Wind'}
# Create the field's data array
data = cf.Data(numpy.arange(100.).reshape(10, 10), 'm s-1')
# Finally, create the field
f = cf.Field(properties=properties)
f.insert_cell_methods('latitude: point')
f.insert_dim(T)
f.insert_dim(X)
f.insert_dim(Y)
f.insert_aux(lat, axes=['Y', 'X'])
f.insert_aux(lon, axes=['X', 'Y'])
f.insert_ref(grid_mapping)
f.insert_data(data, axes=['Y', 'X'])
print f
Running this script produces the following output:
field: eastward_wind
--------------------
Data : eastward_wind(grid_latitude(10), grid_longitude(10)) m s-1
Cell methods : latitude: point
Axes : time(1) = [2000-01-02T00:00:00Z] noleap
: grid_latitude(10) = [0.0, ..., 9.0] degrees
: grid_longitude(10) = [0.0, ..., 9.0] degrees
Aux coords : latitude(grid_latitude(10), grid_longitude(10)) = [[0, ..., 99]] degrees_north
: longitude(grid_longitude(10), grid_latitude(10)) = [[1, ..., 100]] degrees_east
Coord refs : rotated_latitude_longitude