Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/OpenDrift/opendrift into …
Browse files Browse the repository at this point in the history
…dsd_options
  • Loading branch information
GilesFearon committed Jul 10, 2023
2 parents 81753ed + f2f9bac commit ef81dc9
Show file tree
Hide file tree
Showing 63 changed files with 3,042 additions and 596 deletions.
44 changes: 12 additions & 32 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ commands:
cat envconfig
- restore_cache:
key: v19-deps1-{{ checksum "environment.yml" }}-{{ checksum "envconfig" }}
key: v20-deps1-{{ checksum "environment.yml" }}-{{ checksum "envconfig" }}

- run:
name: Install requirements
Expand All @@ -70,7 +70,7 @@ commands:
fi
- save_cache:
key: v19-deps1-{{ checksum "environment.yml" }}-{{ checksum "envconfig" }}
key: v20-deps1-{{ checksum "environment.yml" }}-{{ checksum "envconfig" }}
paths:
- "/opt/conda/envs"
- run:
Expand Down Expand Up @@ -162,8 +162,10 @@ jobs:
- run:
name: Publish packages
command: |
source activate opendrift
poetry publish -vv --skip-existing -u __token__ -p ${PYPI_TOKEN}
if [[ "${CIRCLE_BRANCH}" == "master" ]]; then
source activate opendrift
poetry publish -vv --skip-existing -u __token__ -p ${PYPI_TOKEN}
fi
python_310:
<<: *test-template
Expand Down Expand Up @@ -320,7 +322,7 @@ jobs:
echo "Build examples: ${BUILD_EXAMPLES}"
- restore_cache:
key: v7-docs-deps1-{{ checksum "environment.yml" }}
key: v8-docs-deps1-{{ checksum "environment.yml" }}

- install_conda_environment

Expand All @@ -334,7 +336,7 @@ jobs:
pip install sphinx-rtd-theme
- save_cache:
key: v7-docs-deps1-{{ checksum "environment.yml" }}
key: v8-docs-deps1-{{ checksum "environment.yml" }}
paths:
- "/opt/conda/envs"

Expand Down Expand Up @@ -398,7 +400,7 @@ jobs:
- add_ssh_keys:
fingerprints:
- "49:f4:a4:5c:2f:d4:6a:0f:26:21:a0:f2:d4:3c:71:ff"
- "c0:95:6e:db:93:97:28:a7:45:f4:d7:30:e3:fe:a6:8f"
- run:
name: Deploy docs to gh-pages branch
command: gh-pages --dotfiles --message "[skip ci] Updates" --dist docs/build/html --repo git@github.com:OpenDrift/opendrift.github.io.git --branch master
Expand All @@ -417,8 +419,10 @@ workflows:
- build_package
- python_39
filters:
tags:
only: /^v.*/
branches:
only: master
only: master

docs:
jobs:
Expand All @@ -434,27 +438,3 @@ workflows:
filters:
branches:
only: master

# This workflow will deploy images on merge to master only
# build-and-publish-docker-image:
# jobs:

# - docker-publish/publish:
# image: opendrift/opendrift
# dockerfile: Dockerfile
# tag: latest
# filters:
# branches:
# only: master
# after_build:
# - run:
# name: Publish Docker Containers with Python Version 3
# command: |
# # Here we preview the Docker Tag
# pushd opendrift
# DOCKER_TAG=$(python -c 'import version; print(version.__version__)')
# popd

# echo "Version for Docker tag is ${DOCKER_TAG}"
# docker tag opendrift/opendrift:latest opendrift/opendrift:v${DOCKER_TAG}

26 changes: 26 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: docker

on:
push:
branches:
- 'master'

jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v3
with:
push: true
tags: opendrift/opendrift:latest
12 changes: 2 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
# See https://opendrift.github.io for usage

FROM continuumio/miniconda3
FROM condaforge/mambaforge

ENV DEBIAN_FRONTEND noninteractive
ENV PATH /code/opendrift/opendrift/scripts:$PATH

RUN mkdir /code
WORKDIR /code

RUN conda config --add channels noaa-orr-erd
RUN conda config --add channels conda-forge
RUN conda config --add channels opendrift

# Install opendrift environment into base conda environment
COPY environment.yml .
RUN /opt/conda/bin/conda env update -n base -f environment.yml

# Install roaring-landmask
RUN pip install roaring-landmask
RUN mamba env update -n base -f environment.yml

# Cache cartopy maps
RUN /bin/bash -c "echo -e \"import cartopy\nfor s in ('c', 'l', 'i', 'h', 'f'): cartopy.io.shapereader.gshhs(s)\" | python"
Expand Down
26 changes: 12 additions & 14 deletions docs/source/install.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
Installing OpenDrift
=============================================

Alternative 1: Using Miniconda and Git (recommended)
++++++++++++++++++++++++++++++++++++++++++++++++++++
Alternative 1: Using Mambaforge (alternative to Miniconda) and Git (recommended)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1. Install `miniconda3 <https://docs.conda.io/en/latest/miniconda.html>`_
1. Install `mambaforge <https://mamba.readthedocs.io/en/latest/installation.html>`_ (`download <https://github.com/conda-forge/miniforge#mambaforge>`_)
2. Clone OpenDrift:

.. code-block:: bash
Expand All @@ -16,8 +16,7 @@ Alternative 1: Using Miniconda and Git (recommended)

.. code-block:: bash
$ conda config --add channels conda-forge
$ conda env create -f environment.yml
$ mamba env create -f environment.yml
$ conda activate opendrift
$ pip install --no-deps -e .
Expand All @@ -27,18 +26,17 @@ Occasionally, new dependencies will be added to environment.yml. Then the local

.. code-block:: bash
$ conda env update -f environment.yml
$ mamba env update -f environment.yml
Alternative 2: Using Miniconda
++++++++++++++++++++++++++++++
Alternative 2: Using Mambaforge (alternative to Miniconda)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1. Install `miniconda3 <https://docs.conda.io/en/latest/miniconda.html>`_
1. Install `mambaforge <https://mamba.readthedocs.io/en/latest/installation.html>`_ (`download <https://github.com/conda-forge/miniforge#mambaforge>`_)
2. Set up a *Python 3* environment for opendrift and install opendrift

.. code-block:: bash
$ conda config --add channels conda-forge
$ conda create -n opendrift python=3 opendrift
$ mamba create -n opendrift python=3 opendrift
$ conda activate opendrift
.. _source_install:
Expand All @@ -59,13 +57,13 @@ If you later want to edit the OpenDrift source code, or be able to update from r

.. code-block:: bash
$ conda remove opendrift
$ mamba remove --force opendrift
5. Install as editable:

.. code-block:: bash
$ pip install -e --no-deps .
$ pip install --no-deps -e .
Building and using the Docker image
+++++++++++++++++++++++++++++++++++
Expand Down Expand Up @@ -95,5 +93,5 @@ and run it:

.. code-block:: bash
$ docker run --it --rm opendrift
$ docker run -it --rm opendrift
22 changes: 22 additions & 0 deletions docs/source/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@ Publications

Some papers using or mentioning OpenDrift:

Aghito, M., Calgaro, L., Dagestad, K.-F., Ferrarin, C., Marcomini, A., Breivik, Ø., and Hole, L. R.: ChemicalDrift 1.0: an open-source Lagrangian chemical-fate and transport model for organic aquatic pollutants, Geosci. Model Dev., 16, 2477–2494, https://doi.org/10.5194/gmd-16-2477-2023, 2023.

Nguyen DM, Hole LR, Breivik Ø, Nguyen TB, Pham NK. Marine Plastic Drift from the Mekong River to Southeast Asia. Journal of Marine Science and Engineering. 2023; 11(5):925. https://doi.org/10.3390/jmse11050925

Simonsen, M., Albretsen, J., Saetra, Ø., Asplin, L., Lind, O.C., & Teien, H. (2023). High resolution modeling of aluminium transport in a fjord estuary with focus on mean circulation and irregular flow events. The Science of the total environment, 161399. https://doi.org/10.1016/j.scitotenv.2023.161399

Anselain, T., Heggy, E., Dobbelaere, T. et al. Qatar Peninsula’s vulnerability to oil spills and its implications for the global gas supply. Nat Sustain (2023). https://doi.org/10.1038/s41893-022-01037-w

Merlino, S.; Locritani, M.; Guarnieri, A.; Delrosso, D.; Bianucci, M.; Paterni, M. Marine Litter Tracking System: A Case Study with Open-Source Technology and a Citizen Science-Based Approach. Sensors 2023, 23, 935. https://doi.org/10.3390/s23020935

Bruciaferri, D., Tonani, M., Ascione, I., Al Senafi, F., O'Dea, E., Hewitt, H. T., and Saulter, A.: GULF18, a high-resolution NEMO-based tidal ocean model of the Arabian/Persian Gulf, Geosci. Model Dev., 15, 8705–8730, https://doi.org/10.5194/gmd-15-8705-2022, 2022.

Crivellaro, M.S., Candido, D.V., Lima Silveira T.C., Carvalhal Fonseca A., Segal, B. (2022) A tool for a race against time: Dispersal simulations to support ongoing monitoring program of the invasive coral Tubastraea coccinea. Mar. Pol. Bulletin, 185. ISSN 0025-326X.

Delcloo, A.W., Verstraeten, W.W., Kouznetsov, R., Hoebelke, L., Bruffaerts, N., Sofiev, M. (2022). Forecasting Birch Pollen Levels in Belgium: First Analysis of the 2021 Season. In: Mensink, C., Jorba, O. (eds) Air Pollution Modeling and its Application XXVIII. ITM 2021. Springer Proceedings in Complexity. Springer, Cham. https://doi.org/10.1007/978-3-031-12786-1_16

Rosas, Eloah & Martins, Flávio & Tosic, Marko & Janeiro, Joao & Mendonça, Fernando & Mills, Lara. (2022). Pathways and Hot Spots of Floating and Submerged Microplastics in Atlantic Iberian Marine Waters: A Modelling Approach. Journal of Marine Science and Engineering. 10. 1640. 10.3390/jmse10111640.

Kyriakidis, P., Moutsiou, T., Nikolaidis, A., Reepmeyer, C., Leventis, G., Demesticha, S., Akylas, E., Kassianidou, V., Michailides, C., Zomeni, Z., Bar-Yosef, D., Makovsky, Y., McCartney, C. (2022). Virtual Sea-Drifting Experiments between the Island of Cyprus and the Surrounding Mainland in the Early Prehistoric Eastern Mediterranean. Heritage. 5. 3081-3099. 10.3390/heritage5040160.

Rodríguez-Villegas C., Figueroa R.I, Pérez-Santos I, Molinet C., Saldías G.S., Rosales S.A, Álvarez G., Linford P., Díaz P.A., Continental shelf off northern Chilean Patagonia: A potential risk zone for the onset of Alexandrium catenella toxic bloom? Marine Pollution Bulletin 184 (2022) 114103, https://doi.org/10.1016/j.marpolbul.2022.11410

Devis Morales A.D., Rubio E.R., Martínez D.R., Numerical modeling of oil spills in the Gulf of Morrosquillo, Colombian Caribean, Ciencia, Tecnologia y Futuro Vol 12, Num 1 June 2022. pages 69 - 83, https://doi.org/10.29047/01225383.396.
Expand Down Expand Up @@ -31,6 +51,8 @@ Kotzakoulakis, K., & George, S. (2021). Advanced oil spill modeling and simulati

Reche P., Artal O., Pinilla E., Ruiz C., Venegas O., Arriagada A., Falvey M., CHONOS: Oceanographic information website for Chilean Patagonia, Ocean & Coastal Management, Volume 208, 1 July 2021, https://doi.org/10.1016/j.ocecoaman.2021.105634

J. Anarumo, T. Miles, H. Roarty, J. Kohut and N. Beaird, "An Open-Source Software Application for Drifter Trajectory Prediction in the Mid-Atlantic Bight," Global Oceans 2020: Singapore – U.S. Gulf Coast, Biloxi, MS, USA, 2020, pp. 1-8, https://doi.org/10.1109/IEEECONF38699.2020.9389124

Peytavin, A., Sainte-Rose, B., Forget, G., and Campin, J.-M.: Ocean Plastic Assimilator v0.1: Assimilation of Plastics Concentration Data Into Lagrangian Dispersion Models, Geosci. Model Dev. Discuss. [preprint], https://doi.org/10.5194/gmd-2020-385, in review, 2021.

Melsom A., Kvile K.Ø., Dagestad K.-F., Broström G., Langangen Ø., Exploring drift simulations from ocean circulation experiments: Application to cod eggs and larval drift, Accepted for publication, https://doi.org/10.3354/cr01652
Expand Down
5 changes: 3 additions & 2 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
name: opendrift
channels:
- opendrift
- conda-forge
dependencies:
- matplotlib>=3.5
- numpy>=1.17
- scipy>=1.6
- netcdf4
- netcdf4<=1.6.1
- ffmpeg
- pyproj>=2.3
- libgdal>=3.1
Expand All @@ -30,6 +29,8 @@ dependencies:
- cmocean
- utm
- roaring-landmask>=0.7
- trajan>=0.1.3
- pip
- pip:
- motuclient
- pytest-sphinx
4 changes: 2 additions & 2 deletions examples/example_chemicaldrift.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@

print('Number of transformations:')
for isp in range(o.nspecies):
print('{}'.format(['{:>9}'.format(np.int(item)) for item in o.ntransformations[isp,:]]) )
print('{}'.format(['{:>9}'.format(np.int32(item)) for item in o.ntransformations[isp,:]]) )

mass = o.get_property('mass')
mass_d = o.get_property('mass_degraded')
Expand Down Expand Up @@ -115,4 +115,4 @@

o.plot_mass(legend = legend,
time_unit = 'hours',
title = 'Chemical mass budget')
title = 'Chemical mass budget')
3 changes: 3 additions & 0 deletions examples/example_ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@
ensemble_number = np.remainder(np.arange(o.num_elements_total()), len(r.realizations)) + 1
o.animation(fast=True, color=ensemble_number, legend=['Member ' + str(i) for i in r.realizations], colorbar=False)

#%%
# We see that elements forced by different wind ensemble members move differently

#%%
# .. image:: /gallery/animations/example_ensemble_0.gif
93 changes: 93 additions & 0 deletions examples/example_leeway_backtrack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env python
"""
Leeway backtracking
===================
"""

import os
from datetime import timedelta
import cmocean
import pyproj
import numpy as np
import matplotlib.pyplot as plt
import xarray as xr
import opendrift
from opendrift.readers import reader_netCDF_CF_generic
from opendrift.models.leeway import Leeway

#%%
# We try to find the likelihood of the origin of a found object by two different methods:
# 1. backwards simulation from position where object is found ('Observation')
# 2. forwards simulation from a uniform grid of possible initial locations, selecting the origins of particles actually hitting the observed target
#
# We use 24 hours from the NorKyst ocean model (800m pixel size) and Arome atmospheric model (2.5km pixel size)
o = Leeway(loglevel=50)
reader_arome = reader_netCDF_CF_generic.Reader(o.test_data_folder() +
'16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc')
reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() +
'16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc')
o.add_reader([reader_norkyst, reader_arome])

duration = timedelta(hours=24)
start_time = reader_norkyst.start_time
end_time = start_time + duration

object_type = 26 # 26 = Life-raft, no ballast
outfile = 'leeway.nc'
ilon = 4.3 # Incident position
ilat = 60.6
text = [{'s': 'Observation', 'x': ilon, 'y': ilat, 'fontsize': 20, 'color': 'g', 'zorder': 1000}]
# Define domain of possible origin
lons = np.arange(3.4, 5, .1/20)
lats = np.arange(59.7, 60.8, .05/20)
corners = [lons[0], lons[-1], lats[0], lats[-1]]
lons, lats = np.meshgrid(lons, lats)

#%%
# Simulating first backwards for 24 hours:
o.seed_elements(lon=ilon, lat=ilat, radius=5000, radius_type='uniform', number=30000,
time=end_time, object_type=object_type)
o.run(duration=duration, time_step=-900, time_step_output=3600, outfile=outfile)
od = opendrift.open_xarray(outfile)
density_backwards = od.get_histogram(pixelsize_m=5000).isel(time=-1).isel(origin_marker=0)
density_backwards = density_backwards.where(density_backwards>0)
density_backwards = density_backwards/density_backwards.sum()*100
vmax = density_backwards.max()
o.plot(background=density_backwards, clabel='Probability of origin [%]', text=text, corners=corners, fast=True, markersize=.5, lalpha=.02, vmin=0, vmax=vmax)
os.remove(outfile)

#%%
# Simulating then forwards, starting at a uniform grid 24 hours earlier (440 x 320 = 140800 elements at ~500m separation)
o = Leeway(loglevel=50)
o.add_reader([reader_norkyst, reader_arome])
o.seed_elements(lon=lons, lat=lats, radius=0,
time=start_time, object_type=object_type)
o.run(duration=duration, time_step=900, time_step_output=3600, outfile=outfile)
print(o)

#%%
# Finding the elements actually hitting the target (within 5 km) after 24 hours:
lon, lat = o.get_lonlats()
lonend = lon[:, -1]
latend = lat[:, -1]
geod = pyproj.Geod(ellps='WGS84')
on = np.ones(lonend.shape)
dummy1, dummy2, dist2incident = geod.inv(lonend, latend, ilon*on, ilat*on)
hits = np.where(dist2incident<5000)[0]
hit_start_lons = lon[hits, 0]
hit_start_lats = lat[hits, 0]
o_hit = opendrift.open(outfile, elements=hits)

o.animation(compare=o_hit, legend=['Elements not hitting target', 'Elements hitting target'], fast=True, corners=corners, text=text)

#%%
# .. image:: /gallery/animations/example_leeway_backtrack_0.gif

o.plot(compare=o_hit, legend=['Elements not hitting target', 'Elements hitting target'], show_elements=False, fast=True, corners=corners, text=text)

#%%
# Plot the initial density of elements that actually hit the target after 24 hours. To be compared with the density figure from backwards simulation (see top)
of = opendrift.open_xarray(outfile, elements=hits)
density_forwards = of.get_histogram(pixelsize_m=5000).isel(time=0).isel(origin_marker=0)
density_forwards = density_forwards.where(density_forwards>0)
o_hit.plot(background=density_forwards/density_forwards.sum()*100, clabel='Probability of origin [%]', text=text, corners=corners, fast=True, markersize=.5, lalpha=.02, vmin=0, vmax=vmax)
Loading

0 comments on commit ef81dc9

Please sign in to comment.