OpenDrift is an open-source Python-based framework for Lagrangian particle modelling under development at the Norwegian Meteorological Institute with contributions from the wider scientific community. The framework is highly generic and modular, and is designed to be used for any type of drift calculations in the ocean or atmosphere. A specific module within the OpenDrift framework corresponds to a Lagrangian particle model in the traditional sense. A number of modules have already been developed, including an oil drift module, a stochastic search-and-rescue module, a pelagic egg module, and a basic module for atmospheric drift. The framework allows for the ingestion of an unspecified number of forcing fields (scalar and vectorial) from various sources, including Eulerian ocean, atmosphere and wave models, but also measurements or a priori values for the same variables. A basic backtracking mechanism is inherent, using sign reversal of the total displacement vector and negative time stepping. OpenDrift is fast and simple to set up and use on Linux, Mac and Windows environments, and can be used with minimal or no Python experience. It is designed for flexibility, and researchers may easily adapt or write modules for their specific purpose. OpenDrift is also designed for performance, and simulations with millions of particles may be performed on a laptop. Further, OpenDrift is designed for robustness and is in daily operational use for emergency preparedness modelling (oil drift, search and rescue, and drifting ships) at the Norwegian Meteorological Institute.
Lagrangian trajectory models are used to predict the pathways
and transformations of various types of objects and substances drifting in
the ocean or in the atmosphere. There are many practical and academic
applications, including prediction of
oil drift and weathering to aid mitigation and cleanup operations
drifting objects for search and rescue ( ichthyoplankton transport (fish eggs and larvae) for stock assessments
microplastics suspended in the ocean
(
Table
Lagrangian tools fall in two broad categories: either the trajectories are
computed along with the velocity fields as part of the ocean or atmospheric
circulation model, e.g. so-called floats in the regional ocean modelling
system (ROMS)
Existing trajectory models are in most cases tied to a specific application, and may not be applied to other drift applications without compromising quality or flexibility. In many cases, trajectory models are also tied to a specific Eulerian model, or even a particular institutional ocean model setup, limiting usability for other institutes or researchers. Often, it is also required that Eulerian forcing data must be in a specific file format. This raises the time and effort needed to set up a trajectory model. Further, in an operational setup, the need to convert large files to another format increases both the complexity and computational costs of the processing chain, compromising robustness.
The OpenDrift framework has been designed to perform all tasks which are common to trajectory models, whether oceanic or atmospheric. In short, the main task is to obtain forcing data from various sources and to use this information to move (propagate) the elements in space, while potentially transforming other element properties, such as evaporation of oil, or growth of larvae. In addition, common functionality includes mechanisms for configuration of simulations, seeding of elements, exporting output to file, and tools to visualise and analyse the output. Additionally, several design requirements have been imposed on the development of OpenDrift: (1) platform independence and ease of installation and use; (2) simple and rapid implementation of any purpose-specific processes, yet flexibility to support unforeseen needs; (3) forcing data from any type of source supported, including Eulerian ocean, atmosphere or wave models (typically NetCDF or GRIB files), in situ measurements, vector data sets (e.g. GSHHS coastlines) or analytical fields for conceptual studies; (4) the ability run fast, even with a large number of elements; (5) simulations forward and backward in time; (6) robustness for operational use.
In Sect. 2, we describe the overall design of the code and the general workflow of performing a simulation. In Sect. 3, we give examples of three specific modules which are included in the OpenDrift repository: search and rescue, oil drift and atmospheric transport. The test suite and example scripts are described in Sect. 4, and graphical user interfaces (web and desktop) are described in Sect. 5. Section 6 provides discussion and conclusions.
Some existing trajectory models for various oceanic and atmospheric applications.
To meet the requirements listed above, a simple and flexible object-oriented
data model has been designed, based on two main classes. One class
(“Reader”) is dedicated to obtaining forcing data from external sources, as
described in Sect.
The class Reader obtains forcing data (e.g. wind, waves and currents) from
any possible source and provides this to any OpenDrift model through a common
interface. To avoid duplication of code, a parent class “BaseReader”
contains functionality which is common to all Readers, whereas specific
subclasses take care of only the tasks which are specific to a particular
source of data, e.g. how to decode and interpret a particular file format.
Two methods must be implemented by any Reader subclass: (1) a constructor
method which initialises a Reader object and (2) a method to retrieve data
for given variables, position and time. The constructor (__init__
in Python) can take any arguments as implemented by the specific Reader
class, but it is typical to provide a filename or URL from which data shall
be obtained by this Reader. The following Python commands initialise a Reader
of type NetCDF_CF_generic to obtain data from a file
“ocean_model_output.nc”.
To allow for generic coupling of any OpenDrift model with any Reader, a
naming convention for variables is necessary. By convention, the commonly
used Climate and Forecast (CF) naming convention (
The given Reader class must also have implemented a specific instance of the
method
Readers are, however, normally not called directly by the user or from
specific OpenDrift instances (models) but rather implicitly from the parent
BaseModel class (see Sect.
Functionality exists also for reading and interpolating data from ensemble
models. For example, when obtaining wind from a NetCDF model file containing 10
ensemble members, particles number 1, 11,
Whereas obtaining forcing data from 3-D Eulerian models is the most common in practice, Readers may obtain data from any other possible source. One example is to read a time series from an American Standard Code for Information Interchange (ASCII) file of observations, e.g. from a buoy or a weather station. Another example is to calculate forcing data according to some analytical function. One such example is included in the code repository, providing ocean current vectors according to a “perfect circular eddy” with centre coordinates as given to its constructor. Such analytical forcing data fields are useful for, e.g. testing the accuracy of forward propagation schemes, as discussed below.
OpenDrift also contains some internal convenience methods to calculate geophysical variables from others. For example, if a drift module requires wave height or Stokes drift, this may be parameterised internally based on the wind velocity if no Readers providing wave parameters are available.
Flowchart of an OpenDrift simulation.
Functionality which is common to any trajectory model is described in a main
class, named BaseModel. This functionality includes the following:
A mechanism for configuration of a trajectory model, or a specific simulation is needed.
This may include adjusting the resolution of a coastline or some
model-specific parameters concerning the movement of the elements. The
configuration mechanism of OpenDrift is based upon the ConfigObj package
( A generic method to seed elements for a simulation is required. See Sect. Managing and referencing a set of Readers (Sect. It is required to keep track of the positions and properties of all elements during a simulation
and remove elements scheduled for deactivation. This is stored in 2-D
arrays with two dimensions, time and particle ID. Thus, the trajectory
(propagation with time) of a single element or the simulation state (all
element positions and properties at a given time) is easily and quickly
obtained as vertical or horizontal slices of the array. The history of data
may also be written to file, as described in Sect. Finally, the BaseModel class contains the main loop for time stepping,
performing necessary tasks for a simulation in the correct order, as described
in Sect.
The only part missing is a description of how the elements (e.g. objects or
substance) shall be propagated and potentially transformed along their
trajectories under the influence of environmental forcing data. Such
application-specific description is left to subclasses, yielding trajectory
model instances as exemplified in Sect.
In this section, we describe and explain the general workflow of a simulation
with an OpenDrift model, as illustrated in the flowchart in
Fig.
The first step is to import a specific OpenDrift model (subclass of
BaseModel) and to initialise an instance. The following Python statements
import and initialise an instance of the Leeway search-and-rescue model
(Sect.
If a given model requires, e.g. ocean current and atmospheric wind as
environmental forcing, we need to create and add Reader instances which can
provide these variables. Say that we have a Thredds server which can provide
ocean currents and a local GRIB file which contains atmospheric winds; we
can create and add these Readers to the simulation instance as follows:
It is also possible to perform a simulation even with no Readers added for one or more of the required variables. In this case, constant values may be provided; otherwise, reasonable default values will be used, defaulting to zero values for winds, waves and currents. For example, in the case of having a 5-day wind forecast, but only a 3-day current forecast, it is still possible to run a 5-day trajectory forecast, where the current will be zero for the last 2 days.
A key feature of OpenDrift, for both convenience and robustness, is the possibility to provide a priority list of Readers for a given set of variables. As an example, it is possible to specify that a high-resolution ocean model shall be used whenever particles are within coverage in space and time, and reverting to using another model with larger coverage in space and time whenever particles are outside the time or spatial domain of the high-resolution model. As an important feature for operational setups, the backup Readers will also be used if the first-choice model (file or URL) should not be available, or if there should be any other problems, e.g. corrupt values or files.
The seeding methods of OpenDrift are very flexible. The simplest case is to
seed (initialise) an element at a given position and time:
Another built-in feature is seeding of elements within polygons. This may,
e.g. be done by providing vectors of longitude and latitude:
This example will seed 10 000 elements with regular spacing within the
polygon encompassed by vectors
OpenDrift modules share several configuration settings which may be adjusted
before a simulation, as well as some settings which are module specific. All
possible settings of a module may be shown with the command
Another example of a configuration setting is
The configuration mechanism is based on the widely used ConfigObj package and allows, e.g. exporting to, and importing from, files of the common 'INI' format.
After initialisation, configuration, adding of Readers and seeding of
elements, the model simulation may be started by calling the method
This starts the main loop, as shown on the flowchart of Fig.
For the above example, the simulation will cover 48 h, starting the time of the first seeded elements. The time step of the calculation is given here as 15 min. An output time step might be specified differently, with, e.g. output every hour to save memory and disk space.
All instances of OpenDrift can be run in reverse, i.e. backwards from a final
destination, by reversing the sign of the advective increment. All spatial
increments due to model physics pertinent to the instance in question are
calculated as normal, but the sign of the total increment,
In the above example, the output is saved to a CF-compliant NetCDF file
(trajectory data specification), which is the default output format of
OpenDrift. Both particle positions and any other properties, as well as
configuration settings are stored in the file. If the number of elements and
time steps is too large to keep all data in physical memory, OpenDrift will
flush history data to the output file as needed during the simulation to free
internal memory. The simulation may be imported by OpenDrift, or independent
software, for subsequent analysis or plotting. Stored output files may also
be used as input to a subsequent OpenDrift simulation, allowing for an
intermediate step where the particles are subjected to various considerations
such as a Bayesian update of their probabilities based on posterior
information. Saving data to files is not a requirement, as the output of the
simulations is otherwise held in memory for subsequent plotting or analysis,
either interactively from within Python shell, or by a script. A number of
visualisation tools based on the Matplotlib graphics library of Python are
included within OpenDrift. Some examples of both generic and module-specific
plotting methods are illustrated in Sect.
The OpenDrift Leeway instance (OpenLeeway) is based on the operational
search-and-rescue model of the Norwegian Meteorological Institute
Once an object class has been chosen and the pertinent wind and current forcing fields selected, the particles are seeded based on the available information. If the particles hit the coast, they stick by default. This can, however, be relaxed so that particles detach from the coastline if the wind direction changes.
The OpenLeeway class along with all other subclasses has the option of being
run backwards. This is a convenient feature in the cases where, for example, a
debris field is observed and the location of the accident is sought. Note
that this method is fundamentally different from the BAKTRAK model described
by
OpenLeeway is used operationally at Norwegian Meteorological Institute and is also currently being implemented as the operational search-and-rescue model for the Joint Rescue Coordination Centres (JRCC) of Norway.
The following lines of Python code illustrate a complete working example of
running an OpenLeeway simulation:
The final plotting command yields Fig.
Output from the Leeway example of Sect.
OpenOil is a full-fledged oil drift model, bundled within the OpenDrift
framework. As a model, it has been developed from scratch but is based on a
selection of parameterisations of oil drift as found in the open research
literature. With regard to horizontal drift, three processes are considered:
Any element, whether submerged or at the surface, drifts along with the ocean current. Elements are subject to Stokes drift corresponding to their actual depth.
Surface Stokes drift is normally obtained from a wave model (or by any
Reader), and its decline with depth is calculated as described in
Oil elements at the ocean surface are moved with an additional factor of
2 % (configurable) of the wind. Together with the Stokes drift (typically
1.5 % of the wind at the surface), this sums up to the commonly found
empirical value of 3.5 % of the wind
The above three drift components may lead to a very strong gradient of drift
magnitude and direction in the upper few metres of the ocean. For this
reason, it is also of critical importance to have a good description of the
vertical oil transport processes, which in OpenOil are the sum of the
following factors:
If the vertical ocean current velocity is available from a Reader, the
oil elements will follow it. This part of the movement is, however, often
negligible compared to the processes below. Oil elements at the surface, regarded as being in the state of an oil slick,
may be entrained into the ocean by breaking waves. Presently, OpenOil contains
two different parameterisations of this entrainment rate, from which the user
can chose as part of configuration (see below): Buoyancy of droplets is calculated according to empirical relationships
and the Stokes law of In addition to the wave-induced entrainment, the oil elements are also
subject to vertical turbulence throughout the water column, as parameterised
with a numerical scheme described in
In addition to the vertical and horizontal drift, weathering of the oil also
has to be considered. While parameterisations of weathering might also be
implemented directly within the OpenDrift framework, the OpenOil module
instead interfaces with the already existing OilLibrary software developed by
NOAA (
Oil drift simulation initialised by seeding 2000 oil elements within contours of an oil slick as observed from satellite (Radarsat2). The contour is imported from a Geography Markup Language (GML) file produced by Kongsberg Satellite Services (KSAT).
To run an OpenOil simulation, one could reuse the exact code as for the
Leeway example of Sect.
OpenOil also has module-specific configuration settings. The following
commands specify that the oil entrainment rate shall be calculated
according to
After the simulation is finished, the generic plot command may be used to
produce a map with trajectories as shown in Fig.
The vertical distribution of the elements can be plotted with the command
Plot of the time evolution of the oil budget of a 24 h simulation with OpenOil. Of 500 kg oil initially at the ocean surface, about 20 % is seen to evaporate within the 24 h. The amount of oil submerged due to wave action and ocean turbulence varies with the wind and wave conditions, with more oil resurfacing when wind decreases after about 7 h. After about 18 h, some of the oil is seen to hit the coastline. These results are for the oil type “Martin Linge crude”; very different results could be obtained if using another oil type for the same geophysical conditions.
Vertical profile of the amount of (oil) elements. The bottom bar is an interactive slider, which the user can pull left/right to see the time variation of the vertical distribution.
As an example of a minimalistic trajectory model, we also include the instance
WindBlow, which simply calculates the propagation of a passive particle
subject to a two-dimensional wind field. The code below is the complete and
fully functional WindDrift module.
Because all common functionality is inherited from the main class, the
WindBlow model only needs to address its own specific needs. It will use
elements without any other properties except for position (PassiveTracer),
and the only forcing needed to move the elements is wind, whose vector
components are named
Clearly, an air parcel in the real atmosphere will also be subjected to
updrafts and diffusion, and will with time rise or fall, but the example
serves to demonstrate how little is required to develop a new subclass of
OpenDrift. The model may be made more sophisticated by adding, e.g. vertical
wind (
In addition to the models described above, some other modules are bundled
within the OpenDrift repository, as illustrated in Fig.
A module for drift of icebergs (OpenBerg, not yet included in repository) has been developed by Ron Saper at Carleton University with partial funding from ASL Environmental Sciences of Victoria, Canada, and with data support from the Canadian Ice Service (personal communication, 2017). Two different iceberg drift forecasting approaches are being tested. One approach uses a drag formulation to calculate wind and water drag forces. The challenge with this approach is that the trajectories are very sensitive to underwater draft/shape and suitable drag coefficients, of which information is rarely available. The second approach predicts and subtracts the wind and tidal components of the drift, and then analyses the residual for extrapolation an appropriately short time into the future. Finally, wind and tidal components are added back in to produce a trajectory forecast. The first version of OpenBerg does not include thermodynamic effects (melting) which are important longer timescales from weeks to months.
Drift of marine plastics, including microplastics, is an important application not covered by modules included with the OpenDrift repository version 1.0. However, as most of the needed infrastructure is already provided, including a vertical mixing scheme, a user with knowledge of the relevant physics and basic Python programming should be able to implement such a module with moderate efforts. However, there is no upper limit to the complexity of any module.
Illustration of how OpenDrift modules for specific applications (white boxes) inherit common functionality from the core module. This includes functionality to interact with Readers for obtaining forcing data. Subclassing (inheritance) allows, e.g. both the OpenOil and PelagicEgg models to share further 3-D-functionality through subclassing the OpenDrift3D class. The boxes with solid boundaries illustrate existing modules bundled with the OpenDrift repository, whereas dashed boundaries indicate planned modules. The green box illustrates that OpenOil (oil drift model) utilises functionality from a third-party library, the NOAA OilLibrary.
OpenDrift contains a broad set of automatic tests (Python unittest framework)
which can be run by the user to assure that all calculations are performed
correctly on the local machine. The tests cover both basic calculations, such
as interpolation and rotation of vectors from one spatial reference system
(SRS) to another, but also more extensive integration tests, performing full
simulations with the modules to verify that an expected numerical result is
obtained. Also, very importantly, the tests are also run automatically on a
variety of machine configurations, using the Travis Continuous Integration
(CI) framework (
A user manual of OpenDrift is kept alongside the code repository on the
wiki pages of GitHub (
OpenDrift also comes with a set of handy command line tools, such as
Although running OpenDrift modules with Python scripts (see, e.g.
Sect.
In addition to the native GUI, a web interface has also been developed for remote access without need for any local installation. This is based on communication with OpenDrift through a web processing service (WPS) developed at MET Norway (not included in the repository). Independently, a WPS for the Leeway module has also been developed and implemented at the Swedish Met Office (SMHI). A generic and configurable WPS to be included in the repository is planned for the future.
Screenshot of the graphical user interface included with OpenDrift.
Several offline trajectory models exist to predict the transport and transformation of various substances and objects in the ocean or in the atmosphere. OpenDrift is an open-source Python framework aiming at extracting anything which is common to all such trajectory models in a core library, and combining this with a clean and generic interface for describing any processes which are application specific. Several examples of such specific modules are bundled with the OpenDrift code repository and serve as ready-to-use trajectory models. This includes an oil drift model (OpenOil), a search-and-rescue model (Leeway) and a model for predicting the drift and transformation of ichthyoplankton (PelagicEgg). Interfaces (Readers) towards the most common formats of forcing data (e.g. NetCDF and GRIB) are also included, allowing any of the modules to be forced by data from a combination of files and other sources, including remote Thredds servers. The concept of Readers is also modularised, allowing a scientist or programmer to easily develop an interface towards any other specific source of forcing data, e.g. an ASCII file containing in situ observations from a buoy or weather station, or ocean currents from HF-radar systems in a specific binary format.
A built-in configuration mechanism provides flexibility to the operation of
the OpenDrift modules. However, the fact that the application-specific
processes of these modules are separated from the technical complexities of
the OpenDrift core provides even greater flexibility to the user in that it
is easy to modify existing modules, or even write new modules from scratch.
Several users have already developed or adjusted modules for their specific
purpose and added useful contributions to the OpenDrift core
Whereas flexibility is important for scientific studies, OpenDrift is also designed for performance and robustness and is in daily use for operational emergency response systems at the Norwegian Meteorological Institute. Being able to use the same tool in both cases facilitates rapid transition of the latest research results into operations.
The efficiency of the code has been optimised to the point that more time is
normally spent on reading the forcing data from disk (or a URL) than on
performing actual calculations. Computational performance similar to compiled
languages (Fortran or C) is obtained by, e.g. using primarily NumPy arrays
for calculations (avoiding the slower MaskedArray class) and avoiding “for
loops”. A typical emergency simulation with the Leeway model with 5000
elements and 48 h duration takes on the order of 1 min. A corresponding
simulation with OpenOil takes about 3–5 min, primarily because more layers
of ocean model data have to be read from disk, in contrast to the Leeway
simulation which only needs the surface current. A typical 1-year simulation
of 20 000 drifting cod eggs (developing into larvae) takes about 4 h on a
regular desktop computer
Another great benefit of the modularity provided by OpenDrift is the ability to perform sensitivity tests by varying one component while keeping everything else constant. Much can be learnt from performing two otherwise identical simulations with, e.g. input from two different Eulerian models, or by using two different parameterisations of some process. Further, consistency is also provided by the possibility of handling, e.g. overlap of fish eggs and oil with the same forcing and numerical scheme. Traditionally, it might be difficult to draw conclusions by comparing the output from different trajectory models, as the differences depend on many factors, such as interpolation schemes and numerical algorithms.
The modules presently included with OpenDrift will be improved in the future,
in particular by validation against available relevant observations. Among
the general problems which require more attention, is properly describing
and quantifying the very strong vertical gradients of horizontal drift often
found in the upper few metres of the ocean, as result of a delicate balance
between ocean currents and Stokes drift, as well as the direct wind drift
affecting objects and substances at the very ocean surface. This vertical
gradient of forcing is highly important for drift of, e.g. oil and chemicals,
plankton and microplastics. This implies further that having accurate
parameterisations of the vertical transport processes (wave entrainment,
buoyancy and ocean turbulence) is also very important. For example, a key factor for
successful simulation of the drift of observed oil slicks in
OpenDrift is housed on GitHub:
Knut-Frode Dagestad, Johannes Röhrs and Øyvind Breivik gratefully acknowledge support from the Joint Rescue Coordination Centres through the project OpenLeeway and the Research Council of Norway through the CIRFA (grant no. 237906) and RETROSPECT (grant no. 244262) projects. The Norwegian Clean Seas Association (NOFO) and the Norwegian Coastal Administration have been instrumental in their support and testing of the software during the development phase. Edited by: Robert Marsh Reviewed by: two anonymous referees