Encoding results¶
The encoding CLI writes results; hypline's encoding package
reads them back for downstream analysis — the encoding-side parallel to
read_feature. Imports come from hypline.encoding (not
top-level hypline), which pulls in the encoding stack:
from hypline.encoding import load_eval, load_artifact
An eval (analyze's output) loads as an
xarray.Dataset, the usual downstream target,
since it holds the per-voxel correlations you analyze:
ds = load_eval("data/results/sub-031/encodingEval-selfeval/sub-031_result-encodingEval_desc-selfeval.nc")
# corr is indexed by fold / band / role / voxel — subset by name:
prod_corr = ds["corr"].sel(role="prod")
# provenance rides in the dataset attributes:
ds.attrs["model_sub"], ds.attrs["target_sub"], ds.attrs["delays"]
A model artifact (train's output) loads as an EncodingArtifact, holding the
fitted weights and the recipe, for reusing or inspecting the model:
artifact = load_artifact("data/results/sub-031/encodingModel-v1/sub-031_result-encodingModel_desc-v1.joblib")
artifact.recipe # the XRecipe: features, confounds, delays, alphas, split, …
artifact.models # one FittedModel per fold (its pipeline + the cells it was fit on)
artifact.fold # the FoldSpec, or None for a single unfolded model
load_artifact warns (does not fail) if the artifact was written by a different
hypline version — a provenance signal, not a hard incompatibility.
Reference¶
Full signatures and docstrings for the encoding results API — the loaders above, the types an artifact is made of, and the write seams behind them.
Loading¶
hypline.encoding.load_eval ¶
load_eval(path: str | Path) -> xr.Dataset
Open a saved eval netCDF and return the subsettable xr.Dataset.
The controlled read path (mirrors save_eval): pins the engine and parses
fold_cells back from its JSON string to list[list[CellKey]] — reconstructing
each cell via CellKey(**cell) so loaded keys hash and compare against live
ones (a plain dict never would, since CellKey.__eq__ rejects non-CellKey).
Kept thin — no analysis logic — so the storage boundary stays in exactly these
two functions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to a saved eval netCDF file. |
required |
Returns:
| Type | Description |
|---|---|
Dataset
|
The eval dataset; |
hypline.encoding.load_artifact ¶
load_artifact(path: Path) -> EncodingArtifact
Load an encoding artifact from its .joblib blob.
Logs a warning (does not fail) on a hypline_version mismatch read from the
sidecar — a version skew is a provenance signal, not a hard incompatibility here.
A missing sidecar silently skips the version check.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to the artifact |
required |
Returns:
| Type | Description |
|---|---|
EncodingArtifact
|
The artifact with fitted weights as numpy arrays (converted at save time), so it loads and predicts without torch or CUDA. |
Result types¶
The artifact structure and its parts.
hypline.encoding.EncodingArtifact
dataclass
¶
On-disk encoding result: a shared recipe plus one-or-more fitted models.
Filters that shaped the cell set live on recipe.bids_filters (X identity),
not here.
Attributes:
| Name | Type | Description |
|---|---|---|
recipe |
XRecipe
|
Shared X identity; every model here was built from it. |
sub_id |
str
|
Subject the models were fit on. |
fold |
FoldSpec | None
|
Fold configuration these models were produced under, or |
models |
list[FittedModel]
|
The fitted models: one when unfolded, one per fold otherwise. |
universe |
set[CellKey] | None
|
Bounds the OOS cell set for fold groups; |
hypline.encoding.XRecipe
dataclass
¶
Everything needed to rebuild X identically on another subject.
One source of truth for X identity so the train-time writer and the
predict-time rebuilder cannot drift. device is excluded — it is a
runtime/hardware choice, not part of X identity, and stays on
EncodingConfig.
Attributes:
| Name | Type | Description |
|---|---|---|
features |
dict[str, tuple[str, str | None]]
|
Feature ref name -> its |
confounds |
dict[str, tuple[str, str | None]]
|
Confound ref name -> its |
tasks |
list[str]
|
Cell axis: multiple tasks make cells from different tasks distinct
rows in X/Y. A single-task call holds |
bold_space |
SurfaceSpace | VolumeSpace
|
Target BOLD space; surface (e.g. |
bold_desc |
str
|
|
downsample |
FeatureDownsampleMethod
|
Method mapping feature time series onto the BOLD TR grid. |
bids_filters |
list[str]
|
Extra BIDS filters constraining the cell set — the sole record of
which runs/conditions shaped X (the |
delays |
list[int]
|
FIR delays (in TRs) stacked per regressor, giving the model its HRF lag basis. |
alphas |
list[float]
|
Ridge penalties searched per band during inner-CV. |
split |
bool
|
Whether himalaya keeps per-band prediction shares ( |
col_slices |
dict[str, slice]
|
Band key -> its column block in X. Empty at construction; |
hypline.encoding.FittedModel
dataclass
¶
One fitted model and the cell set it was fit on.
Attributes:
| Name | Type | Description |
|---|---|---|
pipeline |
Pipeline
|
The fitted banded-ridge pipeline: a |
train_cells |
set[CellKey]
|
Post-filter |
hypline.encoding.FoldSpec
dataclass
¶
One fold configuration: the cell axis to fold over and the fold count.
Internal carrier for the paired fold_by/n_folds constructor args; the
public surface stays flat.
Attributes:
| Name | Type | Description |
|---|---|---|
by |
str
|
Cell axis to fold over (e.g. |
n |
int | Literal['loo']
|
Fold count, or the |
Saving¶
The CLI commands write results for you; these are the underlying seams, in case you produce an eval or artifact yourself.
hypline.encoding.save_eval ¶
save_eval(ds: Dataset, path: str | Path) -> None
Write an analyze Dataset to self-contained netCDF-4 at path.
The single storage seam (with load_eval): serializes the one nested value
fold_cells to a JSON string (netCDF attrs hold only scalars/strings/numeric
arrays), leaving the rest of ds — which analyze already built with
attr-safe values — untouched. Does not mutate the caller's ds.
Each CellKey serializes via dict(cell.items()); load_eval inverts this
with CellKey(**cell), so the round-trip is lossless and both sides stay live
CellKeys (entity values are uniformly str — filename entities by parse,
sidecar metadata by _validate_segment_records — so JSON preserves them
exactly).
hypline.encoding.save_artifact ¶
save_artifact(artifact: EncodingArtifact, path: Path) -> None
Dump artifact to path (.joblib) plus a non-pipeline JSON sidecar.
Forces fitted weights to numpy before the joblib dump (see _numpyfy_fitted)
so the blob loads without torch. The sidecar mirrors everything except the
pipeline — recipe, per-model train cell sets, fold, universe, and
hypline_version — making provenance greppable without unpickling.