Source code for openlifu.plan.target_constraints

from __future__ import annotations

import logging
from dataclasses import dataclass
from typing import Annotated

from openlifu.util.annotations import OpenLIFUFieldData
from openlifu.util.dict_conversion import DictMixin
from openlifu.util.units import getunittype


[docs] @dataclass class TargetConstraints(DictMixin): """A class for storing target constraints. Target constraints are used to define the acceptable range of positions for a target. For example, a target constraint could be used to define the acceptable range of values for the x position of a target. """ dim: Annotated[str, OpenLIFUFieldData("Constrained dimension ID", "The dimension ID being constrained")] = "x" """The dimension ID being constrained""" name: Annotated[str, OpenLIFUFieldData("Constrained dimension name", "The name of the dimension being constrained")] = "dim" """The name of the dimension being constrained""" units: Annotated[str, OpenLIFUFieldData("Dimension units", "The units of the dimension being constrained")] = "m" """The units of the dimension being constrained""" min: Annotated[float, OpenLIFUFieldData("Minimum allowed value", "The minimum value of the dimension")] = float("-inf") """The minimum value of the dimension""" max: Annotated[float, OpenLIFUFieldData("Maximum allowed value", "The maximum value of the dimension")] = float("inf") """The maximum value of the dimension""" def __post_init__(self): if not isinstance(self.dim, str): raise TypeError("Dimension ID must be a string") if not isinstance(self.name, str): raise TypeError("Dimension name must be a string") if not isinstance(self.units, str): raise TypeError("Dimension units must be a string") if getunittype(self.units) != 'distance': raise ValueError(f"Units must be a length unit, got {self.units}") if not isinstance(self.min, (int, float)): raise TypeError("Minimum value must be a number") if not isinstance(self.max, (int, float)): raise TypeError("Maximum value must be a number") if self.min > self.max: raise ValueError("Minimum value cannot be greater than maximum value")
[docs] def check_bounds(self, pos: float): """Check if the given position is within bounds.""" if (pos < self.min) or (pos > self.max): logging.error(msg=f"The position {pos} at dimension {self.name} is not within bounds [{self.min}, {self.max}]!") raise ValueError(f"The position {pos} at dimension {self.name} is not within bounds [{self.min}, {self.max}]!")