Expand description
§exg — EEG/ECG/EMG preprocessing in pure Rust
exg is a zero-dependency* Rust library that implements the EEG
preprocessing pipeline. Every DSP step is ported from
MNE-Python and verified against MNE ground truth via
safetensors test vectors (run cargo test).
* No Python, no BLAS, no C libraries — pure Rust + RustFFT.
§Pipeline overview
sample_raw.fif
│
├─ fiff::open_raw() native FIFF reader (no MNE)
├─ resample::resample() FFT polyphase → target_sfreq (default 256 Hz)
├─ filter (FIR HP) firwin + overlap-add → 0.5 Hz cutoff
├─ reference per-timepoint channel mean removed
├─ normalize (z-score) (data − μ) / σ over all ch × t
├─ epoch non-overlapping 5 s windows
├─ baseline correct per-epoch per-channel mean removed
└─ ÷ data_norm ÷ 10 → std ≈ 0.1
│
└─→ Vec<([C, 1280] f32, [C, 3] f32)> (epochs, channel positions)§Quick start
use exg::{preprocess, PipelineConfig};
use exg::fiff::open_raw;
use ndarray::Array2;
// 1. Read a .fif file — no Python required
let raw = open_raw("data/sample1_raw.fif").unwrap();
let data = raw.read_all_data().unwrap(); // [C, T] f64
// 2. Channel positions from the FIF file (metres)
let chan_pos: Array2<f32> = Array2::zeros((raw.info.n_chan, 3));
// 3. Run the full preprocessing pipeline
let cfg = PipelineConfig::default();
let epochs = preprocess(
data.mapv(|v| v as f32),
chan_pos,
raw.info.sfreq as f32,
&cfg,
).unwrap();
for (i, (epoch_data, pos)) in epochs.iter().enumerate() {
println!("Epoch {i}: shape {:?}", epoch_data.dim());
}§Running individual steps
Each preprocessing step is also exposed as a standalone function:
use exg::resample::resample;
use exg::filter::{design_highpass, apply_fir_zero_phase};
use exg::reference::average_reference_inplace;
use exg::normalize::zscore_global_inplace;
use exg::epoch::epoch;
use ndarray::Array2;
let mut data: Array2<f32> = Array2::zeros((12, 3840)); // [C, T]
// Resample from 1024 Hz → 256 Hz
let data = resample(&data, 1024.0, 256.0).unwrap();
// Apply 0.5 Hz highpass FIR
let h = design_highpass(0.5, 256.0);
let mut data = data;
apply_fir_zero_phase(&mut data, &h).unwrap();
// Average reference
average_reference_inplace(&mut data);
// Global z-score
let (mean, std) = zscore_global_inplace(&mut data);
// Epoch into 5 s windows
let epochs = epoch(&data, 1280); // [E, C, 1280]§Feature coverage
See the README for a full table of which MNE features are implemented and which are not yet ported.
Re-exports§
pub use config::PipelineConfig;pub use epoch::epoch;pub use epoch::epoch_and_baseline;pub use fiff::open_raw;pub use fiff::RawFif;pub use fiff::BufferRecord;pub use fiff::ChannelInfo;pub use fiff::MeasInfo;pub use fiff::read_meas_info;pub use fiff::TagHeader;pub use fiff::read_tag_header;pub use fiff::read_i32;pub use fiff::read_f32;pub use fiff::read_f64;pub use fiff::read_string;pub use fiff::read_i32_array;pub use fiff::read_f32_array;pub use fiff::read_f64_array;pub use fiff::read_raw_bytes;pub use fiff::read_directory;pub use fiff::Node;pub use fiff::build_tree;pub use fiff::read_tree;pub use fiff::scan_directory;pub use fiff::try_load_directory;pub use filter::auto_trans_bandwidth;pub use filter::auto_filter_length;pub use filter::design_highpass;pub use filter::firwin;pub use filter::hamming;pub use filter::apply_fir_zero_phase;pub use filter::filter_1d;pub use io::RawData;pub use io::StWriter;pub use io::write_batch;pub use normalize::zscore_global_inplace;pub use normalize::baseline_correct_inplace;pub use reference::average_reference_inplace;pub use resample::resample;pub use resample::resample_1d;pub use resample::auto_npad;pub use resample::rational_approx;pub use resample::final_length;pub use exg_source as source_localization;
Modules§
- config
- Pipeline configuration.
- epoch
- Fixed-length epoching.
- fiff
- FIFF file format reader.
- filter
- FIR filter design and application.
- io
- Safetensors I/O for the preprocessing pipeline.
- normalize
- Z-score normalisation and epoch baseline correction.
- reference
- Average reference: subtract the mean across channels at each time point.
- resample
- FFT-based rational resampler exactly matching MNE’s
resample(..., method='fft').
Structs§
- Eloreta
Options - Options for the eLORETA iterative solver.
- Forward
Operator - Forward operator (gain matrix + metadata).
- Inverse
Operator - Prepared inverse operator, ready for application to data.
- Noise
Cov - Noise covariance matrix.
- Source
Estimate - Source-space estimate produced by
apply_inverse. - Sphere
Model - Parameters of a multi-shell spherical head model.
Enums§
- Inverse
Method - Choice of inverse method.
- PickOri
- How to handle source orientations in free-orientation inverse solutions.
- Regularization
- Regularisation strategy for covariance estimation.
- Source
Orientation - Source orientation constraint.
Functions§
- apply_
inverse - Apply an inverse operator to sensor-space data.
- apply_
inverse_ epochs - Apply inverse operator to each epoch in a batch.
- apply_
inverse_ epochs_ full - Apply inverse to epochs with full options.
- apply_
inverse_ full - Apply inverse with full control over orientation picking and eLORETA options.
- compute_
covariance - Compute noise covariance from continuous data
[n_channels, n_times]. - compute_
covariance_ epochs - Compute noise covariance from epoched data
[n_epochs, n_channels, n_times]. - estimate_
snr - Estimate SNR as a function of time.
- get_
cross_ talk - Cross-talk function (CTF) for a given source index.
- get_
point_ spread - Point-spread function (PSF) for a given source index.
- grid_
source_ space - Generate a volume source space on a regular 3-D grid.
- ico_
n_ vertices - Expected vertex count for a given icosahedron subdivision level.
- ico_
source_ space - Generate a source space by subdividing an icosahedron.
- make_
inverse_ operator - Build an inverse operator from a forward model and noise covariance.
- make_
resolution_ matrix - Compute the resolution matrix
R = K @ G. - make_
sphere_ forward - Compute a fixed-orientation EEG forward model using a spherical head.
- make_
sphere_ forward_ free - Compute a free-orientation EEG forward model using a spherical head.
- peak_
localisation_ error - Compute peak localisation error for each source.
- preprocess
- Run the full EEG preprocessing pipeline on a single continuous recording.
- relative_
amplitude - Compute relative amplitude for each PSF.
- spatial_
spread - Compute spatial spread (half-max width) for each PSF.
- zero_
bad_ channels - Zero-fill channels whose normalised name appears in
bad.