From 2fbe576f26044afa4a9936717fd0ed022ead61eb Mon Sep 17 00:00:00 2001 From: William Jones Date: Wed, 9 Jul 2025 08:22:25 +0100 Subject: [PATCH 1/3] Add failing test for datetime like coords --- tobac/tests/test_xarray_utils.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tobac/tests/test_xarray_utils.py b/tobac/tests/test_xarray_utils.py index caabef8c..e075c4e7 100644 --- a/tobac/tests/test_xarray_utils.py +++ b/tobac/tests/test_xarray_utils.py @@ -4,6 +4,7 @@ from typing import Union +import pandas as pd import pytest import numpy as np import xarray as xr @@ -156,6 +157,22 @@ def test_find_axis_from_dim_coord( (1, 1), {"test_coord1": (1, 1, 1), "test_coord_time": (5, 6, 7)}, ), + ( + ["time", "x", "y"], + { + "test_coord_datetime": ("time", pd.date_range( + datetime.datetime(2000,1,1), datetime.datetime(2000,1,1,6), freq="1h", inclusive="left", + )), + "test_coord_time": ("time", [5, 6, 7, 8, 9, 10]), + }, + (1, 1), + { + "test_coord_datetime": pd.date_range( + datetime.datetime(2000,1,1), datetime.datetime(2000,1,1,3), freq="1h", inclusive="left", + ), + "test_coord_time": (5, 6, 7) + }, + ), ], ) def test_add_coordinates_to_features_interpolate_along_other_dims( @@ -204,3 +221,4 @@ def test_add_coordinates_to_features_interpolate_along_other_dims( assert coord in resulting_df if coord != "time": assert np.all(resulting_df[coord].values == expected_vals[coord]) + From 6747520aefd3950e07a805119697bbded5225f1a Mon Sep 17 00:00:00 2001 From: William Jones Date: Fri, 11 Jul 2025 17:19:46 +0100 Subject: [PATCH 2/3] Fix coordinate interpolation for non-numeric coordinates --- tobac/tests/test_xarray_utils.py | 22 +++++++++++++++------- tobac/utils/internal/xarray_utils.py | 21 ++++++++++++++++----- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/tobac/tests/test_xarray_utils.py b/tobac/tests/test_xarray_utils.py index e075c4e7..3f2028fb 100644 --- a/tobac/tests/test_xarray_utils.py +++ b/tobac/tests/test_xarray_utils.py @@ -160,17 +160,26 @@ def test_find_axis_from_dim_coord( ( ["time", "x", "y"], { - "test_coord_datetime": ("time", pd.date_range( - datetime.datetime(2000,1,1), datetime.datetime(2000,1,1,6), freq="1h", inclusive="left", - )), + "test_coord_datetime": ( + "time", + pd.date_range( + datetime.datetime(2000, 1, 1), + datetime.datetime(2000, 1, 1, 6), + freq="1h", + inclusive="left", + ), + ), "test_coord_time": ("time", [5, 6, 7, 8, 9, 10]), }, (1, 1), { "test_coord_datetime": pd.date_range( - datetime.datetime(2000,1,1), datetime.datetime(2000,1,1,3), freq="1h", inclusive="left", - ), - "test_coord_time": (5, 6, 7) + datetime.datetime(2000, 1, 1), + datetime.datetime(2000, 1, 1, 3), + freq="1h", + inclusive="left", + ), + "test_coord_time": (5, 6, 7), }, ), ], @@ -221,4 +230,3 @@ def test_add_coordinates_to_features_interpolate_along_other_dims( assert coord in resulting_df if coord != "time": assert np.all(resulting_df[coord].values == expected_vals[coord]) - diff --git a/tobac/utils/internal/xarray_utils.py b/tobac/utils/internal/xarray_utils.py index f6802071..cb05f3da 100644 --- a/tobac/utils/internal/xarray_utils.py +++ b/tobac/utils/internal/xarray_utils.py @@ -420,9 +420,20 @@ def add_coordinates_to_features( except KeyError: pass - return_feat_df[interp_coord_name] = renamed_dim_da[interp_coord].interp( - coords={ - dim: dim_interp_coords[dim] for dim in renamed_dim_da[interp_coord].dims - } - ) + try: + # Interpolate over the coordinate + return_feat_df[interp_coord_name] = renamed_dim_da[interp_coord].interp( + coords={ + dim: dim_interp_coords[dim] + for dim in renamed_dim_da[interp_coord].dims + } + ) + except TypeError: + # If non-numeric, we should instead just index the nearest values: + return_feat_df[interp_coord_name] = renamed_dim_da[interp_coord].isel( + **{ + dim: np.round(dim_interp_coords[dim]).astype(int) + for dim in renamed_dim_da[interp_coord].dims + } + ) return return_feat_df From efad7a557017caeda8aa0cfc8a97c8b046df54cd Mon Sep 17 00:00:00 2001 From: William Jones Date: Fri, 11 Jul 2025 17:34:44 +0100 Subject: [PATCH 3/3] Change logic for search for non-numeric dtypes in case xarray error checking is removed --- tobac/utils/internal/xarray_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tobac/utils/internal/xarray_utils.py b/tobac/utils/internal/xarray_utils.py index cb05f3da..5844522a 100644 --- a/tobac/utils/internal/xarray_utils.py +++ b/tobac/utils/internal/xarray_utils.py @@ -420,7 +420,7 @@ def add_coordinates_to_features( except KeyError: pass - try: + if renamed_dim_da[interp_coord].dtype.kind in "uifc": # Interpolate over the coordinate return_feat_df[interp_coord_name] = renamed_dim_da[interp_coord].interp( coords={ @@ -428,7 +428,7 @@ def add_coordinates_to_features( for dim in renamed_dim_da[interp_coord].dims } ) - except TypeError: + else: # If non-numeric, we should instead just index the nearest values: return_feat_df[interp_coord_name] = renamed_dim_da[interp_coord].isel( **{