Study¶
Multi-phase study orchestration.
trade_study.Phase(name, grid, filter_fn=None, n_trials=100, n_reps=1, world=None, scorer=None)
dataclass
¶
A single phase in a multi-phase study.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Phase identifier (e.g. "discovery", "refinement"). |
grid |
list[dict[str, Any]] | str | GridCallable
|
Explicit config list, |
filter_fn |
Callable[[ResultsTable, list[Observable]], NDArray[intp]] | None
|
Optional callable that takes a ResultsTable and returns indices of configs to pass to the next phase. If None, phase is terminal. |
n_trials |
int
|
For adaptive mode, number of optuna trials. |
n_reps |
int
|
Number of times to evaluate each design point, forwarded to grid and adaptive runners. Adaptive results already contain per-trial means; grid results retain raw replicate rows. |
world |
Simulator | None
|
Optional phase-level simulator override. When set, this
phase uses world instead of the |
scorer |
Scorer | None
|
Optional phase-level scorer override. When set, this
phase uses scorer instead of the |
trade_study.Study(world, scorer, observables, phases, annotations=list(), factors=list(), checkpoint_key=None)
dataclass
¶
Multi-phase model criticism study.
Attributes:
| Name | Type | Description |
|---|---|---|
world |
Simulator
|
Simulator generating (truth, observations). |
scorer |
Scorer
|
Scorer evaluating observables against truth. |
observables |
list[Observable]
|
Observable definitions. |
phases |
list[Phase]
|
Ordered list of study phases. |
annotations |
list[Annotation]
|
External information (costs, constraints). |
factors |
list[Any]
|
Factor definitions (needed for adaptive mode). |
checkpoint_key |
str | None
|
Caller-managed model/data revision for checkpoint compatibility. Change this when simulator/scorer instance state, external data, globals or callable behavior changes. Structural definitions and inspectable code are checked automatically; opaque callables require an explicit key. |
run(*, n_jobs=1, callback=None, checkpoint_dir=None)
¶
Execute all phases sequentially.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_jobs
|
int
|
Number of parallel workers for grid phases. |
1
|
callback
|
ProgressCallback | None
|
Optional progress callback invoked after each trial
with |
None
|
checkpoint_dir
|
str | Path | None
|
Optional directory for per-phase checkpoints.
Each completed phase is saved there; on a rerun,
phases already on disk are loaded instead of run, and
filters are replayed on them. Results produced elsewhere
(for example reduced from cluster shards) can be written
into a phase's directory with :func: |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a callable grid is used on the first phase (no previous results to pass). |
Source code in src/trade_study/study.py
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | |
save(path)
¶
Save every completed phase's results as a checkpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Checkpoint directory, compatible with
|
required |
Source code in src/trade_study/study.py
load(path)
¶
Load the completed phases of a checkpoint into this study.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Directory written by :meth: |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
Names of the phases loaded. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If |
Source code in src/trade_study/study.py
results(phase)
¶
Get results for a specific phase.
Returns:
| Type | Description |
|---|---|
ResultsTable
|
ResultsTable for the given phase. |
front(phase)
¶
Get Pareto front indices for a phase.
Returns:
| Type | Description |
|---|---|
NDArray[intp]
|
Integer array of Pareto-optimal row indices. |
Source code in src/trade_study/study.py
front_hypervolume(phase, ref_point)
¶
Compute hypervolume of the Pareto front for a phase.
Returns:
| Type | Description |
|---|---|
float
|
Hypervolume value. |
Source code in src/trade_study/study.py
compare_phases(ref_point=None)
¶
Compare the fronts of the completed phases.
Each phase is summarized over its design points: replicate rows are
averaged first when the phase ran with n_reps > 1, as for
filtering, and rows with a non-finite score are left out of the
front. Each phase after the first is compared with the previous
completed phase by IGD+ in both directions:
igd_plus_gain: IGD+ of the previous front against this phase's front, i.e. how far the previous front falls short of this one. Positive when this phase found better trade-offs.igd_plus_loss: IGD+ of this phase's front against the previous front, i.e. how far this phase falls short of the previous one. Zero when this front weakly dominates the previous front.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ref_point
|
NDArray[floating[Any]] | None
|
Hypervolume reference point, in the observables' units. Defaults to the worst value of each observable over every phase's front, pushed outward by 10% of its range (by 1 when the range is zero), so hypervolumes are comparable across phases. |
None
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
One dict per completed phase, in phase order, with |
list[dict[str, Any]]
|
|
list[dict[str, Any]]
|
|
list[dict[str, Any]]
|
points) and |
list[dict[str, Any]]
|
first phase). Phases without a finite front report NaN. |
Source code in src/trade_study/study.py
stack(phase, *, maximize=False)
¶
Compute score-based stacking weights for a phase.
Returns:
| Type | Description |
|---|---|
NDArray[floating[Any]]
|
Array of stacking weights. |
Source code in src/trade_study/study.py
summary()
¶
Per-phase summary: n_trials, n_front, observable ranges.
Returns:
| Type | Description |
|---|---|
dict[str, dict[str, Any]]
|
Dictionary mapping phase names to summary statistics. |
Source code in src/trade_study/study.py
trade_study.top_k_pareto_filter(k, objective_names=None)
¶
Create a filter that keeps the top-K configs by Pareto rank.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
k
|
int
|
Maximum number of configs to keep. |
required |
objective_names
|
list[str] | None
|
Subset of observables to use for ranking. If None, uses all observables. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[[ResultsTable, list[Observable]], NDArray[intp]]
|
Filter function compatible with Phase.filter_fn. |
Source code in src/trade_study/study.py
trade_study.weighted_sum_filter(weights, k)
¶
Create a filter that keeps the top-K configs by weighted sum.
Scalarises multiple objectives into a single score via a weighted sum
and keeps the k best configs. Scores are min-max normalised
before weighting so that objectives on different scales are
comparable. MAXIMIZE objectives are negated before normalisation so
that lower normalised values are always better.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
weights
|
dict[str, float]
|
Mapping from observable name to its scalarisation weight. Only the named observables are used; the rest are ignored. |
required |
k
|
int
|
Maximum number of configs to keep. |
required |
Returns:
| Type | Description |
|---|---|
Callable[[ResultsTable, list[Observable]], NDArray[intp]]
|
Filter function compatible with |
Source code in src/trade_study/study.py
trade_study.feasibility_filter(constraints)
¶
Create a filter that keeps only designs satisfying all constraints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
constraints
|
list[Constraint]
|
Constraint objects to evaluate against results. |
required |
Returns:
| Type | Description |
|---|---|
Callable[[ResultsTable, list[Observable]], NDArray[intp]]
|
Filter function compatible with |
Source code in src/trade_study/study.py
Checkpoint identity¶
Study.run(checkpoint_dir=...), Study.save() and Study.load() share a
versioned manifest. It checks phase order, grids, replication/trial counts,
factors, objectives, annotations, filters, and inspectable simulator/scorer
code. Incompatible definitions and legacy manifests are refused; use a new
checkpoint directory when intentionally changing the study.
Set Study(..., checkpoint_key="model-v2-data-v1") to identify simulator/scorer
instance configuration, external data, globals, and other behavior that cannot
be inferred from code. Update the key whenever those inputs change. Opaque
callables require a key. A matching key does not override structural mismatches.
A checkpoint is not a serialization of live simulator/scorer objects.
Grid phases also write a trials.sqlite ledger inside their phase directory.
An interrupted phase resumes its unfinished evaluations without repeating
completed design-point/replicate tasks. Adaptive phases retain phase-level
checkpointing; use a persistent AdaptiveSession for external adaptive trial
recovery. Final phase results keep the existing save_results() format.
Externally evaluated phase results can still be supplied with save_results()
after initializing the manifest using Study.save(). Their observable schema
must match the study.