Incompatible differences between versions 1.x and 2.x

For those familiar with the cf-python API at version 1.x, some important, backwards incompatible changes were introduced at version 2.0.

Some of these changes will break code written at version 1.x, causing an exception to be raised. For others, those marked with a warning, version 1.x may work but could produce scientifically different results.

All of the changes have been designed to make the interface more consistent and intuitive to use and were introduced at version 2.0 to coincide with the updated CF data model structure.

axes

Note

At version 2.x cf.Field.axes returns, by default, a dict. If the ordered parameter is True then it returns an OrderedDict.

>>> cf.__version__
2.0
>>> f
<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>
>>> f.axes()
{'dim0': <CF DomainAxis: 12>,
 'dim1': <CF DomainAxis: 64>,
 'dim2': <CF DomainAxis: 128>,
 'dim3': <CF DomainAxis: 1>}
>>> f.axes(ordered=True)
OrderedDict([('dim3', <CF DomainAxis: 1>),
             ('dim0', <CF DomainAxis: 12>),
             ('dim1', <CF DomainAxis: 64>),
             ('dim2', <CF DomainAxis: 128>)])

At version 1.x it returned a set by default or, if the ordered parameter was True, it returned a list.

axis

Note

At version 2.x cf.Field.axis returns, by default, a cf.DomainAxis object. A domain axis identifier (such as “dim2”) may be returned by setting the key parameter to True.

>>> cf.__version__
2.0
>>> f
<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>
>>> f.axis('X')
<CF DomainAxis: 128>
>>> f.axis('X', key=True)
'dim2'

At version 1.x it always returned a domain axis identifier.

collapse

Warning

Running code written at version 1.x with the version 2.x library could produce scientifically different results.

Note

At version 2.x cf.Field.collapse does not, by default, weight the calculations, i.e. the weights parameter defaults to None.

>>> cf.__version__
2.0
>>> f
<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>
>>> g = f.collapse('mean')
>>> g.datum()
279.1922
>>> g = f.collapse('mean', weights=None)
>>> g.datum()
279.1922

Non-equal weighting has to be specifically requested with the weights parameter.

>>> h = f.collapse('mean', weights=['area', 'T'])
>>> h.datum()
288.6733

At version 1.x the weights parameter defaulted to “auto”, meaning that calculations were were weighted according to metadata present in the field.

dump

Note

At version 2.x the output of cf.Field.dump has been reformatted.

read

Note

At version 2.x cf.read always returns a cf.FieldList.

>>> cf.__version__
2.0
>>> fl = cf.read('file[12].nc')
>>> fl
[<CF Field: specific_humidity(latitude(73), longitude(96)) K>,
 <CF Field: air_pressure(height(17), latitude(145), longitude(196)) K>]
>>> fl = cf.read('file3.nc')
>>> fl
[<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>]

The new function cf.read1 will always return a cf.Field if there is only one identified in the input file(s).

>>> f = cf.read1('file3.nc')
>>> f
<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>

At version 1.x cf.read returned a cf.Field if only one field was found in the input files(s), otherwise it returned a cf.FieldList.

regridc

Note

At version 2.x cf.Field.regridc the regridding method must be specified. The method parameter does not have an “auto” option.

>>> cf.__version__
2.0
>>> f
<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>
>>> g
<CF Field: specific_humidity(time(360), latitude(73), longitude(96)) K>
>>> h = f.regridc(g, 'time', 'nearest_stod')
>>> h
<CF Field: air_temperature(time(360), latitude(64), longitude(128)) K>

At version 1.x the regridding method defaulted to “auto”, meaning that the method was inferred according to metadata present in the field.

regrids

Note

At version 2.x cf.Field.regrids the regridding method must be specified. The method parameter does not have an “auto” option.

>>> cf.__version__
2.0
>>> f
<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>
>>> g
<CF Field: specific_humidity(time(360), latitude(73), longitude(96)) K>
>>> h = f.regrids(g, 'conservative')
>>> h
<CF Field: air_temperature(time(12), latitude(73), longitude(96)) K>

At version 1.x the regridding method defaulted to “auto”, meaning that the method was inferred according to metadata present in the field.

select

Note

At version 2.x cf.Field.select has been removed. Use cf.Field.match to see if an individual field meets given criteria.

>>> cf.__version__
2.0
>>> f
<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>
>>> f.match('air_temperature')
True

cf.FieldList.select always returns another field list.

>>> fl
[<CF Field: specific_humidity(latitude(73), longitude(96)) K>,
 <CF Field: air_pressure(height(17), latitude(145), longitude(196)) K>]
>>> fl.select('specific_humidity|air_pressure')
[<CF Field: specific_humidity(latitude(73), longitude(96)) K>,
 <CF Field: air_pressure(height(17), latitude(145), longitude(196)) K>]
>>> fl.select('specific_humidity')
[<CF Field: specific_humidity(latitude(73), longitude(96)) K>]
>>> fl.select('ocean_meridional_overturning_streamfunction')
[]

The new method cf.FieldList.select1 will always return a cf.Field if there is only one identified in the field list.

>>> fl.select1('specific_humidity')
<CF Field: specific_humidity(latitude(73), longitude(96)) K>

At version 1.x cf.FieldList.select returned a cf.Field if only one field element was found in the field list, otherwise it returned a cf.FieldList.

subspace

Warning

Running code written at version 1.x with the version 2.x library could produce scientifically different results.

Note

At version 2.x indexing on a field object returns a subspace of the field, in much the same way that a numpy array is subspaced by indexing. This means that there are now two equivalent ways to subspace a field in index-space: by indexing the field directly or by indexing the cf.Field.subspace attribute.

>>> cf.__version__
2.0
>>> f
<CF Field: air_temperature(time(12), latitude(64), longitude(128)) K>
>>> g = f[::-2, 0, 28:]
>>> g
<CF Field: air_temperature(time(6), latitude(1), longitude(100)) K>
>>> h = f.subspace[::-2, 0, 28:]
>>> h
<CF Field: air_temperature(time(6), latitude(1), longitude(100)) K>
>>> g.equals(h)
True

Assignment to subspaces may be done with either approach.

>>> g = f.copy()
>>> g[0] = -99
>>> h = f.copy()
>>> h.subspace[0] = -99
>>> g.equals(h)
True

Calling the cf.Field.subspace attribute to subspace the field in domain-space still works in the same way.

>>> f.subspace(long=cf.gt(90), Y=0)
<CF Field: air_temperature(time(12), latitude(1), longitude(96)) K>

The cf.FieldList.subspace method has been removed.

At version 1.x direct indexing on a field returned the itself, with no subspacing.