fmridata.modelmpathi

May 7, 2026 · View on GitHub

← back to fmri_data methods · Object methods index · Recasting objects

Estimate cross-validated multivariate pathway-level connectivity (MPathI) between one source region and one target region using PLS regression. A streamlined, single-pathway descendant of model_brain_pathway — same underlying math (find latent population activity in each ROI whose timeseries covary maximally), but no four-pathway on/off-target contrast. Use this when you simply want a multivariate analogue of ROI functional connectivity for a hypothesised X→Y pathway.

Code map

model_mpathi code map

Editable PowerPoint version

Usage

stats = model_mpathi(obj, source_mask, target_mask, ...
    'Indices', wh_subject, 'nboot', 1000, 'plot')

Conventions:

  • X, Y: [images × voxels]
  • T, U: [images × 1] latent timeseries (source / target)
  • Z, V: [voxels × 1] spatial weights (source / target)

Inputs

ArgumentTypeDescription
objfmri_dataImage series (single-trial betas, time series, etc.).
source_maskfmri_dataBinary mask defining the source region X.
target_maskfmri_dataBinary mask defining the target region Y.
'Indices', vint vectorn_images × 1 block IDs (e.g. subject ID). Used for cross-validation folds and bootstrap blocks. Default: 10-fold via crossvalind.
'Align'flagHyperalign training data across subjects (requires 'Indices').
'nboot', NintNumber of block-bootstrap samples for voxelwise inference on Z and V.
'plot'flagBar plot of cross-validated latent correlations per fold.
'noroi'flagDon't return masked ROI data in stats (smaller output).

Outputs

stats is a structure with:

FieldTypeDescription
xval.latent_correlationsvectorcorr(T_hat, U_hat) per cross-validation fold.
xval.T_latent_timeseriesvectorPredicted source latent timeseries (held-out, full length).
xval.U_latent_timeseriesvectorPredicted target latent timeseries (held-out, full length).
xval.whfoldsvectorFold assignment used.
overall_xval_rscalarCorrelation of T_hat and U_hat across all held-out data — the primary pathway-strength index.
overall_xval_dotscalarDot product of T_hat and U_hat across all held-out data.
whole.T_latent_timeseriesvectorWhole-sample source latent timeseries.
whole.U_latent_timeseriesvectorWhole-sample target latent timeseries.
whole.Z_weights[voxels × 1]Whole-sample source voxel weights (pinv(X) * U).
whole.V_weights[voxels × 1]Whole-sample target voxel weights (pinv(Y) * T).
pathway_signscalarSign flip applied to align latents with mean source signal.
PLS_bootstrap_stats_Zstatistic_imageSource-side bootstrap inference (only with 'nboot').
PLS_bootstrap_stats_Vstatistic_imageTarget-side bootstrap inference (only with 'nboot').
source_obj, target_objfmri_dataResampled, masked ROI data (omitted with 'noroi').

Notes

  • The primary pathway-strength index is stats.overall_xval_r. The per-fold values in stats.xval.latent_correlations are useful for diagnostics or as second-level summary statistics across subjects.
  • Latent variable signs are sign-indeterminate in PLS; the function flips them so the source latent positively correlates with the mean source-region signal. The same flip is applied consistently across cross-validation folds and the whole-sample model.
  • For multi-subject data, always pass 'Indices' so cross-validation respects subject grouping. Block bootstrap also resamples subjects.
  • Whole-sample weight maps should be interpreted descriptively unless supported by 'nboot' bootstrap inference.
  • Reference: Kragel et al. (2021), Neuron.

Example: VPL → dorsoposterior insula MPathI on the BMRK3 toy data

% Multi-subject single-trial pain images (6 per subject)
imgs = load_image_set('bmrk3');

% Define ROIs
atlas_obj = load_atlas('canlab2018_2mm');
vpl   = select_atlas_subset(atlas_obj, {'VPL'}, 'flatten');
dpins = select_atlas_subset(atlas_obj, {'Ig'},  'flatten');

% Subject IDs for proper CV/bootstrap blocking
indx = imgs.additional_info.subject_id;

% Single-pathway MPathI with voxelwise bootstrap inference and a plot
stats = model_mpathi(imgs, vpl, dpins, ...
    'Indices', indx, 'nboot', 1000, 'plot');

fprintf('Overall held-out latent r = %.3f\n', stats.overall_xval_r);

% Visualise voxel-level source weights, thresholded
montage(threshold(stats.PLS_bootstrap_stats_Z, .005, 'unc'));

See also