2 releases
new 0.2.21 | Apr 4, 2025 |
---|---|
0.2.2 | Apr 4, 2025 |
#164 in Math
248 downloads per month
86KB
1.5K
SLoC
RustNeuro
RustNeuro is a high-performance Rust library for neural signal analysis and feature extraction. Designed for scientists and researchers working with EEG and other neural signals, RustNeuro provides a suite of tools that cover artifact detection, digital filtering, spectral analysis, and data I/O—all optimized for fast computation.
Overview
RustNeuro leverages Rust’s safety and concurrency features to deliver efficient signal processing routines. Whether you are cleaning your EEG data of artifacts, filtering out noise, or performing detailed spectral analysis, RustNeuro offers flexible, easy-to-use APIs that integrate seamlessly into your research workflows.
Features
-
Data I/OLoad EEG data from CSV files with support for both header and headerless formats. Automatically handle timestamps and event markers.
-
Artifact Detection and RemovalDetect artifacts based on amplitude and gradient thresholds. Merge overlapping artifacts and remove them via various interpolation methods (linear, constant, previous value, or mean).
-
Digital FilteringApply a range of filters to your signals by using the biquad wrapper:
- Low-Pass, High-Pass, and Band-Pass filters
- Notch (or Band-Stop) filters for attenuating power-line noise
- Peak (Peaking EQ) filters for boosting or cutting narrow frequency bands
-
Spectral AnalysisCompute the power spectral density (PSD) of a signal using Welch’s method with adjustable window functions (Rectangular, Hann, Hamming, Blackman, Tukey). Also, measure coherence and derive common EEG frequency bands.
-
Performance Built with speed in mind by using optimized DSP libraries (e.g., rustfft) and parallel processing where applicable.
Installation
Add RustNeuro to your project by including it in your Cargo.toml
:
[dependencies]
rustneuro = "0.2.2"
Then, build your project with:
cargo build
Usage
Loading EEG Data
RustNeuro includes a CSV loader for EEG datasets. For example:
use rustneuro::io::load_csv;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load a CSV file with headers. The first column is interpreted as timestamps,
// and the fourth column (index 3) as event markers.
let data = load_csv("path/to/eeg.csv", 256.0, Some(0), Some(3), true)?;
println!("Loaded {} channels", data.channels.len());
Ok(())
}
Artifact Detection and Removal
Detect and remove artifacts from your EEG data:
use rustneuro::artifacts::{ArtifactDetectionParams, detect_artifacts, remove_artifacts, InterpolationMethod};
use rustneuro::data::EEGData;
fn process_artifacts(eeg_data: &EEGData) -> Result<EEGData, Box<dyn std::error::Error>> {
// Create artifact detection parameters:
// - Amplitude threshold of 100 µV,
// - Optional gradient threshold of 10 µV/sample,
// - Window size of 10 samples, and a minimum artifact duration of 5 samples.
let params = ArtifactDetectionParams::new(100.0, Some(10.0), 10, 5)?;
let artifacts = detect_artifacts(eeg_data, ¶ms)?;
// Remove detected artifacts using linear interpolation
let cleaned_data = remove_artifacts(eeg_data, &artifacts, InterpolationMethod::Linear)?;
Ok(cleaned_data)
}
Filtering Signals
Apply filters to a single-channel signal:
use rustneuro::filter::{apply_filter, FilterConfig, FilterType};
fn filter_signal(signal: &[f64]) -> Result<Vec<f64>, Box<dyn std::error::Error>> {
// Create a low-pass filter with a cutoff at 20 Hz and a Q-factor of 0.707.
let config = FilterConfig::new(FilterType::LowPass, 20.0, 0.707, 1000.0, None)?;
let filtered_signal = apply_filter(signal, &config)?;
Ok(filtered_signal)
}
To filter all channels in an EEG dataset:
use rustneuro::filter::apply_filter_to_all_channels;
use rustneuro::io::load_csv;
use rustneuro::filter::{FilterConfig, FilterType};
fn filter_eeg_data(path: &str) -> Result<(), Box<dyn std::error::Error>> {
let eeg_data = load_csv(path, 1000.0, None, None, true)?;
// Apply a 50 Hz notch filter (commonly used for power-line noise removal)
let config = FilterConfig::new(FilterType::Notch, 50.0, 30.0, 1000.0, None)?;
let filtered_data = apply_filter_to_all_channels(&eeg_data, &config)?;
println!("Filtered data for {} channels", filtered_data.channels.len());
Ok(())
}
Spectral Analysis
Compute the PSD of a signal using Welch’s method:
use rustneuro::spectral::{compute_psd, WindowType};
fn analyze_spectrum(signal: &[f64]) -> Result<(), Box<dyn std::error::Error>> {
// Compute the PSD with a segment length of 256 samples,
// 50% overlap, and a Hann window.
let psd = compute_psd(signal, 1000.0, 256, 0.5, WindowType::Hann)?;
// Find the frequency with the maximum power
if let Some((peak_idx, _)) = psd.psd.iter().enumerate().max_by(|a, b| a.1.partial_cmp(b.1).unwrap()) {
println!("Peak frequency: {:.2} Hz", psd.frequencies[peak_idx]);
}
Ok(())
}
API Documentation
For full API documentation, please see our docs.rs page or check the source code in our GitHub repository.
Running Tests
To run the complete test suite:
cargo test
Contributing
Contributions are welcome! If you have ideas for improvements, new features, or bug fixes, please open an issue or submit a pull request on GitHub repository.
License
RustNeuro is licensed under the MIT License.
Contact
For any questions, issues, or suggestions, please reach out to:
- Yusuf Berdan Guzel – y.guzel@unimelb.edu.au
Dependencies
~7–10MB
~180K SLoC