Skip to content

Add multichannel EGG processing, ICA denoising, and preprocessing filters (Dalmaijer 2025) - #10

Merged
micahgallen merged 7 commits into
mainfrom
dev/multichannel-preprocessing
Feb 17, 2026
Merged

Add multichannel EGG processing, ICA denoising, and preprocessing filters (Dalmaijer 2025)#10
micahgallen merged 7 commits into
mainfrom
dev/multichannel-preprocessing

Conversation

@micahgallen

Copy link
Copy Markdown
Member

Summary

Ports core algorithms from electrography v1.1.1 (Dalmaijer, 2025) into GastroPy, following the neurokit2 convention of named, citable method= variants. Closes #9.

New public functions

Function Module Description
hampel_filter signal Sliding-window median spike removal (Davies & Gather 1993; Dalmaijer 2025)
mad_filter signal Global MAD-based outlier removal
remove_movement_artifacts signal LMMSE Wiener movement filter (Gharibans et al. 2018)
ica_denoise signal FastICA spatial denoising with gastric-band SNR thresholding
fit_sine signal L-BFGS-B sine fitting: amplitude, phase, residual
sine_model signal Sine wave evaluation A·sin(2πft+φ)
egg_process_multichannel egg Three-strategy multichannel pipeline (per_channel / best_channel / ica)

Extended existing functions

  • egg_clean gains method="dalmaijer2025": Hampel → LMMSE → IIR Butterworth pipeline

Dependencies

  • Added scikit-learn>=1.3 as a core dependency (used for FastICA)

Tests

  • 3 new test files: test_preprocessing.py (19 tests), test_ica.py (11 tests), extended test_egg.py (+13 tests)
  • All 270 tests pass on Python 3.10–3.13

Documentation

  • API reference: 7 new functions in docs/api/index.rst
  • Getting started: expanded artifact removal, channel selection, and multichannel sections
  • 2 new example notebooks: artifact_removal.ipynb, multichannel_processing.ipynb
  • Updated examples: egg_process.ipynb (dalmaijer2025 cell), bandpass_filtering.ipynb (fit_sine cell)
  • New tutorial: multichannel_pipeline.ipynb — 28-cell pedagogical guide covering the full multichannel workflow from raw data to sine fitting

Test plan

  • pytest passes on Python 3.10, 3.11, 3.12, 3.13
  • ruff check gastropy/ — no lint errors
  • sphinx-build docs docs/_build -b html -W — no warnings or errors
  • Review new example and tutorial notebooks for correctness

References

  • Dalmaijer, E. S. (2025). electrography v1.1.1. https://github.com/esdalmaijer/electrography
  • Gharibans, A. A., et al. (2018). Artifact rejection methodology enables continuous, noninvasive measurement of gastric myoelectric activity in ambulatory subjects. Scientific Reports, 8, 5019.
  • Davies, P. L., & Gather, U. (1993). The identification of multiple outliers. JASA, 88, 782–792.
  • Hyvärinen, A., & Oja, E. (2000). Independent component analysis: algorithms and applications. Neural Networks, 13, 411–430.

Ports and integrates algorithms from Dalmaijer (2025) electrography into
the gastropy signal processing toolkit. Follows the neurokit2 convention
of named, citable method variants within existing functions.

New in gastropy.signal:
- hampel_filter: sliding-window median spike removal (Dalmaijer 2025)
- mad_filter: global MAD outlier replacement (Dalmaijer 2025)
- remove_movement_artifacts: LMMSE movement filter (Gharibans et al. 2018)
- ica_denoise: FastICA spatial denoising for multi-channel EGG
- fit_sine / sine_model: least-squares sine wave fitting

New in gastropy.egg:
- egg_process_multichannel: per_channel / best_channel / ica strategies
- egg_clean gains method="dalmaijer2025" named pipeline variant

Closes #9.
- API reference: add egg_process_multichannel and 6 new signal
  functions (hampel_filter, mad_filter, remove_movement_artifacts,
  ica_denoise, fit_sine, sine_model)
- getting_started.rst: expand artifact removal, channel selection, and
  egg_clean method sections with examples for all new functionality
- New example notebooks: artifact_removal.ipynb,
  multichannel_processing.ipynb
- Update egg_process.ipynb with dalmaijer2025 cleaning pipeline cell
- Update bandpass_filtering.ipynb with fit_sine demonstration cell
- Register new notebooks in examples/index.rst
…/post timeseries

- Raise ica_snr_threshold to 30.0 so 2/7 components are removed,
  producing visibly different per-channel results vs per_channel method
- Add pre vs post ICA timeseries plot for all channels
- Fix band_power_mean display (was 0.0000 due to tiny values; now uses
  {:.4g} scientific notation)
- Update ICA markdown to explain the stricter demo threshold
- Suppress FastICA ConvergenceWarning in notebook output
- New tutorial: docs/tutorials/multichannel_pipeline.ipynb
  28-cell pedagogical guide covering: data loading, channel quality
  assessment, step-by-step artefact removal (Hampel → LMMSE → IIR),
  all three multichannel strategies (per_channel / best_channel / ica),
  quantitative method comparison, and sine fitting. Fully executed.
- Register tutorial in docs/tutorials/index.rst
- Fix bandpass_filtering.ipynb: psd_welch returns (freqs, psd) ndarrays,
  not (_, info_dict); compute peak_hz correctly from the PSD array

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds comprehensive multi-channel EGG processing capabilities to GastroPy by porting core algorithms from the electrography package (Dalmaijer, 2025). The changes follow GastroPy's existing neurokit2-inspired convention of named, citable method variants and integrate seamlessly with the existing API.

Changes:

  • Adds seven new public functions for preprocessing (Hampel/MAD filters, movement artifact removal), ICA spatial denoising, and sine wave fitting
  • Introduces egg_process_multichannel with three processing strategies: per-channel, best-channel selection, and ICA-based denoising
  • Extends egg_clean with a method="dalmaijer2025" variant that chains Hampel spike removal → LMMSE movement filtering → IIR Butterworth bandpass
  • Adds scikit-learn as a core dependency for FastICA support
  • Includes 43 new tests (19 preprocessing, 11 ICA, 13 multichannel) bringing total coverage to 270 tests
  • Provides extensive documentation updates including API reference additions, expanded getting started guide, and tutorial content

Reviewed changes

Copilot reviewed 17 out of 21 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
gastropy/signal/preprocessing.py Time-domain artifact removal: Hampel filter, MAD filter, LMMSE movement artifact attenuation
gastropy/signal/ica.py FastICA spatial denoising with gastric-band SNR thresholding for multi-channel EGG
gastropy/signal/sine.py L-BFGS-B least-squares sine fitting for frequency/phase/amplitude characterization
gastropy/signal/__init__.py Exports new preprocessing, ICA, and sine fitting functions
gastropy/egg/multichannel.py Multi-channel processing pipeline with three named strategies
gastropy/egg/egg_process.py Extended egg_clean with dalmaijer2025 method variant
gastropy/egg/__init__.py Exports egg_process_multichannel
tests/test_preprocessing.py 19 tests for Hampel, MAD, and movement artifact filters
tests/test_ica.py 11 tests for ICA denoising including edge cases and reproducibility
tests/test_egg.py 13 new tests for multi-channel processing strategies
pyproject.toml Adds scikit-learn>=1.3 dependency
docs/api/index.rst Documents 7 new functions in signal preprocessing section
docs/getting_started.rst Expanded artifact removal, channel selection, and multi-channel sections
docs/examples/egg_process.ipynb Added dalmaijer2025 cleaning method example
docs/examples/index.rst References two new example notebooks
docs/tutorials/index.rst References new multichannel pipeline tutorial
CHANGELOG.md Comprehensive documentation of all additions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/getting_started.rst

``egg_clean`` supports multiple named cleaning pipelines via its
``method`` parameter. ``method="fir"`` (default) uses a zero-phase
FIR bandpass. ``method="dalmaijer2025"`` applies Hampel spike removal

Copilot AI Feb 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation states "0.033-0.067 Hz" for the normogastric band, but the actual NORMOGASTRIA constant uses 0.03333-0.06666 Hz (exactly 2-4 cpm). While functionally equivalent for most purposes, this minor inconsistency could cause confusion. Consider using the more precise values (0.0333-0.0667 Hz) or referring to the band by name (NORMOGASTRIA) to avoid hardcoding approximate values in documentation.

Copilot uses AI. Check for mistakes.
- Make scikit-learn optional ([ica] extra): lazy import in ica_denoise
  raises ImportError with install instructions when sklearn is absent;
  remove sklearn from core dependencies in pyproject.toml
- Add filter_method= parameter to egg_process_multichannel to resolve
  the name collision with the multichannel strategy method= parameter
- Add freq_init= parameter to fit_sine so free-frequency fits work
  outside the normogastric band; document that amplitude may be negative
- Document DC-removal side effect in remove_movement_artifacts (Notes)
- Document best_idx criterion difference between per_channel/ica and
  best_channel strategies (Notes in egg_process_multichannel)
- Add tests/test_sine.py: 16 tests covering sine_model and fit_sine
- Guard test_ica.py and ICA tests in test_egg.py with importorskip/
  skipif so they skip cleanly when sklearn is not installed
- Update CONTRIBUTING.md: sklearn is optional, lazy-imported
@micahgallen
micahgallen merged commit 07884b3 into main Feb 17, 2026
4 of 5 checks passed
@micahgallen
micahgallen deleted the dev/multichannel-preprocessing branch February 17, 2026 11:36
micahgallen added a commit that referenced this pull request Apr 9, 2026
- Revise paper.md and gastropy_paper.tex to cover PR #10 features:
  preprocessing filters (Hampel, MAD, LMMSE), ICA spatial denoising,
  egg_process_multichannel, named method variants (dalmaijer2025)
- Add references: Anisimova 2025, Gharibans 2018, Pedregosa 2011,
  Berther 2026; fix Wolpert 2020 author list
- Update test count 178 -> 297, AI model versions, comparison tables
- Solo author for preprint (Allen)
- Bump pyproject.toml to v0.1.1 with maintainer field and Alpha status
- Recompile preprint PDF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Port electrography methods: multi-channel pipeline, ICA denoising, and preprocessing filters

2 participants