Propagate streamlinesΒΆ
If we have a set of points (x,y), and a field of wind vectors (iris cubes u,v) we can propagate streamlines by integrating the wind field. This is a simple process - we just move each point along the wind vector iteratively (move by epsilon*wind_speed at each step and repeat for iterations steps).
# Functions to make streamlines from wind fields
# Made by forward propagating a set of start points
import numpy as np
# Each point in this field has an index location (i,j)
# and a real (x,y) position
# Convert between index and real positions
def x_to_i(x, xmin, xmax, width):
return np.minimum(
width - 1, np.maximum(0, np.floor((x - xmin) / (xmax - xmin) * (width - 1)))
).astype(int)
def y_to_j(y, ymin, ymax, height):
return np.minimum(
height - 1,
np.maximum(0, np.floor((y - ymin) / (ymax - ymin) * (height - 1))),
).astype(int)
# Propagate the origin points with the wind
# uw, vw are the wind fields - iris cubes
# opx, opy are the streamline origin points - numpy arrays
def wind_vectors(uw, vw, opx, opy, iterations=5, epsilon=1):
op = np.empty((len(opx), 2, iterations + 1))
op[:, 0, 0] = opx
op[:, 1, 0] = opy
xc = uw.coords()[1].points
xmin = np.min(xc)
xmax = np.max(xc)
dwidth = len(xc)
yc = uw.coords()[0].points
ymin = np.min(yc)
ymax = np.max(yc)
dheight = len(yc)
# Repeatedly make a new set of x,y points by moving the previous set with the wind
for k in range(iterations):
i = x_to_i(op[:, 0, k], xmin, xmax, dwidth)
j = y_to_j(op[:, 1, k], ymin, ymax, dheight)
op[:, 0, k + 1] = op[:, 0, k] + epsilon * uw.data[j, i]
op[:, 0, k + 1][op[:, 0, k + 1] > xmax] = xmax
op[:, 0, k + 1][op[:, 0, k + 1] < xmin] = xmin
op[:, 1, k + 1] = op[:, 1, k] + epsilon * vw.data[j, i]
op[:, 1, k + 1][op[:, 1, k + 1] > ymax] = ymax
op[:, 1, k + 1][op[:, 1, k + 1] < ymin] = ymin
return op