# -*- coding: ascii -*-
"""Threshold range definitions for no-reset benchmark campaigns."""
from __future__ import annotations
__author__ = "Mikhail Mikhailov, Andrey Isakov"
__copyright__ = "Copyright (c) 2026 PySATL project"
__license__ = "SPDX-License-Identifier: MIT"
from abc import ABC, abstractmethod
from collections.abc import Sequence
from dataclasses import dataclass, field
import numpy as np
from pysatl_cpd.typedefs import Number
[docs]
@dataclass
class ThresholdsRange(ABC):
"""Base class for threshold range strategies.
Subclasses fill ``thresholds_range`` at initialisation (or defer it).
Attributes
----------
thresholds_range
Sequence of threshold values, populated by ``__post_init__``.
"""
thresholds_range: Sequence[Number] = field(default_factory=tuple)
[docs]
@abstractmethod
def __post_init__(self) -> None: # pragma: no cover
"""Generate a linearly spaced threshold grid.
Raises
------
NotImplementedError
Subclasses must implement this method.
"""
raise NotImplementedError("Subclasses must implement this method")
[docs]
@dataclass
class ManualThresholdsRange(ThresholdsRange):
"""A threshold range defined by an explicit list of values."""
_values: Sequence[Number] = ()
[docs]
def __post_init__(self) -> None:
"""Populate the thresholds range from the explicit value list."""
self.thresholds_range = tuple(self._values)
[docs]
@dataclass
class LinearThresholdsRange(ThresholdsRange):
"""A threshold range generated by linear interpolation.
Attributes
----------
start
Start of the range.
end
End of the range.
count
Number of thresholds.
"""
start: Number = 0.0
end: Number = 1.0
count: int = 10
[docs]
def __post_init__(self) -> None:
"""Generate a linearly spaced threshold grid.
Raises
------
ValueError
If *count* is less than 1.
"""
if self.count < 1:
msg = "count must be >= 1"
raise ValueError(msg)
self.thresholds_range = tuple(np.linspace(self.start, self.end, self.count, dtype=np.float64))
[docs]
@dataclass
class AutoThresholdsRange(ThresholdsRange):
"""Threshold range resolved later by an external analyzer.
Attributes
----------
count
Desired number of thresholds.
"""
count: int = 2
[docs]
def __post_init__(self) -> None:
"""Validate count and leave thresholds empty for later resolution."""
if self.count < 1:
msg = "count must be >= 1"
raise ValueError(msg)
self.thresholds_range = ()