meeg-utils 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. meeg_utils-0.1.0/.github/workflows/ci.yml +173 -0
  2. meeg_utils-0.1.0/.github/workflows/docs.yml +59 -0
  3. meeg_utils-0.1.0/.github/workflows/release.yml +95 -0
  4. meeg_utils-0.1.0/.gitignore +92 -0
  5. meeg_utils-0.1.0/.pre-commit-config.yaml +30 -0
  6. meeg_utils-0.1.0/.python-version +1 -0
  7. meeg_utils-0.1.0/LICENSE +21 -0
  8. meeg_utils-0.1.0/PKG-INFO +137 -0
  9. meeg_utils-0.1.0/README.md +112 -0
  10. meeg_utils-0.1.0/docs/Makefile +19 -0
  11. meeg_utils-0.1.0/docs/make.bat +35 -0
  12. meeg_utils-0.1.0/docs/source/.nojekyll +0 -0
  13. meeg_utils-0.1.0/docs/source/about/changelog.rst +56 -0
  14. meeg_utils-0.1.0/docs/source/about/license.rst +41 -0
  15. meeg_utils-0.1.0/docs/source/api/_autosummary/meeg_utils.preprocessing.bad_channels.rst +12 -0
  16. meeg_utils-0.1.0/docs/source/api/_autosummary/meeg_utils.preprocessing.batch.rst +11 -0
  17. meeg_utils-0.1.0/docs/source/api/_autosummary/meeg_utils.preprocessing.ica.rst +11 -0
  18. meeg_utils-0.1.0/docs/source/api/_autosummary/meeg_utils.preprocessing.line_noise.rst +12 -0
  19. meeg_utils-0.1.0/docs/source/api/_autosummary/meeg_utils.preprocessing.pipeline.rst +11 -0
  20. meeg_utils-0.1.0/docs/source/api/_autosummary/meeg_utils.preprocessing.rst +17 -0
  21. meeg_utils-0.1.0/docs/source/api/batch.rst +45 -0
  22. meeg_utils-0.1.0/docs/source/api/pipeline.rst +48 -0
  23. meeg_utils-0.1.0/docs/source/api/preprocessing.rst +19 -0
  24. meeg_utils-0.1.0/docs/source/conf.py +108 -0
  25. meeg_utils-0.1.0/docs/source/developer/ci_cd.rst +146 -0
  26. meeg_utils-0.1.0/docs/source/developer/contributing.rst +257 -0
  27. meeg_utils-0.1.0/docs/source/developer/release.rst +219 -0
  28. meeg_utils-0.1.0/docs/source/developer/testing.rst +376 -0
  29. meeg_utils-0.1.0/docs/source/index.rst +115 -0
  30. meeg_utils-0.1.0/docs/source/user_guide/batch_processing.rst +339 -0
  31. meeg_utils-0.1.0/docs/source/user_guide/installation.rst +79 -0
  32. meeg_utils-0.1.0/docs/source/user_guide/preprocessing.rst +259 -0
  33. meeg_utils-0.1.0/docs/source/user_guide/quickstart.rst +189 -0
  34. meeg_utils-0.1.0/pyproject.toml +193 -0
  35. meeg_utils-0.1.0/resources/preprocessing_pipeline.png +0 -0
  36. meeg_utils-0.1.0/src/meeg_utils/__init__.py +7 -0
  37. meeg_utils-0.1.0/src/meeg_utils/preprocessing/__init__.py +19 -0
  38. meeg_utils-0.1.0/src/meeg_utils/preprocessing/bad_channels.py +131 -0
  39. meeg_utils-0.1.0/src/meeg_utils/preprocessing/batch.py +259 -0
  40. meeg_utils-0.1.0/src/meeg_utils/preprocessing/ica.py +282 -0
  41. meeg_utils-0.1.0/src/meeg_utils/preprocessing/line_noise.py +131 -0
  42. meeg_utils-0.1.0/src/meeg_utils/preprocessing/pipeline.py +640 -0
  43. meeg_utils-0.1.0/tests/__init__.py +1 -0
  44. meeg_utils-0.1.0/tests/conftest.py +337 -0
  45. meeg_utils-0.1.0/tests/test_preprocessing/README.md +189 -0
  46. meeg_utils-0.1.0/tests/test_preprocessing/__init__.py +1 -0
  47. meeg_utils-0.1.0/tests/test_preprocessing/test_batch.py +456 -0
  48. meeg_utils-0.1.0/tests/test_preprocessing/test_pipeline.py +685 -0
  49. meeg_utils-0.1.0/uv.lock +2265 -0
@@ -0,0 +1,173 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master, develop]
6
+ pull_request:
7
+ branches: [main, master, develop]
8
+ workflow_dispatch:
9
+
10
+ env:
11
+ CACHE_NUMBER: 0 # Increase to reset cache manually
12
+
13
+ jobs:
14
+ # Code quality checks
15
+ lint:
16
+ name: Lint & Format Check
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.11"
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v5
28
+ with:
29
+ enable-cache: true
30
+
31
+ - name: Install dependencies
32
+ run: |
33
+ uv sync --all-extras --dev
34
+
35
+ - name: Run ruff linter
36
+ run: |
37
+ uv run ruff check src/ tests/
38
+
39
+
40
+ # Type checking
41
+ type-check:
42
+ name: Type Check
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - uses: actions/checkout@v4
46
+
47
+ - name: Set up Python
48
+ uses: actions/setup-python@v5
49
+ with:
50
+ python-version: "3.11"
51
+
52
+ - name: Install uv
53
+ uses: astral-sh/setup-uv@v5
54
+ with:
55
+ enable-cache: true
56
+
57
+ - name: Install dependencies
58
+ run: |
59
+ uv sync --all-extras --dev
60
+
61
+ - name: Run mypy
62
+ run: |
63
+ uv run mypy src/
64
+
65
+ # Security checks
66
+ security:
67
+ name: Security Check
68
+ runs-on: ubuntu-latest
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+
72
+ - name: Set up Python
73
+ uses: actions/setup-python@v5
74
+ with:
75
+ python-version: "3.11"
76
+
77
+ - name: Install uv
78
+ uses: astral-sh/setup-uv@v5
79
+ with:
80
+ enable-cache: true
81
+
82
+ - name: Install dependencies
83
+ run: |
84
+ uv sync --all-extras --dev
85
+
86
+ - name: Run bandit
87
+ run: |
88
+ uv run bandit -r src/ -c pyproject.toml
89
+
90
+ # Test suite
91
+ test:
92
+ name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }}
93
+ runs-on: ${{ matrix.os }}
94
+ strategy:
95
+ fail-fast: false
96
+ matrix:
97
+ os: [ubuntu-latest, macos-latest, windows-latest]
98
+ python-version: ["3.11", "3.12"]
99
+
100
+ steps:
101
+ - uses: actions/checkout@v4
102
+
103
+ - name: Set up Python ${{ matrix.python-version }}
104
+ uses: actions/setup-python@v5
105
+ with:
106
+ python-version: ${{ matrix.python-version }}
107
+
108
+ - name: Install uv
109
+ uses: astral-sh/setup-uv@v5
110
+ with:
111
+ enable-cache: true
112
+
113
+ - name: Install dependencies
114
+ run: |
115
+ uv sync --all-extras --dev
116
+
117
+ - name: Run tests
118
+ run: |
119
+ uv run pytest tests/ -v --cov=src/meeg_utils --cov-report=xml --cov-report=term
120
+
121
+ - name: Upload coverage to Codecov
122
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
123
+ uses: codecov/codecov-action@v4
124
+ with:
125
+ file: ./coverage.xml
126
+ flags: unittests
127
+ name: codecov-umbrella
128
+ fail_ci_if_error: false
129
+ token: ${{ secrets.CODECOV_TOKEN }}
130
+
131
+ # Documentation build check
132
+ docs:
133
+ name: Documentation Build
134
+ runs-on: ubuntu-latest
135
+ steps:
136
+ - uses: actions/checkout@v4
137
+
138
+ - name: Set up Python
139
+ uses: actions/setup-python@v5
140
+ with:
141
+ python-version: "3.11"
142
+
143
+ - name: Install uv
144
+ uses: astral-sh/setup-uv@v5
145
+ with:
146
+ enable-cache: true
147
+
148
+ - name: Install dependencies
149
+ run: |
150
+ uv sync --all-extras --dev
151
+
152
+ - name: Check docstring coverage
153
+ run: |
154
+ uv run interrogate src/ --config pyproject.toml
155
+
156
+ # All checks passed
157
+ all-checks:
158
+ name: All Checks Passed
159
+ if: always()
160
+ needs: [lint, type-check, security, test, docs]
161
+ runs-on: ubuntu-latest
162
+ steps:
163
+ - name: Check all job results
164
+ run: |
165
+ if [ "${{ needs.lint.result }}" != "success" ] || \
166
+ [ "${{ needs.type-check.result }}" != "success" ] || \
167
+ [ "${{ needs.security.result }}" != "success" ] || \
168
+ [ "${{ needs.test.result }}" != "success" ] || \
169
+ [ "${{ needs.docs.result }}" != "success" ]; then
170
+ echo "One or more checks failed"
171
+ exit 1
172
+ fi
173
+ echo "All checks passed successfully!"
@@ -0,0 +1,59 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+ pages: write
13
+ id-token: write
14
+
15
+ concurrency:
16
+ group: "pages"
17
+ cancel-in-progress: false
18
+
19
+ jobs:
20
+ build:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.11"
29
+
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@v5
32
+ with:
33
+ enable-cache: true
34
+
35
+ - name: Install dependencies
36
+ run: |
37
+ uv sync --all-extras --dev
38
+
39
+ - name: Build documentation
40
+ run: |
41
+ cd docs
42
+ uv run make html
43
+
44
+ - name: Upload artifact
45
+ uses: actions/upload-pages-artifact@v3
46
+ with:
47
+ path: docs/build/html
48
+
49
+ deploy:
50
+ if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
51
+ needs: build
52
+ runs-on: ubuntu-latest
53
+ environment:
54
+ name: github-pages
55
+ url: ${{ steps.deployment.outputs.page_url }}
56
+ steps:
57
+ - name: Deploy to GitHub Pages
58
+ id: deployment
59
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,95 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+ workflow_dispatch:
8
+ inputs:
9
+ version:
10
+ description: "Version to release (e.g., 0.1.0)"
11
+ required: true
12
+ type: string
13
+
14
+ permissions:
15
+ contents: write
16
+
17
+ jobs:
18
+ build:
19
+ name: Build Distribution
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - name: Set up Python
25
+ uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.11"
28
+
29
+ - name: Install uv
30
+ uses: astral-sh/setup-uv@v5
31
+
32
+ - name: Build package
33
+ run: |
34
+ uv build
35
+
36
+ - name: Store the distribution packages
37
+ uses: actions/upload-artifact@v4
38
+ with:
39
+ name: python-package-distributions
40
+ path: dist/
41
+
42
+ publish-pypi:
43
+ name: Publish to PyPI
44
+ if: startsWith(github.ref, 'refs/tags/')
45
+ needs: [build]
46
+ runs-on: ubuntu-latest
47
+ environment:
48
+ name: pypi
49
+ url: https://pypi.org/p/meeg-utils
50
+
51
+ steps:
52
+ - name: Download all the dists
53
+ uses: actions/download-artifact@v4
54
+ with:
55
+ name: python-package-distributions
56
+ path: dist/
57
+
58
+ - name: Publish to PyPI
59
+ uses: pypa/gh-action-pypi-publish@release/v1
60
+ with:
61
+ password: ${{ secrets.PYPI_API_TOKEN }}
62
+
63
+ github-release:
64
+ name: Create GitHub Release
65
+ needs: [publish-pypi]
66
+ runs-on: ubuntu-latest
67
+ permissions:
68
+ contents: write
69
+ id-token: write
70
+
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+
74
+ - name: Download all the dists
75
+ uses: actions/download-artifact@v4
76
+ with:
77
+ name: python-package-distributions
78
+ path: dist/
79
+
80
+ - name: Create GitHub Release
81
+ env:
82
+ GITHUB_TOKEN: ${{ github.token }}
83
+ run: >-
84
+ gh release create
85
+ '${{ github.ref_name }}'
86
+ --repo '${{ github.repository }}'
87
+ --notes "Release ${{ github.ref_name }}"
88
+
89
+ - name: Upload artifact signatures to GitHub Release
90
+ env:
91
+ GITHUB_TOKEN: ${{ github.token }}
92
+ run: >-
93
+ gh release upload
94
+ '${{ github.ref_name }}' dist/**
95
+ --repo '${{ github.repository }}'
@@ -0,0 +1,92 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # Unit test / coverage reports
30
+ htmlcov/
31
+ .tox/
32
+ .nox/
33
+ .coverage
34
+ .coverage.*
35
+ .cache
36
+ nosetests.xml
37
+ coverage.xml
38
+ *.cover
39
+ *.py,cover
40
+ .hypothesis/
41
+ .pytest_cache/
42
+ cover/
43
+
44
+ # Environments
45
+ .env
46
+ .venv
47
+ env/
48
+ venv/
49
+ ENV/
50
+ env.bak/
51
+ venv.bak/
52
+
53
+ # IDEs
54
+ .idea/
55
+ .vscode/
56
+ *.swp
57
+ *.swo
58
+ *~
59
+ .DS_Store
60
+
61
+ # mypy
62
+ .mypy_cache/
63
+ .dmypy.json
64
+ dmypy.json
65
+
66
+ # ruff
67
+ .ruff_cache/
68
+
69
+ # Jupyter Notebook
70
+ .ipynb_checkpoints
71
+
72
+ # Project specific
73
+ .claude
74
+ derivatives/
75
+ *.fif
76
+ *.vhdr
77
+ *.vmrk
78
+ *.edf
79
+ *.bdf
80
+ *.sqd
81
+ *.con
82
+ *.raw
83
+ *.ave
84
+ *.cov
85
+ *.trans
86
+ *.fwd
87
+ *.inv
88
+ data/
89
+ results/
90
+ outputs/
91
+ *.h5
92
+ *.hdf5
@@ -0,0 +1,30 @@
1
+ # Pre-commit hooks configuration
2
+ # See https://pre-commit.com for more information
3
+
4
+ repos:
5
+ # General file checks
6
+ - repo: https://github.com/pre-commit/pre-commit-hooks
7
+ rev: v5.0.0
8
+ hooks:
9
+ - id: trailing-whitespace
10
+ args: [--markdown-linebreak-ext=md]
11
+ - id: end-of-file-fixer
12
+ - id: check-yaml
13
+ - id: check-toml
14
+ - id: check-json
15
+ - id: check-added-large-files
16
+ args: [--maxkb=1000]
17
+ - id: check-merge-conflict
18
+ - id: check-case-conflict
19
+ - id: mixed-line-ending
20
+ args: [--fix=lf]
21
+
22
+ # Python code formatting with ruff
23
+ - repo: https://github.com/astral-sh/ruff-pre-commit
24
+ rev: v0.8.4
25
+ hooks:
26
+ # Run the linter
27
+ - id: ruff
28
+ args: [--fix, --exit-non-zero-on-fix]
29
+ # Run the formatter
30
+ - id: ruff-format
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 meeg-utils contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: meeg-utils
3
+ Version: 0.1.0
4
+ Summary: A Python-based MEEG processing toolkit primarily based on MNE-Python.
5
+ Author-email: Your Name <your.email@example.com>
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Keywords: EEG,MEEG,MEG,MNE-Python,neuroscience,preprocessing
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Scientific/Engineering
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: loguru>=0.7.3
18
+ Requires-Dist: meegkit>=0.1.9
19
+ Requires-Dist: mne-bids>=0.18.0
20
+ Requires-Dist: mne-icalabel>=0.8.1
21
+ Requires-Dist: mne>=1.11.0
22
+ Requires-Dist: onnxruntime>=1.24.2
23
+ Requires-Dist: pyprep>=0.6.0
24
+ Description-Content-Type: text/markdown
25
+
26
+ # meeg-utils
27
+
28
+ [![CI](https://github.com/colehank/meeg-utils/workflows/CI/badge.svg)](https://github.com/colehank/meeg-utils/actions)
29
+ [![Documentation](https://github.com/colehank/meeg-utils/workflows/Documentation/badge.svg)](https://colehank.github.io/meeg-utils/)
30
+ [![codecov](https://codecov.io/gh/colehank/meeg-utils/branch/main/graph/badge.svg)](https://codecov.io/gh/colehank/meeg-utils)
31
+ [![PyPI version](https://badge.fury.io/py/meeg-utils.svg)](https://badge.fury.io/py/meeg-utils)
32
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
33
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
34
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
35
+
36
+ > A Python-based MEG/EEG processing toolkit built on MNE-Python, providing a high-level, user-friendly API for processing MEG/EEG data.
37
+
38
+ ## Features
39
+ ### Preprocessing
40
+ *Epoching In Progress*
41
+ - High-level `PreprocessingPipeline` class for streamlined MEG/EEG preprocessing.
42
+ ![Pipeline Diagram](resources/preprocessing_pipeline.png)
43
+
44
+ ### Feature Extraction
45
+ *In Progress*
46
+ - Common MEG/EEG features (e.g., power spectral density, connectivity metrics).
47
+
48
+ ## 📦 Installation
49
+
50
+ ```bash
51
+ pip install meeg-utils
52
+ ```
53
+
54
+ ## 🚀 Quick Start
55
+
56
+ ```python
57
+ from meeg_utils.preprocessing import PreprocessingPipeline
58
+ from mne_bids import BIDSPath
59
+
60
+ # Create pipeline
61
+ pipeline = PreprocessingPipeline(
62
+ input_path=BIDSPath(
63
+ subject="01", session="01", task="rest",
64
+ datatype="eeg", root="/data/bids"
65
+ ),
66
+ output_dir="/data/output"
67
+ )
68
+
69
+ # Run preprocessing
70
+ result = pipeline.run(
71
+ filter_params={"highpass": 0.1, "lowpass": 100.0, "sfreq": 250.0},
72
+ detect_bad_channels=True,
73
+ remove_line_noise=True,
74
+ apply_ica=True
75
+ )
76
+
77
+ # Save results
78
+ pipeline.save()
79
+ ```
80
+
81
+ **Batch processing:**
82
+
83
+ ```python
84
+ from meeg_utils.preprocessing import BatchPreprocessingPipeline
85
+
86
+ # Process multiple subjects in parallel
87
+ batch = BatchPreprocessingPipeline(
88
+ input_paths=bids_paths, # List of BIDSPaths
89
+ output_dir="/data/output",
90
+ n_jobs=4 # Use 4 parallel workers
91
+ )
92
+
93
+ batch.run(detect_bad_channels=True, remove_line_noise=True, apply_ica=True)
94
+ ```
95
+
96
+ ## 📚 Documentation
97
+
98
+ **Full documentation:** https://colehank.github.io/meeg-utils/
99
+
100
+ - [Installation Guide](https://colehank.github.io/meeg-utils/user_guide/installation.html)
101
+ - [Quick Start](https://colehank.github.io/meeg-utils/user_guide/quickstart.html)
102
+ - [Preprocessing Guide](https://colehank.github.io/meeg-utils/user_guide/preprocessing.html)
103
+ - [Batch Processing](https://colehank.github.io/meeg-utils/user_guide/batch_processing.html)
104
+ - [API Reference](https://colehank.github.io/meeg-utils/api/preprocessing.html)
105
+ - [Contributing Guide](https://colehank.github.io/meeg-utils/developer/contributing.html)
106
+
107
+ ## 🛠️ Development
108
+
109
+ ```bash
110
+ # Clone and setup
111
+ git clone https://github.com/colehank/meeg-utils.git
112
+ cd meeg-utils
113
+ uv sync --dev
114
+ uv run pre-commit install
115
+
116
+ # Run tests
117
+ uv run pytest
118
+
119
+ # Build docs
120
+ cd docs && uv run make html
121
+ ```
122
+
123
+ See the [Contributing Guide](https://colehank.github.io/meeg-utils/developer/contributing.html) for detailed development instructions.
124
+
125
+ ## 📄 License
126
+
127
+ MIT License - see [LICENSE](LICENSE) file for details.
128
+
129
+ ## 🙏 Acknowledgments
130
+
131
+ Built on the excellent [MNE-Python](https://mne.tools/) ecosystem.
132
+
133
+ ## 📞 Support
134
+
135
+ - 📖 [Documentation](https://colehank.github.io/meeg-utils/)
136
+ - 🐛 [Issue Tracker](https://github.com/colehank/meeg-utils/issues)
137
+ - 💬 [Discussions](https://github.com/colehank/meeg-utils/discussions)