clouddrift.kinematics#
Functions for kinematic computations.
Functions
|
Extract inertial oscillations from consecutive geographical positions. |
|
Compute kinetic energy from zonal and meridional velocities. |
|
Compute positions from arrays of velocities and time and a pair of origin coordinates. |
Return residual longitudes and latitudes along a trajectory on the spherical Earth after correcting for zonal and meridional displacements x and y in meters. |
|
|
Compute spin continuously from velocities and times. |
|
Compute velocity from arrays of positions and time. |
- clouddrift.kinematics.inertial_oscillation_from_position(longitude: ndarray, latitude: ndarray, relative_bandwidth: float | None = None, wavelet_duration: float | None = None, time_step: float = 3600.0, relative_vorticity: float | ndarray = 0.0) ndarray [source]#
Extract inertial oscillations from consecutive geographical positions.
This function acts by performing a time-frequency analysis of horizontal displacements with analytic Morse wavelets. It extracts the portion of the wavelet transform signal that follows the inertial frequency (opposite of Coriolis frequency) as a function of time, potentially shifted in frequency by a measure of relative vorticity. The result is a pair of zonal and meridional relative displacements in meters.
This function is equivalent to a bandpass filtering of the horizontal displacements. The characteristics of the filter are defined by the relative bandwidth of the wavelet transform or by the duration of the wavelet, see the parameters below.
Parameters#
- longitudearray-like
Longitude sequence. Unidimensional array input.
- latitudearray-like
Latitude sequence. Unidimensional array input.
- relative_bandwidthfloat, optional
Bandwidth of the frequency-domain equivalent filter for the extraction of the inertial oscillations; a number less or equal to one which is a fraction of the inertial frequency. A value of 0.1 leads to a bandpass filter equivalent of +/- 10 percent of the inertial frequency.
- wavelet_durationfloat, optional
Duration of the wavelet, or inverse of the relative bandwidth, which can be passed instead of the relative bandwidth.
- time_stepfloat, optional
The constant time interval between data points in seconds. Default is 3600.
- relative_vorticity: Optional, float or array-like
Relative vorticity adding to the local Coriolis frequency. If “f” is the Coriolis frequency then “f” + relative_vorticity will be the effective Coriolis frequency as defined by Kunze (1985). Positive values correspond to cyclonic vorticity, irrespectively of the latitudes of the data points.
Returns#
- xhatarray-like
Zonal relative displacement in meters from inertial oscillations.
- yhatarray-like
Meridional relative displacement in meters from inertial oscillations.
Examples#
To extract displacements from inertial oscillations from sequences of longitude and latitude values, equivalent to bandpass around 20 percent of the local inertial frequency:
>>> xhat, yhat = inertial_oscillation_from_position(longitude, latitude, relative_bandwidth=0.2)
The same result can be obtained by specifying the wavelet duration instead of the relative bandwidth:
>>> xhat, yhat = inertial_oscillation_from_position(longitude, latitude, wavelet_duration=5)
Next, the residual positions from the inertial displacements can be obtained with another function:
>>> residual_longitudes, residual_latitudes = residual_position_from_displacement(longitude, latitude, xhat, yhat)
Raises#
- ValueError
If longitude and latitude arrays do not have the same shape. If relative_vorticity is an array and does not have the same shape as longitude and latitude. If time_step is not a float. If both relative_bandwidth and wavelet_duration are specified. If neither relative_bandwidth nor wavelet_duration are specified. If the absolute value of relative_bandwidth is not in the range (0,1]. If the wavelet duration is not greater than or equal to 1.
See Also#
residual_position_from_displacement()
, wavelet_transform, morse_wavelet
- clouddrift.kinematics.kinetic_energy(u: float | list | ndarray | DataArray | Series, v: float | list | ndarray | DataArray | Series | None = None) float | ndarray | DataArray [source]#
Compute kinetic energy from zonal and meridional velocities.
Parameters#
- ufloat or array-like
Zonal velocity.
- vfloat or array-like, optional.
Meridional velocity. If not provided, the flow is assumed one-dimensional in time and defined by
u
.
Returns#
- kefloat or array-like
Kinetic energy.
Examples#
>>> import numpy as np >>> from clouddrift.kinematics import kinetic_energy >>> u = np.array([1., 2., 3., 4.]) >>> v = np.array([1., 1., 1., 1.]) >>> kinetic_energy(u, v) array([1. , 2.5, 5. , 8.5])
>>> u = np.reshape(np.tile([1., 2., 3., 4.], 2), (2, 4)) >>> v = np.reshape(np.tile([1., 1., 1., 1.], 2), (2, 4)) >>> kinetic_energy(u, v) array([[1. , 2.5, 5. , 8.5], [1. , 2.5, 5. , 8.5]])
- clouddrift.kinematics.position_from_velocity(u: ndarray, v: ndarray, time: ndarray, x_origin: float, y_origin: float, coord_system: str = 'spherical', integration_scheme: str = 'forward', time_axis: int = -1) tuple[ndarray, ndarray] [source]#
Compute positions from arrays of velocities and time and a pair of origin coordinates.
The units of the result are degrees if
coord_system == "spherical"
(default). Ifcoord_system == "cartesian"
, the units of the result are equal to the units of the input velocities multiplied by the units of the input time. For example, if the input velocities are in meters per second and the input time is in seconds, the units of the result will be meters.Integration scheme can take one of three values:
- “forward” (default): integration from x[i] to x[i+1] is performed
using the velocity at x[i].
- “backward”: integration from x[i] to x[i+1] is performed using the
velocity at x[i+1].
- “centered”: integration from x[i] to x[i+1] is performed using the
arithmetic average of the velocities at x[i] and x[i+1]. Note that this method introduces some error due to the averaging.
u, v, and time can be multi-dimensional arrays. If the time axis, along which the finite differencing is performed, is not the last one (i.e. x.shape[-1]), use the
time_axis
optional argument to specify along which axis should the differencing be done.x
,y
, andtime
must have the same shape.This function will not do any special handling of longitude ranges. If the integrated trajectory crosses the antimeridian (dateline) in either direction, the longitude values will not be adjusted to stay in any specific range such as [-180, 180] or [0, 360]. If you need your longitudes to be in a specific range, recast the resulting longitude from this function using the function
clouddrift.sphere.recast_lon()
.Parameters#
- unp.ndarray
An array of eastward velocities.
- vnp.ndarray
An array of northward velocities.
- timenp.ndarray
An array of time values.
- x_originfloat
Origin x-coordinate or origin longitude.
- y_originfloat
Origin y-coordinate or origin latitude.
- coord_systemstr, optional
The coordinate system of the input. Can be “spherical” or “cartesian”. Default is “spherical”.
- integration_schemestr, optional
The difference scheme to use for computing the position. Can be “forward” or “backward”. Default is “forward”.
- time_axisint, optional
The axis of the time array. Default is -1, which corresponds to the last axis.
Returns#
- xnp.ndarray
An array of zonal displacements or longitudes.
- ynp.ndarray
An array of meridional displacements or latitudes.
Examples#
Simple integration on a plane, using the forward scheme by default:
>>> import numpy as np >>> from clouddrift.analysis import position_from_velocity >>> u = np.array([1., 2., 3., 4.]) >>> v = np.array([1., 1., 1., 1.]) >>> time = np.array([0., 1., 2., 3.]) >>> x, y = position_from_velocity(u, v, time, 0, 0, coord_system="cartesian") >>> x array([0., 1., 3., 6.]) >>> y array([0., 1., 2., 3.])
As above, but using centered scheme:
>>> x, y = position_from_velocity(u, v, time, 0, 0, coord_system="cartesian", integration_scheme="centered") >>> x array([0., 1.5, 4., 7.5]) >>> y array([0., 1., 2., 3.])
Simple integration on a sphere (default):
>>> u = np.array([1., 2., 3., 4.]) >>> v = np.array([1., 1., 1., 1.]) >>> time = np.array([0., 1., 2., 3.]) * 1e5 >>> x, y = position_from_velocity(u, v, time, 0, 0) >>> x array([0. , 0.89839411, 2.69584476, 5.39367518]) >>> y array([0. , 0.89828369, 1.79601515, 2.69201609])
Integrating across the antimeridian (dateline) by default does not recast the resulting longitude:
>>> u = np.array([1., 1.]) >>> v = np.array([0., 0.]) >>> time = np.array([0, 1e5]) >>> x, y = position_from_velocity(u, v, time, 179.5, 0) >>> x array([179.5 , 180.3983205]) >>> y array([0., 0.])
Use the
clouddrift.sphere.recast_lon
function to recast the longitudes to the desired range:>>> from clouddrift.sphere import recast_lon >>> recast_lon(x, -180) array([ 179.5 , -179.6016795])
Raises#
- ValueError
If u and v do not have the same shape. If the time axis is outside of the valid range ([-1, N-1]). If lengths of x, y, and time along time_axis are not equal. If the input coordinate system is not “spherical” or “cartesian”. If the input integration scheme is not “forward”, “backward”, or “centered”
See Also#
- clouddrift.kinematics.residual_position_from_displacement(longitude: float | ndarray | DataArray, latitude: float | ndarray | DataArray, x: float | ndarray, y: float | ndarray) tuple[float] | tuple[ndarray] [source]#
Return residual longitudes and latitudes along a trajectory on the spherical Earth after correcting for zonal and meridional displacements x and y in meters.
This is applicable as an example when one seeks to correct a trajectory for horizontal oscillations due to inertial motions, tides, etc.
Parameters#
- longitudefloat or array-like
Longitude in degrees.
- latitudefloat or array-like
Latitude in degrees.
- xfloat or np.ndarray
Zonal displacement in meters.
- yfloat or np.ndarray
Meridional displacement in meters.
Returns#
- residual_longitudefloat or np.ndarray
Residual longitude after correcting for zonal displacement, in degrees.
- residual_latitudefloat or np.ndarray
Residual latitude after correcting for meridional displacement, in degrees.
Examples#
Obtain the new geographical position for a displacement of 1/360-th of the circumference of the Earth from original position (longitude,latitude) = (1,0):
>>> from clouddrift.sphere import EARTH_RADIUS_METERS >>> residual_position_from_displacement(1,0,2 * np.pi * EARTH_RADIUS_METERS / 360,0) (0.0, 0.0)
- clouddrift.kinematics.spin(u: ndarray, v: ndarray, time: ndarray, difference_scheme: str = 'forward', time_axis: int = -1) float | ndarray [source]#
Compute spin continuously from velocities and times.
Spin is traditionally (Sawford, 1999; Veneziani et al., 2005) defined as (<u’dv’ - v’du’>) / (2 dt EKE) where u’ and v’ are eddy-perturbations of the velocity field, EKE is eddy kinetic energy, dt is the time step, and du’ and dv’ are velocity component increments during dt, and < > denotes ensemble average.
To allow computing spin based on full velocity fields, this function does not do any demeaning of the velocity fields. If you need the spin based on velocity anomalies, ensure to demean the velocity fields before passing them to this function. This function also returns instantaneous spin values, so the rank of the result is not reduced relative to the input.
u
,v
, andtime
can be multi-dimensional arrays. If the time axis, along which the finite differencing is performed, is not the last one (i.e.u.shape[-1]
), use the time_axis optional argument to specify along which the spin should be calculated. u, v, and time must either have the same shape, or time must be a 1-d array with the same length asu.shape[time_axis]
.Difference scheme can be one of three values:
“forward” (default): finite difference is evaluated as
dx[i] = dx[i+1] - dx[i]
;“backward”: finite difference is evaluated as
dx[i] = dx[i] - dx[i-1]
;“centered”: finite difference is evaluated as
dx[i] = (dx[i+1] - dx[i-1]) / 2
.
Forward and backward schemes are effectively the same except that the position at which the velocity is evaluated is shifted one element down in the backward scheme relative to the forward scheme. In the case of a forward or backward difference scheme, the last or first element of the velocity, respectively, is extrapolated from its neighboring point. In the case of a centered difference scheme, the start and end boundary points are evaluated using the forward and backward difference scheme, respectively.
Parameters#
- unp.ndarray
Zonal velocity
- vnp.ndarray
Meridional velocity
- timearray-like
Time
- difference_schemestr, optional
Difference scheme to use; possible values are “forward”, “backward”, and “centered”.
- time_axisint, optional
Axis along which the time varies (default is -1)
Returns#
- sfloat or np.ndarray
Spin
Raises#
- ValueError
If u and v do not have the same shape. If the time axis is outside of the valid range ([-1, N-1]). If lengths of u, v, and time along time_axis are not equal. If difference_scheme is not “forward”, “backward”, or “centered”.
Examples#
>>> from clouddrift.kinematics import spin >>> import numpy as np >>> u = np.array([1., 2., -1., 4.]) >>> v = np.array([1., 3., -2., 1.]) >>> time = np.array([0., 1., 2., 3.]) >>> spin(u, v, time) array([ 0.5 , -0.07692308, 1.4 , 0.41176471])
Use
difference_scheme
to specify an alternative finite difference scheme for the velocity differences:>>> spin(u, v, time, difference_scheme="centered") array([0.5 , 0. , 0.6 , 0.41176471]) >>> spin(u, v, time, difference_scheme="backward") array([ 0.5 , 0.07692308, -0.2 , 0.41176471])
References#
Sawford, B.L., 1999. Rotation of trajectories in Lagrangian stochastic models of turbulent dispersion. Boundary-layer meteorology, 93, pp.411-424. https://doi.org/10.1023/A:1002114132715
Veneziani, M., Griffa, A., Garraffo, Z.D. and Chassignet, E.P., 2005. Lagrangian spin parameter and coherent structures from trajectories released in a high-resolution ocean model. Journal of Marine Research, 63(4), pp.753-788. https://elischolar.library.yale.edu/journal_of_marine_research/100/
- clouddrift.kinematics.velocity_from_position(x: ndarray, y: ndarray, time: ndarray, coord_system: str = 'spherical', difference_scheme: str = 'forward', time_axis: int = -1) tuple[DataArray, DataArray] [source]#
Compute velocity from arrays of positions and time.
x and y can be provided as longitude and latitude in degrees if coord_system == “spherical” (default), or as easting and northing if coord_system == “cartesian”.
The units of the result are meters per unit of time if coord_system == “spherical”. For example, if the time is provided in the units of seconds, the resulting velocity is in the units of meters per second. Otherwise, if coord_system == “cartesian”, the units of the resulting velocity correspond to the units of the input. For example, if zonal and meridional displacements are in the units of kilometers and time is in the units of hours, the resulting velocity is in the units of kilometers per hour.
x, y, and time can be multi-dimensional arrays. If the time axis, along which the finite differencing is performed, is not the last one (i.e. x.shape[-1]), use the time_axis optional argument to specify along which axis should the differencing be done. x, y, and time must have the same shape.
Difference scheme can take one of three values:
“forward” (default): finite difference is evaluated as
dx[i] = dx[i+1] - dx[i]
;“backward”: finite difference is evaluated as
dx[i] = dx[i] - dx[i-1]
;“centered”: finite difference is evaluated as
dx[i] = (dx[i+1] - dx[i-1]) / 2
.
Forward and backward schemes are effectively the same except that the position at which the velocity is evaluated is shifted one element down in the backward scheme relative to the forward scheme. In the case of a forward or backward difference scheme, the last or first element of the velocity, respectively, is extrapolated from its neighboring point. In the case of a centered difference scheme, the start and end boundary points are evaluated using the forward and backward difference scheme, respectively.
Parameters#
- xarray_like
An N-d array of x-positions (longitude in degrees or zonal displacement in any unit)
- yarray_like
An N-d array of y-positions (latitude in degrees or meridional displacement in any unit)
- timearray_like
An N-d array of times as floating point values (in any unit)
- coord_systemstr, optional
Coordinate system that x and y arrays are in; possible values are “spherical” (default) or “cartesian”.
- difference_schemestr, optional
Difference scheme to use; possible values are “forward”, “backward”, and “centered”.
- time_axisint, optional
Axis along which to differentiate (default is -1)
Returns#
- unp.ndarray
Zonal velocity
- vnp.ndarray
Meridional velocity
Raises#
- ValueError
If x and y do not have the same shape. If time_axis is outside of the valid range. If lengths of x, y, and time along time_axis are not equal. If coord_system is not “spherical” or “cartesian”. If difference_scheme is not “forward”, “backward”, or “centered”.
Examples#
Simple integration on a sphere, using the forward scheme by default:
>>> import numpy as np >>> from clouddrift.kinematics import velocity_from_position >>> lon = np.array([0., 1., 3., 6.]) >>> lat = np.array([0., 1., 2., 3.]) >>> time = np.array([0., 1., 2., 3.]) * 1e5 >>> u, v = velocity_from_position(lon, lat, time) >>> u array([1.11307541, 2.22513331, 3.33515501, 3.33515501]) >>> v array([1.11324496, 1.11409224, 1.1167442 , 1.1167442 ])
Integration on a Cartesian plane, using the forward scheme by default:
>>> x = np.array([0., 1., 3., 6.]) >>> y = np.array([0., 1., 2., 3.]) >>> time = np.array([0., 1., 2., 3.]) >>> u, v = velocity_from_position(x, y, time, coord_system="cartesian") >>> u array([1., 2., 3., 3.]) >>> v array([1., 1., 1., 1.])
See Also#