Skip to content

Commit

Permalink
Merge pull request #53 from JaimeCalzadaNOAA/develop
Browse files Browse the repository at this point in the history
tidal dataset class inheritance
  • Loading branch information
zacharyburnett authored Mar 5, 2021
2 parents 113c484 + 79b0d83 commit 9b392ae
Show file tree
Hide file tree
Showing 9 changed files with 412 additions and 271 deletions.
59 changes: 29 additions & 30 deletions adcircpy/cmd/basecmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import pathlib

from adcircpy import AdcircMesh, AdcircRun, Tides, server
from adcircpy.forcing.tides import TPXO, HAMTIDE


class AdcircCommand:
Expand All @@ -17,28 +16,28 @@ def run(self):
# write and exit if generate only
if self._args.generate_only:
self.driver.write(
self._args.output_directory,
overwrite=self._args.overwrite
self._args.output_directory,
overwrite=self._args.overwrite
)
return

outputs = self.driver.run(
outdir=self.output_directory,
nproc=self._args.nproc,
overwrite=self._args.overwrite,
server_config=self.server_config,
outdir=self.output_directory,
nproc=self._args.nproc,
overwrite=self._args.overwrite,
server_config=self.server_config,
)
self._output_collection = outputs

@property
@lru_cache(maxsize=None)
def driver(self):
driver = AdcircRun(
self.mesh,
self.start_date,
self.end_date,
self.spinup_time,
server_config=self.server_config
self.mesh,
self.start_date,
self.end_date,
self.spinup_time,
server_config=self.server_config
)
self._enable_outputs(driver)
if self._args.timestep:
Expand Down Expand Up @@ -69,7 +68,7 @@ def mesh(self):
@property
@lru_cache(maxsize=None)
def tidal_forcing(self):
tidal_forcing = Tides(database=self._args.tidal_database)
tidal_forcing = Tides(tidal_source=self._args.tidal_database)
for constituent in self.constituents:
tidal_forcing.use_constituent(constituent)
return tidal_forcing
Expand Down Expand Up @@ -130,12 +129,12 @@ def server_config(self):
not self._args.use_torque or
not self._args.use_pbs):
return server.ServerConfig(
hostname=self._args.hostname,
nprocs=self._args.nproc,
wdir=self._args.wdir,
binaries_prefix=self._args.binaries_prefix,
source_script=self._args.source_script,
additional_mpi_options=self._args.additional_mpi_options,
hostname=self._args.hostname,
nprocs=self._args.nproc,
wdir=self._args.wdir,
binaries_prefix=self._args.binaries_prefix,
source_script=self._args.source_script,
additional_mpi_options=self._args.additional_mpi_options,
)

if self._args.use_slurm:
Expand Down Expand Up @@ -182,16 +181,16 @@ def _enable_output(self, driver, name, _type):
ha = getattr(self._args, f"{name}_{_type}_harmonic_analysis")
# has = getattr(self._args, f"{name}_{_type}_harmonic_analysis_spinup")
getattr(driver, f"set_{name}_{_type}_output")(
sampling_rate=fs,
harmonic_analysis=ha,
spinup=fss,
netcdf=self._args.netcdf,
sampling_rate=fs,
harmonic_analysis=ha,
spinup=fss,
netcdf=self._args.netcdf,
)

def _init_output_stations(self, driver):
if self._args.stations_file is not None:
driver.import_stations(
pathlib.Path(self._args.stations_file).resolve())
pathlib.Path(self._args.stations_file).resolve())
self._enable_output(driver, 'elevation', 'stations')
self._enable_output(driver, 'velocity', 'stations')
self._enable_output(driver, 'meteorological', 'stations')
Expand All @@ -201,21 +200,21 @@ def _init_output_stations(self, driver):
@lru_cache(maxsize=None)
def _mesh(self):
mesh = AdcircMesh.open(
self._args.mesh,
self._args.crs
self._args.mesh,
self._args.crs
)

if self._args.generate_boundaries:
mesh.generate_boundaries(
threshold=self._args.boundaries_threshold,
land_ibtype=self._args.land_ibtype,
interior_ibtype=self._args.island_ibtype,
threshold=self._args.boundaries_threshold,
land_ibtype=self._args.land_ibtype,
interior_ibtype=self._args.island_ibtype,
)

# set nodal attributes
if self._args.fort13 is not None:
mesh.import_nodal_attributes(
pathlib.Path(self._args.fort13).resolve()
pathlib.Path(self._args.fort13).resolve()
)

if 'all' in self._args.coldstart_attributes:
Expand Down
7 changes: 5 additions & 2 deletions adcircpy/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,11 +778,14 @@ def _validate_argument(value: Any, types: [type], name: str = None,
include_none: bool = True):
if isinstance(types, type):
types = [types]
name = f'"{name}"' if name is not None else 'value'
if include_none:
types.append(type(None))
types = tuple(types)

name = f'"{name}"' if name is not None else 'value'

if not isinstance(value, types):
raise ValueError(f'{name} is not of type(s) {types}')
raise TypeError(f'{name} is not of type(s) {types}')

@staticmethod
def _launch_command(cmd, rundir):
Expand Down
5 changes: 1 addition & 4 deletions adcircpy/forcing/tides/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
from adcircpy.forcing.tides.tpxo import TPXO
from adcircpy.forcing.tides.hamtide import HAMTIDE
from adcircpy.forcing.tides.tides import Tides

# from pyschism.forcing.wind import WindForcing
from adcircpy.forcing.tides.tpxo import TPXO

__all__ = [
"Tides",
'TPXO',
'HAMTIDE'
# "WindForcing",
]
84 changes: 84 additions & 0 deletions adcircpy/forcing/tides/dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from abc import ABC, abstractmethod
from os import PathLike

import numpy as np


class TidalDataset(ABC):
CONSTITUENTS: [str] = NotImplementedError

def __init__(self, path: PathLike = None):
"""
create a new tidal dataset object
:param path: file path or URL pointing to dataset location
"""

self.path = str(path) if path is not None else None

@abstractmethod
def __call__(
self,
constituent: str,
vertices: np.ndarray
) -> (np.ndarray, np.ndarray):
"""
get tidal ampltidue and phase
:param constituent: tidal constituent
:param vertices: XY locations at which to sample (Mx2)
:return: amplitude and phase arrays at given locations
"""
return self.get_amplitude(constituent, vertices), \
self.get_phase(constituent, vertices)

@abstractmethod
def get_amplitude(
self,
constituent: str,
vertices: np.ndarray
) -> np.ndarray:
"""
generate tidal ampltidue
:param constituent: tidal constituent
:param vertices: XY locations at which to sample (Mx2)
:return: amplitude at given locations
"""
raise NotImplementedError

@abstractmethod
def get_phase(
self,
constituent: str,
vertices: np.ndarray
) -> np.ndarray:
"""
generate tidal phase
:param constituent: tidal constituent
:param vertices: XY locations at which to sample (Mx2)
:return: phase at given locations
"""
raise NotImplementedError

@property
@abstractmethod
def x(self) -> np.ndarray:
"""
:return: 1D array of X values of vertices
"""
raise NotImplementedError

@property
@abstractmethod
def y(self) -> np.ndarray:
"""
:return: 1D array of Y values of vertices
"""
raise NotImplementedError

@staticmethod
def _assert_vertices(vertices: np.ndarray):
"""
:param vertices: list of XY locations
:return: whether vertices are in XY format (Mx2)
"""
assert len(vertices.shape) == 2 and vertices.shape[1] == 2, \
'vertices must be of shape Mx2'
Loading

0 comments on commit 9b392ae

Please sign in to comment.