Skip to content

Commit 10e57ba

Browse files
committed
Provide 'side' to pick whether we want the closest, left, or right value
1 parent d50bd5d commit 10e57ba

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

yt/data_objects/time_series.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import weakref
77
from abc import ABC, abstractmethod
88
from functools import wraps
9-
from typing import Optional, Union
9+
from typing import Literal, Optional, Union
1010

1111
import numpy as np
1212
from more_itertools import always_iterable
@@ -445,6 +445,7 @@ def _get_by_attribute(
445445
attribute: str,
446446
value: Union[unyt_quantity, tuple[float, str]],
447447
tolerance: Union[None, unyt_quantity, tuple[float, str]] = None,
448+
side: Union[Literal["nearest"], Literal["left"], Literal["right"]] = "nearest",
448449
) -> "Dataset":
449450
r"""
450451
Get a dataset at or near to a given value.
@@ -462,8 +463,14 @@ def _get_by_attribute(
462463
within the tolerance value. If None, simply return the
463464
nearest dataset.
464465
Default: None.
466+
side : str
467+
The side of the value to return. Can be 'nearest', 'left' or 'right'.
468+
Default: 'nearest'.
465469
"""
466470

471+
if side not in ("nearest", "left", "right"):
472+
raise ValueError(f"side must be 'nearest', 'left' or 'right', got {side}.")
473+
467474
# Use a binary search to find the closest value
468475
iL = 0
469476
iH = len(self._pre_outputs) - 1
@@ -518,7 +525,13 @@ def _get_by_attribute(
518525
dsL = dsH = dsM
519526
break
520527

521-
if abs(value - getattr(dsL, attribute)) < abs(value - getattr(dsH, attribute)):
528+
if side == "left":
529+
ds_best = dsL
530+
elif side == "right":
531+
ds_best = dsH
532+
elif abs(value - getattr(dsL, attribute)) < abs(
533+
value - getattr(dsH, attribute)
534+
):
522535
ds_best = dsL
523536
else:
524537
ds_best = dsH
@@ -534,6 +547,7 @@ def get_by_time(
534547
self,
535548
time: Union[unyt_quantity, tuple],
536549
tolerance: Union[None, unyt_quantity, tuple] = None,
550+
side: Union[Literal["nearest"], Literal["left"], Literal["right"]] = "nearest",
537551
):
538552
"""
539553
Get a dataset at or near to a given time.
@@ -547,16 +561,26 @@ def get_by_time(
547561
within the tolerance value. If None, simply return the
548562
nearest dataset.
549563
Default: None.
564+
side : str
565+
The side of the value to return. Can be 'nearest', 'left' or 'right'.
566+
Default: 'nearest'.
550567
551568
Examples
552569
--------
553570
>>> ds = ts.get_by_time((12, "Gyr"))
554571
>>> t = ts[0].quan(12, "Gyr")
555572
... ds = ts.get_by_time(t, tolerance=(100, "Myr"))
556573
"""
557-
return self._get_by_attribute("current_time", time, tolerance=tolerance)
574+
return self._get_by_attribute(
575+
"current_time", time, tolerance=tolerance, side=side
576+
)
558577

559-
def get_by_redshift(self, redshift: float, tolerance: Optional[float] = None):
578+
def get_by_redshift(
579+
self,
580+
redshift: float,
581+
tolerance: Optional[float] = None,
582+
side: Union[Literal["nearest"], Literal["left"], Literal["right"]] = "nearest",
583+
):
560584
"""
561585
Get a dataset at or near to a given time.
562586
@@ -569,6 +593,9 @@ def get_by_redshift(self, redshift: float, tolerance: Optional[float] = None):
569593
within the tolerance value. If None, simply return the
570594
nearest dataset.
571595
Default: None.
596+
side : str
597+
The side of the value to return. Can be 'nearest', 'left' or 'right'.
598+
Default: 'nearest'.
572599
573600
Examples
574601
--------

0 commit comments

Comments
 (0)