Evaluation API
Evaluation processors for assessing correction quality.
Utilities
ReferenceDataMixin
- class facet.evaluation.metrics.ReferenceDataMixin[source]
Bases:
objectMixin for extracting reference data (outside acquisition).
- get_eeg_channels(raw: BaseRaw) ndarray[source]
Get EEG channel indices.
- Parameters:
raw (
mne.io.BaseRaw) – Raw data object.- Returns:
Array of EEG channel indices.
- Return type:
- get_reference_data(raw: BaseRaw, triggers: ndarray, artifact_length: int, time_buffer: float = 0.1, context: ProcessingContext | None = None) ndarray[source]
Extract reference data (outside acquisition window).
- Parameters:
raw (
mne.io.BaseRaw) – Raw data object.triggers (
numpy.ndarray) – Trigger indices.artifact_length (
int) – Length of one artifact in samples.time_buffer (
float, optional) – Buffer in seconds to stay away from acquisition (default: 0.1).context (
facet.core.ProcessingContext, optional) – Current processing context. If it contains a user-selected reference interval (set byReferenceIntervalSelector), that interval is used before falling back to automatic extraction.
- Returns:
Array of shape (n_channels, n_times) containing concatenated reference data.
- Return type:
- get_acquisition_data(raw: BaseRaw, triggers: ndarray, artifact_length: int, context: ProcessingContext | None = None) ndarray[source]
Extract data within the acquisition window.
- Parameters:
raw (
mne.io.BaseRaw) – Raw data object.triggers (
numpy.ndarray) – Trigger indices.artifact_length (
int) – Length of one artifact in samples.context (
facet.core.ProcessingContext, optional) – Current processing context. If it contains a user-selected evaluation interval (set bySignalIntervalSelector), that interval is used before falling back to automatic extraction.
- Returns:
Array of shape (n_channels, n_times) from the acquisition window.
- Return type:
Interactive Selectors
ReferenceIntervalSelector
- class facet.evaluation.ReferenceIntervalSelector(channel: str | int | None = None, min_duration: float = 0.5, tmin: float | None = None, tmax: float | None = None)[source]
Bases:
Processor,ReferenceDataMixinInteractively select a clean reference interval from a signal plot.
Opens a Matplotlib GUI window for one EEG channel and lets the user drag a time span. The selected region is highlighted in green and, after confirmation, stored in
context.metadata.custom['reference_interval']. Downstream metrics processors can use this interval as explicit reference data.- Parameters:
channel (
strorint, optional) – Channel to display. IfNone(default), the first EEG channel is used.min_duration (
float, optional) – Minimum selectable interval length in seconds (default: 0.5).tmin (
float, optional) – Reference interval start in seconds. If provided together withtmax(or alone), the selector GUI is skipped.tmax (
float, optional) – Reference interval end in seconds. If provided together withtmin(or alone), the selector GUI is skipped.
- __init__(channel: str | int | None = None, min_duration: float = 0.5, tmin: float | None = None, tmax: float | None = None) None[source]
Initialize processor.
- validate(context: ProcessingContext) None[source]
Validate that prerequisites are met.
Override this method to add custom validation logic.
- Parameters:
context – Processing context
- Raises:
ProcessorValidationError – If validation fails
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
SignalIntervalSelector
- class facet.evaluation.SignalIntervalSelector(channel: str | int | None = None, min_duration: float = 0.5, tmin: float | None = None, tmax: float | None = None)[source]
Bases:
Processor,ReferenceDataMixinInteractively select the evaluated signal interval from a signal plot.
Opens a Matplotlib GUI window for one EEG channel and lets the user drag a time span that should be used as evaluated signal (typically acquisition). The selected region is highlighted in blue and, after confirmation, stored in
context.metadata.custom['evaluation_interval']. Downstream metrics processors can use this interval as explicit acquisition/evaluation data.The trigger-derived acquisition window is additionally shown as a weak orange background hint to help orient manual selection when boundaries are not obvious after correction.
- Parameters:
channel (
strorint, optional) – Channel to display. IfNone(default), the first EEG channel is used.min_duration (
float, optional) – Minimum selectable interval length in seconds (default: 0.5).tmin (
float, optional) – Evaluated interval start in seconds. If provided together withtmax(or alone), the selector GUI is skipped.tmax (
float, optional) – Evaluated interval end in seconds. If provided together withtmin(or alone), the selector GUI is skipped.
- __init__(channel: str | int | None = None, min_duration: float = 0.5, tmin: float | None = None, tmax: float | None = None) None[source]
Initialize processor.
- validate(context: ProcessingContext) None[source]
Validate that prerequisites are met.
Override this method to add custom validation logic.
- Parameters:
context – Processing context
- Raises:
ProcessorValidationError – If validation fails
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
Metrics Calculators
SNRCalculator
- class facet.evaluation.SNRCalculator(time_buffer: float = 0.1, verbose: bool = False)[source]
Bases:
Processor,ReferenceDataMixinCalculate Signal-to-Noise Ratio (SNR).
Compares corrected data to a clean reference (data outside acquisition window). Higher SNR indicates better correction.
SNR = variance(reference) / variance(residual)
- Parameters:
time_buffer (
float, optional) – Time buffer around acquisition window in seconds (default: 0.1).
Examples
snr = SNRCalculator() context = snr.execute(context) print(context.metadata.custom['snr'])
- validate(context: ProcessingContext) None[source]
Validate that prerequisites are met.
Override this method to add custom validation logic.
- Parameters:
context – Processing context
- Raises:
ProcessorValidationError – If validation fails
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
LegacySNRCalculator
- class facet.evaluation.LegacySNRCalculator(verbose: bool = False)[source]
Bases:
ProcessorCalculate legacy-style Signal-to-Noise Ratio (SNR).
Mirrors the original FACET implementation by comparing the variance of the corrected data to the variance of the uncorrected reference recording.
- validate(context: ProcessingContext) None[source]
Validate that prerequisites are met.
Override this method to add custom validation logic.
- Parameters:
context – Processing context
- Raises:
ProcessorValidationError – If validation fails
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
RMSCalculator
- class facet.evaluation.RMSCalculator(verbose: bool = False)[source]
Bases:
ProcessorCalculate Root Mean Square (RMS) improvement ratio.
Compares RMS of corrected data to uncorrected data. A higher ratio indicates better correction (more artifact removed).
RMS_ratio = RMS(uncorrected) / RMS(corrected)
Examples
rms = RMSCalculator() context = rms.execute(context) print(context.metadata.custom['rms_ratio'])
- validate(context: ProcessingContext) None[source]
Validate that prerequisites are met.
Override this method to add custom validation logic.
- Parameters:
context – Processing context
- Raises:
ProcessorValidationError – If validation fails
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
RMSResidualCalculator
- class facet.evaluation.RMSResidualCalculator(time_buffer: float = 0.1, verbose: bool = False)[source]
Bases:
Processor,ReferenceDataMixinCalculate RMS Residual Ratio (corrected vs. reference).
Compares the RMS of the corrected signal (during acquisition) to the RMS of the clean reference signal (outside acquisition).
Ratio = RMS(corrected) / RMS(reference)
A ratio of 1.0 is the target. Values below 1.0 suggest over-correction; values above 1.0 indicate residual artifacts. Corresponds to
rms_residualin FACET MATLAB Edition.- Parameters:
time_buffer (
float, optional) – Time buffer around acquisition window in seconds (default: 0.1).
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
MedianArtifactCalculator
- class facet.evaluation.MedianArtifactCalculator(verbose: bool = False)[source]
Bases:
Processor,ReferenceDataMixinCalculate median peak-to-peak artifact amplitude.
Measures the median artifact amplitude across all epochs. Lower values indicate smaller artifacts (better correction).
Also calculates the ratio to the median amplitude of the reference signal (outside acquisition), which should ideally be close to 1.0.
Examples
median = MedianArtifactCalculator() context = median.execute(context) print(context.metadata.custom['median_artifact'])
- validate(context: ProcessingContext) None[source]
Validate that prerequisites are met.
Override this method to add custom validation logic.
- Parameters:
context – Processing context
- Raises:
ProcessorValidationError – If validation fails
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
FFTAllenCalculator
- class facet.evaluation.FFTAllenCalculator(verbose: bool = False)[source]
Bases:
Processor,ReferenceDataMixinCalculate FFT Allen metric.
Compares spectral power in specific frequency bands between corrected data and clean reference data. The metric is the median absolute percent difference per band.
Bands: 0.8–4 Hz (delta), 4–8 Hz (theta), 8–12 Hz (alpha), 12–24 Hz (beta).
Formula:
metric = median(|Power_corr - Power_ref| / Power_ref) * 100
- BANDS = [(0.8, 4, 'Delta'), (4, 8, 'Theta'), (8, 12, 'Alpha'), (12, 24, 'Beta')]
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
FFTNiazyCalculator
- class facet.evaluation.FFTNiazyCalculator(verbose: bool = False)[source]
Bases:
Processor,ReferenceDataMixinCalculate FFT Niazy metric.
Analyzes residual artifacts at slice and volume frequencies by computing the power ratio (uncorrected / corrected) at these frequencies and their harmonics. Values are reported in dB.
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
Reports
MetricsReport
- class facet.evaluation.MetricsReport(name: str | None = None, store: dict | None = None)[source]
Bases:
ProcessorGenerate a summary report of all calculated metrics.
Collects all metrics from context and logs a formatted summary. Can also store results in a shared dictionary for comparison and plotting.
- Parameters:
Examples
# Basic usage report = MetricsReport() context = report.execute(context) # Advanced usage (collecting results for comparison) results = {} report = MetricsReport(name="Pipeline A", store=results) context = report.execute(context) # Plot comparison MetricsReport.plot(results) # Plot specific metrics MetricsReport.plot(results, metrics=['snr', 'rms_ratio'])
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).
- static compare(results: list | dict, labels: list[str] | None = None, title: str = 'Metrics Comparison', save_path: str | None = None, show: bool = True, metrics: list[str] | None = None) None[source]
Compare metrics from a list of
PipelineResultobjects or a plain dict.Accepts either:
A list of
PipelineResultinstances (optionally named via labels).The legacy
{name: {metric: value}}dict format used byMetricsReport.plot.
- Parameters:
results (
listordict) – List ofPipelineResultobjects or legacy dict.labels (
listofstr, optional) – Names for each result when passing a list. Defaults to["Result 1", "Result 2", …].title (
str, optional) – Plot title (default: “Metrics Comparison”).save_path (
str, optional) – If set, save the figure to this path.show (
bool, optional) – Whether to display the figure interactively (default: True).metrics (
listofstr, optional) – Subset of metric keys to show. IfNone, all metrics are plotted.
Examples
result_a = pipeline_aas.run() result_b = pipeline_aas_pca.run() MetricsReport.compare( [result_a, result_b], labels=["AAS only", "AAS + PCA"], )
- static plot(results: dict[str, dict[str, float]], title: str = 'Metrics Comparison', save_path: str | None = None, show: bool = True, metrics: list[str] | None = None) None[source]
Plot comparison of metrics using Matplotlib.
- Parameters:
results (
dict) – Dictionary of results{name: {metric: value}}.title (
str, optional) – Plot title (default: “Metrics Comparison”).save_path (
str, optional) – Path to save the figure.show (
bool, optional) – Whether to show the plot (default: True).metrics (
listofstr, optional) – Subset of metric keys to plot. IfNone, all are shown.
RawPlotter
- class facet.evaluation.RawPlotter(mode: str = 'matplotlib', channel: str | int | None = None, start: float = 0.0, duration: float = 10.0, overlay_original: bool = True, scale: float = 1000000.0, save_path: str | Path | None = None, show: bool = False, auto_close: bool = True, figure_kwargs: dict[str, Any] | None = None, mne_kwargs: dict[str, Any] | None = None, picks: Sequence[int | str] | None = None, title: str | None = None)[source]
Bases:
ProcessorPlot raw EEG data snippets during the pipeline.
Supports both Matplotlib-based summary figures as well as native MNE-Python interactive plots. By default, a Matplotlib plot is generated and saved to the configured path, overlaying the current corrected signal with the original recording for quick visual inspection.
- Parameters:
mode (
str, optional) – Plotting backend:'matplotlib'(default) or'mne'.channel (
strorint, optional) – Single channel to visualise (name or index). Defaults to the first EEG channel, falling back to the first channel overall.start (
float, optional) – Start time in seconds of the snippet to plot (default: 0.0).duration (
float, optional) – Duration in seconds of the snippet to plot (default: 10.0).overlay_original (
bool, optional) – Overlay original recording when available (default: True).scale (
float, optional) – Multiplier applied to amplitude values (default: 1e6 for V → µV).save_path (
strorpathlib.Path, optional) – File path to save the generated plot.show (
bool, optional) – Whether to display the plot interactively (default: False).auto_close (
bool, optional) – Close the figure after saving when running headless (default: True).figure_kwargs (
dict, optional) – Additional keyword arguments forwarded toplt.subplots().mne_kwargs (
dict, optional) – Additional keyword arguments forwarded tomne.io.Raw.plot().picks (
collections.abc.Sequenceofintorstr, optional) – Explicit channel picks for MNE plotting mode.title (
str, optional) – Custom figure title for Matplotlib mode.
- __init__(mode: str = 'matplotlib', channel: str | int | None = None, start: float = 0.0, duration: float = 10.0, overlay_original: bool = True, scale: float = 1000000.0, save_path: str | Path | None = None, show: bool = False, auto_close: bool = True, figure_kwargs: dict[str, Any] | None = None, mne_kwargs: dict[str, Any] | None = None, picks: Sequence[int | str] | None = None, title: str | None = None) None[source]
Initialize processor.
- process(context: ProcessingContext) ProcessingContext[source]
Process the context.
This is the main method to implement in subclasses.
- Parameters:
context – Input processing context
- Returns:
Output processing context. If None is returned, the input context is used (no-op behavior).