coco_pipe.decoding.pipeline#
Study-agnostic per-unit runner and sweep orchestration for decoding.
Mirrors coco_pipe.dim_reduction.pipeline: a study enumerates the
independent decoding units of a sweep (one DecodingUnit each). Two
layers live here and are deliberately free of any report/visualization imports
(reports are built study-side from the saved result.joblib artifacts):
run_decoding_unit()owns the per-unit lifecycle — resume, run, export, record extraction;execute_decoding_sweep()runs many units (optionally in parallel viacoco_pipe.utils.run_task_batch()) and persists one flat result table plus a resumableruns/inventory (sweep_runs.json+run_summary.json+leaderboard.json) and a run-status marker.
Classes#
One independent unit of a decoding sweep, ready to run in isolation. |
|
A saved decoding sweep, as returned by |
Functions#
|
Run one decoding unit and return one record per model. |
|
Return a copy of the experiment config with a new inner |
|
Split a job budget into outer workers and the jobs each unit may use. |
|
Best successful record per group, ranked by the primary metric. |
|
Write |
|
Load the persisted per-unit records for a |
|
Read a saved decoding sweep. |
|
Run a decoding sweep and persist its results + resumable |
|
Run a decoding sweep from a lazy stream of per-scope unit batches. |
Module Contents#
- class coco_pipe.decoding.pipeline.DecodingUnit#
One independent unit of a decoding sweep, ready to run in isolation.
The unit carries a fully-built
ExperimentConfigplus the data and provenance needed to fit, resume, export, and label it. It is a plain data object (picklable) so it can be dispatched to a process pool.- experiment_config: coco_pipe.decoding.configs.ExperimentConfig#
- output_dir: pathlib.Path#
- groups: numpy.ndarray | None = None#
- feature_names: collections.abc.Sequence[str] | None = None#
- sample_ids: collections.abc.Sequence[Any] | None = None#
- sample_metadata: pandas.DataFrame | None = None#
- coco_pipe.decoding.pipeline.run_decoding_unit(unit, *, errors='record')#
Run one decoding unit and return one record per model.
Resumes from a matching completed output when
overwriteis false, else runs the experiment, exports it (result.joblib+run_manifest.json), and extracts records. A resume config-hash mismatch is intentionally not caught — it raises so the sweep aborts rather than silently mixing configs. A runtime failure becomes a singlestatus="failed"record whenerrors="record"(the default for a fault-tolerant sweep).- Parameters:
unit (DecodingUnit)
errors (Literal['raise', 'record'])
- Return type:
- coco_pipe.decoding.pipeline.allocate_inner_jobs(cfg, n_jobs)#
Return a copy of the experiment config with a new inner
n_jobs.Hands the whole job budget to a lone unit’s folds/permutations when only one outer worker is active. The budget is split across the two nesting levels that actually run concurrently — the outer CV-fold loop (
joblib.Parallelovercfg.cv.n_splitsfolds) and, inside each fold, the per-fold hyperparameter search (GridSearchCV/RandomizedSearchCV). Handingn_jobsto both levels independently (as opposed to splitting it) oversubscribes the machine by a factor ofn_splits: each of then_splitsfold workers would spawn its ownn_jobs-worker search pool, for up ton_splits * n_jobsprocesses contending overn_jobscores.- Parameters:
n_jobs (int)
- Return type:
- coco_pipe.decoding.pipeline.allocate_outer_inner(total_jobs, n_units)#
Split a job budget into outer workers and the jobs each unit may use.
Every unit gets a worker while there are workers left; with fewer units than workers, each unit takes an equal share of the budget.
- coco_pipe.decoding.pipeline.build_leaderboard(records, group_fields, *, primary_metric='primary_metric')#
Best successful record per group, ranked by the primary metric.
- Parameters:
records (collections.abc.Sequence[dict[str, Any]])
group_fields (collections.abc.Sequence[str])
primary_metric (str)
- Return type:
- coco_pipe.decoding.pipeline.write_run_summary(output_root, records, failures, *, primary_mask=None, run_metadata=None, report_path=None)#
Write
runs/run_summary.jsonand the top-level status marker.Status is
SUCCESSwhen a primary result succeeded and nothing failed,PARTIALwhen there is any success, elseFAILED— matching the dim-reduction run-status contract. Withoutprimary_maskevery successful unit counts as primary.- Parameters:
output_root (pathlib.Path)
records (collections.abc.Sequence[dict[str, Any]])
failures (collections.abc.Sequence[dict[str, Any]])
primary_mask (PrimaryMask | None)
report_path (pathlib.Path | None)
- Return type:
- coco_pipe.decoding.pipeline.load_sweep_records(output_root)#
Load the persisted per-unit records for a
--reports-onlypass.- Parameters:
output_root (pathlib.Path)
- Return type:
- class coco_pipe.decoding.pipeline.Sweep#
A saved decoding sweep, as returned by
read_sweep().- Variables:
root (Path) – The sweep’s output directory.
results (pandas.DataFrame) – One row per unit and model: the run context, the summary metrics and
output_dir, the folder of the unit.status (str) –
"SUCCESS","PARTIAL"(some units failed, or the run did not finish) or"FAILED".
- root: pathlib.Path#
- results: pandas.DataFrame#
- result(output_dir)#
Load the full result of one unit.
- Parameters:
output_dir (str | pathlib.Path)
- Return type:
- predictions(rows=None)#
Return the predictions of the units in
rows, in one table.- Parameters:
rows (pandas.DataFrame, optional) – A selection of
results. All successful units by default.- Returns:
One row per unit, model and sample, with
output_dirfirst.- Return type:
- coco_pipe.decoding.pipeline.read_sweep(output_root)#
Read a saved decoding sweep.
Only the results table is read; a unit’s full result is loaded when asked for with
Sweep.result()orSweep.predictions(). A sweep that is still running, or that broke, can be read too: its status is"PARTIAL".- Parameters:
output_root (str | pathlib.Path)
- Return type:
- coco_pipe.decoding.pipeline.execute_decoding_sweep(units, failures, *, config, output_root, results_filename=RESULTS_FILENAME, primary_mask=None, leaderboard_group_fields=(), reallocate_inner_jobs=False, frame_post=None, extra_outputs=None, run_metadata=None)#
Run a decoding sweep and persist its results + resumable
runs/inventory.Owns the study-agnostic tail shared by classical and foundation decoding: job allocation, per-unit execution, the flat result table, the
runs/inventory, and the run-status marker. Study-specific pre/post steps (p-value correction, capability matrices) inject via frame_post / extra_outputs.- Parameters:
units (list[DecodingUnit])
output_root (pathlib.Path)
results_filename (str)
primary_mask (PrimaryMask | None)
leaderboard_group_fields (collections.abc.Sequence[str])
reallocate_inner_jobs (bool)
frame_post (collections.abc.Callable[[pandas.DataFrame], pandas.DataFrame] | None)
extra_outputs (collections.abc.Callable[[pandas.DataFrame, list[dict[str, Any]], pathlib.Path], None] | None)
- Return type:
tuple[list[dict[str, Any]], pandas.DataFrame]
- coco_pipe.decoding.pipeline.execute_decoding_sweep_streaming(unit_batches, failures, *, config, output_root, results_filename=RESULTS_FILENAME, primary_mask=None, leaderboard_group_fields=(), reallocate_inner_jobs=False, frame_post=None, extra_outputs=None, run_metadata=None)#
Run a decoding sweep from a lazy stream of per-scope unit batches.
Behaves like
execute_decoding_sweep()but consumes unit_batches one batch at a time — running and then releasing each batch (and, via the generator, its source data container) before the next is materialized — so only one scope’s worth of arrays is resident at once. This keeps host memory bounded to the largest single scope rather than the whole sweep. failures is the caller-owned list of enumeration-time skips, extended in place with runtime failures (so any extra_outputs closure over it sees them all), and every batch shares the same job budget/parallelism policy as the one-shot variant.After every batch the records so far are saved to the
runs/inventory and the run is marked_PARTIAL, so a job that breaks leaves a readable record of what finished. The full outputs are written once the stream is exhausted.- Parameters:
unit_batches (collections.abc.Iterable[collections.abc.Sequence[DecodingUnit]])
output_root (pathlib.Path)
results_filename (str)
primary_mask (PrimaryMask | None)
leaderboard_group_fields (collections.abc.Sequence[str])
reallocate_inner_jobs (bool)
frame_post (collections.abc.Callable[[pandas.DataFrame], pandas.DataFrame] | None)
extra_outputs (collections.abc.Callable[[pandas.DataFrame, list[dict[str, Any]], pathlib.Path], None] | None)
- Return type:
tuple[list[dict[str, Any]], pandas.DataFrame]