MNE-Python Integration

FACETpy is designed to work directly with MNE-Python objects. This page shows how to add FACETpy to an existing MNE-based research workflow without rewriting your project structure.

When to Add FACETpy

A practical pattern in existing MNE pipelines is:

  1. Load data with your current MNE workflow.

  2. Run FACETpy for MRI/BCG artifact correction.

  3. Continue with MNE for ICA, epoching, statistics, and visualization.

Use FACETpy as one processing stage, not as a replacement for your full MNE stack.

Run FACETpy on an Existing MNE Raw

If your project already creates a mne.io.Raw object, wrap it in a facet.core.ProcessingContext and run a FACETpy pipeline.

import mne
from facet import (
    ProcessingContext,
    Pipeline,
    TriggerDetector,
    UpSample,
    TriggerAligner,
    AASCorrection,
    DownSample,
)

raw = mne.io.read_raw_fif("sub-01_task-rest_eeg.fif", preload=True)

# Use copy() to keep your original Raw unchanged for comparisons.
context = ProcessingContext(raw=raw.copy())

correction = Pipeline([
    TriggerDetector(regex=r"\\b1\\b"),
    UpSample(factor=10),
    TriggerAligner(ref_trigger_index=0),
    AASCorrection(window_size=30),
    DownSample(factor=10),
], name="MRI Artifact Correction")

result = correction.run(initial_context=context)
if not result.success:
    raise RuntimeError(result.error)

raw_corrected = result.context.get_raw()

Reuse Events From an Existing MNE Project

If your triggers are already available as MNE events, you can pass them to FACETpy via a context helper and skip trigger detection.

import mne
from facet import ProcessingContext, Pipeline, UpSample, AASCorrection, DownSample

raw = mne.io.read_raw_fif("sub-01_task-rest_eeg.fif", preload=True)
events, event_id = mne.events_from_annotations(raw)

mri_code = event_id["R128"]
context = ProcessingContext(raw=raw.copy()).with_mne_events(
    events,
    event=mri_code,       # alternatively: event="R128"
    event_id=event_id,
    tr_seconds=2.0,       # required for AAS-style correction
)

correction = Pipeline([
    UpSample(factor=10),
    AASCorrection(window_size=30),
    DownSample(factor=10),
])

result = correction.run(initial_context=context)
raw_corrected = result.context.get_raw()

ProcessingContext.with_mne_events(...) automatically converts absolute MNE sample indices to FACETpy-relative trigger indices (accounts for raw.first_samp).

Defaults for Optional Helper Fields

For ProcessingContext.with_mne_events(...):

  • event=None: allowed only if all events have the same event code.

  • event_id=None: only needed when event is passed as a string label.

  • artifact_length=None and tr_seconds=None: artifact_length defaults to the median sample distance between consecutive selected triggers.

  • tr_seconds=None: if provided, it is converted to samples and used as artifact_length.

  • store_event_id=True: stores event_id in context.metadata.custom["event_id"].

For ProcessingContext.with_trigger_samples(...):

  • samples_are_absolute=False: trigger samples are interpreted as context-relative by default.

  • artifact_length=None and tr_seconds=None: artifact_length defaults to the median sample distance between consecutive triggers.

  • custom=None: no additional metadata entries are written.

Continue With MNE After Correction

After correction, continue in your standard MNE analysis pipeline.

# Continue with your normal MNE workflow
raw_corrected = result.context.get_raw()

raw_corrected.filter(l_freq=1.0, h_freq=40.0)
epochs = mne.Epochs(
    raw_corrected,
    events,
    event_id=event_id,
    tmin=-0.2,
    tmax=0.8,
    preload=True,
)

evoked = epochs.average()
evoked.plot()

BIDS-Centered Workflows

If your project is BIDS-based, you can keep everything in BIDS using facet.io.BIDSLoader and facet.io.BIDSExporter.

from facet import Pipeline, BIDSLoader, TriggerDetector, AASCorrection, BIDSExporter

pipeline = Pipeline([
    BIDSLoader(root="./bids", subject="01", session="01", task="rest", run="01"),
    TriggerDetector(regex=r"\\b1\\b"),
    AASCorrection(window_size=30),
    BIDSExporter(root="./bids_derivatives/facetpy", subject="01", session="01", task="rest"),
])

result = pipeline.run()

Recommendations for Research Projects

  • Keep FACETpy correction in one dedicated pipeline stage for reproducibility.

  • Store FACETpy metrics from result.context.metadata.custom next to your MNE outputs.

  • Use raw.copy() before correction when you need before/after comparisons.

  • If you provide triggers manually, always set artifact_length consistently with your TR/slice timing.

  • For teams, version-control your pipeline definitions and processor parameters together with analysis scripts.