Skip to content

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; corr is subsettable by .sel(band=…, role=…).

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 .joblib blob.

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 None when unfolded (a single model).

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; None for a single model, whose OOS is the target subject's available cells minus its train set.

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 (kind, desc) selector. Iteration order fixes X's feature-band column layout, so it is load-bearing, not incidental.

confounds dict[str, tuple[str, str | None]]

Confound ref name -> its (kind, desc) selector. All confounds collapse into one shared ridge band, so within-band order is irrelevant (a single alpha covers them).

tasks list[str]

Cell axis: multiple tasks make cells from different tasks distinct rows in X/Y. A single-task call holds task constant on every cell.

bold_space SurfaceSpace | VolumeSpace

Target BOLD space; surface (e.g. fsaverage6) or volume.

bold_desc str

desc entity of the target BOLD (e.g. denoised) — selects which derivative the model is fit against.

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 sub/task/space/feat/desc entities are reserved and cannot appear here).

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 (split=True) rather than only the summed prediction.

col_slices dict[str, slice]

Band key -> its column block in X. Empty at construction; train fills it from the assembled data. Build order is screens, features, confounds — the band axis labels downstream must match this order.

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 ColumnKernelizer that delays and linear-kernelizes each band (StandardScaler -> CellDelayer -> Kernelizer, screens skipping the scaler), scored by MultipleKernelRidgeCV.

train_cells set[CellKey]

Post-filter row_slices key set — the cells actually fit on.

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. run).

n int | Literal['loo']

Fold count, or the "loo" sentinel for leave-one-out.

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.