Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion doc/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Version 0.9.1
* ``Model.remove_variables`` no longer raises an ``IndexError`` on a quadratic objective. A quadratic term is dropped when any of its factors uses the removed variable. (`#883 <https://github.com/PyPSA/linopy/issues/883>`__, `#895 <https://github.com/PyPSA/linopy/pull/895>`__)
* The Xpress interface no longer calls API functions deprecated in Xpress 9.8. (`#880 <https://github.com/PyPSA/linopy/pull/880>`__)
* The ``docs`` extra no longer pins ``numpy<2``. (`#869 <https://github.com/PyPSA/linopy/pull/869>`__)

* Using timezone-aware ``DatetimeIndex`` coordinates in a model no longer raises a ``ValueError``. The index is now retrieved directly via ``DataArray.to_index()`` instead of rebuilding it with ``pd.Index()``, which dropped the timezone info and failed during alignment. (`#898 <https://github.com/PyPSA/linopy/issues/898>`__)

Version v0.9.0
--------------
Expand Down
8 changes: 5 additions & 3 deletions linopy/alignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,11 @@ def _coords_to_dict(


def _as_index(coord_values: Any) -> pd.Index:
return (
coord_values if isinstance(coord_values, pd.Index) else pd.Index(coord_values)
)
if isinstance(coord_values, DataArray):
return coord_values.to_index()
if isinstance(coord_values, pd.Index):
return coord_values
return pd.Index(coord_values)


def _as_multiindex(coord_values: Any) -> pd.MultiIndex | None:
Expand Down
17 changes: 17 additions & 0 deletions test/test_alignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,17 @@ def test_invalid_entry_raises_typeerror(
class TestAddVariablesCoords:
"""End-to-end: each coords / dims form sets the variable's dimensions."""

@staticmethod
def _datetime_coordinates(timezone: str | None) -> xr.Coordinates:
time = pd.date_range(
"2025-10-26 00:00",
periods=5,
freq="h",
tz=timezone,
name="time",
)
return xr.Coordinates({"time": time})

@pytest.mark.parametrize(
"coords, dims, expected_dims",
[
Expand All @@ -586,6 +597,9 @@ class TestAddVariablesCoords:
([np.array([0, 1, 2])], None, ("dim_0",)),
([pd.Index([0, 1, 2])], None, ("dim_0",)),
([("origin", ["a", "b"]), ("dest", ["x", "y"])], None, ("origin", "dest")),
(_datetime_coordinates(None), None, ("time",)),
(_datetime_coordinates("UTC"), None, ("time",)),
(_datetime_coordinates("Europe/Berlin"), None, ("time",)),
],
ids=[
"tuple",
Expand All @@ -599,6 +613,9 @@ class TestAddVariablesCoords:
"ndarray",
"unnamed-index",
"multiple-tuples",
"xarray-datetime-naive",
"xarray-datetime-utc",
"xarray-datetime-dst",
],
)
def test_coords_set_variable_dims(
Expand Down
Loading