NOD-MEG neurovision workflow#
This workflow downloads the bounded NOD-MEG sample, configures MEG trials and stimuli, extracts selected model activations, and saves one VneuroTK HDF5 recording.
Data-rights warning#
Technical access does not grant permission to use or redistribute recordings, metadata, stimuli, or derived files. Verify authoritative licenses, citations, consent or ethics conditions, privacy requirements, and stimulus terms before use. Saved HDF5 files can contain neural arrays, trial metadata, model provenance, and stimulus pixels; review them before sharing.
Read the sample#
The fetcher may use the network on first run. vtk.read() keeps neural values lazy until accessed.
from pathlib import Path
import mne
import numpy as np
import pandas as pd
import torch
import vneurotk as vtk
from vneurotk.datasets import sample
from vneurotk.io import MNEPath, VTKPath
sample_root = sample.data_path("nod-meg")
nod_root = sample_root / "nod-meg"
subject, session, run = sample.NOD_SUBJECT, sample.NOD_SESSION, sample.NOD_RUN
source = MNEPath(
root=nod_root / "meg",
subject=subject,
session=session,
task=sample.NOD_TASK,
run=run,
suffix="meg_clean",
extension=".fif",
)
data = vtk.read(source)
Configure trial alignment#
The events table supplies stimulus IDs in run order; MNE annotations supply onset samples. Float trial_window bounds are seconds.
events = pd.read_csv(nod_root / "events" / f"sub-{subject}_events.csv")
run_number = int(run)
run_events = events.query("run == @run_number and session == @session")
stim_ids = run_events["image_id"].to_numpy()
images = {sid: nod_root / "stimuli" / f"{sid}.JPEG" for sid in np.unique(stim_ids)}
raw = mne.io.read_raw(source.fpath, preload=False, verbose=False)
onsets = vtk.utils.get_event_samples(raw, event_name="stim_on")
data.configure(
stim_ids=stim_ids,
vision_onsets=onsets,
trial_window=[-0.2, 0.8],
vision_db=images,
)
Extract representations#
The integrated extractor stores activations once per unique stimulus. data.vision[...] aligns them back to trial order.
device = "cuda" if torch.cuda.is_available() else "cpu"
model = vtk.VisionModel("facebook/dinov2-base", backend="transformers", device=device)
model.set_selector(module_name="layernorm")
data.vision.extract_from(model, batch_size=16)
trial_aligned = data.vision["layernorm"]
Save the recording#
VTKPath receives an output directory and appends the filename. Saving creates parent directories as needed.
output = VTKPath(
root=Path("outputs"),
subject=subject,
session=session,
task=sample.NOD_TASK,
run=run,
)
data.save(output)