Source code for pyetsimul.simulation.generic

"""Generic parameter variation for any eye model parameter."""

from collections.abc import Iterable

import numpy as np

from ..core import Eye
from .core import EyeParameterVariation


[docs] class GenericEyeVariation(EyeParameterVariation): """Generic parameter variation for any eye model parameter. Supports direct property assignment, method calls, and nested object parameters through string-based parameter paths. """
[docs] def __init__( self, parameter_name: str, value_range: list[float], num_steps: int, description: str | None = None ) -> None: """Initialize generic parameter variation. Args: parameter_name: Parameter path (e.g., "fovea_alpha_deg", "cornea.anterior_radius") value_range: [min_value, max_value] range num_steps: Number of steps to generate description: Optional human-readable description """ super().__init__(parameter_name) self.value_range = value_range self.num_steps = num_steps self._description = description
[docs] def describe(self) -> str: """Return human-readable description of the parameter variation.""" param_name = self.param_name.replace("_", " ") min_val, max_val = self.value_range return f"{param_name} {min_val:.3f}-{max_val:.3f} ({self.num_steps} steps)"
def __len__(self) -> int: """Return the number of variation steps.""" return self.num_steps
[docs] def generate_values(self) -> Iterable[float]: """Generate parameter values using numpy linspace.""" if self.num_steps == 1: yield (self.value_range[0] + self.value_range[1]) / 2 return yield from np.linspace(self.value_range[0], self.value_range[1], self.num_steps)
[docs] def apply_to_eye(self, eye: Eye, value: float) -> None: """Apply parameter value to eye using parameter path resolution.""" GenericEyeVariation._set_parameter(eye, self.param_name, value)
@staticmethod def _set_parameter(eye: Eye, parameter_path: str, value: float) -> None: """Set parameter value using path resolution.""" # Handle method calls if parameter_path == "pupil_diameter": eye.set_pupil_diameter(value) return # Handle nested object parameters if "." in parameter_path: obj_name, attr_name = parameter_path.split(".", 1) obj = getattr(eye, obj_name) setattr(obj, attr_name, value) return # Handle direct property assignment setattr(eye, parameter_path, value)