-
Notifications
You must be signed in to change notification settings - Fork 168
Closed
Description
While working on #2483, I ran into an issue in our timedelta_to_float function in time.py, which can't handle the array below
[datetime.timedelta(0) datetime.timedelta(days=1)
datetime.timedelta(days=2) datetime.timedelta(days=3)
datetime.timedelta(days=4) datetime.timedelta(days=5)
datetime.timedelta(days=6) datetime.timedelta(days=7)
datetime.timedelta(days=8) datetime.timedelta(days=9)]The following test breaks
data_folder = parcels.download_example_dataset("MITgcm_example_data")
ds_fields = xr.open_dataset(data_folder / "mitgcm_UV_surface_zonally_reentrant.nc")
# t = ds_fields["time"].values
# secs = np.array([(ti - t[0]).total_seconds() for ti in t])
# td_ns = np.rint(secs * 1e9).astype("int64").astype("timedelta64[ns]")
# ds_fields = ds_fields.assign_coords(time=td_ns)
coords = ds_fields[["XG", "YG", "Zl", "time"]]
ds_fset = convert.mitgcm_to_sgrid(fields={"U": ds_fields.UVEL, "V": ds_fields.VVEL}, coords=coords)
fieldset = FieldSet.from_sgrid_conventions(ds_fset)
npart = 10
lon = [24e3] * npart
lat = np.linspace(22e3, 1950e3, npart)
pset = parcels.ParticleSet(fieldset, lon=lon, lat=lat)
pset.execute(AdvectionRK4, runtime=np.timedelta64(5, "D"), dt=np.timedelta64(30, "m"))with error
src/parcels/_core/particleset.py:463: in execute
self._kernel.execute(self, endtime=next_time, dt=dt)
src/parcels/_core/kernel.py:256: in execute
f(pset[evaluate_particles], self._fieldset)
src/parcels/kernels/_advection.py:61: in AdvectionRK4
(u1, v1) = fieldset.UV[particles]
^^^^^^^^^^^^^^^^^^^^^^
src/parcels/_core/field.py:337: in __getitem__
return self.eval(key.time, key.z, key.lat, key.lon, key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/parcels/_core/field.py:322: in eval
particle_positions, grid_positions = _get_positions(self.U, time, z, y, x, particles, _ei)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/parcels/_core/field.py:468: in _get_positions
grid_positions.update(_search_time_index(field, time))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/parcels/_core/index_search.py:89: in _search_time_index
time_flt = timedelta_to_float(field.data.time.data - field.time_interval.left)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
dt = array([datetime.timedelta(0), datetime.timedelta(days=1),
datetime.timedelta(days=2), datetime.timedelta(days=3...ays=6), datetime.timedelta(days=7),
datetime.timedelta(days=8), datetime.timedelta(days=9)],
dtype=object)
def timedelta_to_float(dt: float | timedelta | np.timedelta64) -> float:
"""Convert a timedelta to a float in seconds."""
print(dt)
if isinstance(dt, timedelta):
return dt.total_seconds()
if isinstance(dt, np.timedelta64):
return float(dt / np.timedelta64(1, "s"))
if hasattr(dt, "dtype") and np.issubdtype(dt.dtype, np.timedelta64): # in case of array
return (dt / np.timedelta64(1, "s")).astype(float)
> return float(dt)
^^^^^^^^^
E TypeError: only length-1 arrays can be converted to Python scalars
src/parcels/_core/utils/time.py:168: TypeError
Note that the code does work with the commented-out lines (so updating ds_fields["time"]), which originally is
<xarray.DataArray 'time' (time: 10)> Size: 80B
array([cftime.Datetime360Day(2000, 1, 2, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 3, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 4, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 5, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 6, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 7, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 8, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 9, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 10, 0, 0, 0, 0, has_year_zero=True),
cftime.Datetime360Day(2000, 1, 11, 0, 0, 0, 0, has_year_zero=True)],
dtype=object)Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
Done