Skip to content

Protocols

Core types and interfaces for trade-study workflows.

trade_study.Direction

Bases: Enum

Optimization direction for an observable.

trade_study.Observable(name, direction, weight=1.0) dataclass

A structured observable evaluated against known truth.

Attributes:

Name Type Description
name str

Identifier (e.g. "coverage_95", "relWIS", "wall_seconds").

direction Direction

Whether lower or higher values are better.

weight float

Relative importance for weighted Pareto analysis. Default 1.0 preserves unweighted behavior.

trade_study.Annotation(name, lookup, key) dataclass

External information attached to configurations.

Used for costs, constraints, or metadata not computed by the simulator (e.g. dollar costs from a surveillance costing sheet).

Attributes:

Name Type Description
name str

Column name in the results table.

lookup dict[str, float] | Any

Dictionary mapping config key → value, or a callable.

key str

Which config field to use for lookup.

resolve(config)

Resolve the annotation value for a given config.

Returns:

Type Description
float

The resolved annotation value as a float.

Source code in src/trade_study/protocols.py
def resolve(self, config: dict[str, Any]) -> float:
    """Resolve the annotation value for a given config.

    Returns:
        The resolved annotation value as a float.
    """
    k = config[self.key]
    if callable(self.lookup):
        return float(self.lookup(k))
    return float(self.lookup[k])

trade_study.Scorer

Bases: Protocol

Protocol for scoring model output against truth.

score(truth, observations, config)

Score a single trial, returning values for each observable.

Parameters:

Name Type Description Default
truth Any

Known latent state from the simulator.

required
observations Any

Observed data from the simulator.

required
config dict[str, Any]

The configuration that produced this trial.

required

Returns:

Type Description
dict[str, float]

Dictionary mapping observable names to scalar scores.

Source code in src/trade_study/protocols.py
def score(
    self,
    truth: Any,
    observations: Any,
    config: dict[str, Any],
) -> dict[str, float]:
    """Score a single trial, returning values for each observable.

    Args:
        truth: Known latent state from the simulator.
        observations: Observed data from the simulator.
        config: The configuration that produced this trial.

    Returns:
        Dictionary mapping observable names to scalar scores.
    """
    ...

trade_study.Simulator

Bases: Protocol

Protocol for generating ground truth and observations.

A simulator produces (truth, observations) pairs where truth is the known latent state and observations are what a real system would see.

generate(config)

Generate a (truth, observations) pair for a given configuration.

Parameters:

Name Type Description Default
config dict[str, Any]

Dictionary of factor values defining this trial.

required

Returns:

Type Description
Any

A tuple of (truth, observations) where truth is the known latent

Any

state and observations are the (possibly noisy/masked) data.

Source code in src/trade_study/protocols.py
def generate(self, config: dict[str, Any]) -> tuple[Any, Any]:
    """Generate a (truth, observations) pair for a given configuration.

    Args:
        config: Dictionary of factor values defining this trial.

    Returns:
        A tuple of (truth, observations) where truth is the known latent
        state and observations are the (possibly noisy/masked) data.
    """
    ...

trade_study.TrialResult(config, scores, wall_seconds=0.0, metadata=dict()) dataclass

Result of a single simulation trial.

trade_study.ResultsTable(configs, scores, observable_names, annotations=None, annotation_names=list(), metadata=list()) dataclass

Scored results from a study phase.

Stores configs, observable scores, annotations, and metadata as parallel arrays backed by numpy.

feasible(constraints)

Return a boolean mask indicating which rows satisfy all constraints.

Each constraint references an observable or annotation column by name. A row is feasible only when every constraint evaluates to True.

Parameters:

Name Type Description Default
constraints list[Constraint]

Constraint objects to evaluate.

required

Returns:

Type Description
NDArray[bool_]

Boolean array of shape (n_trials,).

Raises:

Type Description
KeyError

If a constraint references a column not found in either observable_names or annotation_names.

Source code in src/trade_study/protocols.py
def feasible(self, constraints: list[Constraint]) -> NDArray[np.bool_]:
    """Return a boolean mask indicating which rows satisfy all constraints.

    Each constraint references an observable or annotation column by
    name.  A row is feasible only when **every** constraint evaluates
    to ``True``.

    Args:
        constraints: Constraint objects to evaluate.

    Returns:
        Boolean array of shape ``(n_trials,)``.

    Raises:
        KeyError: If a constraint references a column not found in
            either ``observable_names`` or ``annotation_names``.
    """
    import numpy as np

    mask = np.ones(len(self.configs), dtype=np.bool_)
    for con in constraints:
        if con.observable in self.observable_names:
            col_idx = self.observable_names.index(con.observable)
            values = self.scores[:, col_idx]
        elif (
            con.observable in self.annotation_names and self.annotations is not None
        ):
            col_idx = self.annotation_names.index(con.observable)
            values = self.annotations[:, col_idx]
        else:
            msg = (
                f"Constraint {con.name!r}: column {con.observable!r} "
                f"not found in observables or annotations"
            )
            raise KeyError(msg)
        mask &= _OP_MAP[con.op](values, con.threshold)
    return mask