Source Reconstruction and Population Codes¶
This tutorial explains the concepts behind pyAVS’s source reconstruction pipeline and where to find the runnable code for each step. For copy-pasteable code, see Source Reconstruction Examples – this page focuses on why each step exists and how the pieces fit together.
Why Beamforming?¶
pyAVS’s source reconstruction is built around LCMV beamforming (Linearly Constrained Minimum Variance): a spatial filter, computed per subject/session from a forward model and a data/noise covariance estimate, that projects sensor-space MEG data onto estimated cortical source activity. This is the same family of method used for the source-projected fixation ERFs described in Example Analyses and in the Methods section (Source Reconstruction).
The pipeline has three stages:
Forward modeling –
pyavs.create_bem_model(),pyavs.create_source_space(),pyavs.setup_coregistration(),pyavs.load_forward_model()combine a subject’s structural MRI (FreeSurfer reconstruction) and MEG sensor geometry into a forward solution: how activity at each cortical location would project onto each sensor.Filter computation –
pyavs.compute_beamformer_filters()(or, for filters shared across a session,compute_per_session_lcmv_filters()) inverts that relationship given a data covariance estimate, producing a spatial filter per source location.Application and summarization – the filters are applied to epoched data (
pyavs.apply_source_reconstruction()orapply_beamformer()) to get per-epoch source-space data, which can then be summarized within regions of interest (pyavs.extract_roi_data()) and averaged into condition-level population codes (pyavs.compute_population_codes()).
Why Per-Session Filters?¶
Because AVS sessions are recorded on different days (median 2 days apart, up to 93 days –
see Participants), head position relative to the MEG sensors drifts between
sessions despite the individualized head-stabilizing casts. Computing beamformer filters
independently per session, but from a shared cross-session data covariance estimate
(compute_cross_session_data_covariance()), keeps the source
estimates comparable across sessions without needing millimeter-perfect repositioning. See
Cross-Session Beamformer Filters for the standalone script that computes
this, and Source Reconstruction Examples for how the filters are then
applied within the full population-code pipeline.
From Source Data to Population Codes¶
Raw source-reconstructed data has shape (n_epochs, n_sources, n_times) – one value per
cortical source location, per timepoint, per epoch. Two further steps make this usable for
encoding/RSA-style analyses:
ROI extraction (
pyavs.extract_roi_data()) reduces the source dimension by averaging (or otherwise summarizing) within named regions – e.g. early visual cortex, via the Glasser atlas (pyavs.get_glasser_roi_labels()) or the FreeSurfer-based scheme (pyavs.get_roi_labels()).Population codes (
pyavs.compute_population_codes()) further average within a time window and group epochs by experimental condition (e.g. fixated object category), producing the condition-level representations used in analyses like the dRSA pipeline in Example Analyses.
Results are saved via pyavs.save_population_codes_h5() in a standardized HDF5 format,
and can be rediscovered later with pyavs.find_population_codes_files() and
pyavs.list_available_parameter_sets().
Next Steps¶
Source Reconstruction Examples for the full, runnable code
Source Reconstruction (pyavs.source) for the complete forward-modeling and beamforming API
Source Reconstruction for the acquisition/reconstruction parameters used in the AVS dataset paper itself