The read function will read CF-netCDF and PP format files from disk (or netCDF file from an OPeNDAP server) and return their contents as a field list, i.e. an ordered collection of fields stored in a FieldList object:
>>> f = cf.read('data.nc')
>>> type(f)
<class 'cf.field.FieldList'>
>>> f
[<CF Field: pressure(30, 24)>,
<CF Field: u_compnt_of_wind(19, 29, 24)>,
<CF Field: v_compnt_of_wind(19, 29, 24)>,
<CF Field: potential_temperature(19, 30, 24)>]
>>> type(f[-1])
<class 'cf.field.Field'>
>>> f[-1]
<CF Field: potential_temperature(19, 30, 24)>
The read function always returns a field list as opposed to a field. If a single field as a Field object is required, then the read function (or rather its returned field list) may be indexed:
>>> f = cf.read('file1.nc')[0]
>>> type(f)
<class 'cf.field.Field'>
See the section on variable lists for more details on fields and list of fields.
>>> f = cf.read('*.nc')
>>> f = cf.read('file[1-9a-c].nc')
>>> f = cf.read('dir*/*.pp')
>>> f = cf.read(['file1.nc', 'file2.nc'])
The file format is inferred from the file contents, not from the file name suffix.
The write function will write fields to a CF-netCDF file on disk:
>>> type(g)
<class 'cf.field.Field'>
>>> cf.write(g, 'newfile.nc')
>>> type(f)
<class 'cf.field.FieldList'>
>>> cf.write(f, 'newfile.nc')
A sequence of fields and field lists may be written to the same file:
>>> cf.write([f, g], 'newfile.nc')
All of the input fields are written to the same output file, but if metadata (such as coordinates) are identical in two or more fields then that metadata is only written once to the output file.
Output file names are arbitrary (in particular, they do not require a suffix).
The field’s standard and non-standard CF attributes are returned by the attributes attribute:
>>> f.attributes
{'_FillValue': 1e+20,
'cell_methods': <CF CellMethods: time: mean>,
'standard_name': 'air_temperature',
'units': 'K'}
Individual attributes recognised by the CF conventions (such as standard_name) may be set, retrieved and deleted as standard python object attributes:
>>> f.standard_name = 'air_temperature'
>>> f.standard_name
'air_temperature'
>>> del f.standard_name
>>> setattr(f, 'standard_name', 'air_pressure')
>>> getattr(f, 'standard_name')
'air_pressure'
>>> delattr(f, 'standard_name')
Any attribute (recognised by the CF conventions or not) may be retrieved with the field’s getattr method, which accepts an optional default value argument in the same way as the python built-in getattr function:
>>> f.getattr('standard_name')
'air_temperature'
>>> f.getattr('non_standard_attribute', None)
3.5
>>> f.hasattr('another_non_standard_attribute')
False
>>> f.getattr('another_non_standard_attribute', None)
None
Any attribute (recognised by the CF conventions or not) may be set with the field’s setattr method:
>>> f.setattr('standard_name', 'air_temperature')
>>> f.setattr('non_standard_attribute', 3.5)
Any attribute (recognised by the CF conventions or not) may be deleted with the field’s delattr method.
>>> f.delattr('standard_name')
>>> f.delattr('non_standard_attribute')
Other attributes (called private attributes) which do not clash with reserved names (such as ‘long_name’, ‘match’, etc.) may be set, retrieved and deleted as usual, but they will not appear in the attributes returned by the attributes dictionary:
>>> f.ncvar = 'tas'
>>> f.ncvar
>>> 'tas'
>>> del f.ncvar
>>> f.file
'file.nc'
Fields may be selected with the match and extract. These methods take conditions on field attributes and coordinates as inputs:
>>> f
[<CF Field: eastward_wind(110, 106)>,
<CF Field: air_temperature(12, 73, 96)>]
>>> f.match(attr={'standard_name': '.*temperature'})
[False, True]
>>> g = f.extract(attr={'standard_name': '.*temperature'}, coord={'longitude': 0})
>>> g
[<CF Field: air_temperature(12, 73, 96)>]
The fields data array may be retrieved as an independent numpy array with the field’s array attribute:
>>> f.array
masked_array(data =
[[ 2. 4.]
[ 5. 1.]],
mask = False,
fill_value = 1e+20)
The first and last elements of the data array may be retrieved as with the field’s first_datum and last_datum attributes:
>>> f.first_datum
2.0
>>> f.last_datum
1.0
A coordinate of the field’s coordinate system is returned by the field’s coord method. A coordinate has the same attribute and data access principles as a field:
>>> c = f.coord('time')
>>> c
<CF Coordinate: time(12)>
>>> c.attributes
{'_FillValue': None,
'axis': 'T',
'bounds': <CF CoordinateBounds: time_bnds(12, 2)>,
'calendar': 'noleap',
'long_name': 'time',
'standard_name': 'time',
'units': 'days since 0000-1-1'}
>>> c.Units
<CF Units: days since 0000-1-1 calendar=noleap>
>>> c.array
masked_array(data = [ 0 30 60 90 120 150 180 210 240 270 300 330],
mask = False,
fill_value = 999999)