Tutorial: The Ocean Module
Note
You can download an executable version (Jupyter Notebook) of this tutorial
here
.
Kadlu's Ocean Module¶
The ocean module is an abstraction of Kadlu's loading and interpolation functions, which provides a unified interface to quickly load and interpolate many different environmental variables. In this tutorial, we will take a closer look at the key functionalities of the ocean module.
We begin by importing the necessary modules, functions, etc.
import numpy as np
from datetime import datetime
from kadlu import source_map
from kadlu.geospatial.ocean import Ocean
The geographical and temporal boundaries are specified as python dictionary, to be passed to the plotting function later. In this example, we are concerned with a rectangular area in the Gulf of St. Lawrence, which extends from $47.8^o$N to $48.8^o$N and $-63.4^o$W to $-61.8^o$W, as shown on the map below. Note, also, that we are only loading data for the first 100 m of the water column (bottom=100, top=0) on the first 12 hours of January 9, 2015.
# ocean boundaries:
bounds = dict(
start=datetime(2015, 1, 9), end=datetime(2015, 1, 9, 12),
south=47.8, west=-63.4,
north=48.8, east=-61.8,
top=0, bottom=100
)
Initialization and querying¶
The ocean module can be instatiated without specifying any data sources. This is the simplest way of instantiating the ocean module and result in an ocean with null data everywere.
o = Ocean(**bounds) # instantiate ocean with null values
The ocean module has a bunch of methods for querying various environmental data. For a full list, see the ocean module's documentation page. For example, bathymetric data can be queried with the bathy
method as follows,
o.bathy(lat=[48.5, 48.1], lon=[-63, -62.5]) # query bathymetric interpolator for values at given coordinates
To query using planar coordinates, use the bathy_xy
method instead,
o.bathy_xy(x=[-2000, 3500], y=[10000, 15000]) # query bathymetric interpolator for values at given displacements
Here, x
and y
are the horizontal (W-E) and vertical (S-N) displacements in meters, respectively, in a planar coordinate system centered at the mid-point of the geographical region under consideration.
Automatic loading of data¶
In order to use Kadlu's automated data loading functionalities, you simply have to specify one (or several) of the data sources listed in the source_map. For example,
o = Ocean(load_salinity='hycom', **bounds) # instantiate interpolator with HYCOM salinity data
o.salinity(lat=[48.5, 48.1], lon=[-64, -62.5], depth=[0, 10]) # query interpolator for values at given coordinates
o.waveheight(lat=[48.5, 48.1], lon=[-64, -62.5]) # query waveheight interpolator: values remain null
Kadlu can check for missing data and prepare interpolators for many variables at the same time
# source strings passed as load arguments tells the ocean module where to source the data
sources = dict(
load_bathymetry='gebco',
load_temp='hycom',
load_salinity='hycom',
load_wavedir='era5',
load_waveheight='era5',
load_waveperiod='era5',
load_wavedirection='era5',
load_windspeed='era5'
)
o = Ocean(**sources, **bounds)
Now we can query any of the loaded variable at any set of coordinates, e.g., wave height:
o.waveheight(lat=[48.5, 48.1], lon=[-64, -62.5]) # query waveheight interpolator
Manual loading of data¶
Kadlu also supports ocean interpolation using arbitrary environmental data. An ocean can be initialized by passing a float or array of floats to the load_variable keyword argument. Arrays must be ordered by [values, lat, lon] for 2D data, or [values, lat, lon, depth] for 3D data.
When a float value is used, a uniform "interpolation" of that value will be returned for every coordinate location
bathy_arr = np.array((
np.random.rand(100) * 500., # array of length 100 with random values in the range 0-500.
bounds['south'] + np.random.rand(100) * (bounds['north'] - bounds['south']), # latitudes
bounds['west'] + np.random.rand(100) * (bounds['east'] - bounds['west']) # longitudes
))
temp_float = 10
salinity_float = 35
o = Ocean(load_bathymetry=bathy_arr, load_temp=temp_float, load_salinity=salinity_float, **bounds)
print('bathymetry:\t', o.bathy( lat=[47.5, 48.1], lon=[-64, -62.5]))
print('temperature:\t', o.temp( lat=[47.5, 48.1], lon=[-64, -62.5], depth=[0, 50]))
print('salinity:\t', o.salinity(lat=[47.5, 48.1], lon=[-64, -62.5], depth=[0, 50]))
for a list of possible strings accepted as input for the load_variable arguments, choose one of the sources listed in the source_map that supports that variable:
print(source_map)