Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/virtualship/instruments/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import abc
import collections
import tempfile
from datetime import timedelta
from itertools import pairwise
from pathlib import Path
Expand Down Expand Up @@ -183,6 +184,9 @@ def _generate_fieldset(self) -> parcels.FieldSet:
Create and combine FieldSets for each variable, supporting both local and Copernicus Marine data sources.

N.B. Per variable avoids issues when using copernicusmarine and creating directly one FieldSet of ds's sourced from different Copernicus Marine product IDs (which can also have different temporal resolutions), which is often the case for BGC variables.

Includes an intermediate step of writing to tmp files, as per https://github.com/Parcels-code/parcels-benchmarks/pull/49
TODO: the need for this step may be removed as Parcels x copernicusmarine integration improves, tracked in https://github.com/Parcels-code/Parcels/issues/2756 and xref'd in VirtualShip #357 (https://github.com/Parcels-code/virtualship/issues/357)
"""
fieldsets_list = []
keys = list(self.variables.keys())
Expand Down Expand Up @@ -222,11 +226,12 @@ def _generate_fieldset(self) -> parcels.FieldSet:
ds["depth"] = -ds["depth"]
ds = ds.reindex(depth=ds["depth"][::-1])

# TODO: update when decision on handling of nans/0s in v4 is made (i.e. https://github.com/Parcels-code/Parcels/issues/2393)
# TODO: to be removed when Parcels #2746 is merged (i.e. https://github.com/Parcels-code/Parcels/pull/2746)
ds = ds.fillna(0)

fields = {key: ds[field_var_name]}
ds_fset = parcels.convert.copernicusmarine_to_sgrid(fields=fields)
ds_fset = self._via_tmp_ds(ds_fset)

fs = parcels.FieldSet.from_sgrid_conventions(ds_fset)

Expand All @@ -253,3 +258,12 @@ def _get_spec_value(self, spec_type: str, key: str, default=None):
"""Helper to extract a value from spacetime_buffer_size or limit_spec."""
spec = self.spacetime_buffer_size if spec_type == "buffer" else self.limit_spec
return spec.get(key) if spec and spec.get(key) is not None else default

@staticmethod
def _via_tmp_ds(ds) -> xr.Dataset:
"""Create and re-load a temporary local dataset."""
tmpdir = tempfile.TemporaryDirectory()
tmp_fpath = Path(tmpdir.name).joinpath("tmp.nc")
ds.to_netcdf(tmp_fpath)
del ds
return xr.open_dataset(tmp_fpath)
Loading