hypertools.align

hypertools.align(data, model='HyperAlign', return_model=False, manip=None, normalize=None, reduce=None, ndims=None, cluster=None, format_data=True, **kwargs)[source]

Aligns a list of datasets into a shared coordinate space.

Resolves model (and any cross-module stage kwargs) into a fitted Aligner and applies it, following the same model-spec grammar as hypertools.reduce.reduce.reduce/hypertools.cluster.cluster.cluster.

Parameters:
datanumpy array, pandas/polars DataFrame, or list/tuple of these

The datasets to align. Any input format is funneled into DataFrame(s) before dispatch (a tuple of datasets is treated exactly like a list). Rows are matched across datasets by index value and returned in the FIRST dataset’s index order; datasets with DUPLICATED index labels keep only the first row per label (with a UserWarning), so output rows always match one-to-one across datasets. None raises a TypeError; an empty list raises a ValueError.

modelstr, class, instance, dict, fitted Aligner, False, or None

Alignment algorithm to use. Supported names: ‘HyperAlign’ (hyperalignment, Haxby et al. 2011; ‘hyper’ is a deprecated alias and emits a DeprecationWarning naming the canonical spelling), ‘SharedResponseModel’ (‘SRM’ alias), ‘DeterministicSharedResponseModel’ (‘DetSRM’ alias), ‘RobustSharedResponseModel’ (‘RSRM’ alias), ‘Procrustes’, and ‘NullAlign’ (returns the trimmed/padded data unchanged). Can be passed as a string, a bare (uninstantiated) Aligner subclass, an already-constructed instance (the classes are importable as e.g. from hypertools.align import HyperAlign, Procrustes, SharedResponseModel, NullAlign), the canonical dict spec {‘model’: …, ‘args’: […], ‘kwargs’: {…}}, or the LEGACY dict spec {‘model’: …, ‘params’: {…}} (accepted for backward compatibility, but emits a DeprecationWarning). A previously-fitted Aligner (as returned by return_model=True) is applied via .transform instead of being refit. False or None skips alignment entirely and returns the data unchanged (model=True raises a ValueError – name an algorithm instead). (default: ‘HyperAlign’).

return_modelbool

If True, also return the fitted model: the fitted Aligner when only the align stage ran, or a fitted hypertools.Pipeline when manip=/normalize=/reduce=/cluster= made multiple stages run (default: False).

manip, normalize, reduce, clustermodel spec or None

Cross-module stage kwargs (GH #138): when any of these is given, the other stages also run (via hypertools.core.pipeline.build_pipeline), in the canonical order manip -> normalize -> reduce -> align -> cluster (GH #153), with this function’s own model=/n_iter=/etc. slotted in at the align stage (default: None for all four, i.e. only align runs).

ndimsint or None

Passed through to the reduce stage (as ndims=) when reduce= is also given.

format_databool

Whether or not to first run the missing-data-fill / text-to-matrix format_data pass (default: True).

**kwargs

Extra keyword arguments forwarded to model’s constructor when model is a bare registry name/class (e.g. n_iter= for ‘HyperAlign’, features= for the SRM family). Keyword arguments the model does not accept raise a TypeError naming them (they used to be silently ignored, so a typo’d parameter went unnoticed). align= is also accepted here as a DEPRECATED alias for model= (emits a DeprecationWarning; passing both model= – with a non-default value – and align= raises ValueError), preserving the classic hyp.plot(…, align=’hyper’)-style call.

Returns:
alignedlist of numpy arrays (or a single array)

The aligned data, in the same list/single-item shape as data (matching hyp.reduce/hyp.cluster and the classic hyp.align API, which return numpy arrays; note that hyp.manip instead returns pandas DataFrames): a list input returns a list, a single bare array/DataFrame returns a single array. Output rows follow the FIRST dataset’s index order. If return_model=True, an (aligned, model) tuple is returned instead.

Raises:
ValueError

If data is an empty list (nothing to align), if any dataset has more than 2 dimensions (pass a list of 2-D observations-by- features datasets, not a 3-D stack), if the datasets share no common row-index values, or if model is an unknown name / True.

TypeError

If data is None, or a keyword argument is not accepted by the resolved model’s constructor (e.g. a misspelled parameter name).

Examples

>>> import numpy as np
>>> import hypertools as hyp
>>> rng = np.random.default_rng(0)
>>> a = rng.standard_normal((30, 4))
>>> b = a @ np.linalg.qr(rng.standard_normal((4, 4)))[0]  # rotated copy
>>> aligned = hyp.align([a, b], model='HyperAlign')
>>> [d.shape for d in aligned]
[(30, 4), (30, 4)]