Skip to content

Commit

Permalink
adding xarray dataset option to ROMS reader
Browse files Browse the repository at this point in the history
  • Loading branch information
rsignell committed Jan 16, 2024
1 parent f486f2d commit 45251a3
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 27 deletions.
37 changes: 37 additions & 0 deletions examples/example_roms_native_xarray_dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env python
"""
ROMS native reader
==================================
"""

import numpy as np
from opendrift.readers import reader_ROMS_native
from opendrift.models.oceandrift import OceanDrift
import xarray as xr

o = OceanDrift(loglevel=20) # Set loglevel to 0 for debug information

#%%
filename = (o.test_data_folder() +
'2Feb2016_Nordic_sigma_3d/Nordic-4km_SLEVELS_avg_00_subset2Feb2016.nc')

# Creating and adding reader for Nordic 4km current dataset

ds = xr.open_dataset(filename, decode_times=False)
nordic_native = reader_ROMS_native.Reader(ds)
o.add_reader(nordic_native)

#%%
# Seed elements at defined positions, depth and time
o.seed_elements(lon=12.0, lat=68.3, radius=0, number=10,
z=np.linspace(0, -150, 10), time=nordic_native.start_time)

#%%
# Running model
o.run(time_step=3600)

#%%
# Print and plot results, with lines colored by particle depth
print(o)
o.plot(linecolor='z', fast=True)
#o.animation()
106 changes: 79 additions & 27 deletions opendrift/readers/reader_ROMS_native.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,49 @@


class Reader(BaseReader, StructuredReader):
"""
A reader for ROMS Output files. It can take a single file, a file pattern, a URL or an xarray Dataset.
Args:
:param filename: A single netCDF file, a pattern of files, or a xr.Dataset. The
netCDF file can also be an URL to an OPeNDAP server.
:type filename: string, xr.Dataset (required).
:param name: Name of reader
:type name: string, optional
:param proj4: PROJ.4 string describing projection of data.
:type proj4: string, optional
Example:
.. code::
from opendrift.readers.reader_ROMS_native import Reader
r = Reader("roms.nc")
Several files can be specified by using a pattern:
.. code::
from opendrift.readers.reader_ROMS_native import Reader
r = Reader("*.nc")
An OPeNDAP URL can be used:
.. code::
from opendrift.readers.reader_ROMS_native import Reader
r = Reader('https://thredds.met.no/thredds/dodsC/mepslatest/meps_lagged_6_h_latest_2_5km_latest.nc')
A xr.Dataset can be used:
.. code::
from opendrift.readers.reader_ROMS_native import Reader
ds = xr.open_dataset(filename, decode_times=False)
r = Reader(ds)
"""

def __init__(self, filename=None, name=None, gridfile=None, standard_name_mapping={}):

Expand Down Expand Up @@ -79,35 +122,44 @@ def __init__(self, filename=None, name=None, gridfile=None, standard_name_mappin

gls_param = ['gls_cmu0', 'gls_p', 'gls_m', 'gls_n']

filestr = str(filename)
if name is None:
self.name = filestr
if isinstance(filename, xr.Dataset):
self.Dataset = filename
if name is not None:
self.name = name
else:
import re
self.name = re.sub('[^0-9a-zA-Z]+', '_', filename.attrs['title'])
else:
self.name = name

try:
# Open file, check that everything is ok
logger.info('Opening dataset: ' + filestr)
if ('*' in filestr) or ('?' in filestr) or ('[' in filestr):
logger.info('Opening files with MFDataset')
def drop_non_essential_vars_pop(ds):
dropvars = [v for v in ds.variables if v not in
list(self.ROMS_variable_mapping.keys()) + gls_param +
['ocean_time', 'time', 'bulk_time', 's_rho',
'Cs_r', 'hc', 'angle', 'Vtransform']
and v[0:3] not in ['lon', 'lat', 'mas']]
logger.debug('Dropping variables: %s' % dropvars)
ds = ds.drop_vars(dropvars)
return ds
self.Dataset = xr.open_mfdataset(filename,
chunks={'ocean_time': 1}, compat='override', decode_times=False,
preprocess=drop_non_essential_vars_pop,
data_vars='minimal', coords='minimal')

filestr = str(filename)
if name is None:
self.name = filestr
else:
logger.info('Opening file with Dataset')
self.Dataset = xr.open_dataset(filename, decode_times=False)
except Exception as e:
raise ValueError(e)
self.name = name

try:
# Open file, check that everything is ok
logger.info('Opening dataset: ' + filestr)
if ('*' in filestr) or ('?' in filestr) or ('[' in filestr):
logger.info('Opening files with MFDataset')
def drop_non_essential_vars_pop(ds):
dropvars = [v for v in ds.variables if v not in
list(self.ROMS_variable_mapping.keys()) + gls_param +
['ocean_time', 'time', 'bulk_time', 's_rho',
'Cs_r', 'hc', 'angle', 'Vtransform']
and v[0:3] not in ['lon', 'lat', 'mas']]
logger.debug('Dropping variables: %s' % dropvars)
ds = ds.drop_vars(dropvars)
return ds
self.Dataset = xr.open_mfdataset(filename,
chunks={'ocean_time': 1}, compat='override', decode_times=False,
preprocess=drop_non_essential_vars_pop,
data_vars='minimal', coords='minimal')
else:
logger.info('Opening file with Dataset')
self.Dataset = xr.open_dataset(filename, decode_times=False)
except Exception as e:
raise ValueError(e)

if gridfile is not None: # Merging gridfile dataset with main dataset
gf = xr.open_dataset(gridfile)
Expand Down

0 comments on commit 45251a3

Please sign in to comment.