Example #1
0
def test_global_array(test_data):
    reader_global = reader_global_landmask.Reader()
    assert reader_global.extent is None

    reader_nordic = reader_ROMS_native.Reader(
        test_data +
        '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc')

    lon = np.array([15., 5.])
    lat = np.array([65.6, 65.6])

    # global
    oc = OceanDrift(loglevel=00)
    oc.add_reader([reader_nordic, reader_global])
    en, en_prof, missing = oc.get_environment(['land_binary_mask'],
                                              reader_nordic.start_time, lon,
                                              lat, np.array([0, 0]), None)

    np.testing.assert_array_equal(en.land_binary_mask, np.array([True, False]))
    assert len(
        oc.readers) == 2  # make sure opendrift doesn't add default basemap
Example #2
0
    def test_density(self):
        """Test density"""
        outfile = 'test_xarray.nc'
        if os.path.exists(outfile):
            os.remove(outfile)
        o = OceanDrift(loglevel=20)
        o.set_config('environment:fallback:land_binary_mask', 0)
        t1 = datetime.now()
        t2 = t1 + timedelta(hours=6)
        o.seed_elements(time=t1, lon=4, lat=60, number=100,
                        origin_marker=0)
        o.seed_elements(time=[t1, t2], lon=4.2, lat=60.2, number=100,
                        origin_marker=1)
        o.seed_elements(time=[t1, t2], lon=4.1, lat=60.1, number=100,
                        origin_marker=2)
        reader_x = reader_oscillating.Reader('x_sea_water_velocity',
                        amplitude=1, zero_time=t1)
        reader_y = reader_oscillating.Reader('y_sea_water_velocity',
                        amplitude=1, zero_time=t2)
        o.add_reader([reader_x, reader_y])
        o.set_config('drift:horizontal_diffusivity', 10)
        o.run(duration=timedelta(hours=12), time_step=1800, outfile=outfile)
        #o.plot(fast=True)
        density_pixelsize_m=5000
        H, Hsub, Hsurf, lon_array, lat_array = o.get_density_array(pixelsize_m=density_pixelsize_m)

        ox = opendrift.open_xarray(outfile)
        Hx = ox.get_histogram(pixelsize_m=density_pixelsize_m)
        self.assertAlmostEqual(lon_array[0], 3.94, 1)
        self.assertAlmostEqual(lon_array[-1], 4.76, 1)
        self.assertAlmostEqual(Hx.lon_bin[0].values, 3.90, 1)
        self.assertAlmostEqual(Hx.lon_bin[-1].values, 4.67, 1)
        self.assertEqual(Hx.sum(dim='origin_marker').shape, H.shape)
        Hsum = H.sum(axis=1).sum(axis=1)
        Hxsum = Hx.sum(('lon_bin', 'lat_bin', 'origin_marker'))
        self.assertEqual(Hsum[0], 118)
        self.assertEqual(Hxsum[0], 118)
        self.assertEqual(Hsum[-1], 300)
        self.assertEqual(Hxsum[-1], 300)
        os.remove(outfile)
Example #3
0
    def test_stranding_options(self):

        reader_osc = reader_oscillating.Reader('x_sea_water_velocity',
                                               amplitude=1,
                                               zero_time=datetime.now())

        reader_basemap = reader_basemap_landmask.Reader(llcrnrlon=12,
                                                        llcrnrlat=67.6,
                                                        urcrnrlon=13.6,
                                                        urcrnrlat=68.1,
                                                        resolution='i',
                                                        projection='merc')

        # Three different stranding options, with
        # expected final status and position
        options = ['stranding', 'previous', 'none']
        status = ['stranded', 'active', 'active']
        lons = [12.930, 13.348, 12.444]

        for i, option in enumerate(options):
            o = OceanDrift(loglevel=30)
            o.set_config('general:coastline_action', option)
            o.add_reader([reader_osc, reader_basemap])
            # Adding northwards drift
            o.fallback_values['y_sea_water_velocity'] = .2
            o.seed_elements(lon=12.2,
                            lat=67.7,
                            radius=0,
                            time=reader_osc.zero_time)
            o.run(steps=28, time_step=3600 * 2)
            #o.plot()
            print('Testing stranding: %s' % option)
            if len(o.elements) == 1:
                el = o.elements
            else:
                el = o.elements_deactivated
            self.assertEqual(o.status_categories[int(el.status)], status[i])
            self.assertIsNone(
                np.testing.assert_array_almost_equal(el.lon, lons[i], 2))
Example #4
0
 def test_outside_domain(self):
     o = OceanDrift(loglevel=50)
     reader_osc_x = reader_oscillating.Reader('x_sea_water_velocity',
                                              amplitude=1,
                                              zero_time=datetime.now())
     reader_osc_y = reader_oscillating.Reader('y_sea_water_velocity',
                                              amplitude=1,
                                              zero_time=datetime.now())
     o.add_reader([reader_osc_x, reader_osc_y])
     o.set_config('drift:deactivate_east_of', 2.1)
     o.set_config('drift:deactivate_west_of', 1.9)
     o.set_config('drift:deactivate_south_of', 59.9)
     o.set_config('drift:deactivate_north_of', 60.1)
     o.set_config('environment:fallback:land_binary_mask', 0)
     o.seed_elements(lon=2,
                     lat=60,
                     number=1000,
                     time=datetime.now(),
                     radius=10000)
     o.run(duration=timedelta(hours=5))
     self.assertEqual(o.num_elements_deactivated(), 768)
     self.assertEqual(o.num_elements_active(), 232)
Example #5
0
 def test_config_constant_fallback(self):
     o = OceanDrift(loglevel=0)
     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')
     print(reader_norkyst, reader_arome)
     o.add_reader([reader_norkyst, reader_arome])
     o.seed_elements(lon=4, lat=60, time=reader_arome.end_time -
                     timedelta(hours=3), number=1)
     o.set_config('environment:fallback:land_binary_mask', 0)
     o.set_config('environment:fallback:x_sea_water_velocity', 1)
     o.set_config('environment:fallback:y_sea_water_velocity', 0)
     o.set_config('environment:constant:x_wind', 0)
     o.set_config('environment:constant:y_wind', 5)
     o.run(duration=timedelta(hours=6))
     y_wind = np.array(o.get_property('y_wind')[0][:,0])
     x_current = np.array(o.get_property('x_sea_water_velocity')[0][:,0])
     # Check that constant wind is used for whole simulation
     self.assertAlmostEqual(y_wind[0], 5, 2)
     self.assertAlmostEqual(y_wind[-1], 5, 2)
     # Check that fallback current is used only after end of reader
     self.assertAlmostEqual(x_current[0], 0.155, 2)
     self.assertAlmostEqual(x_current[-1], 1, 2)
Example #6
0
def test_global_array(test_data):
    shpfilename = shpreader.natural_earth(resolution='110m',
                                          category='cultural',
                                          name='admin_0_countries')
    reader_landmask = reader_shape.Reader.from_shpfiles(shpfilename)

    reader_nordic = reader_ROMS_native.Reader(
        test_data +
        '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc')

    lon = np.array([15., 5.])
    lat = np.array([65.6, 65.6])

    # global
    oc = OceanDrift(loglevel=00)
    oc.add_reader([reader_nordic, reader_landmask])
    en, en_prof, missing = oc.get_environment(['land_binary_mask'],
                                              reader_nordic.start_time, lon,
                                              lat, np.array([0, 0]), None)

    np.testing.assert_array_equal(en.land_binary_mask, np.array([True, False]))
    assert len(
        oc.readers) == 2  # make sure opendrift doesn't add default basemap
Example #7
0
 def test_config_seed(self):
     #o = Leeway(loglevel=20)
     o = OceanDrift(loglevel=20)
     o.list_configspec()
Example #8
0
#!/usr/bin/env python
"""
Drifter
==================================
"""

from datetime import timedelta
import numpy as np
from opendrift.readers import reader_netCDF_CF_generic
from opendrift.models.oceandrift import OceanDrift

o = OceanDrift(
    loglevel=20)  # Basic drift model suitable for passive tracers or drifters

#%%
# Preparing Readers

reader_current = reader_netCDF_CF_generic.Reader(
    o.test_data_folder() +
    '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc')
reader_wind = reader_netCDF_CF_generic.Reader(
    o.test_data_folder() +
    '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc')

o.add_reader([reader_current, reader_wind])

#%%
# Seeding elements
#
# Elements are moved with the ocean current, in addition to a fraction of
# the wind speed (wind_drift_factor). This factor depends on the properties
Example #9
0
#!/usr/bin/env python
"""
Thredds resources for GUI
=========================
"""

from datetime import datetime
from opendrift.models.oceandrift import OceanDrift
from opendrift.readers.reader_netCDF_CF_generic import Reader

o = OceanDrift(loglevel=0)

thredds_resources = open(
    o.test_data_folder() +
    '../../opendrift/scripts/data_sources.txt').readlines()
times = {}

#%%
# Open each thredds dataset to check contents and spatial coverage
for t in thredds_resources:
    if t.startswith('http') and 'nrt.cmems' not in t:
        start = datetime.now()
        print('\n#%%\n%s\n' % t)
        r = Reader(t)
        print(r)
        ts = str(datetime.now() - start)
        times[t] = ts
        print('Time to open reader: ', ts)
        if r.global_coverage():
            lscale = 'coarse'
        else:
 def test_invalid_config(self):
     o = OceanDrift(loglevel=20)
     with self.assertRaises(ValueError):
         o.set_config('seed:number_of_elements', 0)
     o.set_config('seed:number_of_elements', 100)
     self.assertEqual(o.get_config('seed:number_of_elements'), 100)
Example #11
0
 def test_automatic_landmask(self):
     o = OceanDrift(loglevel=20)
     self.assertRaises(ValueError, o.run)
     o.seed_elements(lon=4, lat=60, time=datetime(2016,9,1))
     o.run(steps=2)
Example #12
0
 def test_output_time_step(self):
     o1 = OceanDrift(loglevel=30)
     norkyst = reader_netCDF_CF_generic.Reader(
         o1.test_data_folder() +
         '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc')
     basemap = reader_basemap_landmask.Reader(llcrnrlon=4.5,
                                              llcrnrlat=60.0,
                                              urcrnrlon=5.2,
                                              urcrnrlat=60.5,
                                              resolution='i',
                                              projection='merc')
     o1.add_reader([basemap, norkyst])
     o1.seed_elements(4.96,
                      60.1,
                      radius=3000,
                      number=100,
                      time=norkyst.start_time)
     o1.run(duration=timedelta(hours=12),
            time_step=timedelta(minutes=30),
            time_step_output=timedelta(minutes=30),
            outfile='test_time_step30.nc')
     # Check length of time array and output array
     time = o1.get_time_array()[0]
     self.assertEqual(o1.history.shape[1], len(time))
     self.assertEqual(o1.start_time, time[0])
     self.assertEqual(o1.time, time[-1])
     # Second run, with larger output time step
     o2 = OceanDrift(loglevel=30)
     o2.add_reader([basemap, norkyst])
     o2.seed_elements(4.96,
                      60.1,
                      radius=3000,
                      number=100,
                      time=norkyst.start_time)
     o2.run(duration=timedelta(hours=12),
            time_step=timedelta(minutes=30),
            time_step_output=timedelta(minutes=60),
            outfile='test_time_step60.nc')
     self.assertEqual(o1.history.shape, (100, 25))
     self.assertEqual(o2.history.shape, (100, 13))
     # Check that start and end conditions (longitudes) are idential
     self.assertItemsEqual(o1.history['lon'][:, 24].compressed(),
                           o2.history['lon'][:, 12].compressed())
     self.assertItemsEqual(o1.history['lon'][:, 0].compressed(),
                           o2.history['lon'][:, 0].compressed())
     # Check that also run imported from file is identical
     o1i = OceanDrift(loglevel=20)
     o1i.io_import_file('test_time_step30.nc')
     o2i = OceanDrift(loglevel=20)
     o2i.io_import_file('test_time_step60.nc')
     os.remove('test_time_step30.nc')
     os.remove('test_time_step60.nc')
     self.assertItemsEqual(o2i.history['lon'][:, 12].compressed(),
                           o2.history['lon'][:, 12].compressed())
     # Check number of activated elements
     self.assertEqual(o1.num_elements_total(), o2.num_elements_total())
     self.assertEqual(o1.num_elements_total(), o1i.num_elements_total())
     self.assertEqual(o1.num_elements_total(), o2i.num_elements_total())
     # Check number of deactivated elements
     self.assertEqual(o1.num_elements_deactivated(),
                      o2.num_elements_deactivated())
     self.assertEqual(o1.num_elements_deactivated(),
                      o1i.num_elements_deactivated())
     self.assertEqual(o1.num_elements_deactivated(),
                      o2i.num_elements_deactivated())
Example #13
0
    def test_seed_cone(self):

        # Some cases with expected outcome
        lon0 = 3
        lon1 = 4
        lon2 = 5
        lat0 = 60
        lat1 = 60.2
        lat2 = 60.4
        lon_vec = np.array([lon0, lon1, lon2])
        lat_vec = np.array([lat0, lat1, lat2])
        t0 = datetime.now()
        t1 = t0 + timedelta(hours=6)
        t2 = t1 + timedelta(hours=6)
        t_vec = [t0, t1, t2]
        r0 = 1000
        r1 = 2000
        number_config = 222

        cases = [
            {
                'lon': lon0,
                'lat': lat0,
                'time': t0,
                'number': None,
                'expected': number_config
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': t0,
                'number': 12,
                'expected': 12,
                'maxlat': lat0
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': t0,
                'radius': 1000,
                'number': 12,
                'expected': 12,
                'maxlat': lat0 + .013
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': [t0, t1],
                'maxtime': t1,
                'number': 12,
                'expected': 12
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': t_vec,
                'number': 12,
                'expected': 'error'
            },
            {
                'lon': lon_vec,
                'lat': lat_vec,
                'time': t0,
                'number': None,
                'expected': 'error'
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': t0,
                'wind_drift_factor': .05,
                'number': None,
                'expected': number_config
            },
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': t0,
                'number': None,
                'expected': number_config
            },
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': t0,
                'number': 12,
                'expected': 12
            },
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': t0,
                'radius': 0,
                'number': 200,
                'expected': 200,
                'maxlat': lat1
            },
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': t0,
                'radius': 2000,
                'number': 200,
                'expected': 200,
                'maxlat': lat1 + .024
            },
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': t0,
                'radius': [1000, 2000],
                'number': 200,
                'expected': 200,
                'maxlat': lat1 + .024
            },
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': t0,
                'radius': [1000, 2000, 3000],
                'number': 200,
                'expected': 'error'
            },
            #'wind_drift_factor': [.01, .02, .03],
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': [t0, t1],
                'number': None,
                'expected': number_config,
                'maxtime': t1
            },
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': [t0, t1],
                'radius': [r0, r1],
                'number': None,
                'expected': number_config,
                'maxtime': t1
            },
            {
                'lon': [lon0, lon1],
                'lat': [lat0, lat1],
                'time': [t0, t1],
                'radius': [r0, r0],
                'number': None,
                'expected': number_config,
                'maxtime': t1
            },
        ]

        for case in cases:
            o = OceanDrift(loglevel=50)
            o._set_config_default('seed:number', number_config)
            expected = case['expected']
            del case['expected']
            if 'maxlat' in case:
                maxlat = case['maxlat']
                del case['maxlat']
            else:
                maxlat = None
            if 'maxtime' in case:
                maxtime = case['maxtime']
                del case['maxtime']
            else:
                maxtime = None
            if expected == 'error':
                with self.assertRaises(ValueError):
                    n = o.seed_cone(**case)
            else:
                o.seed_cone(**case)
                self.assertEqual(o.num_elements_total(), expected)
                if maxlat is not None:
                    self.assertAlmostEqual(o.elements_scheduled.lat.max(),
                                           maxlat, 2)
                if maxtime is not None:
                    self.assertEqual(
                        o.elements_scheduled_time.max().replace(microsecond=0),
                        maxtime.replace(microsecond=0))
                if 'wind_drift_factor' in case:
                    self.assertEqual(
                        np.array(case['wind_drift_factor']).max().astype(
                            np.float32),
                        o.elements_scheduled.wind_drift_factor.max())
Example #14
0
    def test_vertical_mixing_profiles(self):
        # Testing an isolated mixing timestep

        cases = [  # Some cases with expected outcome
            {
                'vt': 0,
                'K': 0,
                'K_below': .01,
                'T': 60,  # No mixing
                'zmin': -10,
                'zmax': -10,
                'zmean': -10
            },
            {
                'vt': -.005,
                'K': 0,
                'K_below': .01,
                'T': 60,  # Sinking
                #'zmin': -74.0, 'zmax': -21.4, 'zmean': -50.2},  # With old seed_elements
                'zmin': -74.79,
                'zmax': -21.6,
                'zmean': -49.97
            },
            {
                'vt': 0,
                'K': .01,
                'K_below': .01,
                'T': 60,  # Mixing
                #'zmin': -39.8, 'zmax': -0.1, 'zmean': -14.5},
                'zmin': -42.76,
                'zmax': -0.02,
                'zmean': -14.38
            },
            {
                'vt': .005,
                'K': .01,
                'K_below': .01,
                'T': 60,  # Mixing and rising
                #'zmin': -8.1, 'zmax': -0.01, 'zmean': -2.1},
                'zmin': -7.86,
                'zmax': -0.01,
                'zmean': -2.1
            },
            {
                'vt': -0.005,
                'K': .01,
                'K_below': .01,
                'T': 60,  # Mixing and sinking
                #'zmin': -75.8, 'zmax': -20.7, 'zmean': -48.1},
                'zmin': -78.76,
                'zmax': -19.74,
                'zmean': -48.0
            },
            {
                'vt': 0,
                'K': .02,
                'K_below': .001,
                'T': 60,  # Mixing in mixed layer
                #'zmin': -22.8, 'zmax': -0.1, 'zmean': -9.8},
                'zmin': -21.3,
                'zmax': -0.1,
                'zmean': -9.55
            },
        ]

        N = 100
        z = np.arange(0, -30, -2)
        time = datetime.now()
        for case in cases:
            diffusivity = np.ones(z.shape) * case['K']
            diffusivity[z < -15] = case['K_below']
            o = OceanDrift(loglevel=20)
            o.set_config('drift:vertical_mixing', True)
            o.set_config('vertical_mixing:diffusivitymodel', 'environment')
            o.set_config('vertical_mixing:timestep', case['T'])
            o.seed_elements(lon=4,
                            lat=60,
                            z=-10,
                            time=time,
                            number=N,
                            terminal_velocity=case['vt'])
            o.time = time
            o.time_step = timedelta(hours=2)
            o.release_elements()
            o.set_config('environment:fallback:land_binary_mask', 0)
            o.environment = np.array(np.ones(N) * 100,
                                     dtype=[('sea_floor_depth_below_sea_level',
                                             np.float32)]).view(np.recarray)
            o.environment_profiles = {
                'z': z,
                'ocean_vertical_diffusivity': np.tile(diffusivity, (N, 1)).T
            }
            o.set_fallback_values()
            o.vertical_mixing()
            self.assertAlmostEqual(o.elements.z.min(), case['zmin'], 1)
            self.assertAlmostEqual(o.elements.z.max(), case['zmax'], 1)
            self.assertAlmostEqual(o.elements.z.mean(), case['zmean'], 1)
Example #15
0
 def test_automatic_basemap(self):
     o = OceanDrift(loglevel=20)
     self.assertRaises(ValueError, o.run)
     o.seed_elements(lon=4, lat=60, time=datetime(2016, 9, 1))
     o.set_config('general:basemap_resolution', 'c')  # To make test fast
     o.run(steps=2)
Example #16
0
"""
Convolve input
==============

Decreasing the spatial resolution of fields from a reader by convolution.
This may improve accuracy, see: https://doi.org/10.1016/j.rse.2019.01.001
"""

from datetime import datetime, timedelta
import matplotlib.pyplot as plt
from opendrift.readers import reader_netCDF_CF_generic
from opendrift.models.oceandrift import OceanDrift

lon = 4.9
lat = 60.0
o = OceanDrift(loglevel=20)

reader_norkyst = reader_netCDF_CF_generic.Reader(
    o.test_data_folder() +
    '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc')
time = reader_norkyst.start_time

o.add_reader([reader_norkyst])
o.seed_elements(lon, lat, radius=1000, number=1000, time=time)
o.run(steps=20)

#%%
# Store final field of x-component of current
original_current = reader_norkyst.var_block_after[list(
    reader_norkyst.var_block_after.keys(
    ))[0]].data_dict['x_sea_water_velocity'].copy()
Example #17
0
import os
import sys
import numpy as np
from datetime import datetime, timedelta
from opendrift.readers import reader_global_landmask
from opendrift.readers import reader_ROMS_native_MOANA
from opendrift.models.oceandrift import OceanDrift
#from opendrift.models.pelagicplankton_moana import PelagicPlanktonDrift
#from opendrift.models.sedimentdrift import SedimentDrift

###############################
# MODEL SELECTION
###############################

o = OceanDrift(loglevel=100)
#o = SedimentDrift(loglevel=100)  # 0 for debug output
#o = PelagicPlanktonDrift(loglevel=50)  # Set loglevel to 0 for debug information
o.max_speed = 3.0  #

###############################
# READERS
###############################

thredds_path_1 = 'http://thredds.moanaproject.org:8080/thredds/dodsC/moana/ocean/NZB/v1.9/raw_3D/nz5km_his_201709.nc?ntimes,dt,hc,grid,s_rho[5:1:12],Cs_r[5:1:12],h[0:1:466][0:1:396],lon_rho[0:1:466][0:1:396],lat_rho[0:1:466][0:1:396],lon_u[0:1:466][0:1:395],lat_u[0:1:466][0:1:395],lon_v[0:1:465][0:1:396],lat_v[0:1:465][0:1:396],lon_psi[0:1:465][0:1:395],angle[0:1:466][0:1:396],mask_rho[0:1:466][0:1:396],mask_u[0:1:466][0:1:395],mask_v[0:1:465][0:1:396],ocean_time[0:1:240],z_rho[0:1:240][5:1:12][0:1:466][0:1:396],u_eastward[0:1:240][5:1:12][0:1:466][0:1:396],v_northward[0:1:240][5:1:12][0:1:466][0:1:396]'  # Limit to selected depths (raw data: [0:1:39])#'http://thredds.moanaproject.org:8080/thredds/dodsC/moana/ocean/NZB/v1.9/raw_3D/nz5km_his_201710.nc'
reader_moana_v19_1 = reader_ROMS_native_MOANA.Reader(
    [thredds_path_1])  #load data for that year
reader_moana_v19_1.multiprocessing_fail = True  # bypass the use of multi core for coordinates conversion and seems to make the model run much faster.

thredds_path_2 = 'http://thredds.moanaproject.org:8080/thredds/dodsC/moana/ocean/NZB/v1.9/raw_3D/nz5km_his_201708.nc?ntimes,dt,hc,grid,s_rho[5:1:12],Cs_r[5:1:12],h[0:1:466][0:1:396],lon_rho[0:1:466][0:1:396],lat_rho[0:1:466][0:1:396],lon_u[0:1:466][0:1:395],lat_u[0:1:466][0:1:395],lon_v[0:1:465][0:1:396],lat_v[0:1:465][0:1:396],lon_psi[0:1:465][0:1:395],angle[0:1:466][0:1:396],mask_rho[0:1:466][0:1:396],mask_u[0:1:466][0:1:395],mask_v[0:1:465][0:1:396],ocean_time[0:1:248],z_rho[0:1:248][5:1:12][0:1:466][0:1:396],u_eastward[0:1:248][5:1:12][0:1:466][0:1:396],v_northward[0:1:248][5:1:12][0:1:466][0:1:396]'  # to finish the run in the previous month
reader_moana_v19_2 = reader_ROMS_native_MOANA.Reader([thredds_path_2])  #
"""
Convolve input
=============

Demonstrating how the spatial resolution of
fields from a reader may be reduced.
"""

from datetime import datetime, timedelta
import matplotlib.pyplot as plt
from opendrift.readers import reader_netCDF_CF_generic
from opendrift.models.oceandrift import OceanDrift


lon = 4.9; lat = 60.0
o = OceanDrift()

reader_norkyst = reader_netCDF_CF_generic.Reader(o.test_data_folder() + '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc')
time = reader_norkyst.start_time

o.add_reader([reader_norkyst])
o.seed_elements(lon, lat, radius=1000, number=1000, time=time)
o.run(steps=20)

# Store final field of x-component of current
original_current = reader_norkyst.var_block_after[list(reader_norkyst.var_block_after.keys())[0]].data_dict['x_sea_water_velocity'].copy()

# For the second run, the NorKyst currents are convolved with a kernel,
# effectively lowering the spatial resolution.
# <reader>.convolve may also be given as an array (kernel) directly
N = 10  # Convolusion kernel size
Example #19
0
 def test_seed_cone(self):
     o = OceanDrift(loglevel=20)
     o.seed_cone(time=[datetime.now(),
             datetime.now() + timedelta(hours=3)],
             number=100, lat=[60.5, 60.6], lon=[4.4, 4.5])
     self.assertAlmostEqual(o.elements_scheduled.lon[50], 4.450, 2)
Example #20
0
 def make_OceanDrift_object(self):
     self.o = OceanDrift(loglevel=30)
     self.fake_eddy = reader_ArtificialOceanEddy.Reader(2, 62)
     self.reader_landmask = reader_global_landmask.Reader(
         extent=[-1.5, 59, 7, 64])
     self.o.add_reader([self.fake_eddy, self.reader_landmask])
    def test_dateline(self):

        # Make synthetic netCDF file with currents from 0 to 360 deg longitude
        fc = 'opendrift_test_current_0_360.nc'
        lon = np.arange(0, 360)
        lat = np.arange(-88, 89)
        start_time = datetime(2021, 1, 1)
        time = [start_time + i * timedelta(hours=24) for i in range(3)]
        t, xcurr, ycurr = np.meshgrid(time,
                                      np.zeros(lat.shape),
                                      np.zeros(lon.shape),
                                      indexing='ij')
        xcurr[:, :, 0:180] = 1  # eastward
        xcurr[:, :, 180:] = -1  # westward, i.e. current divergence at lon=0
        ds = xr.Dataset(
            {
                "xcurr": (("time", "lat", "lon"), xcurr, {
                    'standard_name': 'x_sea_water_velocity'
                }),
                "ycurr": (("time", "lat", "lon"), ycurr, {
                    'standard_name': 'y_sea_water_velocity'
                })
            },
            coords={
                "lon": lon,
                "lat": lat,
                "time": time
            })
        ds.to_netcdf(fc)

        # Make synthetic netCDF file with winds from -180 to 180 deg longitude
        fw = 'opendrift_test_winds_180_180.nc'
        lon = np.arange(-180, 180)
        t, xwind, ywind = np.meshgrid(time,
                                      np.zeros(lat.shape),
                                      np.zeros(lon.shape),
                                      indexing='ij')
        ywind[:, :, 0:180] = 1  # northward
        ywind[:, :, 180:] = -1  # southward, i.e. wind divergence at lon=180
        ds = xr.Dataset(
            {
                "xwind": (("time", "lat", "lon"), xwind, {
                    'standard_name': 'x_wind'
                }),
                "ywind": (("time", "lat", "lon"), ywind, {
                    'standard_name': 'y_wind'
                })
            },
            coords={
                "lon": lon,
                "lat": lat,
                "time": time
            })
        ds.to_netcdf(fw)

        reader_current = reader_netCDF_CF_generic.Reader(fc)
        reader_wind = reader_netCDF_CF_generic.Reader(fw)

        # Simulation across 0 meridian
        o = OceanDrift(loglevel=30)
        o.add_readers_from_list([fc, fw])
        o.seed_elements(lon=[-2, 2],
                        lat=[60, 60],
                        time=start_time,
                        wind_drift_factor=.1)
        o.run(steps=2)
        # Check that current give divergence, and that
        # wind is northwards east of 0 and southwards to the east
        np.testing.assert_array_almost_equal(o.elements.lon, [-2.129, 2.129],
                                             decimal=3)
        np.testing.assert_array_almost_equal(o.elements.lat, [60.006, 59.994],
                                             decimal=3)

        # Simulation across dateline (180 E/W)
        o = OceanDrift(loglevel=30)
        o.add_readers_from_list([fc, fw])
        o.seed_elements(lon=[-175, 175],
                        lat=[60, 60],
                        time=start_time,
                        wind_drift_factor=.1)
        o.run(steps=2)
        #o.plot(fast=True)
        # Check that current give convergence, and that
        # wind is northwards east of 180 and southwards to the west
        np.testing.assert_array_almost_equal(o.elements.lon,
                                             [-175.129, 175.129],
                                             decimal=3)
        np.testing.assert_array_almost_equal(o.elements.lat, [60.006, 59.994],
                                             decimal=3)

        # Cleaning up
        os.remove(fw)
        os.remove(fc)
Example #22
0
#
# Copyright 2015, Knut-Frode Dagestad, MET Norway

import unittest
from datetime import datetime, timedelta

import numpy as np

from opendrift.models.oceandrift import OceanDrift
from opendrift.readers import reader_netCDF_CF_generic
from opendrift.readers import reader_ROMS_native
from opendrift.readers import reader_basemap_landmask
from opendrift.models.pelagicegg import PelagicEggDrift


o = OceanDrift()
basemap = reader_basemap_landmask.Reader(
            llcrnrlon=-1.5, llcrnrlat=59,
            urcrnrlon=7, urcrnrlat=64, resolution='c')

class TestReaders(unittest.TestCase):
    """Tests for readers"""

    def test_adding_readers(self):
        o = OceanDrift()
        r = reader_ROMS_native.Reader(o.test_data_folder() +
            '2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc')
        o.add_reader([r, basemap])
        self.assertEqual(o.priority_list['land_binary_mask'],
                         ['roms native', 'basemap_landmask'])
        self.assertEqual(o.priority_list['x_sea_water_velocity'],
Example #23
0
#!/usr/bin/env python

from datetime import timedelta
import numpy as np

from opendrift.readers import reader_netCDF_CF_generic
from opendrift.models.oceandrift import OceanDrift

o = OceanDrift()  # Basic drift model suitable for passive tracers or drifters

#######################
# Preparing Readers
#######################

reader_current = reader_netCDF_CF_generic.Reader(
    o.test_data_folder() +
    '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc')
reader_wind = reader_netCDF_CF_generic.Reader(
    o.test_data_folder() +
    '16Nov2015_NorKyst_z_surface/arome_subset_16Nov2015.nc')

o.add_reader([reader_current, reader_wind])

#######################
# Seeding elements
#######################

# Elements are moved with the ocean current, in addition to a fraction of
# the wind speed (wind_drift_factor). This factor depends on the properties
# of the elements. Typical empirical values are:
# - 0.035 (3.5 %) for oil and iSphere driftes
Example #24
0
    def test_seed_elements(self):
        # Some cases with expected outcome
        lon_vec = np.array([3, 4, 5])
        lat_vec = np.array([63, 64, 65])
        lon0 = 3
        lat0 = 60
        t0 = datetime.now()
        t1 = t0 + timedelta(hours=6)
        t2 = t1 + timedelta(hours=6)
        t_vec = [t0, t1, t2]
        number_config = 222

        cases = [
            {
                'lon': lon0,
                'lat': lat0,
                'time': t0,
                'number': None,
                'expected': number_config
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': t0,
                'number': 12,
                'expected': 12,
                'maxlat': lat0
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': t0,
                'radius': 1000,
                'number': 12,
                'expected': 12,
                'maxlat': lat0 + .013
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': [t0, t1],
                'maxtime': t1,
                'number': 12,
                'expected': 12
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': t_vec,  # Time series
                'maxtime': t2,
                'number': None,
                'expected': len(t_vec)
            },
            {
                'lon': lon0,
                'lat': lat0,
                'time': t_vec,
                'number': 12,
                'expected': 'error'
            },
            {
                'lon': lon_vec,
                'lat': lat_vec,
                'time': t0,
                'number': None,
                'expected': 3
            },
            {
                'lon': lon_vec,
                'lat': lat_vec,
                'time': t0,
                'wind_drift_factor': .05,
                'number': None,
                'expected': 3
            },
            {
                'lon': lon_vec,
                'lat': lat_vec,
                'time': t0,
                'wind_drift_factor': [.01, .02, .03],
                'number': None,
                'expected': 3
            },
            {
                'lon': lon_vec,
                'lat': lat_vec,
                'time': t0,
                'number': 4,
                'expected': 'error'
            },
            {
                'lon': lon_vec,
                'lat': lat_vec,
                'time': t_vec,
                'number': None,
                'expected': 3,
                'maxtime': t_vec[-1]
            },
        ]

        for case in cases:
            o = OceanDrift(loglevel=50)
            o._set_config_default('seed:number', number_config)
            expected = case['expected']
            del case['expected']
            if 'maxlat' in case:
                maxlat = case['maxlat']
                del case['maxlat']
            else:
                maxlat = None
            if 'maxtime' in case:
                maxtime = case['maxtime']
                del case['maxtime']
            else:
                maxtime = None
            if expected == 'error':
                with self.assertRaises(ValueError):
                    n = o.seed_elements(**case)
            else:
                o.seed_elements(**case)
                self.assertEqual(o.num_elements_total(), expected)
                if maxlat is not None:
                    self.assertAlmostEqual(o.elements_scheduled.lat.max(),
                                           maxlat, 2)
                if maxtime is not None:
                    self.assertEqual(
                        o.elements_scheduled_time.max().replace(microsecond=0),
                        maxtime.replace(microsecond=0))
                if 'wind_drift_factor' in case:
                    self.assertEqual(
                        np.array(case['wind_drift_factor']).max().astype(
                            np.float32),
                        o.elements_scheduled.wind_drift_factor.max())
Example #25
0
def test_plot(tmpdir):

    anifile = os.path.join(tmpdir, 'anim.mp4')
    plotfile = os.path.join(tmpdir, 'plot.png')
    #anifile = None
    #plotfile = None
    o = OceanDrift(loglevel=30)
    rn = reader_netCDF_CF_generic.Reader(
        o.test_data_folder() +
        '16Nov2015_NorKyst_z_surface/norkyst800_subset_16Nov2015.nc')
    o.add_reader(rn)
    o.seed_elements(lon=4.8,
                    lat=60.0,
                    number=10,
                    radius=1000,
                    time=rn.start_time)
    o.run(steps=5)

    # Making figures/animations
    o.plot(filename=plotfile,
           fast=True,
           background=['x_sea_water_velocity', 'y_sea_water_velocity'])
    o.animation(color='lat',
                filename=anifile,
                show_trajectories=True,
                fast=True)
    o.animation(density=True,
                filename=anifile,
                show_trajectories=True,
                fast=True)
    o.animation(filename=anifile, show_trajectories=True, fast=True)
    o.animation(filename=anifile,
                fast=True,
                background=['x_sea_water_velocity', 'y_sea_water_velocity'])
    o.plot(filename=plotfile, fast=True, linecolor='lat')
    o.plot(filename=plotfile, fast=False)

    # Second run for comparison
    o2 = OceanDrift(loglevel=30)
    o2.add_reader(rn)
    o2.fallback_values['x_wind'] = 15  # Adding wind
    o2.fallback_values['y_wind'] = 0
    o2.seed_elements(lon=4.8,
                     lat=60.0,
                     number=10,
                     radius=1000,
                     time=rn.start_time)
    o2.run(steps=5)

    o.animation(filename=anifile,
                compare=o2,
                fast=True,
                legend=['No wind', '10 m/s wind'])
    o.plot(filename=plotfile,
           compare=o2,
           fast=True,
           legend=['No wind', '10 m/s wind'])

    # Check that files have been written
    assert os.path.exists(anifile)
    assert os.path.exists(plotfile)
Example #26
0
Double gyre
=============

Illustrating the difference between Euler and Runge-Kutta propagation
schemes, using an idealised (analytical) eddy current field.

Double gyre current field from
http://shaddenlab.berkeley.edu/uploads/LCS-tutorial/examples.html
"""

from datetime import datetime, timedelta

from opendrift.readers import reader_double_gyre
from opendrift.models.oceandrift import OceanDrift

o = OceanDrift(loglevel=20)  # Set loglevel to 0 for debug information
o.fallback_values['land_binary_mask'] = 0
o.set_config('drift:scheme', 'runge-kutta4')

double_gyre = reader_double_gyre.Reader(epsilon=.25, omega=0.628, A=0.1)
print(double_gyre)

o.add_reader(double_gyre)

x = [.9]
y = [.5]
lon, lat = double_gyre.xy2lonlat(x, y)

o.seed_elements(lon,
                lat,
                radius=.1,
Example #27
0
"""

from datetime import datetime, timedelta
from opendrift.models.oceandrift import OceanDrift
from opendrift.readers.reader_constant import Reader as ConstantReader

#%%
# Mixed Layer Depth of 20m West of 3 deg E, and 50m to the east
r1 = ConstantReader({'ocean_mixed_layer_thickness': 20})
r2 = ConstantReader({'ocean_mixed_layer_thickness': 50})
r1.xmax = 3
r2.xmin = 3

#%%
# First with Sundby1983 parameterization of diffusivity, based on wind and MLD
o = OceanDrift(loglevel=50)
o.seed_cone(lon=[2, 4], lat=[60, 60], time=datetime.now(), number=5000)
o.add_reader([r1, r2])
o.set_config('environment:constant:y_wind', 8)  # Some wind for mixing
o.set_config('drift:vertical_mixing', True)
o.set_config('vertical_mixing:diffusivitymodel', 'windspeed_Sundby1983')
# Increasing background diffusivity beyond default (1.2e-5) to avoid artefact due to sharp gradient at MLD
o.set_config('vertical_mixing:background_diffusivity', 0.001)
o.run(duration=timedelta(hours=48))
o.animation_profile()

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

#%%
# Same, but with Large1994 parameterization of diffusivity