Source code for wavespectra.input.octopus

"""Read Octopus spectra files."""
from xarray.backends import BackendEntrypoint
import gzip
import datetime
import numpy as np
import xarray as xr

from wavespectra.specdataset import SpecDataset
from wavespectra.core.attributes import set_spec_attributes


[docs] def read_octopus(filename_or_obj): """Read spectra from Octopus file format. Args: - filename_or_obj (str, Path, filelike obj): Octopus file to read. Returns: - dset (SpecDataset): spectra dataset object. """ try: if hasattr(filename_or_obj, "read"): f = filename_or_obj elif str(filename_or_obj).endswith(".gz"): f = gzip.open(filename_or_obj, "rt") else: f = open(filename_or_obj, "rt") efths = [] wspds = [] wdirs = [] times = [] dset = xr.Dataset() description = f.readline().rstrip("\n") nfreqs = int(f.readline().split(",")[1]) ndirs = int(f.readline().split(",")[1]) nrecs = int(f.readline().split(",")[1]) # Coordinates dset["lat"] = xr.DataArray([float(f.readline().split(",")[1])], dims=("site",)) dset["lon"] = xr.DataArray([float(f.readline().split(",")[1])], dims=("site",)) dset["site"] = [0] __ = float(f.readline().split(",")[1]) # Append each record for i in range(nrecs): for __ in range(2): next(f) parts = [part.lstrip("'") for part in f.readline().split(",")] times.append(datetime.datetime.strptime("".join(parts[0:2]), "%Y%m%d%H%M")) wdirs.append(float(parts[3])) wspds.append(float(parts[4])) # Frequencies freqs = [float(f) for f in f.readline().split(",")[1:-1]] if len(freqs) != nfreqs: raise OSError(f"Invalid frequency row for record {times[-1]}") data = np.genfromtxt( f, delimiter=",", dtype="float", usecols=np.arange(nfreqs + 1), max_rows=ndirs, unpack=True, ) # Directions dirs = data[0, :] # Energy data efths.append(data[1:, :]) for __ in range(2): next(f) except Exception as e: raise (e) finally: f.close() # Output ds = xr.DataArray( data=efths, coords={"time": times, "freq": freqs, "dir": dirs}, dims=("time", "freq", "dir"), name="efth", ).to_dataset() dset["efth"] = (ds.efth / (ds.spec.df * ds.spec.dd)).expand_dims("site", axis=1) dset["wspd"] = xr.DataArray(wspds, dims=("time",)).expand_dims("site", axis=1) dset["wdir"] = xr.DataArray(wdirs, dims=("time",)).expand_dims("site", axis=1) # Set attributes set_spec_attributes(dset) dset.attrs.update({"description": description}) return dset
class OctopusBackendEntrypoint(BackendEntrypoint): """Octopus backend engine.""" def open_dataset( self, filename_or_obj, *, drop_variables=None, ): return read_octopus(filename_or_obj) def guess_can_open(self, filename_or_obj): return False description = "Open Octopus spectra files as a wavespectra dataset." url = "https://github.com/wavespectra/wavespectra"