pompy.models module

Implementations of puff-based plume model components.

class pompy.models.Puff(x, y, z, r_sq)[source]

Container for the properties of a single odour puff.

__init__(x, y, z, r_sq)[source]
Parameters:
  • x (float) – x-coordinate of puff centre.
  • y (float) – y-coordinate of puff centre.
  • z (float) – z-coordinate of puff centre.
  • r_sq (float) – Squared radius of puff.
class pompy.models.Rectangle(x_min, x_max, y_min, y_max)[source]

Axis-aligned rectangular region.

Rectangle is defined by two points (x_min, y_min) and (x_max, y_max) with it required that x_max > x_min and y_max > y_min.

__init__(x_min, x_max, y_min, y_max)[source]
Parameters:
  • x_min (float) – x-coordinate of bottom-left corner of rectangle.
  • y_min (float) – x-coordinate of bottom-right corner of rectangle.
  • x_max (float) – x-coordinate of top-right corner of rectangle.
  • y_max (float) – y-coordinate of top-right corner of rectangle.
w

Width of rectangle (i.e. distance covered on x-axis).

h

Height of rectangle (i.e. distance covered on y-axis).

contains(x, y)[source]

Whether (x, y)` position is contained within this rectangle.

Tests whether the supplied position, an (x,y) pair, is contained within the region defined by this Rectangle object and returns True if so and False if not.

Parameters:
  • x (float) – x-coordinate of position to test.
  • y (float) – y-coordinate of position to test.
Returns:

containsTrue if (x, y) is within the rectangle and False otherwise.

Return type:

boolean

class pompy.models.PlumeModel(sim_region=None, source_pos=(5.0, 0.0, 0.0), wind_model=None, model_z_disp=True, centre_rel_diff_scale=2.0, puff_init_rad=0.0316, puff_spread_rate=0.001, puff_release_rate=10, init_num_puffs=10, max_num_puffs=1000, rng=None)[source]

Puff-based odour plume dispersion model from Farrell et. al. (2002).

The odour plume is modelled as a series of odour puffs which are released from a fixed source position. The odour puffs are dispersed by a modelled 2D wind velocity field plus a white noise process model of mid-scale puff mass diffusion relative to the plume centre line. The puffs also spread in size over time to model fine-scale diffusive processes.

__init__(sim_region=None, source_pos=(5.0, 0.0, 0.0), wind_model=None, model_z_disp=True, centre_rel_diff_scale=2.0, puff_init_rad=0.0316, puff_spread_rate=0.001, puff_release_rate=10, init_num_puffs=10, max_num_puffs=1000, rng=None)[source]
Parameters:
  • sim_region (Rectangle) – 2D rectangular region of space over which the simulation is conducted. This should be a subset of the simulation region defined for the wind model.
  • source_pos (float iterable) – Coordinates of the fixed source position within the simulation region from which puffs are released. If a length 2 iterable is passed, the z coordinate will be set a default of 0 (dimension: length).
  • wind_model (WindModel) – Dynamic model of the large scale wind velocity field in the simulation region.
  • model_z_disp (boolean) – Whether to model dispersion of puffs from plume centre-line in z direction. If set True then the puffs will be modelled as dispersing in the vertical direction by a random walk process (the wind model is limited to 2D hence the vertical wind speed is assumed to be zero), if set False the puff z-coordinates will not be updated from their initial value of 0.
  • centre_rel_diff_scale (float or float iterable) – Scaling for the stochastic process used to model the centre-line relative diffusive transport of puffs. Either a single float value of isotropic diffusion in all directions, or one of a pair of values specifying different scales for the x and y directions respectively if model_z_disp=False or a triplet of values specifying different scales for x, y and z scales respectively if model_z_disp=True (dimension: length / time**0.5).
  • puff_init_rad (float) – Initial radius of the puffs (dimension: length).
  • puff_spread_rate (float) – Constant which determines the rate at which the odour puffs increase in size over time (dimension: length**2 / time).
  • puff_release_rate (float) – Mean rate at which new puffs are released into the plume. Puff release is modelled as a stochastic Poisson process, with each puff released assumed to be independent and the mean release rate fixed (dimension: count/time).
  • init_num_puffs (integer) – Initial number of puffs to release at the beginning of the simulation.
  • max_num_puffs (integer) – Maximum number of puffs to permit to be in existence simultaneously within model, used to limit memory and processing requirements of model. This parameter needs to be set carefully in relation to the puff release rate and simulation region size as if too small it will lead to breaks in puff release when the number of puffs remaining in the simulation region reaches the limit.
  • rng (RandomState) – Random number generator to use in generating input noise. Defaults to numpy.random global generator if set to None however a seeded RandomState object can be passed if it is desired to have reproducible output.
update(dt)[source]

Update plume puff objects by forward intgating one time-step.

Performs a single time-step update of plume model using Euler integration scheme.

Parameters:dt (float) – Simulation time-step (dimension: time).
puff_array

NumPy array of the properties of the simulated puffs.

Each row corresponds to one puff with the first column containing the puff position x-coordinate, the second the y-coordinate, the third the z-coordinate and the fourth the puff squared radius.

class pompy.models.WindModel(sim_region=None, n_x=21, n_y=21, u_av=1.0, v_av=0.0, k_x=20.0, k_y=20.0, noise_gain=2.0, noise_damp=0.1, noise_bandwidth=0.2, use_original_noise_updates=False, rng=None)[source]

Wind velocity model to calculate advective transport of odour.

A 2D approximation is used as described in the paper, with the wind velocities calculated over a regular 2D grid of points using a finite difference method. The boundary conditions at the edges of the simulated region are for both components of the velocity field constant mean values plus coloured noise. For each of the field components these are calculated for the four corners of the simulated region and then linearly interpolated over the edges.

__init__(sim_region=None, n_x=21, n_y=21, u_av=1.0, v_av=0.0, k_x=20.0, k_y=20.0, noise_gain=2.0, noise_damp=0.1, noise_bandwidth=0.2, use_original_noise_updates=False, rng=None)[source]
Parameters:
  • sim_region (Rectangle) – Two-dimensional rectangular region over which to model wind velocity field.
  • n_x (integer) – Number of grid points in x direction.
  • n_y (integer) – Number of grid points in y direction.
  • u_av (float) – Mean x-component of wind velocity (dimension: length / time).
  • v_av (float) – Mean y-component of wind velocity (dimension: length / time).
  • k_x (float or array_like) – Diffusivity constant in x direction. Either a single scalar value across the whole simulated region or an array of size (n_x, n_y) defining values for each grid point (dimension: length**2 / time).
  • k_y (float or array_like) – Diffusivity constant in y direction. Either a single scalar value across the whole simulated region or an array of size (n_x, n_y) defining values for each grid point (dimension: length**2 / time).
  • noise_gain (float) – Input gain constant for boundary condition noise generation (dimensionless).
  • noise_damp (float) – Damping ratio for boundary condition noise generation (dimensionless).
  • noise_bandwidth (float) – Bandwidth for boundary condition noise generation (dimension: angle / time).
  • use_original_noise_updates (boolean) – Whether to use the original non-SDE based updates for the noise process as defined in Farrell et al. (2002), see notes in ColouredNoiseGenerator documentation.
  • rng (RandomState) – Random number generator to use in generating input noise. Defaults to numpy.random global generator if set to None however a seeded RandomState object can be passed if it is desired to have reproducible output.
x_points

1D array of the range of x-coordinates of simulated grid points.

y_points

1D array of the range of y-coordinates of simulated grid points.

velocity_field

Current calculated velocity field across simulated grid points.

velocity_at_pos(x, y)[source]

Calculate velocity at a position or positions.

Calculates the components of the velocity field at arbitrary point(s) in the simulation region using a bivariate spline interpolation over the calculated grid point values.

Parameters:
  • x (float or array) – x-coordinate of the point(s) to calculate the velocity at (dimension: length).
  • y (float or array) – y-coordinate of the point(s) to calculate the velocity at (dimension: length).
Returns:

vel – Velocity field (2D) values evaluated at specified point(s) (dimension: length / time).

Return type:

array

update(dt)[source]

Update wind velocity field by forward integrating one time-step.

Updates wind velocity field values using finite difference approximations for spatial derivatives and Euler integration for time-step update.

Parameters:dt (float) – Simulation time-step (dimension: time).
class pompy.models.ColouredNoiseGenerator(init_state, damping=0.1, bandwidth=0.2, gain=1.0, use_original_updates=False, rng=None)[source]

Generator of coloured (correlated) Gaussian noise process.

Generates a coloured noise output via numerical integration of a stochastic differential equation formulation. The system is assumed to be defined by the system of SDEs:

dx_0  = x_1 * dt
dx_1  = -(a * x_0 + b * x_1) * dt + c * dn

where a = bandwidth**2 and b = 2 * damping * bandwidth, c = gain * bandwidth**2 and dn is a standard Gaussian white noise process. This is numerically integrated using an Euler-Maruyama scheme:

for t in range(n_timestep):
    x[t+1,0] = x[t,0] + dt * x[t,1]
    x[t+1,1] = x[t,1] - dt * (a*x[t,0] + b*x[t,1]) + dt**0.5 * c * n[t]

where x is an array of shape (n_timestep, 2) and n is an array of shape (n_timestep) filled with random standard normal draws.

This differs from the code accompanying Farrell et al. (2002) which applies an Euler integration scheme to a state space formulation of a second-order linear system with Gaussian noise input at each time step, resulting in updates of the form:

for t in range(n_timestep):
    x[t+1,0] = x[t,0] + dt * x[t,1]
    x[t+1,1] = x[t,1] + dt * (-a * x[t,0] - b * x[t,1] + c * n[t])

This differs from the scheme implemented here by scaling the noise input by the timestep dt rather than its square root dt**0.5. This introduces an implicit dependence of the amplitude of the process on dt, in particular that the amplitude scales roughly as dt**0.5.

Updates consistent with the Farrell et al. (2002) implementation can be achieved by setting the use_original_updates flat to True.

__init__(init_state, damping=0.1, bandwidth=0.2, gain=1.0, use_original_updates=False, rng=None)[source]
Parameters:
  • init_state (array_like) – The initial state of system, must be of shape (2,n) where n is the size of the noise vector to be produced. The first row sets the initial values and the second the initial first derivatives.
  • damping (float) – Damping ratio for the system, affects system damping, values of < 1 give an underdamped system, = 1 a critically damped system and > 1 an overdamped system (dimensionless).
  • bandwidth (float) – Bandwidth or equivalently undamped natural frequency of system, affects system reponsiveness to variations in (noise) input (dimension = 1 / time).
  • gain (float) – Input gain of system, affects scaling of (noise) input.
  • rng (RandomState) – Random number generator to use in generating input noise. Defaults to numpy.random global generator if set to None however a seeded RandomState object can be passed if it is desired to have reproducible output.
  • use_original_updates (boolean) – Whether to use the original non-SDE based updates for the noise process as defined in Farrell et al. (2002), see above notes.
output

Coloured noise output.

update(dt)[source]

Update state of noise generator.

Parameters:dt (float) – Integrator time step.