# cf.Field.convolution_filter¶

Field.convolution_filter(window=None, axis=None, mode=None, cval=None, origin=0, update_bounds=True, inplace=False, weights=None, i=False)[source]

Convolve the field construct along the given axis with the specified filter.

The magnitude of the integral of the filter (i.e. the sum of the window weights defined by the window parameter) affects the convolved values. For example, window weights of [0.2, 0.2 0.2, 0.2, 0.2] will produce a non-weighted 5-point running mean; and window weights of [1, 1, 1, 1, 1] will produce a 5-point running sum. Note that the window weights returned by functions of the scipy.signal.windows package do not necessarily sum to 1 (see the examples for details).

Note

The moving_window method can not, in general, be emulated by the convolution_filter method, as the latter i) can not change the window weights as the filter passes through the axis; and ii) does not update the cell method constructs.

Parameters
window: sequence of numbers

Specify the window weights to use for the filter.

Parameter example:

An unweighted 5-point moving average can be computed with window=[0.2, 0.2, 0.2, 0.2, 0.2]

Note that the scipy.signal.windows package has suite of window functions for creating window weights for filtering (see the examples for details).

New in version 3.3.0: (replaces the old weights parameter)

axis:

Select the domain axis over which the filter is to be applied, defined by that which would be selected by passing the given axis description to a call of the field construct’s domain_axis method. For example, for a value of 'X', the domain axis construct returned by f.domain_axis('X') is selected.

mode: str, optional

The mode parameter determines how the input array is extended when the filter overlaps an array border. The default value is 'constant' or, if the dimension being convolved is cyclic (as ascertained by the iscyclic method), 'wrap'. The valid values and their behaviours are as follows:

mode

Description

Behaviour

'reflect'

The input is extended by reflecting about the edge

(c b a | a b c | c b a)

'constant'

The input is extended by filling all values beyond the edge with the same constant value (k), defined by the cval parameter.

(k k k | a b c | k k k)

'nearest'

The input is extended by replicating the last point

(a a a | a b c | d d d)

'mirror'

The input is extended by reflecting about the centre of the last point.

(c b | a b c | b a)

'wrap'

The input is extended by wrapping around to the opposite edge.

(a b c | a b c | a b c)

The position of the window relative to each value can be changed by using the origin parameter.

cval: scalar, optional

Value to fill past the edges of the array if mode is 'constant'. Ignored for other modes. Defaults to None, in which case the edges of the array will be filled with missing data.

Parameter example:

To extend the input by filling all values beyond the edge with zero: cval=0

origin: int, optional

Controls the placement of the filter. Defaults to 0, which is the centre of the window. If the window has an even number of weights then then a value of 0 defines the index defined by width/2 -1.

Parameter example:

For a weighted moving average computed with a weights window of [0.1, 0.15, 0.5, 0.15, 0.1], if origin=0 then the average is centred on each point. If origin=-2 then the average is shifted to include the previous four points. If origin=1 then the average is shifted to include the previous point and the and the next three points.

update_bounds: bool, optional

If False then the bounds of a dimension coordinate construct that spans the convolved axis are not altered. By default, the bounds of a dimension coordinate construct that spans the convolved axis are updated to reflect the width and origin of the window.

inplace: bool, optional

If True then do the operation in-place and return None.

i: deprecated at version 3.0.0

weights: deprecated at version 3.3.0

Returns
Field or None

The convolved field construct, or None if the operation was in-place.

Examples:

>>> f = cf.example_field(2)
>>> print(f)
Field: air_potential_temperature (ncvar%air_potential_temperature)
------------------------------------------------------------------
Data            : air_potential_temperature(time(36), latitude(5), longitude(8)) K
Cell methods    : area: mean
Dimension coords: time(36) = [1959-12-16 12:00:00, ..., 1962-11-16 00:00:00]
: latitude(5) = [-75.0, ..., 75.0] degrees_north
: longitude(8) = [22.5, ..., 337.5] degrees_east
: air_pressure(1) = [850.0] hPa
>>> print(f.array[:, 0, 0])
[210.7 305.3 249.4 288.9 231.1 200.  234.4 289.2 204.3 203.6 261.8 256.2
212.3 231.7 255.1 213.9 255.8 301.2 213.3 200.1 204.6 203.2 244.6 238.4
304.5 269.8 267.9 282.4 215.  288.7 217.3 307.1 299.3 215.9 290.2 239.9]
>>> print(f.coordinate('T').bounds.dtarray[0])
[cftime.DatetimeGregorian(1959-12-01 00:00:00)
cftime.DatetimeGregorian(1960-01-01 00:00:00)]
>>> print(f.coordinate('T').bounds.dtarray[2])
[cftime.DatetimeGregorian(1960-02-01 00:00:00)
cftime.DatetimeGregorian(1960-03-01 00:00:00)]


Create a 5-point (non-weighted) running mean:

>>> g = f.convolution_filter([0.2, 0.2, 0.2, 0.2, 0.2], 'T')
>>> print(g)
Field: air_potential_temperature (ncvar%air_potential_temperature)
------------------------------------------------------------------
Data            : air_potential_temperature(time(36), latitude(5), longitude(8)) K
Cell methods    : area: mean
Dimension coords: time(36) = [1959-12-16 12:00:00, ..., 1962-11-16 00:00:00]
: latitude(5) = [-75.0, ..., 75.0] degrees_north
: longitude(8) = [22.5, ..., 337.5] degrees_east
: air_pressure(1) = [850.0] hPa
>>> print(g.array[:, 0, 0])
[ -- -- 257.08 254.94 240.76 248.72 231.8 226.3 238.66 243.02 227.64
233.12 243.42 233.84 233.76 251.54 247.86 236.86 235.0 224.48 213.16
218.18 239.06 252.1 265.04 272.6 267.92 264.76 254.26 262.1 265.48
265.66 265.96 270.48 -- --]
>>> print(g.coordinate('T').bounds.dtarray[0])
[cftime.DatetimeGregorian(1959-12-01 00:00:00)
cftime.DatetimeGregorian(1960-03-01 00:00:00)]
>>> print(g.coordinate('T').bounds.dtarray[2])
[cftime.DatetimeGregorian(1959-12-01 00:00:00)
cftime.DatetimeGregorian(1960-05-01 00:00:00)]


Create a 5-point running sum:

>>> g = f.convolution_filter([1, 1, 1, 1, 1], 'T')
>>> print(g)
Field: air_potential_temperature (ncvar%air_potential_temperature)
------------------------------------------------------------------
Data            : air_potential_temperature(time(36), latitude(5), longitude(8)) K
Cell methods    : area: mean
Dimension coords: time(36) = [1959-12-16 12:00:00, ..., 1962-11-16 00:00:00]
: latitude(5) = [-75.0, ..., 75.0] degrees_north
: longitude(8) = [22.5, ..., 337.5] degrees_east
: air_pressure(1) = [850.0] hPa
>>> print(g.array[:, 0, 0])
[ -- -- 1285.4 1274.7 1203.8 1243.6 1159.0 1131.5 1193.3 1215.1
1138.2 1165.6 1217.1 1169.2 1168.8 1257.7 1239.3 1184.3 1175.0
1122.4 1065.8 1090.9 1195.3 1260.5 1325.2 1363.0 1339.6 1323.8
1271.3 1310.5 1327.4 1328.3 1329.8 1352.4 -- --]
>>> print(g.coordinate('T').bounds.dtarray[0])
[cftime.DatetimeGregorian(1959-12-01 00:00:00)
cftime.DatetimeGregorian(1960-03-01 00:00:00)]
>>> print(g.coordinate('T').bounds.dtarray[2])
[cftime.DatetimeGregorian(1959-12-01 00:00:00)
cftime.DatetimeGregorian(1960-05-01 00:00:00)]


Calculate a convolution along the time axis with Gaussian window weights, using the “nearest” mode at the border of the edges of the time dimension (note that the window weights returned by scipy.signal.windows functions do not necessarily sum to 1):

>>> import scipy.signal.windows
>>> gaussian_window = scipy.signal.windows.gaussian(3, std=0.4)
>>> print(gaussian_window)
[0.04393693 1.         0.04393693]
>>> g = f.convolution_filter(gaussian_window, 'T', mode='nearest')
>>> print(g.array[:, 0, 0])
[233.37145775 325.51538316 275.50732596 310.01169661 252.58076685
220.4526426  255.89394793 308.47513278 225.95212089 224.07900476
282.00220208 277.03050023 233.73682991 252.23612278 274.67829762
236.34737939 278.43191451 321.81081556 235.32558483 218.46124456
222.31976533 222.93647058 264.00254989 262.52577025 326.82874967
294.94950081 292.16197475 303.61714525 240.09238279 307.69393641
243.47762505 329.79781991 322.27901629 241.80082237 310.22645435
263.19096851]
>>> print(g.coordinate('T').bounds.dtarray[0])
[cftime.DatetimeGregorian(1959-12-01 00:00:00)
cftime.DatetimeGregorian(1960-02-01 00:00:00)]
>>> print(g.coordinate('T').bounds.dtarray[1])
[cftime.DatetimeGregorian(1959-12-01 00:00:00)
cftime.DatetimeGregorian(1960-03-01 00:00:00)]