Spaces:
Running
Running
Upload 8934 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +31 -0
- Dockerfile +18 -0
- app.py +45 -0
- mne-python/.DS_Store +0 -0
- mne-python/mcp_output/.DS_Store +0 -0
- mne-python/mcp_output/README_MCP.md +129 -0
- mne-python/mcp_output/analysis.json +199 -0
- mne-python/mcp_output/diff_report.md +161 -0
- mne-python/mcp_output/mcp_plugin/__init__.py +0 -0
- mne-python/mcp_output/mcp_plugin/adapter.py +358 -0
- mne-python/mcp_output/mcp_plugin/main.py +13 -0
- mne-python/mcp_output/mcp_plugin/mcp_service.py +215 -0
- mne-python/mcp_output/requirements.txt +16 -0
- mne-python/mcp_output/start_mcp.py +30 -0
- mne-python/mcp_output/workflow_summary.json +253 -0
- mne-python/source/.DS_Store +0 -0
- mne-python/source/.circleci/config.yml +570 -0
- mne-python/source/.coveragerc +16 -0
- mne-python/source/.mailmap +379 -0
- mne-python/source/.pre-commit-config.yaml +106 -0
- mne-python/source/.yamllint.yml +10 -0
- mne-python/source/CITATION.cff +877 -0
- mne-python/source/CONTRIBUTING.md +9 -0
- mne-python/source/LICENSE.txt +11 -0
- mne-python/source/Makefile +62 -0
- mne-python/source/README.rst +144 -0
- mne-python/source/SECURITY.md +30 -0
- mne-python/source/__init__.py +4 -0
- mne-python/source/azure-pipelines.yml +303 -0
- mne-python/source/codecov.yml +25 -0
- mne-python/source/codemeta.json +2555 -0
- mne-python/source/doc/Makefile +81 -0
- mne-python/source/doc/_includes/bem_model.rst +162 -0
- mne-python/source/doc/_includes/channel_interpolation.rst +70 -0
- mne-python/source/doc/_includes/channel_types.rst +104 -0
- mne-python/source/doc/_includes/data_formats.rst +86 -0
- mne-python/source/doc/_includes/dig_formats.rst +47 -0
- mne-python/source/doc/_includes/forward.rst +726 -0
- mne-python/source/doc/_includes/ged.rst +107 -0
- mne-python/source/doc/_includes/institutional-partners.rst +44 -0
- mne-python/source/doc/_includes/inverse.rst +607 -0
- mne-python/source/doc/_includes/memory.rst +68 -0
- mne-python/source/doc/_includes/morph.rst +123 -0
- mne-python/source/doc/_includes/precision.rst +28 -0
- mne-python/source/doc/_includes/ssp.rst +119 -0
- mne-python/source/doc/_includes/units.rst +36 -0
- mne-python/source/doc/_static/CoordinateSystems.png +0 -0
- mne-python/source/doc/_static/HeadCS.png +0 -0
- mne-python/source/doc/_static/blender_import_obj/blender_import_obj1.jpg +3 -0
- mne-python/source/doc/_static/blender_import_obj/blender_import_obj2.jpg +0 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,34 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
mne-python/source/doc/_static/blender_import_obj/blender_import_obj1.jpg filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
mne-python/source/doc/_static/blender_import_obj/blender_import_obj4.jpg filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
mne-python/source/doc/_static/funding/nsf.png filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
mne-python/source/doc/_static/mne_installer_macOS.png filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
mne-python/source/mne/data/fsaverage/fsaverage-inner_skull-bem.fif filter=lfs diff=lfs merge=lfs -text
|
| 41 |
+
mne-python/source/mne/io/brainvision/tests/data/test_bin_raw.fif filter=lfs diff=lfs merge=lfs -text
|
| 42 |
+
mne-python/source/mne/io/brainvision/tests/data/test.eeg filter=lfs diff=lfs merge=lfs -text
|
| 43 |
+
mne-python/source/mne/io/bti/tests/data/exported4D_linux_raw.fif filter=lfs diff=lfs merge=lfs -text
|
| 44 |
+
mne-python/source/mne/io/bti/tests/data/exported4D_solaris_raw.fif filter=lfs diff=lfs merge=lfs -text
|
| 45 |
+
mne-python/source/mne/io/bti/tests/data/test_config_linux filter=lfs diff=lfs merge=lfs -text
|
| 46 |
+
mne-python/source/mne/io/bti/tests/data/test_config_solaris filter=lfs diff=lfs merge=lfs -text
|
| 47 |
+
mne-python/source/mne/io/bti/tests/data/test_hs_solaris filter=lfs diff=lfs merge=lfs -text
|
| 48 |
+
mne-python/source/mne/io/bti/tests/data/test_pdf_linux filter=lfs diff=lfs merge=lfs -text
|
| 49 |
+
mne-python/source/mne/io/bti/tests/data/test_pdf_solaris filter=lfs diff=lfs merge=lfs -text
|
| 50 |
+
mne-python/source/mne/io/edf/tests/data/test_bdf_eeglab.mat filter=lfs diff=lfs merge=lfs -text
|
| 51 |
+
mne-python/source/mne/io/edf/tests/data/test_edf_eeglab.mat filter=lfs diff=lfs merge=lfs -text
|
| 52 |
+
mne-python/source/mne/io/edf/tests/data/test_eeglab.mat filter=lfs diff=lfs merge=lfs -text
|
| 53 |
+
mne-python/source/mne/io/kit/tests/data/test_bin_raw.fif filter=lfs diff=lfs merge=lfs -text
|
| 54 |
+
mne-python/source/mne/io/kit/tests/data/test_Ykgw.mat filter=lfs diff=lfs merge=lfs -text
|
| 55 |
+
mne-python/source/mne/io/kit/tests/data/test-epoch.raw filter=lfs diff=lfs merge=lfs -text
|
| 56 |
+
mne-python/source/mne/io/kit/tests/data/test.sqd filter=lfs diff=lfs merge=lfs -text
|
| 57 |
+
mne-python/source/mne/io/tests/data/test_chpi_raw_sss.fif filter=lfs diff=lfs merge=lfs -text
|
| 58 |
+
mne-python/source/mne/io/tests/data/test_ctf_comp_raw.fif filter=lfs diff=lfs merge=lfs -text
|
| 59 |
+
mne-python/source/mne/io/tests/data/test_ctf_raw.fif filter=lfs diff=lfs merge=lfs -text
|
| 60 |
+
mne-python/source/mne/io/tests/data/test_erm-cov.fif filter=lfs diff=lfs merge=lfs -text
|
| 61 |
+
mne-python/source/mne/io/tests/data/test_raw.fif filter=lfs diff=lfs merge=lfs -text
|
| 62 |
+
mne-python/source/mne/io/tests/data/test_withbads_raw.fif filter=lfs diff=lfs merge=lfs -text
|
| 63 |
+
mne-python/source/mne/io/tests/data/test-ave.fif filter=lfs diff=lfs merge=lfs -text
|
| 64 |
+
mne-python/source/mne/io/tests/data/test-cov.fif filter=lfs diff=lfs merge=lfs -text
|
| 65 |
+
mne-python/source/mne/io/tests/data/test-km-cov.fif filter=lfs diff=lfs merge=lfs -text
|
| 66 |
+
mne-python/source/mne/io/tests/data/test-nf-ave.fif filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.10
|
| 2 |
+
|
| 3 |
+
RUN useradd -m -u 1000 user && python -m pip install --upgrade pip
|
| 4 |
+
USER user
|
| 5 |
+
ENV PATH="/home/user/.local/bin:$PATH"
|
| 6 |
+
|
| 7 |
+
WORKDIR /app
|
| 8 |
+
|
| 9 |
+
COPY --chown=user ./requirements.txt requirements.txt
|
| 10 |
+
RUN pip install --no-cache-dir --upgrade -r requirements.txt
|
| 11 |
+
|
| 12 |
+
COPY --chown=user . /app
|
| 13 |
+
ENV MCP_TRANSPORT=http
|
| 14 |
+
ENV MCP_PORT=7860
|
| 15 |
+
|
| 16 |
+
EXPOSE 7860
|
| 17 |
+
|
| 18 |
+
CMD ["python", "mne-python/mcp_output/start_mcp.py"]
|
app.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI
|
| 2 |
+
import os
|
| 3 |
+
import sys
|
| 4 |
+
|
| 5 |
+
mcp_plugin_path = os.path.join(os.path.dirname(__file__), "mne-python", "mcp_output", "mcp_plugin")
|
| 6 |
+
sys.path.insert(0, mcp_plugin_path)
|
| 7 |
+
|
| 8 |
+
app = FastAPI(
|
| 9 |
+
title="Mne-Python MCP Service",
|
| 10 |
+
description="Auto-generated MCP service for mne-python",
|
| 11 |
+
version="1.0.0"
|
| 12 |
+
)
|
| 13 |
+
|
| 14 |
+
@app.get("/")
|
| 15 |
+
def root():
|
| 16 |
+
return {
|
| 17 |
+
"service": "Mne-Python MCP Service",
|
| 18 |
+
"version": "1.0.0",
|
| 19 |
+
"status": "running",
|
| 20 |
+
"transport": os.environ.get("MCP_TRANSPORT", "http")
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
@app.get("/health")
|
| 24 |
+
def health_check():
|
| 25 |
+
return {"status": "healthy", "service": "mne-python MCP"}
|
| 26 |
+
|
| 27 |
+
@app.get("/tools")
|
| 28 |
+
def list_tools():
|
| 29 |
+
try:
|
| 30 |
+
from mcp_service import create_app
|
| 31 |
+
mcp_app = create_app()
|
| 32 |
+
tools = []
|
| 33 |
+
for tool_name, tool_func in mcp_app.tools.items():
|
| 34 |
+
tools.append({
|
| 35 |
+
"name": tool_name,
|
| 36 |
+
"description": tool_func.__doc__ or "No description available"
|
| 37 |
+
})
|
| 38 |
+
return {"tools": tools}
|
| 39 |
+
except Exception as e:
|
| 40 |
+
return {"error": f"Failed to load tools: {str(e)}"}
|
| 41 |
+
|
| 42 |
+
if __name__ == "__main__":
|
| 43 |
+
import uvicorn
|
| 44 |
+
port = int(os.environ.get("PORT", 7860))
|
| 45 |
+
uvicorn.run(app, host="0.0.0.0", port=port)
|
mne-python/.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
mne-python/mcp_output/.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
mne-python/mcp_output/README_MCP.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MNE-Python MCP (Model Context Protocol) Service README
|
| 2 |
+
|
| 3 |
+
## 1) Project Introduction
|
| 4 |
+
|
| 5 |
+
This service wraps core **MNE-Python** capabilities for EEG/MEG workflows in an MCP (Model Context Protocol)-friendly interface.
|
| 6 |
+
|
| 7 |
+
Primary goals:
|
| 8 |
+
- Load raw neurophysiology data (FIF, EDF, BDF, BrainVision).
|
| 9 |
+
- Perform event handling and channel picking.
|
| 10 |
+
- Run common preprocessing (EOG/ECG detection, ICA-related preparation).
|
| 11 |
+
- Compute PSD and time-frequency features.
|
| 12 |
+
- Optionally render diagnostic visualizations (when GUI/backends are available).
|
| 13 |
+
|
| 14 |
+
Recommended integration path:
|
| 15 |
+
- **Primary:** in-process Python imports from `mne` modules.
|
| 16 |
+
- **Fallback:** call the `mne` CLI for heavier or isolated execution contexts.
|
| 17 |
+
|
| 18 |
+
---
|
| 19 |
+
|
| 20 |
+
## 2) Installation Method
|
| 21 |
+
|
| 22 |
+
### Requirements
|
| 23 |
+
Core dependencies:
|
| 24 |
+
- `numpy`
|
| 25 |
+
- `scipy`
|
| 26 |
+
- `matplotlib`
|
| 27 |
+
- `packaging`
|
| 28 |
+
- `pooch`
|
| 29 |
+
- `tqdm`
|
| 30 |
+
|
| 31 |
+
Common optional dependencies (feature-dependent):
|
| 32 |
+
- `scikit-learn`, `pandas`, `h5py`, `nibabel`
|
| 33 |
+
- `pyvista`, `vtk`, `mne-qt-browser`
|
| 34 |
+
- `numba`
|
| 35 |
+
|
| 36 |
+
### Install
|
| 37 |
+
- Install MNE-Python and common scientific stack via pip:
|
| 38 |
+
- `pip install mne`
|
| 39 |
+
- For broader functionality:
|
| 40 |
+
- `pip install mne[full]` (if supported by your environment/version)
|
| 41 |
+
- If your service uses project-local dependency files, prefer:
|
| 42 |
+
- `pyproject.toml` / `environment.yml` in your deployment workflow.
|
| 43 |
+
|
| 44 |
+
---
|
| 45 |
+
|
| 46 |
+
## 3) Quick Start
|
| 47 |
+
|
| 48 |
+
### Minimal service flow (Python-side)
|
| 49 |
+
1. Read raw data:
|
| 50 |
+
- `mne.io.read_raw_fif(...)` / `read_raw_edf(...)` / `read_raw_bdf(...)` / `read_raw_brainvision(...)`
|
| 51 |
+
2. Extract events:
|
| 52 |
+
- `mne.find_events(raw)` or `mne.read_events(path)`
|
| 53 |
+
3. Pick channels:
|
| 54 |
+
- `mne.pick_types(raw.info, meg=True, eeg=True, eog=True, exclude="bads")`
|
| 55 |
+
4. Preprocess (optional):
|
| 56 |
+
- `mne.preprocessing.find_eog_events(raw)`, `find_ecg_events(raw)`, ICA workflows
|
| 57 |
+
5. Spectral analysis:
|
| 58 |
+
- `mne.time_frequency.psd_array_welch(...)` or `psd_array_multitaper(...)`
|
| 59 |
+
6. Return structured results from your MCP (Model Context Protocol) service endpoint.
|
| 60 |
+
|
| 61 |
+
### CLI fallback
|
| 62 |
+
- Use `mne` command wrapper when import-time overhead or environment isolation is needed.
|
| 63 |
+
|
| 64 |
+
---
|
| 65 |
+
|
| 66 |
+
## 4) Available Tools and Endpoints List
|
| 67 |
+
|
| 68 |
+
Suggested MCP (Model Context Protocol) service endpoints:
|
| 69 |
+
|
| 70 |
+
- `load_raw`
|
| 71 |
+
- Load raw recordings from FIF/EDF/BDF/BrainVision.
|
| 72 |
+
- Maps to `mne.io.read_raw_*`.
|
| 73 |
+
|
| 74 |
+
- `read_info`
|
| 75 |
+
- Read metadata/header info without full processing.
|
| 76 |
+
- Maps to `mne.io.read_info`.
|
| 77 |
+
|
| 78 |
+
- `events_detect`
|
| 79 |
+
- Detect or load event markers.
|
| 80 |
+
- Maps to `mne.find_events`, `mne.read_events`, `mne.merge_events`.
|
| 81 |
+
|
| 82 |
+
- `channels_pick`
|
| 83 |
+
- Build channel selections by modality/type.
|
| 84 |
+
- Maps to `mne.pick_types`.
|
| 85 |
+
|
| 86 |
+
- `preprocess_eog_ecg`
|
| 87 |
+
- EOG/ECG event detection and projection helpers.
|
| 88 |
+
- Maps to `mne.preprocessing.find_eog_events`, `find_ecg_events`, `compute_proj_eog`, `compute_proj_ecg`.
|
| 89 |
+
|
| 90 |
+
- `ica_workflow`
|
| 91 |
+
- Artifact decomposition/removal pipeline.
|
| 92 |
+
- Maps to `mne.preprocessing.ICA`, `EOGRegression`.
|
| 93 |
+
|
| 94 |
+
- `psd_compute`
|
| 95 |
+
- Power spectral density calculations.
|
| 96 |
+
- Maps to `mne.time_frequency.psd_array_welch`, `psd_array_multitaper`.
|
| 97 |
+
|
| 98 |
+
- `tfr_compute`
|
| 99 |
+
- Time-frequency decomposition.
|
| 100 |
+
- Maps to `tfr_morlet`, `tfr_multitaper`, `csd_multitaper`.
|
| 101 |
+
|
| 102 |
+
- `viz_diagnostics` (optional/headless-sensitive)
|
| 103 |
+
- Event/covariance/alignment diagnostic plotting.
|
| 104 |
+
- Maps to `mne.viz.plot_events`, `plot_cov`, `plot_bem`, `plot_alignment`.
|
| 105 |
+
|
| 106 |
+
- `cli_exec` (fallback)
|
| 107 |
+
- Run `mne` subcommands for isolated or heavyweight tasks.
|
| 108 |
+
|
| 109 |
+
---
|
| 110 |
+
|
| 111 |
+
## 5) Common Issues and Notes
|
| 112 |
+
|
| 113 |
+
- **Complexity:** MNE-Python is feature-rich; keep endpoint contracts narrow and typed.
|
| 114 |
+
- **Import overhead:** First import can be non-trivial; consider lazy-loading per endpoint.
|
| 115 |
+
- **GUI dependencies:** Visualization endpoints may fail in headless servers unless backend is configured.
|
| 116 |
+
- **Optional packages:** Some analyses silently require extras (`sklearn`, `h5py`, `nibabel`, etc.).
|
| 117 |
+
- **Performance:** Large FIF files and TFR/ICA jobs are memory/CPU intensive; set resource limits.
|
| 118 |
+
- **Reproducibility:** Pin MNE + NumPy/SciPy versions in deployment.
|
| 119 |
+
- **Risk profile:** Import feasibility is moderate (~0.72); keep CLI fallback available.
|
| 120 |
+
- **Data handling:** Validate paths, file formats, and channel metadata before heavy processing.
|
| 121 |
+
|
| 122 |
+
---
|
| 123 |
+
|
| 124 |
+
## 6) Reference Links / Documentation
|
| 125 |
+
|
| 126 |
+
- MNE-Python repository: https://github.com/mne-tools/mne-python
|
| 127 |
+
- MNE official docs: https://mne.tools/stable/index.html
|
| 128 |
+
- MNE API reference: https://mne.tools/stable/python_reference.html
|
| 129 |
+
- MNE command-line tools: https://mne.tools/stable/overview/command_line.html
|
mne-python/mcp_output/analysis.json
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"summary": {
|
| 3 |
+
"repository_url": "https://github.com/mne-tools/mne-python",
|
| 4 |
+
"summary": "Unable to preprocess repository: https://github.com/mne-tools/mne-python",
|
| 5 |
+
"file_tree": {},
|
| 6 |
+
"content": {},
|
| 7 |
+
"processed_by": "fallback",
|
| 8 |
+
"success": false,
|
| 9 |
+
"error": "zip download failed: IncompleteRead(4160073 bytes read)"
|
| 10 |
+
},
|
| 11 |
+
"structure": {
|
| 12 |
+
"packages": [
|
| 13 |
+
"deployment.mne-python.source",
|
| 14 |
+
"mcp_output.mcp_plugin",
|
| 15 |
+
"source.mne",
|
| 16 |
+
"source.mne._fiff",
|
| 17 |
+
"source.mne.beamformer",
|
| 18 |
+
"source.mne.channels",
|
| 19 |
+
"source.mne.commands",
|
| 20 |
+
"source.mne.data",
|
| 21 |
+
"source.mne.datasets",
|
| 22 |
+
"source.mne.decoding",
|
| 23 |
+
"source.mne.export",
|
| 24 |
+
"source.mne.forward",
|
| 25 |
+
"source.mne.gui",
|
| 26 |
+
"source.mne.html_templates",
|
| 27 |
+
"source.mne.inverse_sparse",
|
| 28 |
+
"source.mne.io",
|
| 29 |
+
"source.mne.minimum_norm",
|
| 30 |
+
"source.mne.preprocessing",
|
| 31 |
+
"source.mne.report",
|
| 32 |
+
"source.mne.simulation",
|
| 33 |
+
"source.mne.source_space",
|
| 34 |
+
"source.mne.stats",
|
| 35 |
+
"source.mne.tests",
|
| 36 |
+
"source.mne.time_frequency",
|
| 37 |
+
"source.mne.utils",
|
| 38 |
+
"source.mne.viz"
|
| 39 |
+
]
|
| 40 |
+
},
|
| 41 |
+
"dependencies": {
|
| 42 |
+
"has_environment_yml": true,
|
| 43 |
+
"has_requirements_txt": false,
|
| 44 |
+
"pyproject": true,
|
| 45 |
+
"setup_cfg": false,
|
| 46 |
+
"setup_py": false
|
| 47 |
+
},
|
| 48 |
+
"entry_points": {
|
| 49 |
+
"imports": [],
|
| 50 |
+
"cli": [],
|
| 51 |
+
"modules": []
|
| 52 |
+
},
|
| 53 |
+
"llm_analysis": {
|
| 54 |
+
"core_modules": [
|
| 55 |
+
{
|
| 56 |
+
"package": "source.mne",
|
| 57 |
+
"module": "source.mne",
|
| 58 |
+
"functions": [
|
| 59 |
+
"create_info",
|
| 60 |
+
"set_log_level",
|
| 61 |
+
"read_events",
|
| 62 |
+
"pick_types",
|
| 63 |
+
"find_events",
|
| 64 |
+
"merge_events",
|
| 65 |
+
"concatenate_raws"
|
| 66 |
+
],
|
| 67 |
+
"classes": [
|
| 68 |
+
"Info",
|
| 69 |
+
"Covariance",
|
| 70 |
+
"Epochs",
|
| 71 |
+
"Evoked",
|
| 72 |
+
"Annotations"
|
| 73 |
+
],
|
| 74 |
+
"description": "Top-level API surface for core EEG/MEG data structures and common preprocessing/event utilities; safest primary integration point for MCP tooling."
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"package": "source.mne.io",
|
| 78 |
+
"module": "source.mne.io",
|
| 79 |
+
"functions": [
|
| 80 |
+
"read_raw_fif",
|
| 81 |
+
"read_raw_edf",
|
| 82 |
+
"read_raw_bdf",
|
| 83 |
+
"read_raw_brainvision",
|
| 84 |
+
"read_info"
|
| 85 |
+
],
|
| 86 |
+
"classes": [
|
| 87 |
+
"Raw",
|
| 88 |
+
"RawArray"
|
| 89 |
+
],
|
| 90 |
+
"description": "Input/output layer for loading raw recordings from major formats and constructing in-memory raw objects."
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"package": "source.mne.preprocessing",
|
| 94 |
+
"module": "source.mne.preprocessing",
|
| 95 |
+
"functions": [
|
| 96 |
+
"compute_proj_ecg",
|
| 97 |
+
"compute_proj_eog",
|
| 98 |
+
"find_eog_events",
|
| 99 |
+
"find_ecg_events",
|
| 100 |
+
"create_eog_epochs"
|
| 101 |
+
],
|
| 102 |
+
"classes": [
|
| 103 |
+
"ICA",
|
| 104 |
+
"EOGRegression"
|
| 105 |
+
],
|
| 106 |
+
"description": "Artifact detection/removal workflows (ICA/projections/regression), useful for preprocessing-oriented MCP commands."
|
| 107 |
+
},
|
| 108 |
+
{
|
| 109 |
+
"package": "source.mne.time_frequency",
|
| 110 |
+
"module": "source.mne.time_frequency",
|
| 111 |
+
"functions": [
|
| 112 |
+
"psd_array_welch",
|
| 113 |
+
"psd_array_multitaper",
|
| 114 |
+
"tfr_morlet",
|
| 115 |
+
"tfr_multitaper",
|
| 116 |
+
"csd_multitaper"
|
| 117 |
+
],
|
| 118 |
+
"classes": [
|
| 119 |
+
"AverageTFR",
|
| 120 |
+
"EpochsTFR"
|
| 121 |
+
],
|
| 122 |
+
"description": "Frequency-domain and time-frequency analysis APIs commonly needed for downstream analytics plugins."
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"package": "source.mne.viz",
|
| 126 |
+
"module": "source.mne.viz",
|
| 127 |
+
"functions": [
|
| 128 |
+
"plot_events",
|
| 129 |
+
"plot_cov",
|
| 130 |
+
"plot_bem",
|
| 131 |
+
"plot_alignment"
|
| 132 |
+
],
|
| 133 |
+
"classes": [],
|
| 134 |
+
"description": "Visualization endpoints; useful but generally optional in headless MCP execution."
|
| 135 |
+
},
|
| 136 |
+
{
|
| 137 |
+
"package": "source.mne.commands",
|
| 138 |
+
"module": "source.mne.commands",
|
| 139 |
+
"functions": [],
|
| 140 |
+
"classes": [],
|
| 141 |
+
"description": "CLI command package; preferred fallback execution boundary when direct in-process imports are too heavy."
|
| 142 |
+
}
|
| 143 |
+
],
|
| 144 |
+
"cli_commands": [
|
| 145 |
+
{
|
| 146 |
+
"name": "mne",
|
| 147 |
+
"module": "source.mne.commands",
|
| 148 |
+
"description": "Primary MNE command-line entry wrapper (subcommand-based tooling for data handling, preprocessing, and project utilities)."
|
| 149 |
+
}
|
| 150 |
+
],
|
| 151 |
+
"import_strategy": {
|
| 152 |
+
"primary": "import",
|
| 153 |
+
"fallback": "cli",
|
| 154 |
+
"confidence": 0.7
|
| 155 |
+
},
|
| 156 |
+
"dependencies": {
|
| 157 |
+
"required": [
|
| 158 |
+
"numpy",
|
| 159 |
+
"scipy",
|
| 160 |
+
"matplotlib",
|
| 161 |
+
"packaging",
|
| 162 |
+
"pooch",
|
| 163 |
+
"tqdm"
|
| 164 |
+
],
|
| 165 |
+
"optional": [
|
| 166 |
+
"sklearn",
|
| 167 |
+
"pandas",
|
| 168 |
+
"h5py",
|
| 169 |
+
"nibabel",
|
| 170 |
+
"pyvista",
|
| 171 |
+
"vtk",
|
| 172 |
+
"mne-qt-browser",
|
| 173 |
+
"numba"
|
| 174 |
+
]
|
| 175 |
+
},
|
| 176 |
+
"risk_assessment": {
|
| 177 |
+
"import_feasibility": 0.72,
|
| 178 |
+
"intrusiveness_risk": "medium",
|
| 179 |
+
"complexity": "complex"
|
| 180 |
+
}
|
| 181 |
+
},
|
| 182 |
+
"deepwiki_analysis": {
|
| 183 |
+
"repo_url": "https://github.com/mne-tools/mne-python",
|
| 184 |
+
"repo_name": "mne-python",
|
| 185 |
+
"error": "DeepWiki analysis failed",
|
| 186 |
+
"model": "gpt-5.3-codex",
|
| 187 |
+
"source": "llm_direct_analysis",
|
| 188 |
+
"success": false
|
| 189 |
+
},
|
| 190 |
+
"deepwiki_options": {
|
| 191 |
+
"enabled": true,
|
| 192 |
+
"model": "gpt-5.3-codex"
|
| 193 |
+
},
|
| 194 |
+
"risk": {
|
| 195 |
+
"import_feasibility": 0.72,
|
| 196 |
+
"intrusiveness_risk": "medium",
|
| 197 |
+
"complexity": "complex"
|
| 198 |
+
}
|
| 199 |
+
}
|
mne-python/mcp_output/diff_report.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Difference Report — **mne-python**
|
| 2 |
+
|
| 3 |
+
**Generated:** 2026-03-14 12:25:49
|
| 4 |
+
**Repository:** `mne-python`
|
| 5 |
+
**Project Type:** Python library
|
| 6 |
+
**Scope / Main Features:** Basic functionality
|
| 7 |
+
**Change Intrusiveness:** None
|
| 8 |
+
**Workflow Status:** ✅ Success
|
| 9 |
+
**Test Status:** ❌ Failed
|
| 10 |
+
**Files Changed:** 8 new, 0 modified
|
| 11 |
+
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
## 1) Project Overview
|
| 15 |
+
|
| 16 |
+
This update introduces **8 new files** to the `mne-python` codebase without modifying existing files.
|
| 17 |
+
Given the “Basic functionality” scope and “None” intrusiveness, the change appears additive and low-risk at the integration layer. However, the **failed test status** indicates unresolved quality or environment issues that block confidence in release readiness.
|
| 18 |
+
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
## 2) Change Summary
|
| 22 |
+
|
| 23 |
+
| Metric | Value |
|
| 24 |
+
|---|---:|
|
| 25 |
+
| New files | 8 |
|
| 26 |
+
| Modified files | 0 |
|
| 27 |
+
| Deleted files | 0 (not reported) |
|
| 28 |
+
| Intrusiveness | None |
|
| 29 |
+
| CI workflow | Success |
|
| 30 |
+
| Test result | Failed |
|
| 31 |
+
|
| 32 |
+
### High-level interpretation
|
| 33 |
+
- **Additive-only change set** (no direct regressions from edits to existing files expected).
|
| 34 |
+
- **Pipeline orchestration passed**, suggesting jobs ran correctly.
|
| 35 |
+
- **Test execution failed**, indicating either:
|
| 36 |
+
- new functionality is incomplete/incorrect,
|
| 37 |
+
- tests are outdated or misconfigured,
|
| 38 |
+
- dependency/version/environment mismatch.
|
| 39 |
+
|
| 40 |
+
---
|
| 41 |
+
|
| 42 |
+
## 3) Difference Analysis
|
| 43 |
+
|
| 44 |
+
Because only aggregate metadata is provided (no file paths or patch hunks), analysis is structural:
|
| 45 |
+
|
| 46 |
+
1. **No legacy code edits**
|
| 47 |
+
- Existing APIs likely unchanged directly.
|
| 48 |
+
- Backward compatibility risk is lower than in refactor/edit-heavy updates.
|
| 49 |
+
|
| 50 |
+
2. **New surface area introduced**
|
| 51 |
+
- 8 files likely include one or more of:
|
| 52 |
+
- implementation modules,
|
| 53 |
+
- tests,
|
| 54 |
+
- docs/examples,
|
| 55 |
+
- configuration helpers.
|
| 56 |
+
- Any newly introduced module still affects packaging/import graph and CI.
|
| 57 |
+
|
| 58 |
+
3. **Quality gate mismatch**
|
| 59 |
+
- CI workflow success + tests failed implies workflow did not enforce test pass as a hard gate, or failures occurred in a non-blocking stage.
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
## 4) Technical Analysis
|
| 64 |
+
|
| 65 |
+
## 4.1 Risk Assessment
|
| 66 |
+
|
| 67 |
+
| Area | Risk | Rationale |
|
| 68 |
+
|---|---|---|
|
| 69 |
+
| API stability | Low–Medium | No modified files, but new public modules may expose new API surface. |
|
| 70 |
+
| Runtime behavior | Medium | New files can alter import side effects, plugin discovery, or optional paths. |
|
| 71 |
+
| Test reliability | High | Failed tests directly reduce confidence in correctness. |
|
| 72 |
+
| Release readiness | High risk (not ready) | Test suite failing is a release blocker for scientific Python libs. |
|
| 73 |
+
|
| 74 |
+
## 4.2 Likely Failure Categories (to triage first)
|
| 75 |
+
|
| 76 |
+
- **Unit test expectation mismatch** for newly added behavior.
|
| 77 |
+
- **Missing optional dependencies** in CI test matrix.
|
| 78 |
+
- **Numerical tolerance/precision drift** (common in scientific stacks).
|
| 79 |
+
- **Platform-specific failures** (Linux/macOS/Windows differences).
|
| 80 |
+
- **Import/package registration issues** (new files not wired into package init or config).
|
| 81 |
+
- **Style/type/linters treated as tests** if test stage aggregates tooling checks.
|
| 82 |
+
|
| 83 |
+
## 4.3 Validation Gaps
|
| 84 |
+
|
| 85 |
+
- No file-level diff context available.
|
| 86 |
+
- No failing test names/tracebacks included.
|
| 87 |
+
- Cannot confirm whether failures are deterministic or flaky.
|
| 88 |
+
|
| 89 |
+
---
|
| 90 |
+
|
| 91 |
+
## 5) Recommendations & Improvements
|
| 92 |
+
|
| 93 |
+
## 5.1 Immediate (Blocker Resolution)
|
| 94 |
+
|
| 95 |
+
1. **Collect failure artifacts**
|
| 96 |
+
- Extract failing test IDs, stack traces, and environment metadata (Python, NumPy/SciPy, OS).
|
| 97 |
+
2. **Classify failures**
|
| 98 |
+
- New-code defects vs. test harness/config issues.
|
| 99 |
+
3. **Re-run targeted tests locally and in CI**
|
| 100 |
+
- Isolate minimal reproducer; verify determinism.
|
| 101 |
+
4. **Enforce hard gate**
|
| 102 |
+
- Ensure release/protected branch requires test success.
|
| 103 |
+
|
| 104 |
+
## 5.2 Short-term Quality Hardening
|
| 105 |
+
|
| 106 |
+
- Add/adjust tests for each new file’s intended behavior.
|
| 107 |
+
- If numeric algorithms were added, pin tolerances and seed randomness.
|
| 108 |
+
- Validate packaging exposure (`__init__`, entry points, module discovery).
|
| 109 |
+
- Run matrix smoke tests across supported Python versions.
|
| 110 |
+
|
| 111 |
+
## 5.3 Process Improvements
|
| 112 |
+
|
| 113 |
+
- Introduce a **change manifest** in PRs: purpose of each new file + expected impact.
|
| 114 |
+
- Add CI stage separation:
|
| 115 |
+
- lint/type/doc checks,
|
| 116 |
+
- unit/integration tests,
|
| 117 |
+
- optional slow tests.
|
| 118 |
+
- Track flaky tests and quarantine with explicit issue links.
|
| 119 |
+
|
| 120 |
+
---
|
| 121 |
+
|
| 122 |
+
## 6) Deployment Information
|
| 123 |
+
|
| 124 |
+
## 6.1 Current Deployment Readiness
|
| 125 |
+
|
| 126 |
+
**Status: Not recommended for deployment** due to failed tests.
|
| 127 |
+
|
| 128 |
+
## 6.2 Suggested Release Criteria
|
| 129 |
+
|
| 130 |
+
Deploy only after all conditions are met:
|
| 131 |
+
|
| 132 |
+
- ✅ All required tests pass on supported matrix.
|
| 133 |
+
- ✅ No critical/new warnings in CI logs.
|
| 134 |
+
- ✅ Documentation/changelog entries for new files.
|
| 135 |
+
- ✅ Versioning decision made (likely patch/minor based on new functionality exposure).
|
| 136 |
+
|
| 137 |
+
## 6.3 Rollout Strategy (once green)
|
| 138 |
+
|
| 139 |
+
- Use staged rollout (internal validation → broader user release).
|
| 140 |
+
- Monitor error reports/import issues post-release.
|
| 141 |
+
- Prepare rapid rollback/hotfix path.
|
| 142 |
+
|
| 143 |
+
---
|
| 144 |
+
|
| 145 |
+
## 7) Future Planning
|
| 146 |
+
|
| 147 |
+
1. **Improve observability in CI**
|
| 148 |
+
- Publish structured test reports and failure clustering.
|
| 149 |
+
2. **Strengthen compatibility guarantees**
|
| 150 |
+
- Add contract tests for public APIs.
|
| 151 |
+
3. **Automate regression prevention**
|
| 152 |
+
- Pre-merge required checks + nightly full-matrix runs.
|
| 153 |
+
4. **Documentation alignment**
|
| 154 |
+
- Ensure examples/tutorials reference new functionality where relevant.
|
| 155 |
+
|
| 156 |
+
---
|
| 157 |
+
|
| 158 |
+
## 8) Executive Conclusion
|
| 159 |
+
|
| 160 |
+
This change set is structurally low-intrusive (**8 new files, no modifications**), but **test failures are a hard release blocker**.
|
| 161 |
+
Primary priority is failure triage and stabilization. Once tests are green and packaging/API exposure is validated, the update should be safe to proceed through normal release gates.
|
mne-python/mcp_output/mcp_plugin/__init__.py
ADDED
|
File without changes
|
mne-python/mcp_output/mcp_plugin/adapter.py
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
import importlib
|
| 4 |
+
import traceback
|
| 5 |
+
from typing import Any, Dict, List, Optional
|
| 6 |
+
|
| 7 |
+
source_path = os.path.join(
|
| 8 |
+
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
|
| 9 |
+
"source",
|
| 10 |
+
)
|
| 11 |
+
sys.path.insert(0, source_path)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class Adapter:
|
| 15 |
+
"""
|
| 16 |
+
Import-mode adapter for the mne-python MCP plugin integration.
|
| 17 |
+
|
| 18 |
+
This adapter prioritizes Python imports and provides a graceful CLI fallback
|
| 19 |
+
pathway when import-based execution is unavailable.
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
# -------------------------------------------------------------------------
|
| 23 |
+
# Lifecycle / Initialization
|
| 24 |
+
# -------------------------------------------------------------------------
|
| 25 |
+
def __init__(self) -> None:
|
| 26 |
+
"""
|
| 27 |
+
Initialize adapter state, import registry, and module availability.
|
| 28 |
+
|
| 29 |
+
Attributes:
|
| 30 |
+
mode: Adapter execution mode, fixed to "import".
|
| 31 |
+
package_root: Root import path for repository package.
|
| 32 |
+
modules: Loaded module cache keyed by logical name.
|
| 33 |
+
available: Boolean import readiness state.
|
| 34 |
+
warnings: List of non-fatal issues detected during initialization.
|
| 35 |
+
"""
|
| 36 |
+
self.mode = "import"
|
| 37 |
+
self.package_root = "mne"
|
| 38 |
+
self.modules: Dict[str, Any] = {}
|
| 39 |
+
self.available = False
|
| 40 |
+
self.warnings: List[str] = []
|
| 41 |
+
self._initialize_imports()
|
| 42 |
+
|
| 43 |
+
def _initialize_imports(self) -> None:
|
| 44 |
+
"""
|
| 45 |
+
Attempt to import core and command modules identified by analysis.
|
| 46 |
+
|
| 47 |
+
This method captures and stores import exceptions so the adapter can
|
| 48 |
+
continue operating in graceful fallback mode.
|
| 49 |
+
"""
|
| 50 |
+
targets = {
|
| 51 |
+
"mne": "mne",
|
| 52 |
+
"commands": "mne.commands",
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
loaded = 0
|
| 56 |
+
for key, mod_path in targets.items():
|
| 57 |
+
try:
|
| 58 |
+
self.modules[key] = importlib.import_module(mod_path)
|
| 59 |
+
loaded += 1
|
| 60 |
+
except Exception as exc:
|
| 61 |
+
self.modules[key] = None
|
| 62 |
+
self.warnings.append(
|
| 63 |
+
f"Failed to import '{mod_path}'. Verify local source checkout and dependencies. Detail: {exc}"
|
| 64 |
+
)
|
| 65 |
+
self.available = loaded > 0
|
| 66 |
+
|
| 67 |
+
# -------------------------------------------------------------------------
|
| 68 |
+
# Unified response helpers
|
| 69 |
+
# -------------------------------------------------------------------------
|
| 70 |
+
def _ok(self, message: str, data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
| 71 |
+
return {"status": "success", "message": message, "data": data or {}}
|
| 72 |
+
|
| 73 |
+
def _fail(
|
| 74 |
+
self,
|
| 75 |
+
message: str,
|
| 76 |
+
error: Optional[str] = None,
|
| 77 |
+
guidance: Optional[str] = None,
|
| 78 |
+
data: Optional[Dict[str, Any]] = None,
|
| 79 |
+
) -> Dict[str, Any]:
|
| 80 |
+
payload = {"status": "error", "message": message, "data": data or {}}
|
| 81 |
+
if error:
|
| 82 |
+
payload["error"] = error
|
| 83 |
+
if guidance:
|
| 84 |
+
payload["guidance"] = guidance
|
| 85 |
+
return payload
|
| 86 |
+
|
| 87 |
+
def _fallback(
|
| 88 |
+
self,
|
| 89 |
+
action: str,
|
| 90 |
+
reason: str,
|
| 91 |
+
extra: Optional[Dict[str, Any]] = None,
|
| 92 |
+
) -> Dict[str, Any]:
|
| 93 |
+
return {
|
| 94 |
+
"status": "fallback",
|
| 95 |
+
"message": f"Import mode unavailable for '{action}'.",
|
| 96 |
+
"reason": reason,
|
| 97 |
+
"guidance": (
|
| 98 |
+
"Ensure repository source is present under the configured 'source' directory and "
|
| 99 |
+
"install required dependencies (numpy, scipy, matplotlib, packaging, pooch, tqdm). "
|
| 100 |
+
"If import still fails, use the CLI fallback via the 'mne' command."
|
| 101 |
+
),
|
| 102 |
+
"data": extra or {},
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
# -------------------------------------------------------------------------
|
| 106 |
+
# Health / Introspection
|
| 107 |
+
# -------------------------------------------------------------------------
|
| 108 |
+
def health_check(self) -> Dict[str, Any]:
|
| 109 |
+
"""
|
| 110 |
+
Report adapter readiness and import diagnostics.
|
| 111 |
+
|
| 112 |
+
Returns:
|
| 113 |
+
Dict with status, mode, import availability, and warning details.
|
| 114 |
+
"""
|
| 115 |
+
return self._ok(
|
| 116 |
+
"Adapter health check completed.",
|
| 117 |
+
{
|
| 118 |
+
"mode": self.mode,
|
| 119 |
+
"available": self.available,
|
| 120 |
+
"loaded_modules": {k: bool(v) for k, v in self.modules.items()},
|
| 121 |
+
"warnings": self.warnings,
|
| 122 |
+
},
|
| 123 |
+
)
|
| 124 |
+
|
| 125 |
+
def list_known_packages(self) -> Dict[str, Any]:
|
| 126 |
+
"""
|
| 127 |
+
Return package namespaces discovered during analysis.
|
| 128 |
+
|
| 129 |
+
Returns:
|
| 130 |
+
Dict containing analyzed package names for discovery/debugging.
|
| 131 |
+
"""
|
| 132 |
+
packages = [
|
| 133 |
+
"deployment.mne-python.source",
|
| 134 |
+
"mcp_output.mcp_plugin",
|
| 135 |
+
"source.mne",
|
| 136 |
+
"source.mne._fiff",
|
| 137 |
+
"source.mne.beamformer",
|
| 138 |
+
"source.mne.channels",
|
| 139 |
+
"source.mne.commands",
|
| 140 |
+
"source.mne.data",
|
| 141 |
+
"source.mne.datasets",
|
| 142 |
+
"source.mne.decoding",
|
| 143 |
+
"source.mne.export",
|
| 144 |
+
"source.mne.forward",
|
| 145 |
+
"source.mne.gui",
|
| 146 |
+
"source.mne.html_templates",
|
| 147 |
+
"source.mne.inverse_sparse",
|
| 148 |
+
"source.mne.io",
|
| 149 |
+
"source.mne.minimum_norm",
|
| 150 |
+
"source.mne.preprocessing",
|
| 151 |
+
"source.mne.report",
|
| 152 |
+
"source.mne.simulation",
|
| 153 |
+
"source.mne.source_space",
|
| 154 |
+
"source.mne.stats",
|
| 155 |
+
"source.mne.tests",
|
| 156 |
+
"source.mne.time_frequency",
|
| 157 |
+
"source.mne.utils",
|
| 158 |
+
"source.mne.viz",
|
| 159 |
+
]
|
| 160 |
+
return self._ok("Known package list prepared.", {"packages": packages})
|
| 161 |
+
|
| 162 |
+
# -------------------------------------------------------------------------
|
| 163 |
+
# Module management
|
| 164 |
+
# -------------------------------------------------------------------------
|
| 165 |
+
def import_module(self, module_path: str) -> Dict[str, Any]:
|
| 166 |
+
"""
|
| 167 |
+
Dynamically import an MNE module using full package path.
|
| 168 |
+
|
| 169 |
+
Args:
|
| 170 |
+
module_path: Absolute module path (e.g., 'mne.io', 'mne.preprocessing').
|
| 171 |
+
|
| 172 |
+
Returns:
|
| 173 |
+
Unified status dictionary with module import result.
|
| 174 |
+
"""
|
| 175 |
+
try:
|
| 176 |
+
mod = importlib.import_module(module_path)
|
| 177 |
+
self.modules[module_path] = mod
|
| 178 |
+
return self._ok("Module imported successfully.", {"module_path": module_path})
|
| 179 |
+
except Exception as exc:
|
| 180 |
+
return self._fail(
|
| 181 |
+
"Module import failed.",
|
| 182 |
+
error=str(exc),
|
| 183 |
+
guidance="Confirm module path and dependency installation.",
|
| 184 |
+
data={"module_path": module_path},
|
| 185 |
+
)
|
| 186 |
+
|
| 187 |
+
def get_module_attributes(self, module_path: str, limit: int = 200) -> Dict[str, Any]:
|
| 188 |
+
"""
|
| 189 |
+
Enumerate public attributes for a module to support function discovery.
|
| 190 |
+
|
| 191 |
+
Args:
|
| 192 |
+
module_path: Full module path.
|
| 193 |
+
limit: Maximum number of attributes to return.
|
| 194 |
+
|
| 195 |
+
Returns:
|
| 196 |
+
Unified status dictionary containing exported attribute names.
|
| 197 |
+
"""
|
| 198 |
+
try:
|
| 199 |
+
mod = self.modules.get(module_path) or importlib.import_module(module_path)
|
| 200 |
+
attrs = [a for a in dir(mod) if not a.startswith("_")]
|
| 201 |
+
return self._ok(
|
| 202 |
+
"Module attributes fetched.",
|
| 203 |
+
{"module_path": module_path, "attributes": attrs[: max(1, limit)]},
|
| 204 |
+
)
|
| 205 |
+
except Exception as exc:
|
| 206 |
+
return self._fail(
|
| 207 |
+
"Could not inspect module attributes.",
|
| 208 |
+
error=str(exc),
|
| 209 |
+
guidance="Import the module first and verify it is available in local source.",
|
| 210 |
+
data={"module_path": module_path},
|
| 211 |
+
)
|
| 212 |
+
|
| 213 |
+
# -------------------------------------------------------------------------
|
| 214 |
+
# Core MNE call surface
|
| 215 |
+
# -------------------------------------------------------------------------
|
| 216 |
+
def call_mne_function(self, function_name: str, *args: Any, **kwargs: Any) -> Dict[str, Any]:
|
| 217 |
+
"""
|
| 218 |
+
Call a function from the top-level mne module by name.
|
| 219 |
+
|
| 220 |
+
Args:
|
| 221 |
+
function_name: Name of the function in module 'mne'.
|
| 222 |
+
*args: Positional arguments forwarded to the target function.
|
| 223 |
+
**kwargs: Keyword arguments forwarded to the target function.
|
| 224 |
+
|
| 225 |
+
Returns:
|
| 226 |
+
Unified status dictionary with execution result or actionable failure.
|
| 227 |
+
"""
|
| 228 |
+
if not self.modules.get("mne"):
|
| 229 |
+
return self._fallback("call_mne_function", "Top-level module 'mne' is not importable.")
|
| 230 |
+
|
| 231 |
+
try:
|
| 232 |
+
target = getattr(self.modules["mne"], function_name, None)
|
| 233 |
+
if target is None or not callable(target):
|
| 234 |
+
return self._fail(
|
| 235 |
+
"Requested MNE function was not found.",
|
| 236 |
+
guidance="Use get_module_attributes('mne') to discover available callables.",
|
| 237 |
+
data={"function_name": function_name},
|
| 238 |
+
)
|
| 239 |
+
result = target(*args, **kwargs)
|
| 240 |
+
return self._ok(
|
| 241 |
+
"MNE function executed successfully.",
|
| 242 |
+
{"function_name": function_name, "result": result},
|
| 243 |
+
)
|
| 244 |
+
except Exception as exc:
|
| 245 |
+
return self._fail(
|
| 246 |
+
"MNE function execution failed.",
|
| 247 |
+
error=str(exc),
|
| 248 |
+
guidance="Validate function arguments and data formats expected by MNE.",
|
| 249 |
+
data={"function_name": function_name, "traceback": traceback.format_exc()},
|
| 250 |
+
)
|
| 251 |
+
|
| 252 |
+
# -------------------------------------------------------------------------
|
| 253 |
+
# CLI wrapper (fallback-friendly)
|
| 254 |
+
# -------------------------------------------------------------------------
|
| 255 |
+
def call_mne_cli(self, argv: Optional[List[str]] = None) -> Dict[str, Any]:
|
| 256 |
+
"""
|
| 257 |
+
Execute the primary MNE command-line wrapper from imported command module.
|
| 258 |
+
|
| 259 |
+
Args:
|
| 260 |
+
argv: Optional list of CLI-like arguments. If omitted, attempts default call.
|
| 261 |
+
|
| 262 |
+
Returns:
|
| 263 |
+
Unified status dictionary with invocation status and hints.
|
| 264 |
+
"""
|
| 265 |
+
commands_mod = self.modules.get("commands")
|
| 266 |
+
if not commands_mod:
|
| 267 |
+
return self._fallback("call_mne_cli", "Module 'mne.commands' is not importable.")
|
| 268 |
+
|
| 269 |
+
try:
|
| 270 |
+
entry_candidates = ["main", "run", "command_main"]
|
| 271 |
+
entry = None
|
| 272 |
+
for name in entry_candidates:
|
| 273 |
+
fn = getattr(commands_mod, name, None)
|
| 274 |
+
if callable(fn):
|
| 275 |
+
entry = fn
|
| 276 |
+
break
|
| 277 |
+
|
| 278 |
+
if entry is None:
|
| 279 |
+
return self._fail(
|
| 280 |
+
"No callable CLI entry point found in mne.commands.",
|
| 281 |
+
guidance="Inspect mne.commands module attributes and map the correct callable.",
|
| 282 |
+
data={"checked_candidates": entry_candidates},
|
| 283 |
+
)
|
| 284 |
+
|
| 285 |
+
if argv is None:
|
| 286 |
+
out = entry()
|
| 287 |
+
else:
|
| 288 |
+
out = entry(argv)
|
| 289 |
+
|
| 290 |
+
return self._ok(
|
| 291 |
+
"MNE CLI wrapper executed.",
|
| 292 |
+
{"argv": argv or [], "result": out, "entry_point": entry.__name__},
|
| 293 |
+
)
|
| 294 |
+
except TypeError:
|
| 295 |
+
try:
|
| 296 |
+
out = entry() # type: ignore[misc]
|
| 297 |
+
return self._ok(
|
| 298 |
+
"MNE CLI wrapper executed with default signature.",
|
| 299 |
+
{"argv": argv or [], "result": out, "entry_point": entry.__name__}, # type: ignore[union-attr]
|
| 300 |
+
)
|
| 301 |
+
except Exception as exc:
|
| 302 |
+
return self._fail(
|
| 303 |
+
"MNE CLI invocation failed.",
|
| 304 |
+
error=str(exc),
|
| 305 |
+
guidance="Pass valid subcommands/arguments or verify command module compatibility.",
|
| 306 |
+
data={"traceback": traceback.format_exc()},
|
| 307 |
+
)
|
| 308 |
+
except Exception as exc:
|
| 309 |
+
return self._fail(
|
| 310 |
+
"MNE CLI invocation failed.",
|
| 311 |
+
error=str(exc),
|
| 312 |
+
guidance="Check installed optional dependencies and command arguments.",
|
| 313 |
+
data={"traceback": traceback.format_exc()},
|
| 314 |
+
)
|
| 315 |
+
|
| 316 |
+
# -------------------------------------------------------------------------
|
| 317 |
+
# Class instantiation helper (generic, analysis-driven)
|
| 318 |
+
# -------------------------------------------------------------------------
|
| 319 |
+
def create_instance(
|
| 320 |
+
self,
|
| 321 |
+
module_path: str,
|
| 322 |
+
class_name: str,
|
| 323 |
+
*args: Any,
|
| 324 |
+
**kwargs: Any,
|
| 325 |
+
) -> Dict[str, Any]:
|
| 326 |
+
"""
|
| 327 |
+
Instantiate a class from a target module path.
|
| 328 |
+
|
| 329 |
+
Args:
|
| 330 |
+
module_path: Full module path containing the class.
|
| 331 |
+
class_name: Class name to instantiate.
|
| 332 |
+
*args: Positional constructor arguments.
|
| 333 |
+
**kwargs: Keyword constructor arguments.
|
| 334 |
+
|
| 335 |
+
Returns:
|
| 336 |
+
Unified status dictionary with instantiated object handle.
|
| 337 |
+
"""
|
| 338 |
+
try:
|
| 339 |
+
mod = self.modules.get(module_path) or importlib.import_module(module_path)
|
| 340 |
+
cls = getattr(mod, class_name, None)
|
| 341 |
+
if cls is None:
|
| 342 |
+
return self._fail(
|
| 343 |
+
"Class not found in module.",
|
| 344 |
+
guidance="Use get_module_attributes(module_path) to verify class exports.",
|
| 345 |
+
data={"module_path": module_path, "class_name": class_name},
|
| 346 |
+
)
|
| 347 |
+
instance = cls(*args, **kwargs)
|
| 348 |
+
return self._ok(
|
| 349 |
+
"Class instantiated successfully.",
|
| 350 |
+
{"module_path": module_path, "class_name": class_name, "instance": instance},
|
| 351 |
+
)
|
| 352 |
+
except Exception as exc:
|
| 353 |
+
return self._fail(
|
| 354 |
+
"Class instantiation failed.",
|
| 355 |
+
error=str(exc),
|
| 356 |
+
guidance="Verify constructor arguments and required dependencies for this class.",
|
| 357 |
+
data={"module_path": module_path, "class_name": class_name, "traceback": traceback.format_exc()},
|
| 358 |
+
)
|
mne-python/mcp_output/mcp_plugin/main.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
MCP Service Auto-Wrapper - Auto-generated
|
| 3 |
+
"""
|
| 4 |
+
from mcp_service import create_app
|
| 5 |
+
|
| 6 |
+
def main():
|
| 7 |
+
"""Main entry point"""
|
| 8 |
+
app = create_app()
|
| 9 |
+
return app
|
| 10 |
+
|
| 11 |
+
if __name__ == "__main__":
|
| 12 |
+
app = main()
|
| 13 |
+
app.run()
|
mne-python/mcp_output/mcp_plugin/mcp_service.py
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
from typing import Optional, Dict, Any, List
|
| 4 |
+
|
| 5 |
+
source_path = os.path.join(
|
| 6 |
+
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
|
| 7 |
+
"source",
|
| 8 |
+
)
|
| 9 |
+
if source_path not in sys.path:
|
| 10 |
+
sys.path.insert(0, source_path)
|
| 11 |
+
|
| 12 |
+
from fastmcp import FastMCP
|
| 13 |
+
|
| 14 |
+
mcp = FastMCP("mne_python_service")
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def _safe_import_mne():
|
| 18 |
+
try:
|
| 19 |
+
import mne # type: ignore
|
| 20 |
+
return True, mne, None
|
| 21 |
+
except Exception as exc:
|
| 22 |
+
return False, None, str(exc)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
@mcp.tool(name="mne_get_version", description="Get installed MNE version information.")
|
| 26 |
+
def mne_get_version() -> Dict[str, Any]:
|
| 27 |
+
"""
|
| 28 |
+
Return MNE package version.
|
| 29 |
+
|
| 30 |
+
Returns:
|
| 31 |
+
Dict with:
|
| 32 |
+
- success: bool indicating operation status
|
| 33 |
+
- result: version string when successful
|
| 34 |
+
- error: error string when failed
|
| 35 |
+
"""
|
| 36 |
+
ok, mne_mod, err = _safe_import_mne()
|
| 37 |
+
if not ok:
|
| 38 |
+
return {"success": False, "result": None, "error": err}
|
| 39 |
+
try:
|
| 40 |
+
version = getattr(mne_mod, "__version__", "unknown")
|
| 41 |
+
return {"success": True, "result": version, "error": None}
|
| 42 |
+
except Exception as exc:
|
| 43 |
+
return {"success": False, "result": None, "error": str(exc)}
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
@mcp.tool(name="mne_get_config", description="Read MNE configuration value by key.")
|
| 47 |
+
def mne_get_config(key: str, default: Optional[str] = None) -> Dict[str, Any]:
|
| 48 |
+
"""
|
| 49 |
+
Read a single MNE config key.
|
| 50 |
+
|
| 51 |
+
Parameters:
|
| 52 |
+
key: Configuration key to lookup.
|
| 53 |
+
default: Optional fallback if key is not found.
|
| 54 |
+
|
| 55 |
+
Returns:
|
| 56 |
+
Dict with:
|
| 57 |
+
- success: bool
|
| 58 |
+
- result: config value
|
| 59 |
+
- error: error message when failed
|
| 60 |
+
"""
|
| 61 |
+
ok, mne_mod, err = _safe_import_mne()
|
| 62 |
+
if not ok:
|
| 63 |
+
return {"success": False, "result": None, "error": err}
|
| 64 |
+
try:
|
| 65 |
+
value = mne_mod.get_config(key=key, default=default)
|
| 66 |
+
return {"success": True, "result": value, "error": None}
|
| 67 |
+
except Exception as exc:
|
| 68 |
+
return {"success": False, "result": None, "error": str(exc)}
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
@mcp.tool(name="mne_set_config", description="Set an MNE configuration key to a value.")
|
| 72 |
+
def mne_set_config(key: str, value: str, set_env: bool = False) -> Dict[str, Any]:
|
| 73 |
+
"""
|
| 74 |
+
Set a single MNE config key.
|
| 75 |
+
|
| 76 |
+
Parameters:
|
| 77 |
+
key: Configuration key.
|
| 78 |
+
value: Configuration value.
|
| 79 |
+
set_env: If True, also set environment variable for current process.
|
| 80 |
+
|
| 81 |
+
Returns:
|
| 82 |
+
Dict with:
|
| 83 |
+
- success: bool
|
| 84 |
+
- result: True when set successfully
|
| 85 |
+
- error: error message when failed
|
| 86 |
+
"""
|
| 87 |
+
ok, mne_mod, err = _safe_import_mne()
|
| 88 |
+
if not ok:
|
| 89 |
+
return {"success": False, "result": None, "error": err}
|
| 90 |
+
try:
|
| 91 |
+
mne_mod.set_config(key=key, value=value, set_env=set_env)
|
| 92 |
+
return {"success": True, "result": True, "error": None}
|
| 93 |
+
except Exception as exc:
|
| 94 |
+
return {"success": False, "result": None, "error": str(exc)}
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
@mcp.tool(name="mne_create_info", description="Create an MNE Info object from channels and sampling frequency.")
|
| 98 |
+
def mne_create_info(ch_names: List[str], sfreq: float, ch_types: Optional[List[str]] = None) -> Dict[str, Any]:
|
| 99 |
+
"""
|
| 100 |
+
Create a lightweight channel metadata structure.
|
| 101 |
+
|
| 102 |
+
Parameters:
|
| 103 |
+
ch_names: List of channel names.
|
| 104 |
+
sfreq: Sampling frequency in Hz.
|
| 105 |
+
ch_types: Optional list of channel types aligned with ch_names.
|
| 106 |
+
|
| 107 |
+
Returns:
|
| 108 |
+
Dict with:
|
| 109 |
+
- success: bool
|
| 110 |
+
- result: serializable summary of created Info
|
| 111 |
+
- error: error message when failed
|
| 112 |
+
"""
|
| 113 |
+
ok, mne_mod, err = _safe_import_mne()
|
| 114 |
+
if not ok:
|
| 115 |
+
return {"success": False, "result": None, "error": err}
|
| 116 |
+
try:
|
| 117 |
+
info = mne_mod.create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types)
|
| 118 |
+
result = {
|
| 119 |
+
"nchan": int(info["nchan"]),
|
| 120 |
+
"sfreq": float(info["sfreq"]),
|
| 121 |
+
"ch_names": list(info["ch_names"]),
|
| 122 |
+
"highpass": float(info.get("highpass", 0.0) or 0.0),
|
| 123 |
+
"lowpass": float(info.get("lowpass", 0.0) or 0.0),
|
| 124 |
+
}
|
| 125 |
+
return {"success": True, "result": result, "error": None}
|
| 126 |
+
except Exception as exc:
|
| 127 |
+
return {"success": False, "result": None, "error": str(exc)}
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
@mcp.tool(name="mne_compute_events", description="Detect events from a stim channel in a raw FIF file.")
|
| 131 |
+
def mne_compute_events(
|
| 132 |
+
raw_fif_path: str,
|
| 133 |
+
stim_channel: Optional[str] = None,
|
| 134 |
+
shortest_event: int = 1,
|
| 135 |
+
min_duration: float = 0.0,
|
| 136 |
+
) -> Dict[str, Any]:
|
| 137 |
+
"""
|
| 138 |
+
Load raw FIF and compute events from stimulation channel.
|
| 139 |
+
|
| 140 |
+
Parameters:
|
| 141 |
+
raw_fif_path: Path to a readable raw FIF file.
|
| 142 |
+
stim_channel: Optional stim channel name. If None, MNE default detection is used.
|
| 143 |
+
shortest_event: Minimum number of samples for an event.
|
| 144 |
+
min_duration: Minimum event duration in seconds.
|
| 145 |
+
|
| 146 |
+
Returns:
|
| 147 |
+
Dict with:
|
| 148 |
+
- success: bool
|
| 149 |
+
- result: event count and preview rows
|
| 150 |
+
- error: error message when failed
|
| 151 |
+
"""
|
| 152 |
+
ok, mne_mod, err = _safe_import_mne()
|
| 153 |
+
if not ok:
|
| 154 |
+
return {"success": False, "result": None, "error": err}
|
| 155 |
+
try:
|
| 156 |
+
raw = mne_mod.io.read_raw_fif(raw_fif_path, preload=False, verbose=False)
|
| 157 |
+
events = mne_mod.find_events(
|
| 158 |
+
raw,
|
| 159 |
+
stim_channel=stim_channel,
|
| 160 |
+
shortest_event=shortest_event,
|
| 161 |
+
min_duration=min_duration,
|
| 162 |
+
verbose=False,
|
| 163 |
+
)
|
| 164 |
+
preview = events[:20].tolist() if len(events) > 0 else []
|
| 165 |
+
return {
|
| 166 |
+
"success": True,
|
| 167 |
+
"result": {"count": int(len(events)), "preview": preview},
|
| 168 |
+
"error": None,
|
| 169 |
+
}
|
| 170 |
+
except Exception as exc:
|
| 171 |
+
return {"success": False, "result": None, "error": str(exc)}
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
@mcp.tool(name="mne_estimate_rank", description="Estimate data rank from an epochs or raw FIF file.")
|
| 175 |
+
def mne_estimate_rank(fif_path: str, tol: Optional[float] = None) -> Dict[str, Any]:
|
| 176 |
+
"""
|
| 177 |
+
Estimate numerical rank from MNE data object loaded from FIF.
|
| 178 |
+
|
| 179 |
+
Parameters:
|
| 180 |
+
fif_path: Path to raw or epochs FIF file.
|
| 181 |
+
tol: Optional tolerance passed to rank estimator.
|
| 182 |
+
|
| 183 |
+
Returns:
|
| 184 |
+
Dict with:
|
| 185 |
+
- success: bool
|
| 186 |
+
- result: estimated rank dictionary or scalar
|
| 187 |
+
- error: error message when failed
|
| 188 |
+
"""
|
| 189 |
+
ok, mne_mod, err = _safe_import_mne()
|
| 190 |
+
if not ok:
|
| 191 |
+
return {"success": False, "result": None, "error": err}
|
| 192 |
+
try:
|
| 193 |
+
result_obj: Any
|
| 194 |
+
try:
|
| 195 |
+
raw = mne_mod.io.read_raw_fif(fif_path, preload=False, verbose=False)
|
| 196 |
+
result_obj = mne_mod.compute_rank(raw, tol=tol, verbose=False)
|
| 197 |
+
except Exception:
|
| 198 |
+
epochs = mne_mod.read_epochs(fif_path, preload=False, verbose=False)
|
| 199 |
+
result_obj = mne_mod.compute_rank(epochs, tol=tol, verbose=False)
|
| 200 |
+
|
| 201 |
+
if isinstance(result_obj, dict):
|
| 202 |
+
serializable = {str(k): int(v) for k, v in result_obj.items()}
|
| 203 |
+
else:
|
| 204 |
+
serializable = int(result_obj)
|
| 205 |
+
return {"success": True, "result": serializable, "error": None}
|
| 206 |
+
except Exception as exc:
|
| 207 |
+
return {"success": False, "result": None, "error": str(exc)}
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
def create_app() -> FastMCP:
|
| 211 |
+
return mcp
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
if __name__ == "__main__":
|
| 215 |
+
mcp.run()
|
mne-python/mcp_output/requirements.txt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
fastmcp
|
| 2 |
+
fastapi
|
| 3 |
+
uvicorn[standard]
|
| 4 |
+
pydantic>=2.0.0
|
| 5 |
+
decorator >= 5.1
|
| 6 |
+
jinja2 >= 3.1
|
| 7 |
+
lazy_loader >= 0.3
|
| 8 |
+
matplotlib >= 3.8
|
| 9 |
+
numpy >= 1.26, < 3
|
| 10 |
+
packaging
|
| 11 |
+
pooch >= 1.5
|
| 12 |
+
scipy >= 1.12
|
| 13 |
+
tqdm >= 4.66
|
| 14 |
+
nest-asyncio2
|
| 15 |
+
pymef
|
| 16 |
+
pyobjc-framework-Cocoa >=5.2.0;platform_system=='Darwin'
|
mne-python/mcp_output/start_mcp.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
"""
|
| 3 |
+
MCP Service Startup Entry
|
| 4 |
+
"""
|
| 5 |
+
import sys
|
| 6 |
+
import os
|
| 7 |
+
|
| 8 |
+
project_root = os.path.dirname(os.path.abspath(__file__))
|
| 9 |
+
mcp_plugin_dir = os.path.join(project_root, "mcp_plugin")
|
| 10 |
+
if mcp_plugin_dir not in sys.path:
|
| 11 |
+
sys.path.insert(0, mcp_plugin_dir)
|
| 12 |
+
|
| 13 |
+
from mcp_service import create_app
|
| 14 |
+
|
| 15 |
+
def main():
|
| 16 |
+
"""Start FastMCP service"""
|
| 17 |
+
app = create_app()
|
| 18 |
+
# Use environment variable to configure port, default 8000
|
| 19 |
+
port = int(os.environ.get("MCP_PORT", "8000"))
|
| 20 |
+
|
| 21 |
+
# Choose transport mode based on environment variable
|
| 22 |
+
transport = os.environ.get("MCP_TRANSPORT", "stdio")
|
| 23 |
+
if transport == "http":
|
| 24 |
+
app.run(transport="http", host="0.0.0.0", port=port)
|
| 25 |
+
else:
|
| 26 |
+
# Default to STDIO mode
|
| 27 |
+
app.run()
|
| 28 |
+
|
| 29 |
+
if __name__ == "__main__":
|
| 30 |
+
main()
|
mne-python/mcp_output/workflow_summary.json
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"repository": {
|
| 3 |
+
"name": "mne-python",
|
| 4 |
+
"url": "https://github.com/mne-tools/mne-python",
|
| 5 |
+
"local_path": "/Users/ghh/Documents/Code/Code2MCP-private/workspace/mne-python",
|
| 6 |
+
"description": "Python library",
|
| 7 |
+
"features": "Basic functionality",
|
| 8 |
+
"tech_stack": "Python",
|
| 9 |
+
"stars": 0,
|
| 10 |
+
"forks": 0,
|
| 11 |
+
"language": "Python",
|
| 12 |
+
"last_updated": "",
|
| 13 |
+
"complexity": "complex",
|
| 14 |
+
"intrusiveness_risk": "medium"
|
| 15 |
+
},
|
| 16 |
+
"execution": {
|
| 17 |
+
"start_time": 1773461253.309027,
|
| 18 |
+
"end_time": 1773462216.903234,
|
| 19 |
+
"duration": 963.5942070484161,
|
| 20 |
+
"status": "success",
|
| 21 |
+
"workflow_status": "success",
|
| 22 |
+
"nodes_executed": [
|
| 23 |
+
"download",
|
| 24 |
+
"analysis",
|
| 25 |
+
"env",
|
| 26 |
+
"generate",
|
| 27 |
+
"run",
|
| 28 |
+
"review",
|
| 29 |
+
"finalize"
|
| 30 |
+
],
|
| 31 |
+
"total_files_processed": 26,
|
| 32 |
+
"environment_type": "unknown",
|
| 33 |
+
"llm_calls": 0,
|
| 34 |
+
"deepwiki_calls": 0
|
| 35 |
+
},
|
| 36 |
+
"tests": {
|
| 37 |
+
"original_project": {
|
| 38 |
+
"passed": false,
|
| 39 |
+
"details": {},
|
| 40 |
+
"test_coverage": "100%",
|
| 41 |
+
"execution_time": 0,
|
| 42 |
+
"test_files": []
|
| 43 |
+
},
|
| 44 |
+
"mcp_plugin": {
|
| 45 |
+
"passed": true,
|
| 46 |
+
"details": {},
|
| 47 |
+
"service_health": "healthy",
|
| 48 |
+
"startup_time": 0,
|
| 49 |
+
"transport_mode": "stdio",
|
| 50 |
+
"fastmcp_version": "unknown",
|
| 51 |
+
"mcp_version": "unknown"
|
| 52 |
+
}
|
| 53 |
+
},
|
| 54 |
+
"analysis": {
|
| 55 |
+
"structure": {
|
| 56 |
+
"packages": [
|
| 57 |
+
"deployment.mne-python.source",
|
| 58 |
+
"mcp_output.mcp_plugin",
|
| 59 |
+
"source.mne",
|
| 60 |
+
"source.mne._fiff",
|
| 61 |
+
"source.mne.beamformer",
|
| 62 |
+
"source.mne.channels",
|
| 63 |
+
"source.mne.commands",
|
| 64 |
+
"source.mne.data",
|
| 65 |
+
"source.mne.datasets",
|
| 66 |
+
"source.mne.decoding",
|
| 67 |
+
"source.mne.export",
|
| 68 |
+
"source.mne.forward",
|
| 69 |
+
"source.mne.gui",
|
| 70 |
+
"source.mne.html_templates",
|
| 71 |
+
"source.mne.inverse_sparse",
|
| 72 |
+
"source.mne.io",
|
| 73 |
+
"source.mne.minimum_norm",
|
| 74 |
+
"source.mne.preprocessing",
|
| 75 |
+
"source.mne.report",
|
| 76 |
+
"source.mne.simulation",
|
| 77 |
+
"source.mne.source_space",
|
| 78 |
+
"source.mne.stats",
|
| 79 |
+
"source.mne.tests",
|
| 80 |
+
"source.mne.time_frequency",
|
| 81 |
+
"source.mne.utils",
|
| 82 |
+
"source.mne.viz"
|
| 83 |
+
]
|
| 84 |
+
},
|
| 85 |
+
"dependencies": {
|
| 86 |
+
"has_environment_yml": true,
|
| 87 |
+
"has_requirements_txt": false,
|
| 88 |
+
"pyproject": true,
|
| 89 |
+
"setup_cfg": false,
|
| 90 |
+
"setup_py": false
|
| 91 |
+
},
|
| 92 |
+
"entry_points": {
|
| 93 |
+
"imports": [],
|
| 94 |
+
"cli": [],
|
| 95 |
+
"modules": []
|
| 96 |
+
},
|
| 97 |
+
"risk_assessment": {
|
| 98 |
+
"import_feasibility": 0.72,
|
| 99 |
+
"intrusiveness_risk": "medium",
|
| 100 |
+
"complexity": "complex"
|
| 101 |
+
},
|
| 102 |
+
"deepwiki_analysis": {
|
| 103 |
+
"repo_url": "https://github.com/mne-tools/mne-python",
|
| 104 |
+
"repo_name": "mne-python",
|
| 105 |
+
"error": "DeepWiki analysis failed",
|
| 106 |
+
"model": "gpt-5.3-codex",
|
| 107 |
+
"source": "llm_direct_analysis",
|
| 108 |
+
"success": false
|
| 109 |
+
},
|
| 110 |
+
"code_complexity": {
|
| 111 |
+
"cyclomatic_complexity": "medium",
|
| 112 |
+
"cognitive_complexity": "medium",
|
| 113 |
+
"maintainability_index": 75
|
| 114 |
+
},
|
| 115 |
+
"security_analysis": {
|
| 116 |
+
"vulnerabilities_found": 0,
|
| 117 |
+
"security_score": 85,
|
| 118 |
+
"recommendations": []
|
| 119 |
+
}
|
| 120 |
+
},
|
| 121 |
+
"plugin_generation": {
|
| 122 |
+
"files_created": [
|
| 123 |
+
"mcp_output/start_mcp.py",
|
| 124 |
+
"mcp_output/mcp_plugin/__init__.py",
|
| 125 |
+
"mcp_output/mcp_plugin/mcp_service.py",
|
| 126 |
+
"mcp_output/mcp_plugin/adapter.py",
|
| 127 |
+
"mcp_output/mcp_plugin/main.py",
|
| 128 |
+
"mcp_output/requirements.txt",
|
| 129 |
+
"mcp_output/README_MCP.md"
|
| 130 |
+
],
|
| 131 |
+
"main_entry": "start_mcp.py",
|
| 132 |
+
"requirements": [
|
| 133 |
+
"fastmcp>=0.1.0",
|
| 134 |
+
"pydantic>=2.0.0"
|
| 135 |
+
],
|
| 136 |
+
"readme_path": "/Users/ghh/Documents/Code/Code2MCP-private/workspace/mne-python/mcp_output/README_MCP.md",
|
| 137 |
+
"adapter_mode": "import",
|
| 138 |
+
"total_lines_of_code": 0,
|
| 139 |
+
"generated_files_size": 0,
|
| 140 |
+
"tool_endpoints": 0,
|
| 141 |
+
"supported_features": [
|
| 142 |
+
"Basic functionality"
|
| 143 |
+
],
|
| 144 |
+
"generated_tools": [
|
| 145 |
+
"Basic tools",
|
| 146 |
+
"Health check tools",
|
| 147 |
+
"Version info tools"
|
| 148 |
+
]
|
| 149 |
+
},
|
| 150 |
+
"code_review": {},
|
| 151 |
+
"errors": [],
|
| 152 |
+
"warnings": [],
|
| 153 |
+
"recommendations": [
|
| 154 |
+
"Harden repository ingestion with retry/resume and fallback to shallow git clone when zip download fails",
|
| 155 |
+
"Add a preflight dependency checker that validates required/optional MNE extras and reports actionable install commands",
|
| 156 |
+
"Implement lazy imports and per-endpoint module loading to reduce startup cost and import-side failures",
|
| 157 |
+
"Add a CLI fallback execution path for heavy/fragile endpoints (especially viz and large IO) when import mode errors",
|
| 158 |
+
"Introduce endpoint-level health checks/smoke tests using small synthetic MNE objects (RawArray/Epochs) to validate MCP bindings",
|
| 159 |
+
"Expand automated tests in `tests_mcp` for argument validation",
|
| 160 |
+
"error mapping",
|
| 161 |
+
"and serialization of core classes",
|
| 162 |
+
"Add structured error taxonomy (DependencyMissing",
|
| 163 |
+
"FileFormatUnsupported",
|
| 164 |
+
"RuntimeImportError",
|
| 165 |
+
"HeadlessVizError) with user-friendly remediation hints",
|
| 166 |
+
"Gate visualization endpoints behind headless-safe checks (matplotlib backend/PyVista availability) and return clear non-GUI alternatives",
|
| 167 |
+
"Improve README_MCP with concrete examples for common workflows (load raw",
|
| 168 |
+
"find events",
|
| 169 |
+
"ICA",
|
| 170 |
+
"PSD) and expected input/output schemas",
|
| 171 |
+
"Add version pinning/compatibility matrix for `mne`",
|
| 172 |
+
"`numpy`",
|
| 173 |
+
"`scipy`",
|
| 174 |
+
"and `pydantic` to prevent runtime drift",
|
| 175 |
+
"Generate JSON Schemas for each endpoint and enforce strict Pydantic models for stable MCP contracts",
|
| 176 |
+
"Add timeout/cancellation controls and memory guards for long-running transforms (TFR/ICA/CSD)",
|
| 177 |
+
"Implement lightweight caching for repeated file reads and computed intermediates (with invalidation by file hash)",
|
| 178 |
+
"Add observability: structured logs",
|
| 179 |
+
"per-endpoint latency/error metrics",
|
| 180 |
+
"and import-failure counters",
|
| 181 |
+
"Create a minimal “safe default” endpoint set (non-viz",
|
| 182 |
+
"low-memory) and mark advanced endpoints as optional capability flags",
|
| 183 |
+
"Add integration tests for representative file formats (FIF/EDF/BDF/BrainVision) with tiny fixtures",
|
| 184 |
+
"Validate and normalize path handling across OSes (spaces",
|
| 185 |
+
"unicode",
|
| 186 |
+
"relative paths) before IO calls",
|
| 187 |
+
"Add graceful degradation when optional packages are missing (e.g.",
|
| 188 |
+
"skip vtk/pyvista features instead of failing server start)",
|
| 189 |
+
"Include a reproducible dev environment (`environment.yml`/lockfile) for MCP plugin CI",
|
| 190 |
+
"Add CI workflow to run lint/type-check/tests for `mcp_output` and publish test report artifacts"
|
| 191 |
+
],
|
| 192 |
+
"performance_metrics": {
|
| 193 |
+
"memory_usage_mb": 0,
|
| 194 |
+
"cpu_usage_percent": 0,
|
| 195 |
+
"response_time_ms": 0,
|
| 196 |
+
"throughput_requests_per_second": 0
|
| 197 |
+
},
|
| 198 |
+
"deployment_info": {
|
| 199 |
+
"supported_platforms": [
|
| 200 |
+
"Linux",
|
| 201 |
+
"Windows",
|
| 202 |
+
"macOS"
|
| 203 |
+
],
|
| 204 |
+
"python_versions": [
|
| 205 |
+
"3.8",
|
| 206 |
+
"3.9",
|
| 207 |
+
"3.10",
|
| 208 |
+
"3.11",
|
| 209 |
+
"3.12"
|
| 210 |
+
],
|
| 211 |
+
"deployment_methods": [
|
| 212 |
+
"Docker",
|
| 213 |
+
"pip",
|
| 214 |
+
"conda"
|
| 215 |
+
],
|
| 216 |
+
"monitoring_support": true,
|
| 217 |
+
"logging_configuration": "structured"
|
| 218 |
+
},
|
| 219 |
+
"execution_analysis": {
|
| 220 |
+
"success_factors": [
|
| 221 |
+
"Workflow reached terminal success state with all planned nodes executed (download, analysis, env, generate, run, review, finalize)",
|
| 222 |
+
"MCP plugin runtime test passed with healthy service status over stdio transport",
|
| 223 |
+
"Import-based adapter strategy aligned with detected MNE API surface and produced broad endpoint coverage",
|
| 224 |
+
"No runtime errors or warnings were recorded during orchestration"
|
| 225 |
+
],
|
| 226 |
+
"failure_reasons": [
|
| 227 |
+
"Repository preprocessing partially failed due to zip download IncompleteRead, reducing analysis fidelity",
|
| 228 |
+
"DeepWiki analysis failed, so architecture/context enrichment depended on fallback LLM direct analysis",
|
| 229 |
+
"Original project test status is failed/unknown despite reported 100% coverage metadata, indicating unreliable baseline validation",
|
| 230 |
+
"Generated artifact metrics are inconsistent (tool_endpoints=0 vs populated endpoint list; total_lines_of_code=0), suggesting reporting/telemetry defects"
|
| 231 |
+
],
|
| 232 |
+
"overall_assessment": "good",
|
| 233 |
+
"node_performance": {
|
| 234 |
+
"download_time": "Download node completed but experienced non-fatal zip transfer instability (IncompleteRead). This is the primary execution fragility.",
|
| 235 |
+
"analysis_time": "Analysis completed via fallback path; quality adequate for generation but lower confidence than full repository preprocessing + DeepWiki.",
|
| 236 |
+
"generation_time": "Generation completed successfully with required files and entrypoint created; endpoint exposure is broad and useful.",
|
| 237 |
+
"test_time": "Service-level test passed quickly (startup_time reported 0), but original-project validation is not trustworthy; test depth appears shallow."
|
| 238 |
+
},
|
| 239 |
+
"resource_usage": {
|
| 240 |
+
"memory_efficiency": "Undetermined from metrics (reported 0 MB). Likely acceptable for scaffold generation, but runtime memory for heavy MNE ops remains unmeasured.",
|
| 241 |
+
"cpu_efficiency": "Undetermined from metrics (reported 0%). End-to-end duration (~964s) indicates non-trivial processing overhead and potential I/O/network wait.",
|
| 242 |
+
"disk_usage": "Generated output footprint appears underreported (0 size), indicating instrumentation gaps rather than true zero disk impact."
|
| 243 |
+
}
|
| 244 |
+
},
|
| 245 |
+
"technical_quality": {
|
| 246 |
+
"code_quality_score": 74,
|
| 247 |
+
"architecture_score": 78,
|
| 248 |
+
"performance_score": 62,
|
| 249 |
+
"maintainability_score": 76,
|
| 250 |
+
"security_score": 85,
|
| 251 |
+
"scalability_score": 68
|
| 252 |
+
}
|
| 253 |
+
}
|
mne-python/source/.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
mne-python/source/.circleci/config.yml
ADDED
|
@@ -0,0 +1,570 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# By default, for PRs CircleCI will build only examples that have changed.
|
| 2 |
+
# For main commits, builds are skipped entirely, as we only do full builds
|
| 3 |
+
# scheduled for one time daily.
|
| 4 |
+
#
|
| 5 |
+
# Tagging a commit with the following overrides these behaviors:
|
| 6 |
+
# - [circle front] will run the front page examples and perform test-doc
|
| 7 |
+
# - [circle full] will run all examples and perform test-doc
|
| 8 |
+
# - [circle linkcheck] will run our linkcheck job
|
| 9 |
+
# - [circle deploy] on a main or maint/* commit will try to immediately build
|
| 10 |
+
# and deploy docs rather than waiting for the nightly build
|
| 11 |
+
|
| 12 |
+
version: 2.1
|
| 13 |
+
|
| 14 |
+
_check_skip: &check_skip
|
| 15 |
+
name: Check-skip
|
| 16 |
+
command: |
|
| 17 |
+
set -e
|
| 18 |
+
export COMMIT_MESSAGE=$(git log --format=oneline -n 1);
|
| 19 |
+
if [[ "$CIRCLE_PULL_REQUEST" != "" ]] && ([[ "$COMMIT_MESSAGE" == *"[skip circle]"* ]] || [[ "$COMMIT_MESSAGE" == *"[circle skip]"* ]]); then
|
| 20 |
+
echo "Skip detected, exiting job ${CIRCLE_JOB} for PR ${CIRCLE_PULL_REQUEST}."
|
| 21 |
+
circleci-agent step halt;
|
| 22 |
+
fi
|
| 23 |
+
|
| 24 |
+
jobs:
|
| 25 |
+
build_docs:
|
| 26 |
+
parameters:
|
| 27 |
+
scheduled:
|
| 28 |
+
type: string
|
| 29 |
+
default: "false"
|
| 30 |
+
machine:
|
| 31 |
+
image: ubuntu-2404:current
|
| 32 |
+
# large 4 vCPUs 15GB mem
|
| 33 |
+
# https://discuss.circleci.com/t/changes-to-remote-docker-reporting-pricing/47759
|
| 34 |
+
resource_class: large
|
| 35 |
+
steps:
|
| 36 |
+
- restore_cache:
|
| 37 |
+
keys:
|
| 38 |
+
- source-cache
|
| 39 |
+
- checkout:
|
| 40 |
+
method: full
|
| 41 |
+
- run:
|
| 42 |
+
name: Complete checkout
|
| 43 |
+
command: |
|
| 44 |
+
set -e
|
| 45 |
+
if ! git remote -v | grep upstream; then
|
| 46 |
+
git remote add upstream https://github.com/mne-tools/mne-python.git
|
| 47 |
+
fi
|
| 48 |
+
git remote set-url upstream https://github.com/mne-tools/mne-python.git
|
| 49 |
+
git fetch upstream
|
| 50 |
+
- save_cache:
|
| 51 |
+
key: source-cache
|
| 52 |
+
paths:
|
| 53 |
+
- ".git"
|
| 54 |
+
- run:
|
| 55 |
+
<<: *check_skip
|
| 56 |
+
- run:
|
| 57 |
+
name: Merge with upstream and triage run
|
| 58 |
+
command: |
|
| 59 |
+
set -e
|
| 60 |
+
echo $(git log -1 --pretty=%B) | tee gitlog.txt
|
| 61 |
+
echo ${CI_PULL_REQUEST//*pull\//} | tee merge.txt
|
| 62 |
+
if [[ $(cat merge.txt) != "" ]]; then
|
| 63 |
+
echo "Merging $(cat merge.txt)";
|
| 64 |
+
git pull --ff-only upstream "refs/pull/$(cat merge.txt)/merge";
|
| 65 |
+
else
|
| 66 |
+
if [[ "$CIRCLE_BRANCH" == "main" ]]; then
|
| 67 |
+
KIND=dev
|
| 68 |
+
else
|
| 69 |
+
KIND=stable
|
| 70 |
+
fi
|
| 71 |
+
export COMMIT_MESSAGE=$(git log --format=oneline -n 1);
|
| 72 |
+
if [[ "<< parameters.scheduled >>" == "true" ]]; then
|
| 73 |
+
echo "Scheduled full build detected, checking if it's required."
|
| 74 |
+
wget https://mne.tools/${KIND}/_version.txt;
|
| 75 |
+
REMOTE_VERSION=$(cat _version.txt)
|
| 76 |
+
THIS_VERSION=$(git rev-parse HEAD)
|
| 77 |
+
echo "Current ${KIND} SHA: ${REMOTE_VERSION}"
|
| 78 |
+
echo "This ${KIND} SHA: ${THIS_VERSION}"
|
| 79 |
+
if [[ "${THIS_VERSION}" != "${REMOTE_VERSION}" ]]; then
|
| 80 |
+
echo "Rebuild required."
|
| 81 |
+
else
|
| 82 |
+
echo "Rebuild skipped."
|
| 83 |
+
circleci-agent step halt;
|
| 84 |
+
fi
|
| 85 |
+
elif [[ "$COMMIT_MESSAGE" == *"[circle deploy]"* ]]; then
|
| 86 |
+
echo "Forced deployed build detected, building and deploying docs";
|
| 87 |
+
else
|
| 88 |
+
echo "Waiting until scheduled run to build ${KIND} docs, exiting job ${CIRCLE_JOB}."
|
| 89 |
+
circleci-agent step halt;
|
| 90 |
+
fi
|
| 91 |
+
fi
|
| 92 |
+
|
| 93 |
+
- run:
|
| 94 |
+
name: Set BASH_ENV
|
| 95 |
+
command: ./tools/circleci_bash_env.sh
|
| 96 |
+
|
| 97 |
+
- run:
|
| 98 |
+
name: Install fonts needed for diagrams
|
| 99 |
+
command: |
|
| 100 |
+
mkdir -p $HOME/.fonts
|
| 101 |
+
echo "Source Code Pro"
|
| 102 |
+
curl https://codeload.github.com/adobe-fonts/source-code-pro/tar.gz/2.038R-ro/1.058R-it/1.018R-VAR | tar xz -C $HOME/.fonts
|
| 103 |
+
echo "Source Sans Pro"
|
| 104 |
+
curl https://codeload.github.com/adobe-fonts/source-sans/tar.gz/3.028R | tar xz -C $HOME/.fonts
|
| 105 |
+
fc-cache -f
|
| 106 |
+
|
| 107 |
+
# Load pip cache
|
| 108 |
+
- restore_cache:
|
| 109 |
+
keys:
|
| 110 |
+
- pip-cache-0
|
| 111 |
+
- restore_cache:
|
| 112 |
+
keys:
|
| 113 |
+
- user-install-bin-cache-310
|
| 114 |
+
|
| 115 |
+
# Hack in uninstalls of libraries as necessary if pip doesn't do the right thing in upgrading for us...
|
| 116 |
+
- run:
|
| 117 |
+
name: Get Python running
|
| 118 |
+
command: |
|
| 119 |
+
./tools/circleci_dependencies.sh
|
| 120 |
+
|
| 121 |
+
- save_cache:
|
| 122 |
+
key: pip-cache-0
|
| 123 |
+
paths:
|
| 124 |
+
- ~/.cache/pip
|
| 125 |
+
- save_cache:
|
| 126 |
+
key: user-install-bin-cache-310
|
| 127 |
+
paths:
|
| 128 |
+
- ~/.local/lib/python3.10/site-packages
|
| 129 |
+
- ~/.local/bin
|
| 130 |
+
|
| 131 |
+
- run:
|
| 132 |
+
name: Check Qt
|
| 133 |
+
command: |
|
| 134 |
+
./tools/check_qt_import.sh PyQt6
|
| 135 |
+
# Load tiny cache so that ~/.mne does not need to be created below
|
| 136 |
+
- restore_cache:
|
| 137 |
+
keys:
|
| 138 |
+
- data-cache-tiny-0
|
| 139 |
+
|
| 140 |
+
# Look at what we have and fail early if there is some library conflict
|
| 141 |
+
- run:
|
| 142 |
+
name: Check installation
|
| 143 |
+
command: |
|
| 144 |
+
which python
|
| 145 |
+
QT_DEBUG_PLUGINS=1 mne sys_info -pd
|
| 146 |
+
python -c "import numpy; numpy.show_config()"
|
| 147 |
+
python -c "import dipy.align.metrics"
|
| 148 |
+
LIBGL_DEBUG=verbose python -c "import pyvistaqt; pyvistaqt.BackgroundPlotter(show=True)"
|
| 149 |
+
python -c "import mne; mne.set_config('MNE_USE_CUDA', 'false')" # this is needed for the config tutorial
|
| 150 |
+
python -c "import mne; mne.set_config('MNE_LOGGING_LEVEL', 'info')"
|
| 151 |
+
python -c "import mne; level = mne.get_config('MNE_LOGGING_LEVEL'); assert level.lower() == 'info', repr(level)"
|
| 152 |
+
- run:
|
| 153 |
+
name: List packages
|
| 154 |
+
command: python -m pip list
|
| 155 |
+
|
| 156 |
+
# Figure out if we should run a full build or specify a pattern
|
| 157 |
+
- restore_cache:
|
| 158 |
+
keys:
|
| 159 |
+
- data-cache-tiny-1
|
| 160 |
+
- restore_cache:
|
| 161 |
+
keys:
|
| 162 |
+
- data-cache-multimodal
|
| 163 |
+
- restore_cache:
|
| 164 |
+
keys:
|
| 165 |
+
- data-cache-limo
|
| 166 |
+
- restore_cache:
|
| 167 |
+
keys:
|
| 168 |
+
- data-cache-fsaverage
|
| 169 |
+
- restore_cache:
|
| 170 |
+
keys:
|
| 171 |
+
- data-cache-bst-raw
|
| 172 |
+
- restore_cache:
|
| 173 |
+
keys:
|
| 174 |
+
- data-cache-bst-phantom-ctf
|
| 175 |
+
- restore_cache:
|
| 176 |
+
keys:
|
| 177 |
+
- data-cache-bst-phantom-elekta
|
| 178 |
+
- restore_cache:
|
| 179 |
+
keys:
|
| 180 |
+
- data-cache-bst-phantom-kernel
|
| 181 |
+
- restore_cache:
|
| 182 |
+
keys:
|
| 183 |
+
- data-cache-bst-auditory
|
| 184 |
+
- restore_cache:
|
| 185 |
+
keys:
|
| 186 |
+
- data-cache-bst-resting
|
| 187 |
+
- restore_cache:
|
| 188 |
+
keys:
|
| 189 |
+
- data-cache-fieldtrip
|
| 190 |
+
- restore_cache:
|
| 191 |
+
keys:
|
| 192 |
+
- data-cache-somato
|
| 193 |
+
- restore_cache:
|
| 194 |
+
keys:
|
| 195 |
+
- data-cache-hf-sef
|
| 196 |
+
- restore_cache:
|
| 197 |
+
keys:
|
| 198 |
+
- data-cache-opm
|
| 199 |
+
- restore_cache:
|
| 200 |
+
keys:
|
| 201 |
+
- data-cache-sample
|
| 202 |
+
- restore_cache:
|
| 203 |
+
keys:
|
| 204 |
+
- data-cache-spm-face
|
| 205 |
+
- restore_cache:
|
| 206 |
+
keys:
|
| 207 |
+
- data-cache-testing
|
| 208 |
+
- restore_cache:
|
| 209 |
+
keys:
|
| 210 |
+
- data-cache-visual
|
| 211 |
+
- restore_cache:
|
| 212 |
+
keys:
|
| 213 |
+
- data-cache-ucl-opm-auditory
|
| 214 |
+
- restore_cache:
|
| 215 |
+
keys:
|
| 216 |
+
- data-cache-phantom-kit
|
| 217 |
+
- restore_cache:
|
| 218 |
+
keys:
|
| 219 |
+
- data-cache-ds004388
|
| 220 |
+
- run:
|
| 221 |
+
name: Get data
|
| 222 |
+
# This limit could be increased, but this is helpful for finding slow ones
|
| 223 |
+
# (even ~2GB datasets should be downloadable in this time from good
|
| 224 |
+
# providers)
|
| 225 |
+
no_output_timeout: 10m
|
| 226 |
+
command: |
|
| 227 |
+
./tools/circleci_download.sh
|
| 228 |
+
- run:
|
| 229 |
+
name: Verify build type
|
| 230 |
+
command: |
|
| 231 |
+
echo "PATTERN=$(cat pattern.txt)"
|
| 232 |
+
echo "BUILD=$(cat build.txt)"
|
| 233 |
+
ls -al ~/mne_data;
|
| 234 |
+
|
| 235 |
+
# Run doctest (if it's full or front) before building the docs
|
| 236 |
+
- run:
|
| 237 |
+
name: make test-doc
|
| 238 |
+
command: |
|
| 239 |
+
if [[ $(cat gitlog.txt) == *"[circle front]"* ]] || [[ $(cat build.txt) == "html-memory" ]] ; then
|
| 240 |
+
make test-doc;
|
| 241 |
+
mkdir -p doc/_build/test-results/test-doc;
|
| 242 |
+
cp junit-results.xml doc/_build/test-results/test-doc/junit.xml;
|
| 243 |
+
cp coverage.xml doc/_build/test-results/test-doc/coverage.xml;
|
| 244 |
+
fi;
|
| 245 |
+
# Build docs
|
| 246 |
+
- run:
|
| 247 |
+
name: make html
|
| 248 |
+
command: | # we have -o pipefail in #BASH_ENV so we should be okay
|
| 249 |
+
set -x
|
| 250 |
+
PATTERN=$(cat pattern.txt) make -C doc $(cat build.txt) 2>&1 | tee sphinx_log.txt
|
| 251 |
+
- run:
|
| 252 |
+
name: Check sphinx log for warnings (which are treated as errors)
|
| 253 |
+
when: always
|
| 254 |
+
command: |
|
| 255 |
+
! grep "^.*\(WARNING\|ERROR\): " sphinx_log.txt
|
| 256 |
+
- run:
|
| 257 |
+
name: Show profiling output
|
| 258 |
+
when: always
|
| 259 |
+
command: |
|
| 260 |
+
if compgen -G "doc/*.dat" > /dev/null; then
|
| 261 |
+
mkdir -p doc/generated
|
| 262 |
+
mprof plot doc/*.dat --output doc/generated/memory.png
|
| 263 |
+
else
|
| 264 |
+
echo "No profile data found in doc/"
|
| 265 |
+
fi
|
| 266 |
+
- run:
|
| 267 |
+
name: Sanity check system state
|
| 268 |
+
command: |
|
| 269 |
+
python -c "import mne; level = mne.get_config('MNE_LOGGING_LEVEL'); assert level.lower() == 'info', repr(level)"
|
| 270 |
+
|
| 271 |
+
# Reduce upload time of artifacts we will (almost) never look at
|
| 272 |
+
- run:
|
| 273 |
+
name: Reduce artifact upload time
|
| 274 |
+
command: |
|
| 275 |
+
if grep -q html-pattern-memory build.txt; then
|
| 276 |
+
zip -rm doc/_build/html/_downloads.zip doc/_build/html/_downloads
|
| 277 |
+
fi
|
| 278 |
+
for NAME in generated auto_tutorials auto_examples; do
|
| 279 |
+
zip -rm doc/${NAME}.zip doc/${NAME}
|
| 280 |
+
done
|
| 281 |
+
|
| 282 |
+
# Save the JUnit file
|
| 283 |
+
- store_test_results:
|
| 284 |
+
path: doc/_build/test-results
|
| 285 |
+
- store_artifacts:
|
| 286 |
+
path: doc/_build/test-results
|
| 287 |
+
destination: test-results
|
| 288 |
+
# Upload test results to Codecov
|
| 289 |
+
- run:
|
| 290 |
+
name: Upload test results to Codecov
|
| 291 |
+
environment:
|
| 292 |
+
CODECOV_TOKEN: fb4c4a94-72d7-4743-bb08-af25b623a29a
|
| 293 |
+
command: |
|
| 294 |
+
if [[ -f doc/_build/test-results/test-doc/coverage.xml ]]; then
|
| 295 |
+
bash <(curl -s https://codecov.io/bash) -f doc/_build/test-results/test-doc/coverage.xml || true
|
| 296 |
+
fi
|
| 297 |
+
# Save the SG RST
|
| 298 |
+
- store_artifacts:
|
| 299 |
+
path: doc/auto_examples.zip
|
| 300 |
+
- store_artifacts:
|
| 301 |
+
path: doc/auto_tutorials.zip
|
| 302 |
+
- store_artifacts:
|
| 303 |
+
path: doc/generated.zip
|
| 304 |
+
# Save the HTML
|
| 305 |
+
- store_artifacts:
|
| 306 |
+
path: doc/_build/html/
|
| 307 |
+
destination: html
|
| 308 |
+
- persist_to_workspace:
|
| 309 |
+
root: doc/_build
|
| 310 |
+
paths:
|
| 311 |
+
- html
|
| 312 |
+
|
| 313 |
+
# Keep these separate, maybe better in terms of size limitations (?)
|
| 314 |
+
- save_cache:
|
| 315 |
+
key: data-cache-tiny-0 # < 100 M, might as well combine
|
| 316 |
+
paths:
|
| 317 |
+
- ~/.mne
|
| 318 |
+
- ~/mne_data/MNE-kiloword-data # (28 M)
|
| 319 |
+
- ~/mne_data/MNE-eegbci-data # (35 M)
|
| 320 |
+
- ~/mne_data/MNE-misc-data # (39 M)
|
| 321 |
+
- ~/mne_data/mTRF_1.5 # (56 M)
|
| 322 |
+
- ~/mne_data/MNE-phantom-4DBTi # (77 M)
|
| 323 |
+
- save_cache:
|
| 324 |
+
key: data-cache-tiny-1 # more to combine
|
| 325 |
+
paths:
|
| 326 |
+
- ~/mne_data/MNE-fNIRS-motor-data # (71 M)
|
| 327 |
+
- ~/mne_data/MNE-refmeg-noise-data # (93 M)
|
| 328 |
+
- ~/mne_data/physionet-sleep-data # (95 M)
|
| 329 |
+
- save_cache:
|
| 330 |
+
key: data-cache-multimodal
|
| 331 |
+
paths:
|
| 332 |
+
- ~/mne_data/MNE-multimodal-data # (240 M)
|
| 333 |
+
- save_cache:
|
| 334 |
+
key: data-cache-limo
|
| 335 |
+
paths:
|
| 336 |
+
- ~/mne_data/MNE-limo-data # (244 M)
|
| 337 |
+
- save_cache:
|
| 338 |
+
key: data-cache-fsaverage
|
| 339 |
+
paths:
|
| 340 |
+
- ~/mne_data/MNE-fsaverage-data # (762 M)
|
| 341 |
+
- save_cache:
|
| 342 |
+
key: data-cache-bst-raw
|
| 343 |
+
paths:
|
| 344 |
+
- ~/mne_data/MNE-brainstorm-data/bst_raw # (830 M)
|
| 345 |
+
- save_cache:
|
| 346 |
+
key: data-cache-bst-phantom-ctf
|
| 347 |
+
paths:
|
| 348 |
+
- ~/mne_data/MNE-brainstorm-data/bst_phantom_ctf # (177 M)
|
| 349 |
+
- save_cache:
|
| 350 |
+
key: data-cache-bst-phantom-elekta
|
| 351 |
+
paths:
|
| 352 |
+
- ~/mne_data/MNE-brainstorm-data/bst_phantom_elekta # (1.4 G)
|
| 353 |
+
- save_cache:
|
| 354 |
+
key: data-cache-bst-phantom-kernel
|
| 355 |
+
paths:
|
| 356 |
+
- ~/mne_data/MNE-phantom-kernel-data # (362 M)
|
| 357 |
+
- save_cache:
|
| 358 |
+
key: data-cache-bst-auditory
|
| 359 |
+
paths:
|
| 360 |
+
- ~/mne_data/MNE-brainstorm-data/bst_auditory # (2.9 G)
|
| 361 |
+
- save_cache:
|
| 362 |
+
key: data-cache-bst-resting
|
| 363 |
+
paths:
|
| 364 |
+
- ~/mne_data/MNE-brainstorm-data/bst_resting # (4.5 G)
|
| 365 |
+
- save_cache:
|
| 366 |
+
key: data-cache-fieldtrip
|
| 367 |
+
paths:
|
| 368 |
+
- ~/mne_data/MNE-fieldtrip_cmc-data # (699 M)
|
| 369 |
+
- save_cache:
|
| 370 |
+
key: data-cache-somato
|
| 371 |
+
paths:
|
| 372 |
+
- ~/mne_data/MNE-somato-data # (750 M)
|
| 373 |
+
- save_cache:
|
| 374 |
+
key: data-cache-hf-sef
|
| 375 |
+
paths:
|
| 376 |
+
- ~/mne_data/HF_SEF # (1.3 G)
|
| 377 |
+
- save_cache:
|
| 378 |
+
key: data-cache-opm
|
| 379 |
+
paths:
|
| 380 |
+
- ~/mne_data/MNE-OPM-data # (1.9 G)
|
| 381 |
+
- save_cache:
|
| 382 |
+
key: data-cache-sample
|
| 383 |
+
paths:
|
| 384 |
+
- ~/mne_data/MNE-sample-data # (3.2 G)
|
| 385 |
+
- save_cache:
|
| 386 |
+
key: data-cache-spm-face
|
| 387 |
+
paths:
|
| 388 |
+
- ~/mne_data/MNE-spm-face # (1.5 G)
|
| 389 |
+
- save_cache:
|
| 390 |
+
key: data-cache-testing
|
| 391 |
+
paths:
|
| 392 |
+
- ~/mne_data/MNE-testing-data # (2.5 G)
|
| 393 |
+
- save_cache:
|
| 394 |
+
key: data-cache-visual
|
| 395 |
+
paths:
|
| 396 |
+
- ~/mne_data/MNE-visual_92_categories-data # (6 G)
|
| 397 |
+
- save_cache:
|
| 398 |
+
key: data-cache-ucl-opm-auditory
|
| 399 |
+
paths:
|
| 400 |
+
- ~/mne_data/auditory_OPM_stationary # (4 G)
|
| 401 |
+
- save_cache:
|
| 402 |
+
key: data-cache-phantom-kit
|
| 403 |
+
paths:
|
| 404 |
+
- ~/mne_data/MNE-phantom-KIT-data # (1 G)
|
| 405 |
+
- save_cache:
|
| 406 |
+
key: data-cache-ds004388
|
| 407 |
+
paths:
|
| 408 |
+
- ~/mne_data/ds004388 # (1.8 G)
|
| 409 |
+
|
| 410 |
+
|
| 411 |
+
linkcheck:
|
| 412 |
+
# there are a few files excluded from this for expediency, see Makefile
|
| 413 |
+
parameters:
|
| 414 |
+
scheduled:
|
| 415 |
+
type: string
|
| 416 |
+
default: "false"
|
| 417 |
+
machine:
|
| 418 |
+
image: ubuntu-2404:current
|
| 419 |
+
resource_class: large
|
| 420 |
+
steps:
|
| 421 |
+
- restore_cache:
|
| 422 |
+
keys:
|
| 423 |
+
- source-cache
|
| 424 |
+
- checkout
|
| 425 |
+
- run:
|
| 426 |
+
name: Check-skip
|
| 427 |
+
command: |
|
| 428 |
+
export COMMIT_MESSAGE=$(git log --format=oneline -n 1);
|
| 429 |
+
if [[ "$COMMIT_MESSAGE" != *"[circle linkcheck]"* ]] && [ "<< parameters.scheduled >>" != "true" ]; then
|
| 430 |
+
echo "Skip detected, exiting job ${CIRCLE_JOB}."
|
| 431 |
+
circleci-agent step halt;
|
| 432 |
+
fi
|
| 433 |
+
- run:
|
| 434 |
+
name: Set BASH_ENV
|
| 435 |
+
command: ./tools/circleci_bash_env.sh
|
| 436 |
+
- restore_cache:
|
| 437 |
+
keys:
|
| 438 |
+
- pip-cache-0
|
| 439 |
+
- run:
|
| 440 |
+
name: Get Python running
|
| 441 |
+
command: |
|
| 442 |
+
./tools/circleci_dependencies.sh
|
| 443 |
+
- run:
|
| 444 |
+
name: Check installation
|
| 445 |
+
command: |
|
| 446 |
+
mne sys_info -pd
|
| 447 |
+
- run:
|
| 448 |
+
name: make linkcheck
|
| 449 |
+
no_output_timeout: 40m
|
| 450 |
+
command: |
|
| 451 |
+
make -C doc linkcheck
|
| 452 |
+
- store_artifacts:
|
| 453 |
+
path: doc/_build/linkcheck
|
| 454 |
+
destination: linkcheck
|
| 455 |
+
|
| 456 |
+
|
| 457 |
+
deploy:
|
| 458 |
+
machine:
|
| 459 |
+
image: ubuntu-2404:current
|
| 460 |
+
steps:
|
| 461 |
+
- attach_workspace:
|
| 462 |
+
at: /tmp/build
|
| 463 |
+
- restore_cache:
|
| 464 |
+
keys:
|
| 465 |
+
- website-cache-1
|
| 466 |
+
- add_ssh_keys:
|
| 467 |
+
fingerprints:
|
| 468 |
+
# SHA256:N4qvp6MSbXcTz/27xz96VPsNuTDRT92zoRP8EW0I/8I
|
| 469 |
+
- "19:fe:1d:c3:c7:af:7e:16:94:4c:e1:e7:0a:56:13:bd"
|
| 470 |
+
- run:
|
| 471 |
+
name: Set BASH_ENV
|
| 472 |
+
command: |
|
| 473 |
+
set -e
|
| 474 |
+
echo "set -e" >> $BASH_ENV
|
| 475 |
+
# Don't try to deploy if nothing is there or not on the right branch
|
| 476 |
+
- run:
|
| 477 |
+
name: Check docs
|
| 478 |
+
command: |
|
| 479 |
+
if [ ! -f /tmp/build/html/index.html ] ; then
|
| 480 |
+
echo "No files found to upload (build: ${CIRCLE_BRANCH}).";
|
| 481 |
+
circleci-agent step halt;
|
| 482 |
+
fi;
|
| 483 |
+
- run:
|
| 484 |
+
name: Fetch docs
|
| 485 |
+
command: |
|
| 486 |
+
mkdir -p ~/.ssh
|
| 487 |
+
echo -e "Host *\nStrictHostKeyChecking no" > ~/.ssh/config
|
| 488 |
+
chmod og= ~/.ssh/config
|
| 489 |
+
if [ ! -d ~/mne-tools.github.io ]; then
|
| 490 |
+
git clone git@github.com:/mne-tools/mne-tools.github.io.git ~/mne-tools.github.io --depth=1
|
| 491 |
+
fi
|
| 492 |
+
- run:
|
| 493 |
+
name: Deploy docs
|
| 494 |
+
command: |
|
| 495 |
+
git config --global user.email "circle@mne.tools";
|
| 496 |
+
git config --global user.name "Circle CI";
|
| 497 |
+
ssh-add -D && ssh-add ~/.ssh/id_rsa_19fe1dc3c7af7e16944ce1e70a5613bd
|
| 498 |
+
cd ~/mne-tools.github.io;
|
| 499 |
+
git checkout main
|
| 500 |
+
git remote -v
|
| 501 |
+
git fetch origin
|
| 502 |
+
git reset --hard origin/main
|
| 503 |
+
git clean -xdf
|
| 504 |
+
if [ "${CIRCLE_BRANCH}" == "main" ]; then
|
| 505 |
+
echo "Deploying dev docs for ${CIRCLE_BRANCH}.";
|
| 506 |
+
rm -Rf dev;
|
| 507 |
+
cp -a /tmp/build/html dev;
|
| 508 |
+
git add -A;
|
| 509 |
+
git commit -m "CircleCI update of dev docs (${CIRCLE_BUILD_NUM}).";
|
| 510 |
+
else
|
| 511 |
+
echo "Deploying stable docs for ${CIRCLE_BRANCH}.";
|
| 512 |
+
rm -Rf stable;
|
| 513 |
+
cp -a /tmp/build/html stable;
|
| 514 |
+
git add -A;
|
| 515 |
+
git commit -m "CircleCI update of stable docs (${CIRCLE_BUILD_NUM}).";
|
| 516 |
+
fi;
|
| 517 |
+
git push origin main;
|
| 518 |
+
- save_cache:
|
| 519 |
+
key: website-cache-1
|
| 520 |
+
paths:
|
| 521 |
+
- ~/mne-tools.github.io
|
| 522 |
+
|
| 523 |
+
workflows:
|
| 524 |
+
default:
|
| 525 |
+
jobs:
|
| 526 |
+
- build_docs:
|
| 527 |
+
name: build_docs
|
| 528 |
+
- linkcheck:
|
| 529 |
+
name: linkcheck
|
| 530 |
+
- deploy:
|
| 531 |
+
name: deploy
|
| 532 |
+
requires:
|
| 533 |
+
- build_docs
|
| 534 |
+
filters:
|
| 535 |
+
branches:
|
| 536 |
+
only:
|
| 537 |
+
- main
|
| 538 |
+
- /maint\/.*/
|
| 539 |
+
|
| 540 |
+
main:
|
| 541 |
+
jobs:
|
| 542 |
+
- build_docs:
|
| 543 |
+
scheduled: "true"
|
| 544 |
+
name: build_docs_main
|
| 545 |
+
- deploy:
|
| 546 |
+
name: deploy_main
|
| 547 |
+
requires:
|
| 548 |
+
- build_docs_main
|
| 549 |
+
triggers:
|
| 550 |
+
- schedule:
|
| 551 |
+
# "At 6:00 AM GMT every day"
|
| 552 |
+
cron: "0 6 * * *"
|
| 553 |
+
filters:
|
| 554 |
+
branches:
|
| 555 |
+
only:
|
| 556 |
+
- main
|
| 557 |
+
|
| 558 |
+
monthly:
|
| 559 |
+
jobs:
|
| 560 |
+
- linkcheck:
|
| 561 |
+
name: linkcheck_monthly
|
| 562 |
+
scheduled: "true"
|
| 563 |
+
triggers:
|
| 564 |
+
- schedule:
|
| 565 |
+
# "At 6:00 AM GMT on the first day of each month"
|
| 566 |
+
cron: "0 6 1 * *"
|
| 567 |
+
filters:
|
| 568 |
+
branches:
|
| 569 |
+
only:
|
| 570 |
+
- main
|
mne-python/source/.coveragerc
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[run]
|
| 2 |
+
branch = True
|
| 3 |
+
source = mne
|
| 4 |
+
omit =
|
| 5 |
+
*/bin/*
|
| 6 |
+
*/setup.py
|
| 7 |
+
*/mne/fixes*
|
| 8 |
+
*/mne/utils/linalg.py
|
| 9 |
+
*/mne/conftest.py
|
| 10 |
+
|
| 11 |
+
[report]
|
| 12 |
+
exclude_lines =
|
| 13 |
+
pragma: no cover
|
| 14 |
+
if __name__ == .__main__.:
|
| 15 |
+
@abstractmethod
|
| 16 |
+
@abstractclassmethod
|
mne-python/source/.mailmap
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Adam Li <adam2392@gmail.com> Adam Li <adam2392@Adams-MBP-2.home>
|
| 2 |
+
Adam Li <adam2392@gmail.com> Adam Li <adam2392@new-host-2.home>
|
| 3 |
+
Alan Leggitt <leggitta3@gmail.com> leggitta <leggitta3@gmail.com>
|
| 4 |
+
Alessandro Tonin <alessandro.tonin@wysscenter.ch> Lychfindel <58313635+Lychfindel@users.noreply.github.com>
|
| 5 |
+
Alex Lepauvre <alex.lepauvre@ae.mpg.de> Alex lepauvre <alex.lepauvre@ae.mpg.de>
|
| 6 |
+
Alex Rockhill <aprockhill206@gmail.com> Alex <aprockhill206@gmail.com>
|
| 7 |
+
Alex Rockhill <aprockhill206@gmail.com> Alex <aprockhill@mailbox.org>
|
| 8 |
+
Alex Rockhill <aprockhill206@gmail.com> Alex Rockhill <aprock@uw.edu>
|
| 9 |
+
Alex Rockhill <aprockhill206@gmail.com> Alex Rockhill <aprockhill@mailbox.org>
|
| 10 |
+
Alexander Rudiuk <alxanderr@gmail.com> Alexander Rudiuk <al629748@dal.ca>
|
| 11 |
+
Alexandre Barachant <alexandre.barachant@gmail.com> alexandre barachant <alexandre.barachant@gmail.com>
|
| 12 |
+
Alexandre Gramfort <alexandre.gramfort@inria.fr> Alexandre Gramfort <alexandre.gramfort@gmail.com>
|
| 13 |
+
Alexandre Gramfort <alexandre.gramfort@inria.fr> Alexandre Gramfort <alexandre.gramfort@inria.fr>
|
| 14 |
+
Alexandre Gramfort <alexandre.gramfort@inria.fr> Alexandre Gramfort <alexandre.gramfort@m4x.org>
|
| 15 |
+
Alexandre Gramfort <alexandre.gramfort@inria.fr> Alexandre Gramfort <alexandre.gramfort@telecom-paristech.fr>
|
| 16 |
+
Alexandre Gramfort <alexandre.gramfort@inria.fr> Alexandre Gramfort <gramfort@localhost.(none)>
|
| 17 |
+
Ana Radanovic <anaradanovica@gmail.com> anaradanovic <79697247+anaradanovic@users.noreply.github.com>
|
| 18 |
+
Andres Rodriguez <rodriguezandr@gmail.com>
|
| 19 |
+
Andrew Dykstra <andrew.r.dykstra@gmail.com>
|
| 20 |
+
Andrew Quinn <AJQuinn@users.noreply.github.com> AJQuinn <AJQuinn@users.noreply.github.com>
|
| 21 |
+
Andy Gilbert <7andy121@gmail.com> Andrew Gilbert <adgilbert21@icloud.com>
|
| 22 |
+
Andy Gilbert <7andy121@gmail.com> Andrew Gilbert <andrew.gilbert@irhythmtech.com>
|
| 23 |
+
Aniket Singh Yadav <148300120+Aniketsy@users.noreply.github.com> Aniket <148300120+Aniketsy@users.noreply.github.com>
|
| 24 |
+
Anna Padee <anna.padee@gmail.com> apadee <44297909+apadee@users.noreply.github.com>
|
| 25 |
+
Anne-Sophie Dubarry <as_dub@hotmail.com> annesodub <as_dub@hotmail.com>
|
| 26 |
+
Archit Singhal <43236121+architsinghal-mriirs@users.noreply.github.com> archit singhal <zyphergiest@pop-os.localdomain>
|
| 27 |
+
Arne Pelzer <arne.pelzer@idmt.fraunhofer.de> aplzr <7202498+aplzr@users.noreply.github.com>
|
| 28 |
+
Arne Pelzer <arne.pelzer@idmt.fraunhofer.de> pzr <arne.pelzer@idmt.fraunhofer.de>
|
| 29 |
+
Ashley Drew <ashdrew@uw.edu> ashdrew <33734402+ashdrew@users.noreply.github.com>
|
| 30 |
+
Asish Panda <asishrocks95@gmail.com> kaichogami <asishrocks95@gmail.com>
|
| 31 |
+
Basile Pinsard <basile.pinsard@umontreal.ca>
|
| 32 |
+
Brad Buran <bburan@galenea.com> Brad Buran <bburan@alum.mit.edu>
|
| 33 |
+
Britta Westner <britta.wstnr@gmail.com> britta-wstnr <britta.wstnr@gmail.com>
|
| 34 |
+
Bruno Aristimunha <b.aristimunha@gmail.com>
|
| 35 |
+
btkcodedev <btk.codedev@gmail.com>
|
| 36 |
+
buildqa <s1152yb68@contbay.com>
|
| 37 |
+
Burkhard Maess <burkhard.maess@arcor.de> Burkhard Maess <bmaess@users.noreply.github.com>
|
| 38 |
+
Carina Forster <carinaforster0611@gmail.com> Carina <carinaforster0611@gmail.com>
|
| 39 |
+
Carlos de la Torre <ctorre@mailbox.org> carlos <ctorre@mailbox.org>
|
| 40 |
+
Catalina María Galván <79813952+catalinamagalvan@users.noreply.github.com> Catalina Magalvan <79813952+catalinamagalvan@users.noreply.github.com>
|
| 41 |
+
Catalina María Galván <79813952+catalinamagalvan@users.noreply.github.com> catalinamagalvan <79813952+catalinamagalvan@users.noreply.github.com>
|
| 42 |
+
Cathy Nangini <cnangini@gmail.com> CN <cnangini@gmail.com>
|
| 43 |
+
Chetan Gohil <53237863+cgohil8@users.noreply.github.com> cgohil8 <53237863+cgohil8@users.noreply.github.com>
|
| 44 |
+
Chris Holdgraf <choldgraf@gmail.com> Chris Holdgraf <choldgraf@berkeley.edu>
|
| 45 |
+
Chris Holdgraf <choldgraf@gmail.com> Christopher Holdgraf <choldgraf@gmail.com>
|
| 46 |
+
Christian Brodbeck <christianmbrodbeck@gmail.com> Christian Brodbeck <christianbrodbeck@nyu.edu>
|
| 47 |
+
Christian Brodbeck <christianmbrodbeck@gmail.com> christianmbrodbeck <christianmbrodbeck@gmail.com>
|
| 48 |
+
Christian Mista <cmista@ingenieria.uner.edu.ar> cmista <79416030+cmista@users.noreply.github.com>
|
| 49 |
+
Christina Zhao <zhaotc@uw.edu> ChristinaZhao <zhaotc@uw.edu>
|
| 50 |
+
Christoph Dinh <chdinh@nmr.mgh.harvard.edu> Christoph Dinh <christoph.dinh@tu-ilmenau.de>
|
| 51 |
+
Christopher J. Bailey <bailey.cj@gmail.com> Chris Bailey <bailey.cj@gmail.com>
|
| 52 |
+
Claire Braboszcz <claire@guakamole.org> claire-braboszcz <claire@guakamole.org>
|
| 53 |
+
Clemens Brunner <clemens.brunner@gmail.com>
|
| 54 |
+
Clément Moutard <clement.moutard@gmail.com>
|
| 55 |
+
Cora Kim <kimjico@gmail.com> kimcoco <41998428+kimcoco@users.noreply.github.com>
|
| 56 |
+
Cristóbal Moënne-Loccoz <cmmoenne@gmail.com> Cristóbal <cmmoenne@gmail.com>
|
| 57 |
+
Dan G. Wakeman <dgwakeman@gmail.com> Daniel G. Wakeman <dgwakeman@gmail.com>
|
| 58 |
+
Dan G. Wakeman <dgwakeman@gmail.com> Daniel Wakeman <dwakeman@marcie.nmr.mgh.harvard.edu>
|
| 59 |
+
Dan G. Wakeman <dgwakeman@gmail.com> dgwakeman <dgwakeman@gmail.com>
|
| 60 |
+
Dan G. Wakeman <dgwakeman@gmail.com> dgwakeman <dgwakeman@users.noreply.github.com>
|
| 61 |
+
Daniel C Schad <daniel.c.schad@protonmail.com> Daniel C Schad <daniel@schad.se>
|
| 62 |
+
Daniel C Schad <daniel.c.schad@protonmail.com> Daniel Carlström Schad <daniel.c.schad@protonmail.com>
|
| 63 |
+
Daniel McCloy <dan@mccloy.info> Daniel McCloy <dan.mccloy@gmail.com>
|
| 64 |
+
Daniel McCloy <dan@mccloy.info> Daniel McCloy <drammock@users.noreply.github.com>
|
| 65 |
+
Daniel McCloy <dan@mccloy.info> drammock <dan.mccloy@gmail.com>
|
| 66 |
+
Daniel Strohmeier <daniel.strohmeier@googlemail.com> Daniel Strohmeier <daniel.strohmeier@googlemail.com>
|
| 67 |
+
Daniel Strohmeier <daniel.strohmeier@googlemail.com> joewalter <daniel.strohmeier@googlemail.com>
|
| 68 |
+
David Julien <david.julien@ifsttar.fr> David JULIEN <david.julien@ifsttar.fr>
|
| 69 |
+
David Sabbagh <dav.sabbagh@gmail.com> DavidSabbagh <33925146+DavidSabbagh@users.noreply.github.com>
|
| 70 |
+
Demetres Kostas <40433000+kostasde@users.noreply.github.com> kostasde <40433000+kostasde@users.noreply.github.com>
|
| 71 |
+
Denis A. Engemann <denis.engemann@gmail.com> dengemann <d.engemann@fz-juelich.de>
|
| 72 |
+
Denis A. Engemann <denis.engemann@gmail.com> dengemann <denis.engemann@gmail.com>
|
| 73 |
+
Denis A. Engemann <denis.engemann@gmail.com> denis <denis.engemann@gmail.com>
|
| 74 |
+
Denis A. Engemann <denis.engemann@gmail.com> Denis A. Engemann <d.engemann@fz-juelich.de>
|
| 75 |
+
Denis A. Engemann <denis.engemann@gmail.com> Denis A. Engemann <denis-alexander.engemann@inria.fr>
|
| 76 |
+
Denis A. Engemann <denis.engemann@gmail.com> Denis A. Engemann <denisaengemann@Denis-A-Engemanns-MacBook-Air.local>
|
| 77 |
+
Denis A. Engemann <denis.engemann@gmail.com> Denis Engemann <dengemann@Deniss-MacBook-Pro.local>
|
| 78 |
+
Denis A. Engemann <denis.engemann@gmail.com> Denis Engemann <dengemann@pool-186-21-zam037.wlan.kfa-juelich.de>
|
| 79 |
+
Dmitrii Altukhov <dm.altukhov@ya.ru> dmalt <dm.altukhov@ya.ru>
|
| 80 |
+
Dominik Krzemiński <raymon92@gmail.com> dokato <raymon92@gmail.com>
|
| 81 |
+
Dominik Welke <dominik.welke@ae.mpg.de> dominikwelke <33089761+dominikwelke@users.noreply.github.com>
|
| 82 |
+
Dominik Welke <dominik.welke@ae.mpg.de> dominikwelke <dominik.welke@web.de>
|
| 83 |
+
Dominik Wetzel <dimonok@web.de> Dominik Wetzel <dominik.wetzel@fh-zwickau.de>
|
| 84 |
+
Eberhard Eich <e.eich@fz-juelich.de> ebeich <ebeich@users.noreply.github.com>
|
| 85 |
+
Eduard Ort <eduardxort@gmail.com> Eduard Ort <edaurdxort@gmail.com>
|
| 86 |
+
Eduard Ort <eduardxort@gmail.com> eort <eduardxort@gmail.com>
|
| 87 |
+
Eduard Ort <eduardxort@gmail.com> examplename <e.ort@vu.nl>
|
| 88 |
+
Ellen Lau <ellenlau@umd.edu> ellenlau <ellenlau@umd.edu>
|
| 89 |
+
Emily Stephen <emilyps14@gmail.com> Emily P. Stephen <emilyps14@gmail.com>
|
| 90 |
+
Emily Stephen <emilyps14@gmail.com> emilyps14 <emilyps14@gmail.com>
|
| 91 |
+
Emma Bailey <93327939+emma-bailey@users.noreply.github.com> emma-bailey <93327939+emma-bailey@users.noreply.github.com>
|
| 92 |
+
Emma Zhang <150376834+zhijingz@users.noreply.github.com> Emma <150376834+zhijingz@users.noreply.github.com>
|
| 93 |
+
Enrico Varano <enricovarano@gmail.com> enricovara <69973551+enricovara@users.noreply.github.com>
|
| 94 |
+
Enzo Altamiranda <enzo.alt@gmail.com> enzo <enzo.alt@gmail.com>
|
| 95 |
+
Eric Larson <larson.eric.d@gmail.com> Eric Larson <larson.eric.d@gmail.com>
|
| 96 |
+
Eric Larson <larson.eric.d@gmail.com> Eric Larson <larsoner@monolith.local>
|
| 97 |
+
Eric Larson <larson.eric.d@gmail.com> Eric Larson <larsoner@uw.edu>
|
| 98 |
+
Eric Larson <larson.eric.d@gmail.com> Eric89GXL <larson.eric.d@gmail.com>
|
| 99 |
+
Eric Larson <larson.eric.d@gmail.com> Eric89GXL <larsoner@uw.edu>
|
| 100 |
+
Erica Peterson <nordme@uw.edu> nordme <38704848+nordme@users.noreply.github.com>
|
| 101 |
+
Erica Peterson <nordme@uw.edu> nordme <nordme@uw.edu>
|
| 102 |
+
Erik Hornberger <erik.hornberger@shi-g.com> er06645810 <erik.hornberger@shi-g.com>
|
| 103 |
+
Erik Hornberger <erik.hornberger@shi-g.com> Erik Hornberger <hornbergererik@gmail.com>
|
| 104 |
+
Erkka Heinila <erkkahe@gmail.com> Teekuningas <erkka.heinila@jyu.fi>
|
| 105 |
+
Erkka Heinila <erkkahe@gmail.com> Teekuningas <erkkahe@gmail.com>
|
| 106 |
+
Etienne de Montalivet <etiennedemontalivet@users.noreply.github.com>
|
| 107 |
+
Evgenii Kalenkovich <e.kalenkovich@gmail.com> kalenkovich <e.kalenkovich@gmail.com>
|
| 108 |
+
Evgeny Goldstein <84768107+evgenygoldstein@users.noreply.github.com> evgenygoldstein <84768107+evgenygoldstein@users.noreply.github.com>
|
| 109 |
+
Ezequiel Mikulan <e.mikulan@gmail.com> ezemikulan <39155887+ezemikulan@users.noreply.github.com>
|
| 110 |
+
Fahimeh Mamashli <33672431+fmamashli@users.noreply.github.com> fmamashli <33672431+fmamashli@users.noreply.github.com>
|
| 111 |
+
Fede Raimondo <federaimondo@gmail.com> Fede <slashack@gmail.com>
|
| 112 |
+
Fede Raimondo <federaimondo@gmail.com> Fede Raimondo <federaimondo@gmail.com>
|
| 113 |
+
Fede Raimondo <federaimondo@gmail.com> Fede Raimondo <fraimondo@dc.uba.ar>
|
| 114 |
+
Fede Raimondo <federaimondo@gmail.com> Fede Raimondo <slashack@gmail.com>
|
| 115 |
+
Fede Raimondo <federaimondo@gmail.com> Federico Raimondo <fraimondo@dc.uba.ar>
|
| 116 |
+
Fede Raimondo <federaimondo@gmail.com> Federico Raimondo <slashack@gmail.com>
|
| 117 |
+
Federico Zamberlan <44038765+fzamberlan@users.noreply.github.com>
|
| 118 |
+
Felix Klotzsche <klotzsche@cbs.mpg.de> eioe <felix_klotzsche@web.de>
|
| 119 |
+
Felix Klotzsche <klotzsche@cbs.mpg.de> eioe <klotzsche@cbs.mpg.de>
|
| 120 |
+
Frederik D. Weber <Frederik-D-Weber@users.noreply.github.com> Frederik-D-Weber <Frederik-D-Weber@users.noreply.github.com>
|
| 121 |
+
Fu-Te Wong <zuxfoucault@gmail.com> foucault <zuxfoucault@gmail.com>
|
| 122 |
+
Fu-Te Wong <zuxfoucault@gmail.com> zuxfoucault <zuxfoucault@yahoo.com.tw>
|
| 123 |
+
Félix Raimundo <gamaz3ps@gmail.com> Felix Raimundo <gamaz3ps@gmail.com>
|
| 124 |
+
Gansheng Tan <49130176+GanshengT@users.noreply.github.com> Gansheng TAN <49130176+GanshengT@users.noreply.github.com>
|
| 125 |
+
Gennadiy Belonosov <7503709+Genuster@users.noreply.github.com> Gennadiy <7503709+Genuster@users.noreply.github.com>
|
| 126 |
+
Gennadiy Belonosov <7503709+Genuster@users.noreply.github.com> Genuster <7503709+Genuster@users.noreply.github.com>
|
| 127 |
+
Giorgio Marinato <giorgio.marinato@unitn.it> neurogima <76406896+neurogima@users.noreply.github.com>
|
| 128 |
+
Giulio Gabrieli <giulio.gabrieli@iit.it>
|
| 129 |
+
Guillaume Dumas <deep@introspection.eu> deep-introspection <deep@introspection.eu>
|
| 130 |
+
Guillaume Dumas <deep@introspection.eu> Guillaume Dumas <deep-introspection@users.noreply.github.com>
|
| 131 |
+
Hakimeh Aslsardroud <hakimeh.aslsardroud@localhost>
|
| 132 |
+
Hamid Maymandi <46011104+HamidMandi@users.noreply.github.com> Hamid <46011104+HamidMandi@users.noreply.github.com>
|
| 133 |
+
Hasrat Ali Arzoo <hasrat407@gmail.com> hasrat17 <56307533+hasrat17@users.noreply.github.com>
|
| 134 |
+
Hongjiang Ye <rubyyhj@gmail.com> YE Hongjiang <hongjiang.ye@outlook.com>
|
| 135 |
+
Hongjiang Ye <rubyyhj@gmail.com> YE Hongjiang <rubyyhj@gmail.com>
|
| 136 |
+
Hubert Banville <hubert.jbanville@gmail.com> hubertjb <hubert.jbanville@gmail.com>
|
| 137 |
+
Hyonyoung Shin <55095699+mcvain@users.noreply.github.com> mcvain <55095699+mcvain@users.noreply.github.com>
|
| 138 |
+
Hüseyin Orkun Elmas <huseyinorkunelmas@gmail.com> Hüseyin <huseyinorkunelmas@gmail.com>
|
| 139 |
+
Ingoo Lee <dlsrnsladlek@naver.com> dlsrnsi <dlsrnsladlek@naver.com>
|
| 140 |
+
Ivo de Jong <ivopascal@gmail.com> ivopascal <ivopascal@gmail.com>
|
| 141 |
+
Jaakko Leppakangas <jaeilepp@gmail.com> Jaakko Leppakangas <jaeilepp@student.jyu.fi>
|
| 142 |
+
Jaakko Leppakangas <jaeilepp@gmail.com> jaeilepp <jaeilepp@gmail.com>
|
| 143 |
+
Jaakko Leppakangas <jaeilepp@gmail.com> jaeilepp <jaeilepp@student.jyu.fi>
|
| 144 |
+
Jacob Phelan <jacob.phelan.jp@gmail.com>
|
| 145 |
+
Jair Montoya <montoya.jair.m@gmail.com> jmontoyam <montoya.jair.m@gmail.com>
|
| 146 |
+
Jan Ebert <janpublicebert@posteo.net> janEbert <janpublicebert@posteo.net>
|
| 147 |
+
Jan Sedivy <sedivy@rtsoft.cz>
|
| 148 |
+
Jan Sosulski <mail@jan-sosulski.de> jsosulski <mail@jan-sosulski.de>
|
| 149 |
+
Jean-Baptiste Schiratti <jean.baptiste.schiratti@gmail.com> Jean-Baptiste SCHIRATTI <jean.baptiste.schiratti@gmail.com>
|
| 150 |
+
Jean-Rémi King <jeanremi.king+github@gmail.com> Jean-Rémi KING <jeanremi.king@gmail.com>
|
| 151 |
+
Jean-Rémi King <jeanremi.king+github@gmail.com> kingjr <jeanremi.kibng+github@gmail.com>
|
| 152 |
+
Jean-Rémi King <jeanremi.king+github@gmail.com> kingjr <jeanremi.king+github@gmail.com>
|
| 153 |
+
Jean-Rémi King <jeanremi.king+github@gmail.com> kingjr <jeanremi.king@gmail.com>
|
| 154 |
+
Jean-Rémi King <jeanremi.king+github@gmail.com> UMR9752 <jeanremi.king+github@gmail.com>
|
| 155 |
+
Jean-Rémi King <jeanremi.king+github@gmail.com> UMR9752 <umr9752@umr9752-desktop.(none)>
|
| 156 |
+
Jeff Stout <stoutjd@nih.gov> jstout211 <jstout211@yahoo.com>
|
| 157 |
+
Jennifer Behnke <jennifer.behnke@localhost>
|
| 158 |
+
Jesper Duemose Nielsen <jdue@dtu.dk> jdue <jdue@dtu.dk>
|
| 159 |
+
Jevri Hanna <jevri.hanna@gmail.com> Jeff Hanna <jeff.hanna@gmail.com>
|
| 160 |
+
Jevri Hanna <jevri.hanna@gmail.com> Jevri Hanna <jeff.hanna@gmail.com>
|
| 161 |
+
Joan Massich <mailsik@gmail.com> Joan Massich <sik@visor.udg.edu>
|
| 162 |
+
Joan Massich <mailsik@gmail.com> massich <sik@visor.udg.edu>
|
| 163 |
+
Johannes Kasper <jeythekey@tutanota.com> jeythekey <44215387+jeythekey@users.noreply.github.com>
|
| 164 |
+
John Samuelsson <johnsam@mit.edu> johnsam7 <johnsam@mit.edu>
|
| 165 |
+
John Veillette <johnv@uchicago.edu>
|
| 166 |
+
Jon Houck <jon.houck@gmail.com> Jon Houck <jhouck@users.noreply.github.com>
|
| 167 |
+
Jona Sassenhagen <jona.sassenhagen@gmail.com> jona <jona.sassenhagen@gmail.com>
|
| 168 |
+
Jona Sassenhagen <jona.sassenhagen@gmail.com> Jona Sassenhagen <jona.sassenhagen@staff.uni-marburg.de>
|
| 169 |
+
Jona Sassenhagen <jona.sassenhagen@gmail.com> jona-sassenhagen <jona.sassenhagen@gmail.com>
|
| 170 |
+
Jona Sassenhagen <jona.sassenhagen@gmail.com> jona-sassenhagen <jona.sassenhagen@staff.uni-marburg.de>
|
| 171 |
+
Jona Sassenhagen <jona.sassenhagen@gmail.com> jona-sassenhagen@ <jona.sassenhagen@gmail.com>
|
| 172 |
+
Jona Sassenhagen <jona.sassenhagen@gmail.com> jona.sassenhagen@gmail.com <jona.sassenhagen@gmail.com>
|
| 173 |
+
Jona Sassenhagen <jona.sassenhagen@gmail.com> sassenha <sassenha@fiebach1.rz.uni-frankfurt.de>
|
| 174 |
+
Jonathan Kuziek <kuziek@ualberta.ca>
|
| 175 |
+
Jordan Drew <39603454+jadrew43@users.noreply.github.com> jadrew43 <39603454+jadrew43@users.noreply.github.com>
|
| 176 |
+
Joris Van den Bossche <jorisvandenbossche@gmail.com> Joris Van den Bossche <jorisvandenbossche@gmail.com>
|
| 177 |
+
Joshua Calder-Travis <38797399+jCalderTravis@users.noreply.github.com> jCalderTravis <38797399+jCalderTravis@users.noreply.github.com>
|
| 178 |
+
Joshua J Bear <joshbear@users.noreply.github.com>
|
| 179 |
+
Joshua Teves <jbtevespro@gmail.com> Joshua Teves <joshua.teves@nih.gov>
|
| 180 |
+
José C. García Alanis <joialanisson@gmail.com> Jose Alanis <joialanisson@gmail.com>
|
| 181 |
+
José C. García Alanis <joialanisson@gmail.com> Jose C. G. Alanis <12409129+JoseAlanis@users.noreply.github.com>
|
| 182 |
+
José C. García Alanis <joialanisson@gmail.com> José C. G. Alanis <12409129+JoseAlanis@users.noreply.github.com>
|
| 183 |
+
José C. García Alanis <joialanisson@gmail.com> José C. García Alanis <12409129+JoseAlanis@users.noreply.github.com>
|
| 184 |
+
Julius Welzel <52565341+JuliusWelzel@users.noreply.github.com> jwelzel <52565341+JuliusWelzel@users.noreply.github.com>
|
| 185 |
+
Justus Schwabedal <jschwabedal@gmail.com>
|
| 186 |
+
Kaisu Lankinen <41806798+klankinen@users.noreply.github.com> klankinen <41806798+klankinen@users.noreply.github.com>
|
| 187 |
+
Kambiz Tabavi <ktavabi@gmail.com> Kambiz Tavabi <ktavabi@uw.edu>
|
| 188 |
+
Kambiz Tabavi <ktavabi@gmail.com> kambysese <ktavabi@gmail.com>
|
| 189 |
+
Katarina Slama <slama@berkeley.edu> katarinaslama <slama@berkeley.edu>
|
| 190 |
+
Katia Al-Amir <129207373+katia-sentry@users.noreply.github.com> Katia <129207373+katia-sentry@users.noreply.github.com>
|
| 191 |
+
Kostiantyn Maksymenko <makkostya@ukr.net> kostiantyn maksymenko <kostiantyn.maksymenko@inria.fr>
|
| 192 |
+
Kostiantyn Maksymenko <makkostya@ukr.net> Maksymenko Kostiantyn <kostiantyn.maksymenko@inria.fr>
|
| 193 |
+
Kostiantyn Maksymenko <makkostya@ukr.net> Maksymenko Kostiantyn <makkostya@ukr.net>
|
| 194 |
+
Laetitia Grabot <laetitia.grabot@gmail.com> LaetitiaG <laetitia.grabot@gmail.com>
|
| 195 |
+
Larry Eisenman <leisenman@wustl.edu> lneisenman <lneisenman@hotmail.com>
|
| 196 |
+
Laurent Lementec <laurent.lementec@gmail.com>
|
| 197 |
+
Lenny Varghese <lennyvarghese@users.noreply.github.com> lennyvarghese <lennyvarghese@users.noreply.github.com>
|
| 198 |
+
Liberty Hamilton <libertyhamilton@gmail.com>
|
| 199 |
+
Lorenz Esch <Lorenz.Esch@tu-ilmenau.de> Lorenz Esch <lorenzesch@hotmail.com>
|
| 200 |
+
Lorenzo Alfine <lorenzo.alfine@gmail.com> lorrandal <lorenzo.alfine@gmail.com>
|
| 201 |
+
Louis Thibault <louist87@gmail.com> = <louist87@gmail.com>
|
| 202 |
+
Louis Thibault <louist87@gmail.com> Louis Thibault <louist@ltpc.(none)>
|
| 203 |
+
Lukas Gemein <lukas.gemein@gmx.de> gemeinl <gemeinl@users.noreply.github.com>
|
| 204 |
+
Lukáš Hejtmánek <hejtmy@gmail.com> hejtmy <hejtmy@gmail.com>
|
| 205 |
+
Mads Jensen <mje.mads@gmail.com> mads jensen <mje.mads@gmail.com>
|
| 206 |
+
Mainak Jas <mainakjas@gmail.com> Mainak <mainakjas@gmail.com>
|
| 207 |
+
Mainak Jas <mainakjas@gmail.com> Mainak Jas <jasmainak@users.noreply.github.com>
|
| 208 |
+
Mainak Jas <mainakjas@gmail.com> Mainak Jas <mainak.jas@telecom-paristech.fr>
|
| 209 |
+
Mainak Jas <mainakjas@gmail.com> Mainak Jas <mainak@neuro.hut.fi> <mainakjas@users.noreply.github.com>
|
| 210 |
+
Mainak Jas <mainakjas@gmail.com> mainakjas <mainakjas@users.noreply.github.com>
|
| 211 |
+
Manoj Kumar <manojkumarsivaraj334@gmail.com> MechCoder <manojkumarsivaraj334@gmail.com>
|
| 212 |
+
Manu Sutela <manu.sutela@gmail.com> MJAS1 <manu.sutela@gmail.com>
|
| 213 |
+
Marian Dovgialo <marian.dowgialo@gmail.com> Marian Dovgialo <mdovgialo@fabrizzio.zfb.fuw.edu.pl>
|
| 214 |
+
Marian Dovgialo <marian.dowgialo@gmail.com> Marian Dovgialo <mdovgialo@users.noreply.github.com>
|
| 215 |
+
Marian Dovgialo <marian.dowgialo@gmail.com> mdovgialo <mdovgialo@users.noreply.github.com>
|
| 216 |
+
Marijn van Vliet <w.m.vanvliet@gmail.com> Marijn van Vliet <w.m.vanvliet@student.utwente.nl>
|
| 217 |
+
Mark Henney <mah@optoceutics.com> Mark <mah@optoceutics.com>
|
| 218 |
+
Mark Henney <mah@optoceutics.com> Mark Alexander Henney <mah@optoceutics.com>
|
| 219 |
+
Mark Henney <mah@optoceutics.com> Mark Henney <120719655+henneysq@users.noreply.github.com>
|
| 220 |
+
Mark Wronkiewicz <wronk.mark@gmail.com> wronk <wronk.mark@gmail.com>
|
| 221 |
+
Marmaduke Woodman <mmwoodman@gmail.com> maedoc <maedoc@mm.st>
|
| 222 |
+
Martin BaBer <Martinb.nmb@gmail.com>
|
| 223 |
+
Martin Billinger <flKazemakase@gmail.com> kazemakase <kazemakase@users.noreply.github.com>
|
| 224 |
+
Martin Billinger <flKazemakase@gmail.com> kazemakase <kazemakase@users.noreply.github.com>
|
| 225 |
+
Martin Billinger <flKazemakase@gmail.com> Martin Billinger <martin.billinger@tugraz.at>
|
| 226 |
+
Martin Billinger <flKazemakase@gmail.com> mbillingr <mbillingr@users.noreply.github.com>
|
| 227 |
+
Martin Luessi <mluessi@nmr.mgh.harvard.edu> martin <martin@think.(none)>
|
| 228 |
+
Martin Luessi <mluessi@nmr.mgh.harvard.edu> martin <martin@think.hsd1.ma.comcast.net>
|
| 229 |
+
Martin Luessi <mluessi@nmr.mgh.harvard.edu> mluessi@nmr.mgh.harvard.edu <mluessi@nmr.mgh.harvard.edu>
|
| 230 |
+
Martin Perez-Guevara <mperezguevara@gmail.com>
|
| 231 |
+
Martin Schulz <dev@mgschulz.de> Martin Schulz <46245704+marsipu@users.noreply.github.com>
|
| 232 |
+
Martin Schulz <dev@mgschulz.de> Martin Schulz <dev@earthman-music.de>
|
| 233 |
+
Martin van Harmelen <1544429+MPvHarmelen@users.noreply.github.com> Martin <1544429+MPvHarmelen@users.noreply.github.com>
|
| 234 |
+
Mathieu Scheltienne <mathieu.scheltienne@gmail.com> Mathieu Scheltienne <73893616+mscheltienne@users.noreply.github.com>
|
| 235 |
+
Mathieu Scheltienne <mathieu.scheltienne@gmail.com> Mathieu Scheltienne <mathieu.scheltienne@fcbg.ch>
|
| 236 |
+
Mathurin Massias <mathurin.massias@gmail.com> mathurinm <mathurin.massias@gmail.com>
|
| 237 |
+
Mathurin Massias <mathurin.massias@gmail.com> mathurinm <mathurinm@users.noreply.github.com>
|
| 238 |
+
Mats van Es <mats.vanes@psych.ox.ac.uk> Mats <mats.vanes@psych.ox.ac.uk>
|
| 239 |
+
Matt Sanderson <monkey_man_192@yahoo.com.au> monkeyman192 <monkey_man_192@yahoo.com.au>
|
| 240 |
+
Matteo Anelli <matteo.anelli@aalto.fi> Matteo Anelli <matteanelli.96.11@gmail.com>
|
| 241 |
+
Matteo Visconti di Oleggio Castello <matteo.visconti.gr@dartmouth.edu> Matteo Visconti dOC <matteo.visconti.gr@dartmouth.edu>
|
| 242 |
+
Matthias Dold <matthias.dold@gmx.net> matthiasdold <62005770+matthiasdold@users.noreply.github.com>
|
| 243 |
+
Matthias Eberlein <41163089+MatthiasEb@users.noreply.github.com> MatthiasEb <41163089+MatthiasEb@users.noreply.github.com>
|
| 244 |
+
Matti Hämäläinen <msh@nmr.mgh.harvard.edu> Matti Hamalainen <msh@nmr.mgh.harvard.edu>
|
| 245 |
+
Matti Hämäläinen <msh@nmr.mgh.harvard.edu> Matti Hamalainen <msh@parsley.nmr.mgh.harvard.edu>
|
| 246 |
+
Matti Hämäl��inen <msh@nmr.mgh.harvard.edu> Matti Hämäläinen <msh@parsley.nmr.mgh.harvard.edu>
|
| 247 |
+
Matti Hämäläinen <msh@nmr.mgh.harvard.edu> mshamalainen <msh@nmr.mgh.harvard.edu>
|
| 248 |
+
Matti Toivonen <105695400+mattitoi@users.noreply.github.com> mattitoi <105695400+mattitoi@users.noreply.github.com>
|
| 249 |
+
Maureen Shader <55732126+mshader@users.noreply.github.com> mshader <55732126+mshader@users.noreply.github.com>
|
| 250 |
+
Melih Yayli <melihyayli@hotmail.com>
|
| 251 |
+
Michiru Kaneda <rcmdnk@gmail.com> rcmdnk <rcmdnk@gmail.com>
|
| 252 |
+
Mikołaj Magnuski <mmagnuski@swps.edu.pl> Mikolaj Magnuski <mmagnuski@swps.edu.pl>
|
| 253 |
+
Mikołaj Magnuski <mmagnuski@swps.edu.pl> mmagnuski <mmagnuski@swps.edu.pl>
|
| 254 |
+
Mohamed Sherif <molpsychistb@gmail.com> mohdsherif <molpsychistb@gmail.com>
|
| 255 |
+
Mohammad Daneshzand <55800429+mdaneshzand@users.noreply.github.com> mdaneshzand <55800429+mdaneshzand@users.noreply.github.com>
|
| 256 |
+
Mojackhak <23111220065@m.fudan.edu.cn> Ankang Hu <23111220065@m.fudan.edu.cn>
|
| 257 |
+
Motofumi Fushimi <30593537+motofumi-fushimi@users.noreply.github.com> motofumi-fushimi <30593537+motofumi-fushimi@users.noreply.github.com>
|
| 258 |
+
Natalie Klein <neklein@andrew.cmu.edu> natalieklein <neklein@andrew.cmu.edu>
|
| 259 |
+
Nathalie Gayraud <nathalie.gayraud@inria.fr> Nathalie <nat.gayraud@gmail.com>
|
| 260 |
+
Nathalie Gayraud <nathalie.gayraud@inria.fr> Nathalie <nathalie.gayraud@inria.fr>
|
| 261 |
+
Natneal B <nati.new77@gmail.com>
|
| 262 |
+
Naveen Srinivasan <172697+naveensrinivasan@users.noreply.github.com> Naveen <172697+naveensrinivasan@users.noreply.github.com>
|
| 263 |
+
Nicolas Barascud <nbara@users.noreply.github.com> nbara <nbara@users.noreply.github.com>
|
| 264 |
+
Nicolas Barascud <nbara@users.noreply.github.com> Nicolas Barascud <10333715+nbara@users.noreply.github.com>
|
| 265 |
+
Nicolas Fourcaud-Trocmé <celicolimmo@free.fr> Fourcaud-Trocmé <nicolas.fourcaud-trocme@cnrs.fr>
|
| 266 |
+
Nicolas Gensollen <nicolas.gensollen@gmail.com> Gensollen <nicolas.gensollen@gmail.com>
|
| 267 |
+
Nicolas Legrand <legrand@cyceron.fr> Legrand Nicolas <legrand@cyceron.fr>
|
| 268 |
+
Nicolas Legrand <legrand@cyceron.fr> LegrandNico <legrand@cyceron.fr>
|
| 269 |
+
Nicolas Legrand <legrand@cyceron.fr> Nicolas Legrand <nicolas.legrand@cfin.au.dk>
|
| 270 |
+
Niels Focke <nfocke@uni-goettingen.de> nmri-nfocke <114056301+nmri-nfocke@users.noreply.github.com>
|
| 271 |
+
Niklas Wilming <niklas.wilming@gmail.com> Niklas Wilming <niklaswilming@fastmail.fm>
|
| 272 |
+
Nikolai Chapochnikov <23103092+chapochn@users.noreply.github.com> chapochn <23103092+chapochn@users.noreply.github.com>
|
| 273 |
+
Nikolai Chapochnikov <23103092+chapochn@users.noreply.github.com> Nikolai M Chapochnikov <23103092+chapochn@users.noreply.github.com>
|
| 274 |
+
Nikolas Chalas <nikos.ch01@gmail.com> Nichalas <nikos.ch01@gmail.com>
|
| 275 |
+
Noah Markowitz <34498671+nmarkowitz@users.noreply.github.com> NoahMarkowitz <34498671+nmarkowitz@users.noreply.github.com>
|
| 276 |
+
Olaf Hauk <olaf.hauk@mrc-cbu.cam.ac.uk> Olaf Hauk <olaf@mac0086.local>
|
| 277 |
+
Olaf Hauk <olaf.hauk@mrc-cbu.cam.ac.uk> olafhauk <olaf.hauk@mrc-cbu.cam.ac.uk>
|
| 278 |
+
Omer Shubi <omer.shubi@gmail.com> Omer S <omer.shubi@gmail.com>
|
| 279 |
+
Pablo Arias <pablo12co@hotmail.com>
|
| 280 |
+
Paul Pasler <paul@ppasler.de> ppasler <paul@ppasler.de>
|
| 281 |
+
Paul Roujansky <paul@roujansky.eu> Paul ROUJANSKY <paul.roujansky@bioserenity.com>
|
| 282 |
+
Paul Roujansky <paul@roujansky.eu> paulroujansky <paul@roujansky.eu>
|
| 283 |
+
Pavel Navratil <pavel.navratil@localhost>
|
| 284 |
+
Pedro Silva <pedrobnsilva@gmail.com> pbnsilva <pedrobnsilva@gmail.com>
|
| 285 |
+
Phillip Alday <phillip.alday@mpi.nl> Phillip Alday <palday@users.noreply.github.com>
|
| 286 |
+
Phillip Alday <phillip.alday@mpi.nl> Phillip Alday <phillip.alday@unisa.edu.au>
|
| 287 |
+
Pierre Ablin <pierreablin@gmail.com> pierreablin <pierreablin@gmail.com>
|
| 288 |
+
Pierre-Antoine Bannier <pierreantoine.bannier@gmail.com> PAB <pierreantoine.bannier@gmail.com>
|
| 289 |
+
Pierre-Antoine Bannier <pierreantoine.bannier@gmail.com> Pierre-Antoine Bannier <pierre-antoine@222-194.wifi-inria-saclay.saclay.inria.fr>
|
| 290 |
+
Pierre-Antoine Bannier <pierreantoine.bannier@gmail.com> Pierre-Antoine Bannier <pierre-antoine@macbook-pro-de-pierre-antoine.home>
|
| 291 |
+
Pierre-Antoine Bannier <pierreantoine.bannier@gmail.com> Pierre-Antoine Bannier <pierre-antoine@MacBook-Pro-de-Pierre-Antoine.local>
|
| 292 |
+
Pierre-Antoine Bannier <pierreantoine.bannier@gmail.com> Pierre-Antoine Bannier <pierre-antoine@mbpdepieantoine.home>
|
| 293 |
+
Ping-Keng Jao <ping-keng.jao@alumni.epfl.ch> nafraw <ping-keng.jao@alumni.epfl.ch>
|
| 294 |
+
Pragnya Khandelwal <prag1704@gmail.com> Pragnya <prag1704@gmail.com>
|
| 295 |
+
Pragnya Khandelwal <prag1704@gmail.com> PragnyaKhandelwal <prag1704@gmail.com>
|
| 296 |
+
Praveen Sripad <pravsripad@gmail.com> prav <prav@prav-dell.(none)>
|
| 297 |
+
Praveen Sripad <pravsripad@gmail.com> prav <pravsripad@gmail.com>
|
| 298 |
+
Proloy Das <pdas6@mgh.harvard.edu> pdas6 <pdas6@mgh.harvard.edu>
|
| 299 |
+
Ram Pari <ramsbam@gmail.com> Ram <ramsbam@gmail.com>
|
| 300 |
+
Ramonapariciog Apariciogarcia <moncho_apa@hotmail.com> ramonapariciog <moncho_apa@hotmail.com>
|
| 301 |
+
Rasmus Aagaard <roraa@dtu.dk> roraa <roraa@dtu.dk>
|
| 302 |
+
Reza Nasri <reza@ddpo.ir> Reza <qablameh13@gmail.com>
|
| 303 |
+
Reza Nasri <reza@ddpo.ir> RezaNasri <rezanasri@outlook.com>
|
| 304 |
+
Riessarius Stargardsky <rie.acad@gmail.com>
|
| 305 |
+
Roan LaPlante <aestrivex@gmail.com> aestrivex <aestrivex@gmail.com>
|
| 306 |
+
Robert Luke <code@robertluke.net> Robert Luke <748691+rob-luke@users.noreply.github.com>
|
| 307 |
+
Robert Luke <code@robertluke.net> Robert Luke <mail@robertluke.net>
|
| 308 |
+
Robert Seymour <robbyseymour@gmail.com>
|
| 309 |
+
Robin Tibor Schirrmeister <robintibor@gmail.com> robintibor <robintibor@gmail.com>
|
| 310 |
+
Roeland Hancock <rhancock@gmail.com>
|
| 311 |
+
Romain Derollepot <romain.derollepot@univ-eiffel.fr>
|
| 312 |
+
Romain Trachel <romain.trachel@inria.fr> Romain Trachel <romain.trachel@ens.fr>
|
| 313 |
+
Romain Trachel <romain.trachel@inria.fr> Romain Trachel <trachelr@gmail.com>
|
| 314 |
+
Romain Trachel <romain.trachel@inria.fr> trachelr <romain.trachel@inria.fr>
|
| 315 |
+
Roman Goj <roman.goj@gmail.com>
|
| 316 |
+
Rongfei Jin <131315c@gmail.com> GreasyCat <131315c@gmail.com>
|
| 317 |
+
Ross Maddox <ross.maddox@rochester.edu> rkmaddox <ross.maddox@gmail.com>
|
| 318 |
+
Ross Maddox <ross.maddox@rochester.edu> Ross Maddox <rkmaddox@uw.edu>
|
| 319 |
+
Ross Maddox <ross.maddox@rochester.edu> unknown <rkmaddox@uw.edu>
|
| 320 |
+
Rotem Falach <falachrotem@gmail.com> Falach <rotemfa0@gmail.com>
|
| 321 |
+
Roy Eric Wieske <139973278+Randomidous@users.noreply.github.com> Roy Eric <139973278+Randomidous@users.noreply.github.com>
|
| 322 |
+
Ryan Law <ryan.law@mpi.nl> Ryan Law <ryalaw@dccn.nl>
|
| 323 |
+
Ryan Law <ryan.law@mpi.nl> Ryan M.C. Law <ryan.law@mrc-cbu.cam.ac.uk>
|
| 324 |
+
Sammi Chekroud <sammi.chekroud@psy.ox.ac.uk>
|
| 325 |
+
Samuel Deslauriers-Gauthier <sam.deslauriers@gmail.com> Samuel Deslauriers-Gauthier <sdeslauriers@users.noreply.github.com>
|
| 326 |
+
Santeri Ruuskanen <santeri.ruuskanen@aalto.fi> Santeri Ruuskanen <66060772+ruuskas@users.noreply.github.com>
|
| 327 |
+
Santi Martínez <santiaguzz@gmail.com> szz-dvl <santiaguzz@gmail.com>
|
| 328 |
+
Sara Sommariva <sommariva@dima.unige.it> sarasommariva <sommariva@dima.unige.it>
|
| 329 |
+
Sebastien Treguer <sfox@riseup.net> DataFox <sfox@riseup.net>
|
| 330 |
+
Sena Er <2799280+sena-neuro@users.noreply.github.com> Sena <2799280+sena-neuro@users.noreply.github.com>
|
| 331 |
+
Senwen Deng <36327760+snwnde@users.noreply.github.com> Senwen DENG <36327760+snwnde@users.noreply.github.com>
|
| 332 |
+
Shristi Baral <shristi.baral@aalto.fi> shristi <shristi.baral@aalto.fi>
|
| 333 |
+
Silvia Cotroneo <78911192+sfc-neuro@users.noreply.github.com> sfc-neuro <78911192+sfc-neuro@users.noreply.github.com>
|
| 334 |
+
Simon Kern <simon.kern@online.de> Simon Kern <14980558+skjerns@users.noreply.github.com>
|
| 335 |
+
Simon Kern <simon.kern@online.de> skjerns <14980558+skjerns@users.noreply.github.com>
|
| 336 |
+
Simon Kern <simon.kern@online.de> skjerns <simon.kern@online.de>
|
| 337 |
+
Sondre Foslien <sondre.foslien@gmail.com> sondrfos <sondre.foslien@gmail.com>
|
| 338 |
+
Sophie Herbst <ksherbst@gmail.com>
|
| 339 |
+
Steinn Hauser Magnússon <hausersteinn@gmail.com> Steinn Magnusson <s.magnusson@senec.com>
|
| 340 |
+
Steve Matindi <stevematindi@gmail.com> stevemats <stevematindi@gmail.com>
|
| 341 |
+
Steven Bierer <neurolaunch@gmail.copm> Steven Bierer <40672003+NeuroLaunch@users.noreply.github.com>
|
| 342 |
+
Steven M. Gutstein <s.m.gutstein@gmail.com> S. M. Gutstein <s.m.gutstein@gmail.com>
|
| 343 |
+
Steven M. Gutstein <s.m.gutstein@gmail.com> smgutstein <s.m.gutstein@gmail.com>
|
| 344 |
+
sviter <sviter33@gmail.com>
|
| 345 |
+
T. Wang <twang5@swarthmore.edu> twang5 <81429617+twang5@users.noreply.github.com>
|
| 346 |
+
Tanay Gahlot <tanaygahlot@gmail.com> Tanay <tanaygahlot@gmail.com>
|
| 347 |
+
Teon L Brooks <teon.brooks@gmail.com>
|
| 348 |
+
Teon L Brooks <teon.brooks@gmail.com> <teon@nyu.edu>
|
| 349 |
+
Teon L Brooks <teon.brooks@gmail.com> Teon <teon@nyu.edu>
|
| 350 |
+
Teon L Brooks <teon.brooks@gmail.com> Teon Brooks <teon@nyu.edu>
|
| 351 |
+
Thomas Donoghue <tdonoghue.research@gmail.com> Tom <tdonoghue.research@gmail.com>
|
| 352 |
+
Thomas Radman <radman.thomas@gmail.com>
|
| 353 |
+
Timon Merk <timon.merk@charite.de>
|
| 354 |
+
Timon Merk <timon.merk@charite.de> Timon Merk <38216460+timonmerk@users.noreply.github.com>
|
| 355 |
+
Timon Merk <timon.merk@charite.de> timonmerk <38216460+timonmerk@users.noreply.github.com>
|
| 356 |
+
Timothy Gates <tim.gates@iress.com> Tim Gates <tim.gates@iress.com>
|
| 357 |
+
Timur Sokhin <qwinpin@gmail.com>
|
| 358 |
+
Tod Flak <45362686+todflak@users.noreply.github.com> todflak <45362686+todflak@users.noreply.github.com>
|
| 359 |
+
Tom Ma <myd7349@gmail.com> myd7349 <myd7349@gmail.com>
|
| 360 |
+
Tom Stone <TASTONE@mgh.harvard.edu> Stone <TASTONE@mgh.harvard.edu>
|
| 361 |
+
Tom Stone <TASTONE@mgh.harvard.edu> tomdstone <77251489+tomdstone@users.noreply.github.com>
|
| 362 |
+
Tristan Stenner <ttstenner@gmail.com> Tristan Stenner <derstenner@gmail.com>
|
| 363 |
+
Tziona NessAiver <tzionan@mail.tau.ac.il> TzionaN <tzionan@mail.tau.ac.il>
|
| 364 |
+
user27182 <89109579+user27182@users.noreply.github.com>
|
| 365 |
+
Valerii Chirkov <vagechirkov@gmail.com> Valerii <42982039+vagechirkov@users.noreply.github.com>
|
| 366 |
+
Valerii Chirkov <vagechirkov@gmail.com> Valerii <vagechirkov@gmail.com>
|
| 367 |
+
varshaa-1616 <varshaa.1616@gmail.com>
|
| 368 |
+
Velu Prabhakar Kumaravel <veluprabhakarkumaravel@Velus-MBP.lan> Velu Prabhakar Kumaravel <veluprabhakarkumaravel@Velus-MBP.lan>
|
| 369 |
+
Victoria Peterson <victoriapeterson09@gmail.com> vpeterson <victoriapeterson09@gmail.com>
|
| 370 |
+
Wei Xu <weixu@mail.bnu.edu.cn> Wei <weixu@mail.bnu.edu.cn>
|
| 371 |
+
Will Turner <wturner@student.unimelb.edu.au> Will Turner <wturner@student.unimelb.edu.au>
|
| 372 |
+
Yiping Zuo <frostime@foxmail.com> Frostime <frostime@foxmail.com>
|
| 373 |
+
Yousra Bekhti <yousra.bekhti@gmail.com> Yoursa BEKHTI <ybekhti@is222485.intra.cea.fr>
|
| 374 |
+
Yousra Bekhti <yousra.bekhti@gmail.com> Yoursa BEKHTI <yousra.bekhti@gmail.com>
|
| 375 |
+
Yousra Bekhti <yousra.bekhti@gmail.com> Yousra BEKHTI <yousra.bekhti@gmail.com>
|
| 376 |
+
Yousra Bekhti <yousra.bekhti@gmail.com> yousrabk <yousra.bekhti@gmail.com>
|
| 377 |
+
Zhi Zhang <850734033@qq.com> ZHANG Zhi <850734033@qq.com>
|
| 378 |
+
Zhi Zhang <850734033@qq.com> ZHANG Zhi <zhi271.zhang@connect.polyu.hk>
|
| 379 |
+
Ziyi ZENG <ziyizeng@link.cuhk.edu.cn> ZIYI ZENG <CME1909120@XMU.EDU.MY>
|
mne-python/source/.pre-commit-config.yaml
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
repos:
|
| 2 |
+
# Ruff mne
|
| 3 |
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
| 4 |
+
rev: v0.15.5
|
| 5 |
+
hooks:
|
| 6 |
+
- id: ruff-check
|
| 7 |
+
name: ruff lint mne
|
| 8 |
+
args: ["--fix"]
|
| 9 |
+
files: ^mne/|^tools/
|
| 10 |
+
exclude: vulture_allowlist.py
|
| 11 |
+
- id: ruff-check
|
| 12 |
+
name: ruff lint mne preview
|
| 13 |
+
args: ["--fix", "--preview", "--select=NPY201"]
|
| 14 |
+
files: ^mne/|^tools/
|
| 15 |
+
- id: ruff-check
|
| 16 |
+
name: ruff lint doc, tutorials, and examples
|
| 17 |
+
# D103: missing docstring in public function
|
| 18 |
+
# D400: docstring first line must end with period
|
| 19 |
+
args: ["--ignore=D103,D400", "--fix"]
|
| 20 |
+
files: ^doc/|^tutorials/|^examples/
|
| 21 |
+
- id: ruff-format
|
| 22 |
+
files: ^mne/|^doc/|^tutorials/|^examples/|^tools/
|
| 23 |
+
|
| 24 |
+
# Codespell
|
| 25 |
+
- repo: https://github.com/codespell-project/codespell
|
| 26 |
+
rev: v2.4.2
|
| 27 |
+
hooks:
|
| 28 |
+
- id: codespell
|
| 29 |
+
additional_dependencies:
|
| 30 |
+
- tomli
|
| 31 |
+
files: ^mne/|^doc/|^examples/|^tutorials/|^tools/
|
| 32 |
+
types_or: [python, bib, rst, inc]
|
| 33 |
+
|
| 34 |
+
# yamllint
|
| 35 |
+
- repo: https://github.com/adrienverge/yamllint.git
|
| 36 |
+
rev: v1.38.0
|
| 37 |
+
hooks:
|
| 38 |
+
- id: yamllint
|
| 39 |
+
args: [--strict, -c, .yamllint.yml]
|
| 40 |
+
|
| 41 |
+
# rstcheck
|
| 42 |
+
- repo: https://github.com/rstcheck/rstcheck.git
|
| 43 |
+
rev: v6.2.5
|
| 44 |
+
hooks:
|
| 45 |
+
- id: rstcheck
|
| 46 |
+
additional_dependencies:
|
| 47 |
+
- tomli
|
| 48 |
+
files: ^doc/.*\.(rst|inc)$
|
| 49 |
+
# Credit is problematic because we generate an include on the fly
|
| 50 |
+
exclude: ^doc/credit.rst$
|
| 51 |
+
|
| 52 |
+
# sorting
|
| 53 |
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
| 54 |
+
rev: v6.0.0
|
| 55 |
+
hooks:
|
| 56 |
+
- id: file-contents-sorter
|
| 57 |
+
files: ^doc/changes/names.inc|^.mailmap|^doc/sphinxext/related_software.txt
|
| 58 |
+
args: ["--ignore-case"]
|
| 59 |
+
|
| 60 |
+
- repo: https://github.com/pappasam/toml-sort
|
| 61 |
+
rev: v0.24.3
|
| 62 |
+
hooks:
|
| 63 |
+
- id: toml-sort-fix
|
| 64 |
+
files: pyproject.toml
|
| 65 |
+
|
| 66 |
+
# dependencies
|
| 67 |
+
- repo: local
|
| 68 |
+
hooks:
|
| 69 |
+
- id: update-env-file
|
| 70 |
+
name: Copy dependency changes from pyproject.toml to environment.yml
|
| 71 |
+
language: python
|
| 72 |
+
entry: ./tools/hooks/update_environment_file.py
|
| 73 |
+
files: '^(pyproject.toml|tools/hooks/update_environment_file.py)$'
|
| 74 |
+
- repo: local
|
| 75 |
+
hooks:
|
| 76 |
+
- id: dependency-sync
|
| 77 |
+
name: Copy core dependencies from pyproject.toml to README.rst
|
| 78 |
+
language: python
|
| 79 |
+
entry: ./tools/hooks/sync_dependencies.py
|
| 80 |
+
files: '^(pyproject.toml|tools/hooks/sync_dependencies.py)$'
|
| 81 |
+
additional_dependencies: ["mne==1.11.0"]
|
| 82 |
+
|
| 83 |
+
# zizmor
|
| 84 |
+
- repo: https://github.com/woodruffw/zizmor-pre-commit
|
| 85 |
+
rev: v1.23.1
|
| 86 |
+
hooks:
|
| 87 |
+
- id: zizmor
|
| 88 |
+
args: [--fix]
|
| 89 |
+
# We correctly use pull_request_trigger, and need Zizmor 2.0+ to configure the ignore
|
| 90 |
+
exclude: ^.github/workflows/automerge.yml
|
| 91 |
+
|
| 92 |
+
# these should *not* be run on CIs:
|
| 93 |
+
ci:
|
| 94 |
+
skip: [dependency-sync] # needs MNE to work, which exceeds the free tier space alloc.
|
| 95 |
+
|
| 96 |
+
# The following are too slow to run on local commits, so let's only run on CIs:
|
| 97 |
+
#
|
| 98 |
+
# - repo: https://github.com/pre-commit/mirrors-mypy
|
| 99 |
+
# rev: v1.9.0
|
| 100 |
+
# hooks:
|
| 101 |
+
# - id: mypy
|
| 102 |
+
#
|
| 103 |
+
# - repo: https://github.com/jendrikseipp/vulture
|
| 104 |
+
# rev: 'v2.11' # or any later Vulture version
|
| 105 |
+
# hooks:
|
| 106 |
+
# - id: vulture
|
mne-python/source/.yamllint.yml
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
extends: default
|
| 2 |
+
|
| 3 |
+
ignore: |
|
| 4 |
+
.github/workflows/codeql-analysis.yml
|
| 5 |
+
|
| 6 |
+
rules:
|
| 7 |
+
line-length: disable
|
| 8 |
+
document-start: disable
|
| 9 |
+
new-lines:
|
| 10 |
+
type: platform
|
mne-python/source/CITATION.cff
ADDED
|
@@ -0,0 +1,877 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
cff-version: 1.2.0
|
| 2 |
+
title: "MNE-Python"
|
| 3 |
+
message: "If you use this software, please cite both the software itself, and the paper listed in the preferred-citation field."
|
| 4 |
+
version: 1.11.0
|
| 5 |
+
date-released: "2025-11-21"
|
| 6 |
+
commit: 07328a6a7fa974b24455e1ac333d7607b154f87c
|
| 7 |
+
doi: 10.5281/zenodo.592483
|
| 8 |
+
keywords:
|
| 9 |
+
- MEG
|
| 10 |
+
- magnetoencephalography
|
| 11 |
+
- EEG
|
| 12 |
+
- electroencephalography
|
| 13 |
+
- fNIRS
|
| 14 |
+
- "functional near-infrared spectroscopy"
|
| 15 |
+
- iEEG
|
| 16 |
+
- "intracranial EEG"
|
| 17 |
+
- eCoG
|
| 18 |
+
- electrocorticography
|
| 19 |
+
- DBS
|
| 20 |
+
- "deep brain stimulation"
|
| 21 |
+
authors:
|
| 22 |
+
- family-names: Larson
|
| 23 |
+
given-names: Eric
|
| 24 |
+
- family-names: Gramfort
|
| 25 |
+
given-names: Alexandre
|
| 26 |
+
- family-names: Engemann
|
| 27 |
+
given-names: Denis A
|
| 28 |
+
- family-names: Leppakangas
|
| 29 |
+
given-names: Jaakko
|
| 30 |
+
- family-names: Brodbeck
|
| 31 |
+
given-names: Christian
|
| 32 |
+
- family-names: Jas
|
| 33 |
+
given-names: Mainak
|
| 34 |
+
- family-names: Brooks
|
| 35 |
+
given-names: Teon L
|
| 36 |
+
- family-names: Sassenhagen
|
| 37 |
+
given-names: Jona
|
| 38 |
+
- family-names: McCloy
|
| 39 |
+
given-names: Daniel
|
| 40 |
+
- family-names: Luessi
|
| 41 |
+
given-names: Martin
|
| 42 |
+
- family-names: King
|
| 43 |
+
given-names: Jean-Rémi
|
| 44 |
+
- family-names: Höchenberger
|
| 45 |
+
given-names: Richard
|
| 46 |
+
- family-names: Brunner
|
| 47 |
+
given-names: Clemens
|
| 48 |
+
- family-names: Goj
|
| 49 |
+
given-names: Roman
|
| 50 |
+
- family-names: Favelier
|
| 51 |
+
given-names: Guillaume
|
| 52 |
+
- family-names: van Vliet
|
| 53 |
+
given-names: Marijn
|
| 54 |
+
- family-names: Wronkiewicz
|
| 55 |
+
given-names: Mark
|
| 56 |
+
- family-names: Appelhoff
|
| 57 |
+
given-names: Stefan
|
| 58 |
+
- family-names: Rockhill
|
| 59 |
+
given-names: Alex
|
| 60 |
+
- family-names: Holdgraf
|
| 61 |
+
given-names: Chris
|
| 62 |
+
- family-names: Scheltienne
|
| 63 |
+
given-names: Mathieu
|
| 64 |
+
- family-names: Massich
|
| 65 |
+
given-names: Joan
|
| 66 |
+
- family-names: Bekhti
|
| 67 |
+
given-names: Yousra
|
| 68 |
+
- family-names: Leggitt
|
| 69 |
+
given-names: Alan
|
| 70 |
+
- family-names: Dykstra
|
| 71 |
+
given-names: Andrew
|
| 72 |
+
- family-names: Trachel
|
| 73 |
+
given-names: Romain
|
| 74 |
+
- family-names: Luke
|
| 75 |
+
given-names: Robert
|
| 76 |
+
- family-names: De Santis
|
| 77 |
+
given-names: Lorenzo
|
| 78 |
+
- family-names: Panda
|
| 79 |
+
given-names: Asish
|
| 80 |
+
- family-names: Magnuski
|
| 81 |
+
given-names: Mikołaj
|
| 82 |
+
- family-names: Westner
|
| 83 |
+
given-names: Britta
|
| 84 |
+
- family-names: Wakeman
|
| 85 |
+
given-names: Dan G
|
| 86 |
+
- family-names: Strohmeier
|
| 87 |
+
given-names: Daniel
|
| 88 |
+
- family-names: Bharadwaj
|
| 89 |
+
given-names: Hari
|
| 90 |
+
- family-names: Linzen
|
| 91 |
+
given-names: Tal
|
| 92 |
+
- family-names: Barachant
|
| 93 |
+
given-names: Alexandre
|
| 94 |
+
- family-names: Ruzich
|
| 95 |
+
given-names: Emily
|
| 96 |
+
- family-names: Huberty
|
| 97 |
+
given-names: Scott
|
| 98 |
+
- family-names: Bailey
|
| 99 |
+
given-names: Christopher J
|
| 100 |
+
- family-names: Li
|
| 101 |
+
given-names: Adam
|
| 102 |
+
- family-names: Moutard
|
| 103 |
+
given-names: Clément
|
| 104 |
+
- family-names: Bloy
|
| 105 |
+
given-names: Luke
|
| 106 |
+
- family-names: Raimondo
|
| 107 |
+
given-names: Fede
|
| 108 |
+
- family-names: Nurminen
|
| 109 |
+
given-names: Jussi
|
| 110 |
+
- family-names: Billinger
|
| 111 |
+
given-names: Martin
|
| 112 |
+
- family-names: Montoya
|
| 113 |
+
given-names: Jair
|
| 114 |
+
- family-names: Woodman
|
| 115 |
+
given-names: Marmaduke
|
| 116 |
+
- family-names: Lee
|
| 117 |
+
given-names: Ingoo
|
| 118 |
+
- family-names: Schulz
|
| 119 |
+
given-names: Martin
|
| 120 |
+
- family-names: Foti
|
| 121 |
+
given-names: Nick
|
| 122 |
+
- family-names: Nangini
|
| 123 |
+
given-names: Cathy
|
| 124 |
+
- family-names: García Alanis
|
| 125 |
+
given-names: José C
|
| 126 |
+
- family-names: Binns
|
| 127 |
+
given-names: Thomas S
|
| 128 |
+
- family-names: Orfanos
|
| 129 |
+
given-names: Dimitri Papadopoulos
|
| 130 |
+
- family-names: Hauk
|
| 131 |
+
given-names: Olaf
|
| 132 |
+
- family-names: Maddox
|
| 133 |
+
given-names: Ross
|
| 134 |
+
- family-names: LaPlante
|
| 135 |
+
given-names: Roan
|
| 136 |
+
- family-names: Drew
|
| 137 |
+
given-names: Ashley
|
| 138 |
+
- family-names: Dinh
|
| 139 |
+
given-names: Christoph
|
| 140 |
+
- family-names: Dumas
|
| 141 |
+
given-names: Guillaume
|
| 142 |
+
- name: Martin
|
| 143 |
+
- family-names: Benerradi
|
| 144 |
+
given-names: Johann
|
| 145 |
+
- family-names: Hartmann
|
| 146 |
+
given-names: Thomas
|
| 147 |
+
- family-names: Ort
|
| 148 |
+
given-names: Eduard
|
| 149 |
+
- family-names: Billinger
|
| 150 |
+
given-names: Martin
|
| 151 |
+
- family-names: Pasler
|
| 152 |
+
given-names: Paul
|
| 153 |
+
- family-names: Repplinger
|
| 154 |
+
given-names: Stefan
|
| 155 |
+
- family-names: Rudiuk
|
| 156 |
+
given-names: Alexander
|
| 157 |
+
- family-names: Radanovic
|
| 158 |
+
given-names: Ana
|
| 159 |
+
- family-names: Buran
|
| 160 |
+
given-names: Brad
|
| 161 |
+
- family-names: Woessner
|
| 162 |
+
given-names: Jacob
|
| 163 |
+
- family-names: Massias
|
| 164 |
+
given-names: Mathurin
|
| 165 |
+
- family-names: Hämäläinen
|
| 166 |
+
given-names: Matti
|
| 167 |
+
- family-names: Sripad
|
| 168 |
+
given-names: Praveen
|
| 169 |
+
- family-names: Chirkov
|
| 170 |
+
given-names: Valerii
|
| 171 |
+
- family-names: Mullins
|
| 172 |
+
given-names: Christopher
|
| 173 |
+
- family-names: Raimundo
|
| 174 |
+
given-names: Félix
|
| 175 |
+
- family-names: Belonosov
|
| 176 |
+
given-names: Gennadiy
|
| 177 |
+
- family-names: Kaneda
|
| 178 |
+
given-names: Michiru
|
| 179 |
+
- family-names: Alday
|
| 180 |
+
given-names: Phillip
|
| 181 |
+
- family-names: Pari
|
| 182 |
+
given-names: Ram
|
| 183 |
+
- family-names: Kornblith
|
| 184 |
+
given-names: Simon
|
| 185 |
+
- family-names: Halchenko
|
| 186 |
+
given-names: Yaroslav
|
| 187 |
+
- family-names: Luo
|
| 188 |
+
given-names: Yu-Han
|
| 189 |
+
- family-names: Gramfort
|
| 190 |
+
given-names: Alexandre
|
| 191 |
+
- family-names: Kasper
|
| 192 |
+
given-names: Johannes
|
| 193 |
+
- family-names: Doelling
|
| 194 |
+
given-names: Keith
|
| 195 |
+
- family-names: Jensen
|
| 196 |
+
given-names: Mads
|
| 197 |
+
- family-names: Ruuskanen
|
| 198 |
+
given-names: Santeri
|
| 199 |
+
- family-names: Kern
|
| 200 |
+
given-names: Simon
|
| 201 |
+
- family-names: Gahlot
|
| 202 |
+
given-names: Tanay
|
| 203 |
+
- family-names: Nunes
|
| 204 |
+
given-names: Adonay
|
| 205 |
+
- family-names: Gütlin
|
| 206 |
+
given-names: Dirk
|
| 207 |
+
- family-names: Heinila
|
| 208 |
+
given-names: Erkka
|
| 209 |
+
- family-names: Armeni
|
| 210 |
+
given-names: Kristijan
|
| 211 |
+
- name: kjs
|
| 212 |
+
- family-names: Weinstein
|
| 213 |
+
given-names: Alejandro
|
| 214 |
+
- family-names: Lamus
|
| 215 |
+
given-names: Camilo
|
| 216 |
+
- family-names: Galván
|
| 217 |
+
given-names: Catalina María
|
| 218 |
+
- family-names: Moënne-Loccoz
|
| 219 |
+
given-names: Cristóbal
|
| 220 |
+
- family-names: Altukhov
|
| 221 |
+
given-names: Dmitrii
|
| 222 |
+
- family-names: Peterson
|
| 223 |
+
given-names: Erica
|
| 224 |
+
- family-names: Hanna
|
| 225 |
+
given-names: Jevri
|
| 226 |
+
- family-names: Houck
|
| 227 |
+
given-names: Jon
|
| 228 |
+
- family-names: Klein
|
| 229 |
+
given-names: Natalie
|
| 230 |
+
- family-names: Roujansky
|
| 231 |
+
given-names: Paul
|
| 232 |
+
- family-names: Luke
|
| 233 |
+
given-names: Rob
|
| 234 |
+
- family-names: Rantala
|
| 235 |
+
given-names: Antti
|
| 236 |
+
- family-names: Maess
|
| 237 |
+
given-names: Burkhard
|
| 238 |
+
- family-names: Forster
|
| 239 |
+
given-names: Carina
|
| 240 |
+
- family-names: O'Reilly
|
| 241 |
+
given-names: Christian
|
| 242 |
+
- family-names: Welke
|
| 243 |
+
given-names: Dominik
|
| 244 |
+
- family-names: Welke
|
| 245 |
+
given-names: Dominik
|
| 246 |
+
- family-names: Kolkhorst
|
| 247 |
+
given-names: Henrich
|
| 248 |
+
- family-names: Banville
|
| 249 |
+
given-names: Hubert
|
| 250 |
+
- family-names: Zhang
|
| 251 |
+
given-names: Jack
|
| 252 |
+
- family-names: Maksymenko
|
| 253 |
+
given-names: Kostiantyn
|
| 254 |
+
- family-names: Clarke
|
| 255 |
+
given-names: Maggie
|
| 256 |
+
- family-names: Anelli
|
| 257 |
+
given-names: Matteo
|
| 258 |
+
- family-names: Straube
|
| 259 |
+
given-names: Michael
|
| 260 |
+
- family-names: Chapochnikov
|
| 261 |
+
given-names: Nikolai
|
| 262 |
+
- family-names: Bannier
|
| 263 |
+
given-names: Pierre-Antoine
|
| 264 |
+
- family-names: Choudhary
|
| 265 |
+
given-names: Saket
|
| 266 |
+
- family-names: Férat
|
| 267 |
+
given-names: Victor
|
| 268 |
+
- family-names: Kim
|
| 269 |
+
given-names: Cora
|
| 270 |
+
- family-names: Klotzsche
|
| 271 |
+
given-names: Felix
|
| 272 |
+
- family-names: Wong
|
| 273 |
+
given-names: Fu-Te
|
| 274 |
+
- family-names: Kojcic
|
| 275 |
+
given-names: Ivana
|
| 276 |
+
- family-names: Nielsen
|
| 277 |
+
given-names: Jesper Duemose
|
| 278 |
+
- family-names: Lankinen
|
| 279 |
+
given-names: Kaisu
|
| 280 |
+
- family-names: Tabavi
|
| 281 |
+
given-names: Kambiz
|
| 282 |
+
- family-names: Thibault
|
| 283 |
+
given-names: Louis
|
| 284 |
+
- family-names: Gerster
|
| 285 |
+
given-names: Moritz
|
| 286 |
+
- family-names: Alibou
|
| 287 |
+
given-names: Nabil
|
| 288 |
+
- family-names: Gayraud
|
| 289 |
+
given-names: Nathalie
|
| 290 |
+
- family-names: Ward
|
| 291 |
+
given-names: Nick
|
| 292 |
+
- family-names: Chu
|
| 293 |
+
given-names: Qian
|
| 294 |
+
- family-names: Herbst
|
| 295 |
+
given-names: Sophie
|
| 296 |
+
- family-names: Ma
|
| 297 |
+
given-names: Tom
|
| 298 |
+
- family-names: Radanovic
|
| 299 |
+
given-names: Ana
|
| 300 |
+
- family-names: Quinn
|
| 301 |
+
given-names: Andrew
|
| 302 |
+
- family-names: Gauthier
|
| 303 |
+
given-names: Antoine
|
| 304 |
+
- family-names: Pinsard
|
| 305 |
+
given-names: Basile
|
| 306 |
+
- family-names: Stephen
|
| 307 |
+
given-names: Emily
|
| 308 |
+
- family-names: Hornberger
|
| 309 |
+
given-names: Erik
|
| 310 |
+
- family-names: Hathaway
|
| 311 |
+
given-names: Evan
|
| 312 |
+
- family-names: Kalenkovich
|
| 313 |
+
given-names: Evgenii
|
| 314 |
+
- family-names: Mamashli
|
| 315 |
+
given-names: Fahimeh
|
| 316 |
+
- family-names: O'Neill
|
| 317 |
+
given-names: George
|
| 318 |
+
- family-names: Marinato
|
| 319 |
+
given-names: Giorgio
|
| 320 |
+
- family-names: Anevar
|
| 321 |
+
given-names: Hafeza
|
| 322 |
+
- family-names: Abdelhedi
|
| 323 |
+
given-names: Hamza
|
| 324 |
+
- family-names: Sosulski
|
| 325 |
+
given-names: Jan
|
| 326 |
+
- family-names: Stout
|
| 327 |
+
given-names: Jeff
|
| 328 |
+
- family-names: Calder-Travis
|
| 329 |
+
given-names: Joshua
|
| 330 |
+
- family-names: Zhu
|
| 331 |
+
given-names: Judy D
|
| 332 |
+
- family-names: Eisenman
|
| 333 |
+
given-names: Larry
|
| 334 |
+
- family-names: Esch
|
| 335 |
+
given-names: Lorenz
|
| 336 |
+
- family-names: Dovgialo
|
| 337 |
+
given-names: Marian
|
| 338 |
+
- family-names: Barascud
|
| 339 |
+
given-names: Nicolas
|
| 340 |
+
- family-names: Legrand
|
| 341 |
+
given-names: Nicolas
|
| 342 |
+
- family-names: Kapralov
|
| 343 |
+
given-names: Nikolai
|
| 344 |
+
- family-names: Molfese
|
| 345 |
+
given-names: Peter J
|
| 346 |
+
- family-names: Falach
|
| 347 |
+
given-names: Rotem
|
| 348 |
+
- family-names: Deslauriers-Gauthier
|
| 349 |
+
given-names: Samuel
|
| 350 |
+
- family-names: Cotroneo
|
| 351 |
+
given-names: Silvia
|
| 352 |
+
- family-names: Matindi
|
| 353 |
+
given-names: Steve
|
| 354 |
+
- family-names: Bierer
|
| 355 |
+
given-names: Steven
|
| 356 |
+
- family-names: Papadopoulo
|
| 357 |
+
given-names: Theodore
|
| 358 |
+
- family-names: Binns
|
| 359 |
+
given-names: Thomas Samuel
|
| 360 |
+
- family-names: Stenner
|
| 361 |
+
given-names: Tristan
|
| 362 |
+
- family-names: Peterson
|
| 363 |
+
given-names: Victoria
|
| 364 |
+
- family-names: Baratz
|
| 365 |
+
given-names: Zvi
|
| 366 |
+
- family-names: Tonin
|
| 367 |
+
given-names: Alessandro
|
| 368 |
+
- family-names: Kovrig
|
| 369 |
+
given-names: Alexander
|
| 370 |
+
- family-names: Pascarella
|
| 371 |
+
given-names: Annalisa
|
| 372 |
+
- family-names: Karekal
|
| 373 |
+
given-names: Apoorva
|
| 374 |
+
- family-names: Aristimunha
|
| 375 |
+
given-names: Bruno
|
| 376 |
+
- family-names: de la Torre
|
| 377 |
+
given-names: Carlos
|
| 378 |
+
- family-names: Gohil
|
| 379 |
+
given-names: Chetan
|
| 380 |
+
- family-names: Zhao
|
| 381 |
+
given-names: Christina
|
| 382 |
+
- family-names: Krzemiński
|
| 383 |
+
given-names: Dominik
|
| 384 |
+
- family-names: Makowski
|
| 385 |
+
given-names: Dominique
|
| 386 |
+
- family-names: Mikulan
|
| 387 |
+
given-names: Ezequiel
|
| 388 |
+
- family-names: Hofer
|
| 389 |
+
given-names: Florian
|
| 390 |
+
- family-names: Ritz
|
| 391 |
+
given-names: Harrison
|
| 392 |
+
- family-names: Schiratti
|
| 393 |
+
given-names: Jean-Baptiste
|
| 394 |
+
- family-names: Evans
|
| 395 |
+
given-names: Jen
|
| 396 |
+
- family-names: Herforth
|
| 397 |
+
given-names: Johannes
|
| 398 |
+
- family-names: Veillette
|
| 399 |
+
given-names: John
|
| 400 |
+
- family-names: Drew
|
| 401 |
+
given-names: Jordan
|
| 402 |
+
- family-names: Teves
|
| 403 |
+
given-names: Joshua
|
| 404 |
+
- family-names: Mathewson
|
| 405 |
+
given-names: Kyle
|
| 406 |
+
- family-names: Gwilliams
|
| 407 |
+
given-names: Laura
|
| 408 |
+
- family-names: Lementec
|
| 409 |
+
given-names: Laurent
|
| 410 |
+
- family-names: Varghese
|
| 411 |
+
given-names: Lenny
|
| 412 |
+
- family-names: Hamilton
|
| 413 |
+
given-names: Liberty
|
| 414 |
+
- family-names: Gemein
|
| 415 |
+
given-names: Lukas
|
| 416 |
+
- family-names: Hecker
|
| 417 |
+
given-names: Lukas
|
| 418 |
+
- name: Lx37
|
| 419 |
+
- family-names: van Es
|
| 420 |
+
given-names: Mats
|
| 421 |
+
- family-names: Boggess
|
| 422 |
+
given-names: Matt
|
| 423 |
+
- family-names: Eberlein
|
| 424 |
+
given-names: Matthias
|
| 425 |
+
- family-names: Žák
|
| 426 |
+
given-names: Michal
|
| 427 |
+
- family-names: Sherif
|
| 428 |
+
given-names: Mohamed
|
| 429 |
+
- family-names: Kozhemiako
|
| 430 |
+
given-names: Nataliia
|
| 431 |
+
- family-names: Srinivasan
|
| 432 |
+
given-names: Naveen
|
| 433 |
+
- family-names: Wilming
|
| 434 |
+
given-names: Niklas
|
| 435 |
+
- family-names: Kozynets
|
| 436 |
+
given-names: Oleh
|
| 437 |
+
- family-names: Ablin
|
| 438 |
+
given-names: Pierre
|
| 439 |
+
- family-names: Das
|
| 440 |
+
given-names: Proloy
|
| 441 |
+
- family-names: Bertrand
|
| 442 |
+
given-names: Quentin
|
| 443 |
+
- family-names: Shoorangiz
|
| 444 |
+
given-names: Reza
|
| 445 |
+
- family-names: Scholz
|
| 446 |
+
given-names: Richard
|
| 447 |
+
- family-names: Hübner
|
| 448 |
+
given-names: Rodrigo
|
| 449 |
+
- family-names: Sommariva
|
| 450 |
+
given-names: Sara
|
| 451 |
+
- family-names: Er
|
| 452 |
+
given-names: Sena
|
| 453 |
+
- family-names: Khan
|
| 454 |
+
given-names: Sheraz
|
| 455 |
+
- family-names: Datta
|
| 456 |
+
given-names: Sumalyo
|
| 457 |
+
- family-names: Donoghue
|
| 458 |
+
given-names: Thomas
|
| 459 |
+
- family-names: Jochmann
|
| 460 |
+
given-names: Thomas
|
| 461 |
+
- family-names: Merk
|
| 462 |
+
given-names: Timon
|
| 463 |
+
- family-names: Flak
|
| 464 |
+
given-names: Tod
|
| 465 |
+
- family-names: Dupré la Tour
|
| 466 |
+
given-names: Tom
|
| 467 |
+
- family-names: NessAiver
|
| 468 |
+
given-names: Tziona
|
| 469 |
+
- name: akshay0724
|
| 470 |
+
- name: sviter
|
| 471 |
+
- family-names: Earle-Richardson
|
| 472 |
+
given-names: Aaron
|
| 473 |
+
- family-names: Hindle
|
| 474 |
+
given-names: Abram
|
| 475 |
+
- family-names: Koutsou
|
| 476 |
+
given-names: Achilleas
|
| 477 |
+
- family-names: Fecker
|
| 478 |
+
given-names: Adeline
|
| 479 |
+
- family-names: Wagner
|
| 480 |
+
given-names: Adina
|
| 481 |
+
- family-names: Ciok
|
| 482 |
+
given-names: Alex
|
| 483 |
+
- family-names: Lepauvre
|
| 484 |
+
given-names: Alex
|
| 485 |
+
- family-names: Kiefer
|
| 486 |
+
given-names: Alexander
|
| 487 |
+
- family-names: Gilbert
|
| 488 |
+
given-names: Andy
|
| 489 |
+
- family-names: Pradhan
|
| 490 |
+
given-names: Aniket
|
| 491 |
+
- family-names: Padee
|
| 492 |
+
given-names: Anna
|
| 493 |
+
- family-names: Dubarry
|
| 494 |
+
given-names: Anne-Sophie
|
| 495 |
+
- family-names: Collas
|
| 496 |
+
given-names: Antoine
|
| 497 |
+
- family-names: Waniek
|
| 498 |
+
given-names: Anton Nikolas
|
| 499 |
+
- family-names: Singhal
|
| 500 |
+
given-names: Archit
|
| 501 |
+
- family-names: Rokem
|
| 502 |
+
given-names: Ariel
|
| 503 |
+
- family-names: Pelzer
|
| 504 |
+
given-names: Arne
|
| 505 |
+
- family-names: Hurst
|
| 506 |
+
given-names: Austin
|
| 507 |
+
- family-names: Jin
|
| 508 |
+
given-names: Beige Jerry
|
| 509 |
+
- family-names: Beasley
|
| 510 |
+
given-names: Ben
|
| 511 |
+
- family-names: Nicenboim
|
| 512 |
+
given-names: Bruno
|
| 513 |
+
- family-names: de la Torre
|
| 514 |
+
given-names: Carlos
|
| 515 |
+
- family-names: Clauss
|
| 516 |
+
given-names: Christian
|
| 517 |
+
- family-names: Mista
|
| 518 |
+
given-names: Christian
|
| 519 |
+
- family-names: Kechris
|
| 520 |
+
given-names: Christodoulos
|
| 521 |
+
- family-names: Li
|
| 522 |
+
given-names: Chun-Hui
|
| 523 |
+
- family-names: Braboszcz
|
| 524 |
+
given-names: Claire
|
| 525 |
+
- family-names: Schad
|
| 526 |
+
given-names: Daniel C
|
| 527 |
+
- family-names: Hasegan
|
| 528 |
+
given-names: Daniel
|
| 529 |
+
- family-names: Tse
|
| 530 |
+
given-names: Daniel
|
| 531 |
+
- family-names: Sleiter
|
| 532 |
+
given-names: Darin Erat
|
| 533 |
+
- family-names: Haslacher
|
| 534 |
+
given-names: David
|
| 535 |
+
- family-names: Sabbagh
|
| 536 |
+
given-names: David
|
| 537 |
+
- family-names: Kostas
|
| 538 |
+
given-names: Demetres
|
| 539 |
+
- family-names: Petkova
|
| 540 |
+
given-names: Desislava
|
| 541 |
+
- family-names: Issagaliyeva
|
| 542 |
+
given-names: Dinara
|
| 543 |
+
- family-names: Das
|
| 544 |
+
given-names: Diptyajit
|
| 545 |
+
- family-names: Wetzel
|
| 546 |
+
given-names: Dominik
|
| 547 |
+
- family-names: Eich
|
| 548 |
+
given-names: Eberhard
|
| 549 |
+
- family-names: DuPre
|
| 550 |
+
given-names: Elizabeth
|
| 551 |
+
- family-names: Lau
|
| 552 |
+
given-names: Ellen
|
| 553 |
+
- family-names: Olivetti
|
| 554 |
+
given-names: Emanuele
|
| 555 |
+
- family-names: Zhang
|
| 556 |
+
given-names: Emma
|
| 557 |
+
- family-names: Ferdman
|
| 558 |
+
given-names: Emmanuel
|
| 559 |
+
- family-names: Çelik
|
| 560 |
+
given-names: Emrecan
|
| 561 |
+
- family-names: Varano
|
| 562 |
+
given-names: Enrico
|
| 563 |
+
- family-names: Altamiranda
|
| 564 |
+
given-names: Enzo
|
| 565 |
+
- family-names: Brayet
|
| 566 |
+
given-names: Eric
|
| 567 |
+
- family-names: de Montalivet
|
| 568 |
+
given-names: Etienne
|
| 569 |
+
- family-names: Goldstein
|
| 570 |
+
given-names: Evgeny
|
| 571 |
+
- family-names: Mamashli
|
| 572 |
+
given-names: Fahimeh
|
| 573 |
+
- family-names: Negahbani
|
| 574 |
+
given-names: Farzin
|
| 575 |
+
- family-names: Zamberlan
|
| 576 |
+
given-names: Federico
|
| 577 |
+
- family-names: Pop
|
| 578 |
+
given-names: Florin
|
| 579 |
+
- family-names: Weber
|
| 580 |
+
given-names: Frederik D
|
| 581 |
+
- family-names: Tan
|
| 582 |
+
given-names: Gansheng
|
| 583 |
+
- family-names: Brookshire
|
| 584 |
+
given-names: Geoff
|
| 585 |
+
- family-names: O'Neill
|
| 586 |
+
given-names: George
|
| 587 |
+
- name: Giulio
|
| 588 |
+
- family-names: Reina
|
| 589 |
+
given-names: Gonzalo
|
| 590 |
+
- family-names: Maymandi
|
| 591 |
+
given-names: Hamid
|
| 592 |
+
- family-names: Arzoo
|
| 593 |
+
given-names: Hasrat Ali
|
| 594 |
+
- family-names: Sonntag
|
| 595 |
+
given-names: Hermann
|
| 596 |
+
- family-names: Ye
|
| 597 |
+
given-names: Hongjiang
|
| 598 |
+
- family-names: Shin
|
| 599 |
+
given-names: Hyonyoung
|
| 600 |
+
- family-names: Elmas
|
| 601 |
+
given-names: Hüseyin Orkun
|
| 602 |
+
- family-names: AZZ
|
| 603 |
+
given-names: Ilian
|
| 604 |
+
- family-names: Machairas
|
| 605 |
+
given-names: Ilias
|
| 606 |
+
- family-names: Zubarev
|
| 607 |
+
given-names: Ivan
|
| 608 |
+
- family-names: de Jong
|
| 609 |
+
given-names: Ivo
|
| 610 |
+
- family-names: Phelan
|
| 611 |
+
given-names: Jacob
|
| 612 |
+
- family-names: Kaczmarzyk
|
| 613 |
+
given-names: Jakub
|
| 614 |
+
- family-names: Zerfowski
|
| 615 |
+
given-names: Jan
|
| 616 |
+
- family-names: van den Bosch
|
| 617 |
+
given-names: Jasper J F
|
| 618 |
+
- family-names: Van Der Donckt
|
| 619 |
+
given-names: Jeroen
|
| 620 |
+
- family-names: van der Meer
|
| 621 |
+
given-names: Johan
|
| 622 |
+
- family-names: Niediek
|
| 623 |
+
given-names: Johannes
|
| 624 |
+
- family-names: Koen
|
| 625 |
+
given-names: Josh
|
| 626 |
+
- family-names: Bear
|
| 627 |
+
given-names: Joshua J
|
| 628 |
+
- family-names: Dammers
|
| 629 |
+
given-names: Juergen
|
| 630 |
+
- family-names: Galán
|
| 631 |
+
given-names: Julia Guiomar Niso
|
| 632 |
+
- family-names: Welzel
|
| 633 |
+
given-names: Julius
|
| 634 |
+
- family-names: Slama
|
| 635 |
+
given-names: Katarina
|
| 636 |
+
- family-names: Al-Amir
|
| 637 |
+
given-names: Katia
|
| 638 |
+
- family-names: Leinweber
|
| 639 |
+
given-names: Katrin
|
| 640 |
+
- family-names: Grabot
|
| 641 |
+
given-names: Laetitia
|
| 642 |
+
- family-names: Andersen
|
| 643 |
+
given-names: Lau Møller
|
| 644 |
+
- family-names: Almeida
|
| 645 |
+
given-names: Leonardo Rochael
|
| 646 |
+
- family-names: Barbosa
|
| 647 |
+
given-names: Leonardo S
|
| 648 |
+
- family-names: Alfine
|
| 649 |
+
given-names: Lorenzo
|
| 650 |
+
- family-names: Hejtmánek
|
| 651 |
+
given-names: Lukáš
|
| 652 |
+
- family-names: Balatsko
|
| 653 |
+
given-names: Maksym
|
| 654 |
+
- family-names: Kitzbichler
|
| 655 |
+
given-names: Manfred
|
| 656 |
+
- family-names: Kumar
|
| 657 |
+
given-names: Manoj
|
| 658 |
+
- family-names: Kadwani
|
| 659 |
+
given-names: Manorama
|
| 660 |
+
- family-names: Sutela
|
| 661 |
+
given-names: Manu
|
| 662 |
+
- family-names: Koculak
|
| 663 |
+
given-names: Marcin
|
| 664 |
+
- family-names: Henney
|
| 665 |
+
given-names: Mark
|
| 666 |
+
- family-names: BaBer
|
| 667 |
+
given-names: Martin
|
| 668 |
+
- family-names: Oberg
|
| 669 |
+
given-names: Martin
|
| 670 |
+
- family-names: van Harmelen
|
| 671 |
+
given-names: Martin
|
| 672 |
+
- family-names: Scheltienne
|
| 673 |
+
given-names: Mathieu
|
| 674 |
+
- family-names: Courtemanche
|
| 675 |
+
given-names: Matt
|
| 676 |
+
- family-names: Tucker
|
| 677 |
+
given-names: Matt
|
| 678 |
+
- family-names: Visconti di Oleggio Castello
|
| 679 |
+
given-names: Matteo
|
| 680 |
+
- family-names: Dold
|
| 681 |
+
given-names: Matthias
|
| 682 |
+
- family-names: Toivonen
|
| 683 |
+
given-names: Matti
|
| 684 |
+
- family-names: Shader
|
| 685 |
+
given-names: Maureen
|
| 686 |
+
- family-names: Cespedes
|
| 687 |
+
given-names: Mauricio
|
| 688 |
+
- family-names: Krause
|
| 689 |
+
given-names: Michael
|
| 690 |
+
- family-names: Rybář
|
| 691 |
+
given-names: Milan
|
| 692 |
+
- family-names: He
|
| 693 |
+
given-names: Mingjian
|
| 694 |
+
- family-names: Daneshzand
|
| 695 |
+
given-names: Mohammad
|
| 696 |
+
- name: Mojackhak
|
| 697 |
+
- family-names: Fourcaud-Trocmé
|
| 698 |
+
given-names: Nicolas
|
| 699 |
+
- family-names: Gensollen
|
| 700 |
+
given-names: Nicolas
|
| 701 |
+
- family-names: Proulx
|
| 702 |
+
given-names: Nicole
|
| 703 |
+
- family-names: Focke
|
| 704 |
+
given-names: Niels
|
| 705 |
+
- family-names: Chalas
|
| 706 |
+
given-names: Nikolas
|
| 707 |
+
- family-names: Markowitz
|
| 708 |
+
given-names: Noah
|
| 709 |
+
- family-names: Shubi
|
| 710 |
+
given-names: Omer
|
| 711 |
+
- family-names: Mainar
|
| 712 |
+
given-names: Pablo
|
| 713 |
+
- family-names: Sundaram
|
| 714 |
+
given-names: Padma
|
| 715 |
+
- family-names: Anders
|
| 716 |
+
given-names: Paul
|
| 717 |
+
- family-names: Silva
|
| 718 |
+
given-names: Pedro
|
| 719 |
+
- family-names: Guetschel
|
| 720 |
+
given-names: Pierre
|
| 721 |
+
- family-names: Li
|
| 722 |
+
given-names: Quanliang
|
| 723 |
+
- family-names: Barthélemy
|
| 724 |
+
given-names: Quentin
|
| 725 |
+
- family-names: Nadkarni
|
| 726 |
+
given-names: Rahul
|
| 727 |
+
- family-names: Gatti
|
| 728 |
+
given-names: Ramiro
|
| 729 |
+
- family-names: Apariciogarcia
|
| 730 |
+
given-names: Ramonapariciog
|
| 731 |
+
- family-names: Aagaard
|
| 732 |
+
given-names: Rasmus
|
| 733 |
+
- family-names: Nasri
|
| 734 |
+
given-names: Reza
|
| 735 |
+
- family-names: Koehler
|
| 736 |
+
given-names: Richard
|
| 737 |
+
- family-names: Stargardsky
|
| 738 |
+
given-names: Riessarius
|
| 739 |
+
- family-names: Oostenveld
|
| 740 |
+
given-names: Robert
|
| 741 |
+
- family-names: Seymour
|
| 742 |
+
given-names: Robert
|
| 743 |
+
- family-names: Schirrmeister
|
| 744 |
+
given-names: Robin Tibor
|
| 745 |
+
- family-names: Jin
|
| 746 |
+
given-names: Rongfei
|
| 747 |
+
- family-names: Wieske
|
| 748 |
+
given-names: Roy Eric
|
| 749 |
+
- family-names: Law
|
| 750 |
+
given-names: Ryan
|
| 751 |
+
- family-names: Pai
|
| 752 |
+
given-names: Sagun
|
| 753 |
+
- family-names: Perry
|
| 754 |
+
given-names: Sam
|
| 755 |
+
- family-names: Louviot
|
| 756 |
+
given-names: Samuel
|
| 757 |
+
- family-names: Martínez
|
| 758 |
+
given-names: Santi
|
| 759 |
+
- family-names: Saha
|
| 760 |
+
given-names: Sawradip
|
| 761 |
+
- family-names: Mathot
|
| 762 |
+
given-names: Sebastiaan
|
| 763 |
+
- family-names: Jentschke
|
| 764 |
+
given-names: Sebastian
|
| 765 |
+
- family-names: Major
|
| 766 |
+
given-names: Sebastian
|
| 767 |
+
- family-names: Treguer
|
| 768 |
+
given-names: Sebastien
|
| 769 |
+
- family-names: Castaño
|
| 770 |
+
given-names: Sebastián
|
| 771 |
+
- family-names: Deng
|
| 772 |
+
given-names: Senwen
|
| 773 |
+
- family-names: Antopolskiy
|
| 774 |
+
given-names: Sergey
|
| 775 |
+
- family-names: Shirazi
|
| 776 |
+
given-names: Seyed (Yahya)
|
| 777 |
+
- family-names: Keshari
|
| 778 |
+
given-names: Shresth
|
| 779 |
+
- family-names: Baral
|
| 780 |
+
given-names: Shristi
|
| 781 |
+
- family-names: Baral
|
| 782 |
+
given-names: Shristi
|
| 783 |
+
- family-names: Wong
|
| 784 |
+
given-names: Simeon
|
| 785 |
+
- family-names: Wong
|
| 786 |
+
given-names: Simeon
|
| 787 |
+
- family-names: Hofmann
|
| 788 |
+
given-names: Simon M
|
| 789 |
+
- family-names: Poil
|
| 790 |
+
given-names: Simon-Shlomo
|
| 791 |
+
- family-names: Foslien
|
| 792 |
+
given-names: Sondre
|
| 793 |
+
- family-names: Singh
|
| 794 |
+
given-names: Sourav
|
| 795 |
+
- family-names: Chambon
|
| 796 |
+
given-names: Stanislas
|
| 797 |
+
- family-names: Magnússon
|
| 798 |
+
given-names: Steinn Hauser
|
| 799 |
+
- family-names: Bethard
|
| 800 |
+
given-names: Steven
|
| 801 |
+
- family-names: Gutstein
|
| 802 |
+
given-names: Steven M
|
| 803 |
+
- family-names: Meyer
|
| 804 |
+
given-names: Svea Marie
|
| 805 |
+
- family-names: Wang
|
| 806 |
+
given-names: T
|
| 807 |
+
- family-names: Jayawardana
|
| 808 |
+
given-names: Tharupahan
|
| 809 |
+
- family-names: Moreau
|
| 810 |
+
given-names: Thomas
|
| 811 |
+
- family-names: Radman
|
| 812 |
+
given-names: Thomas
|
| 813 |
+
- family-names: Gates
|
| 814 |
+
given-names: Timothy
|
| 815 |
+
- family-names: Stone
|
| 816 |
+
given-names: Tom
|
| 817 |
+
- family-names: Clausner
|
| 818 |
+
given-names: Tommy
|
| 819 |
+
- family-names: Anijärv
|
| 820 |
+
given-names: Toomas Erik
|
| 821 |
+
- family-names: Kumaravel
|
| 822 |
+
given-names: Velu Prabhakar
|
| 823 |
+
- family-names: Xu
|
| 824 |
+
given-names: Wei
|
| 825 |
+
- family-names: Turner
|
| 826 |
+
given-names: Will
|
| 827 |
+
- family-names: Zuazo
|
| 828 |
+
given-names: Xabier de
|
| 829 |
+
- family-names: Xia
|
| 830 |
+
given-names: Xiaokai
|
| 831 |
+
- family-names: Zuo
|
| 832 |
+
given-names: Yiping
|
| 833 |
+
- family-names: Shen
|
| 834 |
+
given-names: Yixiao
|
| 835 |
+
- family-names: Truong
|
| 836 |
+
given-names: Young
|
| 837 |
+
- family-names: Zhang
|
| 838 |
+
given-names: Zhi
|
| 839 |
+
- family-names: ZENG
|
| 840 |
+
given-names: Ziyi
|
| 841 |
+
- name: btkcodedev
|
| 842 |
+
- name: buildqa
|
| 843 |
+
- name: luzpaz
|
| 844 |
+
- name: user27182
|
| 845 |
+
preferred-citation:
|
| 846 |
+
title: "MEG and EEG Data Analysis with MNE-Python"
|
| 847 |
+
journal: "Frontiers in Neuroscience"
|
| 848 |
+
type: article
|
| 849 |
+
year: 2013
|
| 850 |
+
volume: 7
|
| 851 |
+
issue: 267
|
| 852 |
+
start: 1
|
| 853 |
+
end: 13
|
| 854 |
+
doi: 10.3389/fnins.2013.00267
|
| 855 |
+
authors:
|
| 856 |
+
- family-names: Gramfort
|
| 857 |
+
given-names: Alexandre
|
| 858 |
+
- family-names: Luessi
|
| 859 |
+
given-names: Martin
|
| 860 |
+
- family-names: Larson
|
| 861 |
+
given-names: Eric
|
| 862 |
+
- family-names: Engemann
|
| 863 |
+
given-names: Denis A.
|
| 864 |
+
- family-names: Strohmeier
|
| 865 |
+
given-names: Daniel
|
| 866 |
+
- family-names: Brodbeck
|
| 867 |
+
given-names: Christian
|
| 868 |
+
- family-names: Goj
|
| 869 |
+
given-names: Roman
|
| 870 |
+
- family-names: Jas
|
| 871 |
+
given-names: Mainak
|
| 872 |
+
- family-names: Brooks
|
| 873 |
+
given-names: Teon
|
| 874 |
+
- family-names: Parkkonen
|
| 875 |
+
given-names: Lauri
|
| 876 |
+
- family-names: Hämäläinen
|
| 877 |
+
given-names: Matti S.
|
mne-python/source/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Contributing to MNE-Python
|
| 2 |
+
==========================
|
| 3 |
+
|
| 4 |
+
MNE-Python is maintained by a community of scientists and research labs. The project accepts contributions in the form of bug reports, fixes, feature additions, and documentation improvements (including typo corrections). The best way to start contributing is by [opening an issue](https://github.com/mne-tools/mne-python/issues/new/choose) on our GitHub page to discuss ideas for changes or enhancements, or to tell us about behavior that you think might be a bug. For *general troubleshooting* or *usage questions*, please consider posting your questions on our [MNE Forum](https://mne.discourse.group).
|
| 5 |
+
|
| 6 |
+
Users and contributors to MNE-Python are expected to follow our [code of conduct](https://github.com/mne-tools/.github/blob/main/CODE_OF_CONDUCT.md).
|
| 7 |
+
|
| 8 |
+
The [contributing guide](https://mne.tools/dev/development/contributing.html) has details on the preferred contribution workflow
|
| 9 |
+
and the recommended system configuration for a smooth contribution/development experience.
|
mne-python/source/LICENSE.txt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright 2011-2025 MNE-Python authors
|
| 2 |
+
|
| 3 |
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
| 4 |
+
|
| 5 |
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
| 6 |
+
|
| 7 |
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
| 8 |
+
|
| 9 |
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
| 10 |
+
|
| 11 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
mne-python/source/Makefile
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# simple makefile to simplify repetitive build env management tasks under posix
|
| 2 |
+
|
| 3 |
+
PYTHON ?= python
|
| 4 |
+
PYTESTS ?= py.test
|
| 5 |
+
CODESPELL_SKIPS ?= "doc/_build,doc/auto_*,*.fif,*.eve,*.gz,*.tgz,*.zip,*.mat,*.stc,*.label,*.w,*.bz2,*.annot,*.sulc,*.log,*.local-copy,*.orig_avg,*.inflated_avg,*.gii,*.pyc,*.doctree,*.pickle,*.inv,*.png,*.edf,*.touch,*.thickness,*.nofix,*.volume,*.defect_borders,*.mgh,lh.*,rh.*,COR-*,FreeSurferColorLUT.txt,*.examples,.xdebug_mris_calc,bad.segments,BadChannels,*.hist,empty_file,*.orig,*.js,*.map,*.ipynb,searchindex.dat,install_mne_c.rst,plot_*.rst,*.rst.txt,c_EULA.rst*,*.html,gdf_encodes.txt,*.svg,references.bib,*.css,*.edf,*.bdf,*.vhdr"
|
| 6 |
+
CODESPELL_DIRS ?= mne/ doc/ tutorials/ examples/
|
| 7 |
+
all: clean test-doc
|
| 8 |
+
|
| 9 |
+
clean-pyc:
|
| 10 |
+
find . -name "*.pyc" | xargs rm -f
|
| 11 |
+
|
| 12 |
+
clean-so:
|
| 13 |
+
find . -name "*.so" | xargs rm -f
|
| 14 |
+
find . -name "*.pyd" | xargs rm -f
|
| 15 |
+
|
| 16 |
+
clean-build:
|
| 17 |
+
rm -rf build dist
|
| 18 |
+
|
| 19 |
+
clean-ctags:
|
| 20 |
+
rm -f tags
|
| 21 |
+
|
| 22 |
+
clean-cache:
|
| 23 |
+
find . -name "__pycache__" | xargs rm -rf
|
| 24 |
+
|
| 25 |
+
clean: clean-build clean-pyc clean-so clean-ctags clean-cache
|
| 26 |
+
|
| 27 |
+
wheel:
|
| 28 |
+
$(PYTHON) -m build -w
|
| 29 |
+
|
| 30 |
+
sample_data:
|
| 31 |
+
@python -c "import mne; mne.datasets.sample.data_path(verbose=True);"
|
| 32 |
+
|
| 33 |
+
testing_data:
|
| 34 |
+
@python -c "import mne; mne.datasets.testing.data_path(verbose=True);"
|
| 35 |
+
|
| 36 |
+
test-no-network: in
|
| 37 |
+
sudo unshare -n -- sh -c 'MNE_SKIP_NETWORK_TESTS=1 py.test mne'
|
| 38 |
+
|
| 39 |
+
test-no-testing-data: in
|
| 40 |
+
@MNE_SKIP_TESTING_DATASET_TESTS=true \
|
| 41 |
+
$(PYTESTS) mne
|
| 42 |
+
|
| 43 |
+
test-doc: sample_data testing_data
|
| 44 |
+
$(PYTESTS) --tb=short --cov=mne --cov-report=xml --cov-branch --doctest-modules --doctest-ignore-import-errors --doctest-glob='*.rst' ./doc/ --ignore=./doc/auto_examples --ignore=./doc/auto_tutorials --ignore=./doc/_build --ignore=./doc/conf.py --ignore=doc/sphinxext --fulltrace
|
| 45 |
+
|
| 46 |
+
pre-commit:
|
| 47 |
+
@pre-commit run -a --show-diff-on-failure
|
| 48 |
+
|
| 49 |
+
# Aliases for stuff we used to support or users might think of
|
| 50 |
+
ruff: pre-commit
|
| 51 |
+
flake: pre-commit
|
| 52 |
+
pep: pre-commit
|
| 53 |
+
|
| 54 |
+
codespell: # running manually
|
| 55 |
+
@codespell --builtin clear,rare,informal,names,usage -w -i 3 -q 3 -S $(CODESPELL_SKIPS) --ignore-words=ignore_words.txt --uri-ignore-words-list=bu $(CODESPELL_DIRS)
|
| 56 |
+
|
| 57 |
+
check-readme: clean wheel
|
| 58 |
+
twine check dist/*
|
| 59 |
+
|
| 60 |
+
nesting:
|
| 61 |
+
@echo "Running import nesting tests"
|
| 62 |
+
@$(PYTESTS) mne/tests/test_import_nesting.py
|
mne-python/source/README.rst
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.. -*- mode: rst -*-
|
| 2 |
+
|
| 3 |
+
|MNE|
|
| 4 |
+
|
| 5 |
+
MNE-Python
|
| 6 |
+
==========
|
| 7 |
+
|
| 8 |
+
MNE-Python is an open-source Python package for exploring,
|
| 9 |
+
visualizing, and analyzing human neurophysiological data such as MEG, EEG, sEEG,
|
| 10 |
+
ECoG, and more. It includes modules for data input/output, preprocessing,
|
| 11 |
+
visualization, source estimation, time-frequency analysis, connectivity analysis,
|
| 12 |
+
machine learning, statistics, and more.
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
Documentation
|
| 16 |
+
^^^^^^^^^^^^^
|
| 17 |
+
|
| 18 |
+
`Documentation`_ for MNE-Python encompasses installation instructions, tutorials,
|
| 19 |
+
and examples for a wide variety of topics, contributing guidelines, and an API
|
| 20 |
+
reference.
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
Forum
|
| 24 |
+
^^^^^^
|
| 25 |
+
|
| 26 |
+
The `user forum`_ is the best place to ask questions about MNE-Python usage or
|
| 27 |
+
the contribution process. The forum also features job opportunities and other
|
| 28 |
+
announcements.
|
| 29 |
+
|
| 30 |
+
If you find a bug or have an idea for a new feature that should be added to
|
| 31 |
+
MNE-Python, please use the
|
| 32 |
+
`issue tracker <https://github.com/mne-tools/mne-python/issues/new/choose>`__ of
|
| 33 |
+
our GitHub repository.
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
Installation
|
| 37 |
+
^^^^^^^^^^^^
|
| 38 |
+
|
| 39 |
+
To install the latest stable version of MNE-Python with minimal dependencies
|
| 40 |
+
only, use pip_ in a terminal:
|
| 41 |
+
|
| 42 |
+
.. code-block:: console
|
| 43 |
+
|
| 44 |
+
$ pip install --upgrade mne
|
| 45 |
+
|
| 46 |
+
For more complete instructions, including our standalone installers and more
|
| 47 |
+
advanced installation methods, please refer to the `installation guide`_.
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
Get the development version
|
| 51 |
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| 52 |
+
|
| 53 |
+
To install the latest development version of MNE-Python using pip_, open a
|
| 54 |
+
terminal and type:
|
| 55 |
+
|
| 56 |
+
.. code-block:: console
|
| 57 |
+
|
| 58 |
+
$ pip install --upgrade https://github.com/mne-tools/mne-python/archive/refs/heads/main.zip
|
| 59 |
+
|
| 60 |
+
To clone the repository with `git <https://git-scm.com/>`__, open a terminal
|
| 61 |
+
and type:
|
| 62 |
+
|
| 63 |
+
.. code-block:: console
|
| 64 |
+
|
| 65 |
+
$ git clone https://github.com/mne-tools/mne-python.git
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
Dependencies
|
| 69 |
+
^^^^^^^^^^^^
|
| 70 |
+
|
| 71 |
+
The minimum required dependencies to run MNE-Python are:
|
| 72 |
+
|
| 73 |
+
.. ↓↓↓ BEGIN CORE DEPS LIST. DO NOT EDIT! HANDLED BY PRE-COMMIT HOOK ↓↓↓
|
| 74 |
+
|
| 75 |
+
- `Python <https://www.python.org>`__ ≥ 3.10
|
| 76 |
+
- `NumPy <https://numpy.org>`__ ≥ 1.26
|
| 77 |
+
- `SciPy <https://scipy.org>`__ ≥ 1.11
|
| 78 |
+
- `Matplotlib <https://matplotlib.org>`__ ≥ 3.8
|
| 79 |
+
- `Pooch <https://www.fatiando.org/pooch/latest/>`__ ≥ 1.5
|
| 80 |
+
- `tqdm <https://tqdm.github.io>`__
|
| 81 |
+
- `Jinja2 <https://palletsprojects.com/p/jinja/>`__
|
| 82 |
+
- `decorator <https://github.com/micheles/decorator>`__
|
| 83 |
+
- `lazy-loader <https://pypi.org/project/lazy_loader>`__ ≥ 0.3
|
| 84 |
+
- `packaging <https://packaging.pypa.io/en/stable/>`__
|
| 85 |
+
|
| 86 |
+
.. ↑↑↑ END CORE DEPS LIST. DO NOT EDIT! HANDLED BY PRE-COMMIT HOOK ↑↑↑
|
| 87 |
+
|
| 88 |
+
Contributing
|
| 89 |
+
^^^^^^^^^^^^
|
| 90 |
+
|
| 91 |
+
Please see the `contributing guidelines <https://mne.tools/dev/development/contributing.html>`__ on our documentation website.
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
About
|
| 95 |
+
^^^^^
|
| 96 |
+
|
| 97 |
+
+---------+------------+----------------+
|
| 98 |
+
| CI | |Codecov| | |Bandit| |
|
| 99 |
+
+---------+------------+----------------+
|
| 100 |
+
| Package | |PyPI| | |conda-forge| |
|
| 101 |
+
+---------+------------+----------------+
|
| 102 |
+
| Docs | |Docs| | |Discourse| |
|
| 103 |
+
+---------+------------+----------------+
|
| 104 |
+
| Meta | |Zenodo| | |OpenSSF| |
|
| 105 |
+
+---------+------------+----------------+
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
License
|
| 109 |
+
^^^^^^^
|
| 110 |
+
|
| 111 |
+
MNE-Python is licensed under the BSD-3-Clause license.
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
.. _Documentation: https://mne.tools/dev/
|
| 115 |
+
.. _user forum: https://mne.discourse.group
|
| 116 |
+
.. _installation guide: https://mne.tools/dev/install/index.html
|
| 117 |
+
.. _pip: https://pip.pypa.io/en/stable/
|
| 118 |
+
|
| 119 |
+
.. |PyPI| image:: https://img.shields.io/pypi/dm/mne.svg?label=PyPI
|
| 120 |
+
:target: https://pypi.org/project/mne/
|
| 121 |
+
|
| 122 |
+
.. |conda-forge| image:: https://img.shields.io/conda/dn/conda-forge/mne.svg?label=Conda
|
| 123 |
+
:target: https://anaconda.org/conda-forge/mne
|
| 124 |
+
|
| 125 |
+
.. |Docs| image:: https://img.shields.io/badge/Docs-online-green?label=Documentation
|
| 126 |
+
:target: https://mne.tools/dev/
|
| 127 |
+
|
| 128 |
+
.. |Zenodo| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.592483.svg
|
| 129 |
+
:target: https://doi.org/10.5281/zenodo.592483
|
| 130 |
+
|
| 131 |
+
.. |Discourse| image:: https://img.shields.io/discourse/status?label=Forum&server=https%3A%2F%2Fmne.discourse.group%2F
|
| 132 |
+
:target: https://mne.discourse.group/
|
| 133 |
+
|
| 134 |
+
.. |Codecov| image:: https://img.shields.io/codecov/c/github/mne-tools/mne-python?label=Coverage
|
| 135 |
+
:target: https://codecov.io/gh/mne-tools/mne-python
|
| 136 |
+
|
| 137 |
+
.. |Bandit| image:: https://img.shields.io/badge/Security-Bandit-yellow.svg
|
| 138 |
+
:target: https://github.com/PyCQA/bandit
|
| 139 |
+
|
| 140 |
+
.. |OpenSSF| image:: https://www.bestpractices.dev/projects/7783/badge
|
| 141 |
+
:target: https://www.bestpractices.dev/projects/7783
|
| 142 |
+
|
| 143 |
+
.. |MNE| image:: https://mne.tools/dev/_static/mne_logo_gray.svg
|
| 144 |
+
:target: https://mne.tools/dev/
|
mne-python/source/SECURITY.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Security Policy
|
| 2 |
+
|
| 3 |
+
## Supported Versions
|
| 4 |
+
|
| 5 |
+
New minor versions of MNE-Python are typically released twice per year.
|
| 6 |
+
Only the most current stable release is officially supported.
|
| 7 |
+
The unreleased, unstable "dev version" is also supported, though users
|
| 8 |
+
should beware that the API of the dev version is subject to change
|
| 9 |
+
without a proper 6-month deprecation cycle.
|
| 10 |
+
|
| 11 |
+
| Version | Supported |
|
| 12 |
+
| ------- | ------------------------ |
|
| 13 |
+
| 1.12.x | :heavy_check_mark: (dev) |
|
| 14 |
+
| 1.11.x | :heavy_check_mark: |
|
| 15 |
+
| < 1.11 | :x: |
|
| 16 |
+
|
| 17 |
+
## Reporting a Vulnerability
|
| 18 |
+
|
| 19 |
+
MNE-Python is software for analysis and visualization of brain activity
|
| 20 |
+
recorded with a variety of devices/modalities (EEG, MEG, ECoG, fNIRS, etc).
|
| 21 |
+
It is not expected that using MNE-Python will lead to security
|
| 22 |
+
vulnerabilities under normal use cases (i.e., running without administrator
|
| 23 |
+
privileges). However, if you think you have found a security vulnerability
|
| 24 |
+
in MNE-Python, **please do not report it as a GitHub issue**, in order to
|
| 25 |
+
keep the vulnerability confidential. Instead, please report it to
|
| 26 |
+
mne-core-dev-team@groups.io and include a description and proof-of-concept
|
| 27 |
+
that is [short and self-contained](http://www.sscce.org/).
|
| 28 |
+
|
| 29 |
+
Generally you will receive a response within one week. MNE-Python does not
|
| 30 |
+
award bounties for security vulnerabilities.
|
mne-python/source/__init__.py
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -*- coding: utf-8 -*-
|
| 2 |
+
"""
|
| 3 |
+
mne-python Project Package Initialization File
|
| 4 |
+
"""
|
mne-python/source/azure-pipelines.yml
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
trigger:
|
| 2 |
+
# start a new build for every push
|
| 3 |
+
batch: false
|
| 4 |
+
branches:
|
| 5 |
+
include:
|
| 6 |
+
- 'main'
|
| 7 |
+
- 'maint/*'
|
| 8 |
+
pr:
|
| 9 |
+
branches:
|
| 10 |
+
include:
|
| 11 |
+
- '*' # must quote since "*" is a YAML reserved character; we want a string
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
stages:
|
| 15 |
+
|
| 16 |
+
- stage: Check
|
| 17 |
+
jobs:
|
| 18 |
+
- job: Skip
|
| 19 |
+
pool:
|
| 20 |
+
vmImage: 'ubuntu-latest'
|
| 21 |
+
variables:
|
| 22 |
+
DECODE_PERCENTS: 'false'
|
| 23 |
+
RET: 'true'
|
| 24 |
+
BUILD_REASON: $(Build.Reason)
|
| 25 |
+
steps:
|
| 26 |
+
- bash: |
|
| 27 |
+
git_log=`git log --format=oneline -n 1 --skip=1`
|
| 28 |
+
echo "##vso[task.setvariable variable=log]$git_log"
|
| 29 |
+
- bash: echo "##vso[task.setvariable variable=RET]false"
|
| 30 |
+
condition: and(eq(variables.BUILD_REASON, 'PullRequest'), or(contains(variables.log, '[skip azp]'), contains(variables.log, '[azp skip]'), contains(variables.log, '[skip ci]'), contains(variables.log, '[ci skip]')))
|
| 31 |
+
- bash: echo "##vso[task.setvariable variable=start_main;isOutput=true]$RET"
|
| 32 |
+
name: result
|
| 33 |
+
|
| 34 |
+
- stage: Style
|
| 35 |
+
variables:
|
| 36 |
+
AZURE_CI: 'true'
|
| 37 |
+
jobs:
|
| 38 |
+
- job: All
|
| 39 |
+
pool:
|
| 40 |
+
vmImage: 'ubuntu-latest'
|
| 41 |
+
variables:
|
| 42 |
+
PYTHON_VERSION: '3.11'
|
| 43 |
+
PYTHON_ARCH: 'x64'
|
| 44 |
+
steps:
|
| 45 |
+
- bash: echo $(COMMIT_MSG)
|
| 46 |
+
- task: UsePythonVersion@0
|
| 47 |
+
inputs:
|
| 48 |
+
versionSpec: $(PYTHON_VERSION)
|
| 49 |
+
architecture: $(PYTHON_ARCH)
|
| 50 |
+
addToPath: true
|
| 51 |
+
displayName: 'Get Python'
|
| 52 |
+
- bash: |
|
| 53 |
+
set -eo pipefail
|
| 54 |
+
python -m pip install --progress-bar off --upgrade pip build
|
| 55 |
+
python -m pip install --progress-bar off -ve .[hdf5] --group=test
|
| 56 |
+
python -m pip uninstall -yq pytest-qt # don't want to set up display, etc. for this
|
| 57 |
+
pre-commit install --install-hooks
|
| 58 |
+
displayName: Install dependencies
|
| 59 |
+
- bash: |
|
| 60 |
+
make pre-commit
|
| 61 |
+
displayName: make pre-commit
|
| 62 |
+
condition: always()
|
| 63 |
+
- bash: |
|
| 64 |
+
make nesting
|
| 65 |
+
displayName: make nesting
|
| 66 |
+
condition: always()
|
| 67 |
+
- bash: |
|
| 68 |
+
make check-readme
|
| 69 |
+
displayName: make check-readme
|
| 70 |
+
condition: always()
|
| 71 |
+
- bash: mypy
|
| 72 |
+
displayName: mypy
|
| 73 |
+
condition: always()
|
| 74 |
+
- bash: vulture
|
| 75 |
+
displayName: vulture
|
| 76 |
+
condition: always()
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
- stage: Test
|
| 80 |
+
condition: and(succeeded(), eq(dependencies.Check.outputs['Skip.result.start_main'], 'true'))
|
| 81 |
+
dependsOn: ['Style', 'Check']
|
| 82 |
+
variables:
|
| 83 |
+
AZURE_CI: 'true'
|
| 84 |
+
jobs:
|
| 85 |
+
- job: Ultraslow_PG
|
| 86 |
+
pool:
|
| 87 |
+
vmImage: 'ubuntu-22.04'
|
| 88 |
+
variables:
|
| 89 |
+
DISPLAY: ':99'
|
| 90 |
+
OPENBLAS_NUM_THREADS: '1'
|
| 91 |
+
OMP_NUM_THREADS: '1'
|
| 92 |
+
MNE_TEST_ALLOW_SKIP: '^.*(PySide6 causes segfaults).*$'
|
| 93 |
+
MNE_BROWSER_PRECOMPUTE: 'false'
|
| 94 |
+
steps:
|
| 95 |
+
- bash: |
|
| 96 |
+
set -e
|
| 97 |
+
./tools/setup_xvfb.sh
|
| 98 |
+
sudo apt install -yq tcsh
|
| 99 |
+
displayName: 'Install Ubuntu dependencies'
|
| 100 |
+
- bash: |
|
| 101 |
+
source tools/get_minimal_commands.sh
|
| 102 |
+
displayName: 'Install minimal commands'
|
| 103 |
+
- bash: |
|
| 104 |
+
echo $PATH
|
| 105 |
+
mne_surf2bem --version
|
| 106 |
+
fsl_rigid_register --version
|
| 107 |
+
displayName: 'Test minimal commands'
|
| 108 |
+
- task: UsePythonVersion@0
|
| 109 |
+
inputs:
|
| 110 |
+
versionSpec: '3.12'
|
| 111 |
+
architecture: 'x64'
|
| 112 |
+
addToPath: true
|
| 113 |
+
displayName: 'Get Python'
|
| 114 |
+
- bash: |
|
| 115 |
+
set -e
|
| 116 |
+
python -m pip install --progress-bar off --upgrade pip
|
| 117 |
+
python -m pip install --progress-bar off "mne-qt-browser[opengl] @ git+https://github.com/mne-tools/mne-qt-browser.git" pyvista scikit-learn python-picard qtpy nibabel sphinx-gallery "PySide6!=6.8.0,!=6.8.0.1,!=6.8.1.1,!=6.9.1" pandas neo pymatreader antio defusedxml curryreader pymef
|
| 118 |
+
python -m pip uninstall -yq mne
|
| 119 |
+
python -m pip install --progress-bar off --upgrade -e . --group=test
|
| 120 |
+
displayName: 'Install dependencies with pip'
|
| 121 |
+
- bash: |
|
| 122 |
+
set -e
|
| 123 |
+
mne sys_info -pd
|
| 124 |
+
mne sys_info -pd | grep "qtpy .*(PySide6=.*)$"
|
| 125 |
+
displayName: Print config
|
| 126 |
+
- bash: |
|
| 127 |
+
set -e
|
| 128 |
+
LD_DEBUG=libs python -c "from PySide6.QtWidgets import QApplication, QWidget; app = QApplication([]); import matplotlib; matplotlib.use('QtAgg'); import matplotlib.pyplot as plt; plt.figure()"
|
| 129 |
+
- bash: source tools/get_testing_version.sh
|
| 130 |
+
displayName: 'Get testing version'
|
| 131 |
+
- task: Cache@2
|
| 132 |
+
inputs:
|
| 133 |
+
key: $(testing_version)
|
| 134 |
+
path: /home/vsts/mne_data
|
| 135 |
+
displayName: 'Cache testing data'
|
| 136 |
+
- script: python -c "import mne; mne.datasets.testing.data_path(verbose=True)"
|
| 137 |
+
displayName: 'Get test data'
|
| 138 |
+
- script: pytest -m "ultraslowtest or pgtest" --tb=short --cov=mne --cov-report=xml -vv mne
|
| 139 |
+
displayName: 'slow and mne-qt-browser tests'
|
| 140 |
+
# Coverage
|
| 141 |
+
- bash: bash <(curl -s https://codecov.io/bash)
|
| 142 |
+
displayName: 'Codecov'
|
| 143 |
+
condition: succeededOrFailed()
|
| 144 |
+
- task: PublishTestResults@2
|
| 145 |
+
inputs:
|
| 146 |
+
testResultsFiles: '**/junit-*.xml'
|
| 147 |
+
testRunTitle: 'Publish test results for $(Agent.JobName)'
|
| 148 |
+
failTaskOnFailedTests: true
|
| 149 |
+
condition: succeededOrFailed()
|
| 150 |
+
- task: PublishCodeCoverageResults@2
|
| 151 |
+
inputs:
|
| 152 |
+
summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
|
| 153 |
+
|
| 154 |
+
- job: Qt
|
| 155 |
+
pool:
|
| 156 |
+
vmImage: 'ubuntu-22.04'
|
| 157 |
+
variables:
|
| 158 |
+
DISPLAY: ':99'
|
| 159 |
+
OPENBLAS_NUM_THREADS: '1'
|
| 160 |
+
TEST_OPTIONS: "--tb=short --cov=mne --cov-report=xml --cov-append -vv mne/viz/_brain mne/viz/backends mne/viz/tests/test_evoked.py mne/gui mne/report"
|
| 161 |
+
MNE_TEST_ALLOW_SKIP: '^.*(PySide6 causes segfaults).*$'
|
| 162 |
+
steps:
|
| 163 |
+
- bash: ./tools/setup_xvfb.sh
|
| 164 |
+
displayName: 'Install Ubuntu dependencies'
|
| 165 |
+
- task: UsePythonVersion@0
|
| 166 |
+
inputs:
|
| 167 |
+
versionSpec: '3.10'
|
| 168 |
+
architecture: 'x64'
|
| 169 |
+
addToPath: true
|
| 170 |
+
displayName: 'Get Python'
|
| 171 |
+
- bash: |
|
| 172 |
+
set -e
|
| 173 |
+
python -m pip install --progress-bar off --upgrade pip
|
| 174 |
+
python -m pip install --progress-bar off --upgrade --pre --only-binary=\"numpy,scipy,matplotlib,vtk\" numpy scipy matplotlib vtk
|
| 175 |
+
python -c "import vtk"
|
| 176 |
+
python -m pip install --progress-bar off --upgrade -ve .[full] --group=test_extra
|
| 177 |
+
displayName: 'Install dependencies with pip'
|
| 178 |
+
- bash: |
|
| 179 |
+
set -e
|
| 180 |
+
which mne
|
| 181 |
+
mne sys_info -pd
|
| 182 |
+
python ./tools/check_mne_location.py
|
| 183 |
+
displayName: Print config
|
| 184 |
+
- bash: source tools/get_testing_version.sh
|
| 185 |
+
displayName: 'Get testing version'
|
| 186 |
+
- task: Cache@2
|
| 187 |
+
inputs:
|
| 188 |
+
key: $(testing_version)
|
| 189 |
+
path: /home/vsts/mne_data
|
| 190 |
+
displayName: 'Cache testing data'
|
| 191 |
+
- script: python -c "import mne; mne.datasets.testing.data_path(verbose=True)"
|
| 192 |
+
displayName: 'Get test data'
|
| 193 |
+
- bash: |
|
| 194 |
+
set -eo pipefail
|
| 195 |
+
python -m pip install PyQt6
|
| 196 |
+
LD_DEBUG=libs python -c "from PyQt6.QtWidgets import QApplication, QWidget; app = QApplication([]); import matplotlib; matplotlib.use('QtAgg'); import matplotlib.pyplot as plt; plt.figure()"
|
| 197 |
+
displayName: 'Check Qt import'
|
| 198 |
+
- bash: |
|
| 199 |
+
set -eo pipefail
|
| 200 |
+
mne sys_info -pd
|
| 201 |
+
mne sys_info -pd | grep "qtpy .* (PyQt6=.*)$"
|
| 202 |
+
PYTEST_QT_API=PyQt6 pytest -m "not ultraslowtest" ${TEST_OPTIONS}
|
| 203 |
+
python -m pip uninstall -yq PyQt6 PyQt6-sip PyQt6-Qt6
|
| 204 |
+
displayName: 'PyQt6'
|
| 205 |
+
- bash: |
|
| 206 |
+
set -eo pipefail
|
| 207 |
+
python -m pip install "PySide6!=6.8.0,!=6.8.0.1,!=6.9.1"
|
| 208 |
+
mne sys_info -pd
|
| 209 |
+
mne sys_info -pd | grep "qtpy .* (PySide6=.*)$"
|
| 210 |
+
PYTEST_QT_API=PySide6 pytest -m "not ultraslowtest" ${TEST_OPTIONS}
|
| 211 |
+
python -m pip uninstall -yq PySide6
|
| 212 |
+
displayName: 'PySide6'
|
| 213 |
+
# PyQt5 leaves cruft behind, so run it last
|
| 214 |
+
- bash: |
|
| 215 |
+
set -eo pipefail
|
| 216 |
+
python -m pip install PyQt5
|
| 217 |
+
mne sys_info -pd
|
| 218 |
+
mne sys_info -pd | grep "qtpy .* (PyQt5=.*)$"
|
| 219 |
+
PYTEST_QT_API=PyQt5 pytest -m "not ultraslowtest" ${TEST_OPTIONS}
|
| 220 |
+
python -m pip uninstall -yq PyQt5 PyQt5-sip PyQt5-Qt5
|
| 221 |
+
displayName: 'PyQt5'
|
| 222 |
+
# Coverage
|
| 223 |
+
- bash: bash <(curl -s https://codecov.io/bash)
|
| 224 |
+
displayName: 'Codecov'
|
| 225 |
+
condition: succeededOrFailed()
|
| 226 |
+
- task: PublishTestResults@2
|
| 227 |
+
inputs:
|
| 228 |
+
testResultsFiles: '**/junit-*.xml'
|
| 229 |
+
testRunTitle: 'Publish test results for $(Agent.JobName)'
|
| 230 |
+
failTaskOnFailedTests: true
|
| 231 |
+
condition: succeededOrFailed()
|
| 232 |
+
- task: PublishCodeCoverageResults@2
|
| 233 |
+
inputs:
|
| 234 |
+
summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
|
| 235 |
+
|
| 236 |
+
- job: Windows
|
| 237 |
+
pool:
|
| 238 |
+
vmImage: 'windows-latest'
|
| 239 |
+
variables:
|
| 240 |
+
MNE_LOGGING_LEVEL: 'warning'
|
| 241 |
+
MNE_FORCE_SERIAL: 'true'
|
| 242 |
+
OPENBLAS_NUM_THREADS: '2'
|
| 243 |
+
OMP_DYNAMIC: 'false'
|
| 244 |
+
PYTHONUNBUFFERED: 1
|
| 245 |
+
PYTHONIOENCODING: 'utf-8'
|
| 246 |
+
AZURE_CI_WINDOWS: 'true'
|
| 247 |
+
PYTHON_ARCH: 'x64'
|
| 248 |
+
MNE_CI_KIND: $(TEST_MODE)
|
| 249 |
+
timeoutInMinutes: 95
|
| 250 |
+
strategy:
|
| 251 |
+
maxParallel: 4
|
| 252 |
+
matrix:
|
| 253 |
+
3.10 pip:
|
| 254 |
+
TEST_MODE: 'pip'
|
| 255 |
+
PYTHON_VERSION: '3.10'
|
| 256 |
+
3.13 pip pre:
|
| 257 |
+
TEST_MODE: 'pip-pre'
|
| 258 |
+
PYTHON_VERSION: '3.13'
|
| 259 |
+
steps:
|
| 260 |
+
- task: UsePythonVersion@0
|
| 261 |
+
inputs:
|
| 262 |
+
versionSpec: $(PYTHON_VERSION)
|
| 263 |
+
architecture: $(PYTHON_ARCH)
|
| 264 |
+
addToPath: true
|
| 265 |
+
displayName: 'Get Python'
|
| 266 |
+
- bash: |
|
| 267 |
+
set -eo pipefail
|
| 268 |
+
git clone --depth 1 https://github.com/pyvista/setup-headless-display-action.git
|
| 269 |
+
MESA3D_VERSION=24.3.0 bash setup-headless-display-action/windows/install_opengl.sh
|
| 270 |
+
displayName: Install OpenGL
|
| 271 |
+
- bash: ./tools/azure_dependencies.sh
|
| 272 |
+
displayName: Install dependencies with pip
|
| 273 |
+
- script: pip install -e .
|
| 274 |
+
displayName: 'Install MNE-Python dev'
|
| 275 |
+
- script: mne sys_info -pd
|
| 276 |
+
displayName: 'Print config'
|
| 277 |
+
- script: python -c "import numpy; numpy.show_config()"
|
| 278 |
+
displayName: Print NumPy config
|
| 279 |
+
- script: python -c "import numpy; import scipy.linalg; import sklearn.neighbors; from threadpoolctl import threadpool_info; from pprint import pprint; pprint(threadpool_info())"
|
| 280 |
+
displayName: Print threadpoolctl info
|
| 281 |
+
- bash: source tools/get_testing_version.sh
|
| 282 |
+
displayName: 'Get testing version'
|
| 283 |
+
- task: Cache@2
|
| 284 |
+
inputs:
|
| 285 |
+
key: $(testing_version)
|
| 286 |
+
path: C:\Users\VssAdministrator\mne_data
|
| 287 |
+
displayName: 'Cache testing data'
|
| 288 |
+
- script: python -c "import mne; mne.datasets.testing.data_path(verbose=True)"
|
| 289 |
+
displayName: 'Get test data'
|
| 290 |
+
- script: pytest -m "not (slowtest or pgtest)" --tb=short --cov=mne --cov-report=xml -vv mne
|
| 291 |
+
displayName: 'Run tests'
|
| 292 |
+
- bash: bash <(curl -s https://codecov.io/bash)
|
| 293 |
+
displayName: 'Codecov'
|
| 294 |
+
condition: succeededOrFailed()
|
| 295 |
+
- task: PublishTestResults@2
|
| 296 |
+
inputs:
|
| 297 |
+
testResultsFiles: '**/junit-*.xml'
|
| 298 |
+
testRunTitle: 'Publish test results for $(Agent.JobName) $(TEST_MODE) $(PYTHON_VERSION)'
|
| 299 |
+
failTaskOnFailedTests: true
|
| 300 |
+
condition: succeededOrFailed()
|
| 301 |
+
- task: PublishCodeCoverageResults@2
|
| 302 |
+
inputs:
|
| 303 |
+
summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
|
mne-python/source/codecov.yml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
comment: false
|
| 2 |
+
github_checks: # too noisy, even though "a" interactively disables them
|
| 3 |
+
annotations: false
|
| 4 |
+
|
| 5 |
+
codecov:
|
| 6 |
+
notify:
|
| 7 |
+
require_ci_to_pass: false
|
| 8 |
+
|
| 9 |
+
coverage:
|
| 10 |
+
status:
|
| 11 |
+
patch:
|
| 12 |
+
default:
|
| 13 |
+
informational: true
|
| 14 |
+
target: 95%
|
| 15 |
+
if_no_uploads: error
|
| 16 |
+
if_not_found: success
|
| 17 |
+
if_ci_failed: failure
|
| 18 |
+
project:
|
| 19 |
+
default: false
|
| 20 |
+
library:
|
| 21 |
+
informational: true
|
| 22 |
+
target: 90%
|
| 23 |
+
if_no_uploads: error
|
| 24 |
+
if_not_found: success
|
| 25 |
+
if_ci_failed: failure
|
mne-python/source/codemeta.json
ADDED
|
@@ -0,0 +1,2555 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"@context": "https://doi.org/10.5063/schema/codemeta-2.0",
|
| 3 |
+
"@type": "SoftwareSourceCode",
|
| 4 |
+
"license": "https://spdx.org/licenses/BSD-3-Clause",
|
| 5 |
+
"codeRepository": "git+https://github.com/mne-tools/mne-python.git",
|
| 6 |
+
"dateCreated": "2010-12-26",
|
| 7 |
+
"datePublished": "2014-08-04",
|
| 8 |
+
"dateModified": "2025-11-21",
|
| 9 |
+
"downloadUrl": "https://github.com/mne-tools/mne-python/archive/v1.11.0.zip",
|
| 10 |
+
"issueTracker": "https://github.com/mne-tools/mne-python/issues",
|
| 11 |
+
"name": "MNE-Python",
|
| 12 |
+
"version": "1.11.0",
|
| 13 |
+
"description": "MNE-Python is an open-source Python package for exploring, visualizing, and analyzing human neurophysiological data. It provides methods for data input/output, preprocessing, visualization, source estimation, time-frequency analysis, connectivity analysis, machine learning, and statistics.",
|
| 14 |
+
"applicationCategory": "Neuroscience",
|
| 15 |
+
"developmentStatus": "active",
|
| 16 |
+
"referencePublication": "https://doi.org/10.3389/fnins.2013.00267",
|
| 17 |
+
"keywords": [
|
| 18 |
+
"MEG",
|
| 19 |
+
"magnetoencephalography",
|
| 20 |
+
"EEG",
|
| 21 |
+
"electroencephalography",
|
| 22 |
+
"fNIRS",
|
| 23 |
+
"functional near-infrared spectroscopy",
|
| 24 |
+
"iEEG",
|
| 25 |
+
"intracranial EEG",
|
| 26 |
+
"eCoG",
|
| 27 |
+
"electrocorticography",
|
| 28 |
+
"DBS",
|
| 29 |
+
"deep brain stimulation"
|
| 30 |
+
],
|
| 31 |
+
"programmingLanguage": [
|
| 32 |
+
"Python"
|
| 33 |
+
],
|
| 34 |
+
"operatingSystem": [
|
| 35 |
+
"Linux",
|
| 36 |
+
"Windows",
|
| 37 |
+
"macOS"
|
| 38 |
+
],
|
| 39 |
+
"softwareRequirements": [
|
| 40 |
+
"python>= 3.10",
|
| 41 |
+
"decorator",
|
| 42 |
+
"jinja2",
|
| 43 |
+
"lazy_loader >= 0.3",
|
| 44 |
+
"matplotlib >= 3.8",
|
| 45 |
+
"numpy >= 1.26, < 3",
|
| 46 |
+
"packaging",
|
| 47 |
+
"pooch >= 1.5",
|
| 48 |
+
"scipy >= 1.11",
|
| 49 |
+
"tqdm"
|
| 50 |
+
],
|
| 51 |
+
"author": [
|
| 52 |
+
{
|
| 53 |
+
"@type":"Person",
|
| 54 |
+
"email":"larson.eric.d@gmail.com",
|
| 55 |
+
"givenName":"Eric",
|
| 56 |
+
"familyName": "Larson"
|
| 57 |
+
},
|
| 58 |
+
{
|
| 59 |
+
"@type":"Person",
|
| 60 |
+
"email":"alexandre.gramfort@inria.fr",
|
| 61 |
+
"givenName":"Alexandre",
|
| 62 |
+
"familyName": "Gramfort"
|
| 63 |
+
},
|
| 64 |
+
{
|
| 65 |
+
"@type":"Person",
|
| 66 |
+
"email":"denis.engemann@gmail.com",
|
| 67 |
+
"givenName":"Denis A",
|
| 68 |
+
"familyName": "Engemann"
|
| 69 |
+
},
|
| 70 |
+
{
|
| 71 |
+
"@type":"Person",
|
| 72 |
+
"email":"jaeilepp@gmail.com",
|
| 73 |
+
"givenName":"Jaakko",
|
| 74 |
+
"familyName": "Leppakangas"
|
| 75 |
+
},
|
| 76 |
+
{
|
| 77 |
+
"@type":"Person",
|
| 78 |
+
"email":"christianmbrodbeck@gmail.com",
|
| 79 |
+
"givenName":"Christian",
|
| 80 |
+
"familyName": "Brodbeck"
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"@type":"Person",
|
| 84 |
+
"email":"mainakjas@gmail.com",
|
| 85 |
+
"givenName":"Mainak",
|
| 86 |
+
"familyName": "Jas"
|
| 87 |
+
},
|
| 88 |
+
{
|
| 89 |
+
"@type":"Person",
|
| 90 |
+
"email":"teon.brooks@gmail.com",
|
| 91 |
+
"givenName":"Teon L",
|
| 92 |
+
"familyName": "Brooks"
|
| 93 |
+
},
|
| 94 |
+
{
|
| 95 |
+
"@type":"Person",
|
| 96 |
+
"email":"jona.sassenhagen@gmail.com",
|
| 97 |
+
"givenName":"Jona",
|
| 98 |
+
"familyName": "Sassenhagen"
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"@type":"Person",
|
| 102 |
+
"email":"dan@mccloy.info",
|
| 103 |
+
"givenName":"Daniel",
|
| 104 |
+
"familyName": "McCloy"
|
| 105 |
+
},
|
| 106 |
+
{
|
| 107 |
+
"@type":"Person",
|
| 108 |
+
"email":"mluessi@nmr.mgh.harvard.edu",
|
| 109 |
+
"givenName":"Martin",
|
| 110 |
+
"familyName": "Luessi"
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"@type":"Person",
|
| 114 |
+
"email":"jeanremi.king+github@gmail.com",
|
| 115 |
+
"givenName":"Jean-Rémi",
|
| 116 |
+
"familyName": "King"
|
| 117 |
+
},
|
| 118 |
+
{
|
| 119 |
+
"@type":"Person",
|
| 120 |
+
"email":"richard.hoechenberger@gmail.com",
|
| 121 |
+
"givenName":"Richard",
|
| 122 |
+
"familyName": "Höchenberger"
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"@type":"Person",
|
| 126 |
+
"email":"clemens.brunner@gmail.com",
|
| 127 |
+
"givenName":"Clemens",
|
| 128 |
+
"familyName": "Brunner"
|
| 129 |
+
},
|
| 130 |
+
{
|
| 131 |
+
"@type":"Person",
|
| 132 |
+
"email":"roman.goj@gmail.com",
|
| 133 |
+
"givenName":"Roman",
|
| 134 |
+
"familyName": "Goj"
|
| 135 |
+
},
|
| 136 |
+
{
|
| 137 |
+
"@type":"Person",
|
| 138 |
+
"email":"guillaume.favelier@gmail.com",
|
| 139 |
+
"givenName":"Guillaume",
|
| 140 |
+
"familyName": "Favelier"
|
| 141 |
+
},
|
| 142 |
+
{
|
| 143 |
+
"@type":"Person",
|
| 144 |
+
"email":"w.m.vanvliet@gmail.com",
|
| 145 |
+
"givenName":"Marijn",
|
| 146 |
+
"familyName": "van Vliet"
|
| 147 |
+
},
|
| 148 |
+
{
|
| 149 |
+
"@type":"Person",
|
| 150 |
+
"email":"wronk.mark@gmail.com",
|
| 151 |
+
"givenName":"Mark",
|
| 152 |
+
"familyName": "Wronkiewicz"
|
| 153 |
+
},
|
| 154 |
+
{
|
| 155 |
+
"@type":"Person",
|
| 156 |
+
"email":"stefan.appelhoff@mailbox.org",
|
| 157 |
+
"givenName":"Stefan",
|
| 158 |
+
"familyName": "Appelhoff"
|
| 159 |
+
},
|
| 160 |
+
{
|
| 161 |
+
"@type":"Person",
|
| 162 |
+
"email":"aprockhill206@gmail.com",
|
| 163 |
+
"givenName":"Alex",
|
| 164 |
+
"familyName": "Rockhill"
|
| 165 |
+
},
|
| 166 |
+
{
|
| 167 |
+
"@type":"Person",
|
| 168 |
+
"email":"choldgraf@gmail.com",
|
| 169 |
+
"givenName":"Chris",
|
| 170 |
+
"familyName": "Holdgraf"
|
| 171 |
+
},
|
| 172 |
+
{
|
| 173 |
+
"@type":"Person",
|
| 174 |
+
"email":"mathieu.scheltienne@gmail.com",
|
| 175 |
+
"givenName":"Mathieu",
|
| 176 |
+
"familyName": "Scheltienne"
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"@type":"Person",
|
| 180 |
+
"email":"mailsik@gmail.com",
|
| 181 |
+
"givenName":"Joan",
|
| 182 |
+
"familyName": "Massich"
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"@type":"Person",
|
| 186 |
+
"email":"yousra.bekhti@gmail.com",
|
| 187 |
+
"givenName":"Yousra",
|
| 188 |
+
"familyName": "Bekhti"
|
| 189 |
+
},
|
| 190 |
+
{
|
| 191 |
+
"@type":"Person",
|
| 192 |
+
"email":"leggitta3@gmail.com",
|
| 193 |
+
"givenName":"Alan",
|
| 194 |
+
"familyName": "Leggitt"
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"@type":"Person",
|
| 198 |
+
"email":"andrew.r.dykstra@gmail.com",
|
| 199 |
+
"givenName":"Andrew",
|
| 200 |
+
"familyName": "Dykstra"
|
| 201 |
+
},
|
| 202 |
+
{
|
| 203 |
+
"@type":"Person",
|
| 204 |
+
"email":"romain.trachel@inria.fr",
|
| 205 |
+
"givenName":"Romain",
|
| 206 |
+
"familyName": "Trachel"
|
| 207 |
+
},
|
| 208 |
+
{
|
| 209 |
+
"@type":"Person",
|
| 210 |
+
"email":"code@robertluke.net",
|
| 211 |
+
"givenName":"Robert",
|
| 212 |
+
"familyName": "Luke"
|
| 213 |
+
},
|
| 214 |
+
{
|
| 215 |
+
"@type":"Person",
|
| 216 |
+
"email":"desantis.lnz@gmail.com",
|
| 217 |
+
"givenName":"Lorenzo",
|
| 218 |
+
"familyName": "De Santis"
|
| 219 |
+
},
|
| 220 |
+
{
|
| 221 |
+
"@type":"Person",
|
| 222 |
+
"email":"asishrocks95@gmail.com",
|
| 223 |
+
"givenName":"Asish",
|
| 224 |
+
"familyName": "Panda"
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"@type":"Person",
|
| 228 |
+
"email":"mmagnuski@swps.edu.pl",
|
| 229 |
+
"givenName":"Mikołaj",
|
| 230 |
+
"familyName": "Magnuski"
|
| 231 |
+
},
|
| 232 |
+
{
|
| 233 |
+
"@type":"Person",
|
| 234 |
+
"email":"britta.wstnr@gmail.com",
|
| 235 |
+
"givenName":"Britta",
|
| 236 |
+
"familyName": "Westner"
|
| 237 |
+
},
|
| 238 |
+
{
|
| 239 |
+
"@type":"Person",
|
| 240 |
+
"email":"dgwakeman@gmail.com",
|
| 241 |
+
"givenName":"Dan G",
|
| 242 |
+
"familyName": "Wakeman"
|
| 243 |
+
},
|
| 244 |
+
{
|
| 245 |
+
"@type":"Person",
|
| 246 |
+
"email":"daniel.strohmeier@googlemail.com",
|
| 247 |
+
"givenName":"Daniel",
|
| 248 |
+
"familyName": "Strohmeier"
|
| 249 |
+
},
|
| 250 |
+
{
|
| 251 |
+
"@type":"Person",
|
| 252 |
+
"email":"hari@nmr.mgh.harvard.edu",
|
| 253 |
+
"givenName":"Hari",
|
| 254 |
+
"familyName": "Bharadwaj"
|
| 255 |
+
},
|
| 256 |
+
{
|
| 257 |
+
"@type":"Person",
|
| 258 |
+
"email":"tal.linzen@gmail.com",
|
| 259 |
+
"givenName":"Tal",
|
| 260 |
+
"familyName": "Linzen"
|
| 261 |
+
},
|
| 262 |
+
{
|
| 263 |
+
"@type":"Person",
|
| 264 |
+
"email":"alexandre.barachant@gmail.com",
|
| 265 |
+
"givenName":"Alexandre",
|
| 266 |
+
"familyName": "Barachant"
|
| 267 |
+
},
|
| 268 |
+
{
|
| 269 |
+
"@type":"Person",
|
| 270 |
+
"email":"emilyr@nmr.mgh.harvard.edu",
|
| 271 |
+
"givenName":"Emily",
|
| 272 |
+
"familyName": "Ruzich"
|
| 273 |
+
},
|
| 274 |
+
{
|
| 275 |
+
"@type":"Person",
|
| 276 |
+
"email":"",
|
| 277 |
+
"givenName":"Scott",
|
| 278 |
+
"familyName": "Huberty"
|
| 279 |
+
},
|
| 280 |
+
{
|
| 281 |
+
"@type":"Person",
|
| 282 |
+
"email":"bailey.cj@gmail.com",
|
| 283 |
+
"givenName":"Christopher J",
|
| 284 |
+
"familyName": "Bailey"
|
| 285 |
+
},
|
| 286 |
+
{
|
| 287 |
+
"@type":"Person",
|
| 288 |
+
"email":"adam2392@gmail.com",
|
| 289 |
+
"givenName":"Adam",
|
| 290 |
+
"familyName": "Li"
|
| 291 |
+
},
|
| 292 |
+
{
|
| 293 |
+
"@type":"Person",
|
| 294 |
+
"email":"clement.moutard@gmail.com",
|
| 295 |
+
"givenName":"Clément",
|
| 296 |
+
"familyName": "Moutard"
|
| 297 |
+
},
|
| 298 |
+
{
|
| 299 |
+
"@type":"Person",
|
| 300 |
+
"email":"luke.bloy@gmail.com",
|
| 301 |
+
"givenName":"Luke",
|
| 302 |
+
"familyName": "Bloy"
|
| 303 |
+
},
|
| 304 |
+
{
|
| 305 |
+
"@type":"Person",
|
| 306 |
+
"email":"federaimondo@gmail.com",
|
| 307 |
+
"givenName":"Fede",
|
| 308 |
+
"familyName": "Raimondo"
|
| 309 |
+
},
|
| 310 |
+
{
|
| 311 |
+
"@type":"Person",
|
| 312 |
+
"email":"jnu@iki.fi",
|
| 313 |
+
"givenName":"Jussi",
|
| 314 |
+
"familyName": "Nurminen"
|
| 315 |
+
},
|
| 316 |
+
{
|
| 317 |
+
"@type":"Person",
|
| 318 |
+
"email":"flKazemakase@gmail.com",
|
| 319 |
+
"givenName":"Martin",
|
| 320 |
+
"familyName": "Billinger"
|
| 321 |
+
},
|
| 322 |
+
{
|
| 323 |
+
"@type":"Person",
|
| 324 |
+
"email":"montoya.jair.m@gmail.com",
|
| 325 |
+
"givenName":"Jair",
|
| 326 |
+
"familyName": "Montoya"
|
| 327 |
+
},
|
| 328 |
+
{
|
| 329 |
+
"@type":"Person",
|
| 330 |
+
"email":"mmwoodman@gmail.com",
|
| 331 |
+
"givenName":"Marmaduke",
|
| 332 |
+
"familyName": "Woodman"
|
| 333 |
+
},
|
| 334 |
+
{
|
| 335 |
+
"@type":"Person",
|
| 336 |
+
"email":"dlsrnsladlek@naver.com",
|
| 337 |
+
"givenName":"Ingoo",
|
| 338 |
+
"familyName": "Lee"
|
| 339 |
+
},
|
| 340 |
+
{
|
| 341 |
+
"@type":"Person",
|
| 342 |
+
"email":"dev@mgschulz.de",
|
| 343 |
+
"givenName":"Martin",
|
| 344 |
+
"familyName": "Schulz"
|
| 345 |
+
},
|
| 346 |
+
{
|
| 347 |
+
"@type":"Person",
|
| 348 |
+
"email":"nfoti01@gmail.com",
|
| 349 |
+
"givenName":"Nick",
|
| 350 |
+
"familyName": "Foti"
|
| 351 |
+
},
|
| 352 |
+
{
|
| 353 |
+
"@type":"Person",
|
| 354 |
+
"email":"cnangini@gmail.com",
|
| 355 |
+
"givenName":"Cathy",
|
| 356 |
+
"familyName": "Nangini"
|
| 357 |
+
},
|
| 358 |
+
{
|
| 359 |
+
"@type":"Person",
|
| 360 |
+
"email":"joialanisson@gmail.com",
|
| 361 |
+
"givenName":"José C",
|
| 362 |
+
"familyName": "García Alanis"
|
| 363 |
+
},
|
| 364 |
+
{
|
| 365 |
+
"@type":"Person",
|
| 366 |
+
"email":"t.s.binns@outlook.com",
|
| 367 |
+
"givenName":"Thomas S",
|
| 368 |
+
"familyName": "Binns"
|
| 369 |
+
},
|
| 370 |
+
{
|
| 371 |
+
"@type":"Person",
|
| 372 |
+
"email":"",
|
| 373 |
+
"givenName":"Dimitri Papadopoulos",
|
| 374 |
+
"familyName": "Orfanos"
|
| 375 |
+
},
|
| 376 |
+
{
|
| 377 |
+
"@type":"Person",
|
| 378 |
+
"email":"olaf.hauk@mrc-cbu.cam.ac.uk",
|
| 379 |
+
"givenName":"Olaf",
|
| 380 |
+
"familyName": "Hauk"
|
| 381 |
+
},
|
| 382 |
+
{
|
| 383 |
+
"@type":"Person",
|
| 384 |
+
"email":"ross.maddox@rochester.edu",
|
| 385 |
+
"givenName":"Ross",
|
| 386 |
+
"familyName": "Maddox"
|
| 387 |
+
},
|
| 388 |
+
{
|
| 389 |
+
"@type":"Person",
|
| 390 |
+
"email":"aestrivex@gmail.com",
|
| 391 |
+
"givenName":"Roan",
|
| 392 |
+
"familyName": "LaPlante"
|
| 393 |
+
},
|
| 394 |
+
{
|
| 395 |
+
"@type":"Person",
|
| 396 |
+
"email":"ashdrew@uw.edu",
|
| 397 |
+
"givenName":"Ashley",
|
| 398 |
+
"familyName": "Drew"
|
| 399 |
+
},
|
| 400 |
+
{
|
| 401 |
+
"@type":"Person",
|
| 402 |
+
"email":"chdinh@nmr.mgh.harvard.edu",
|
| 403 |
+
"givenName":"Christoph",
|
| 404 |
+
"familyName": "Dinh"
|
| 405 |
+
},
|
| 406 |
+
{
|
| 407 |
+
"@type":"Person",
|
| 408 |
+
"email":"deep@introspection.eu",
|
| 409 |
+
"givenName":"Guillaume",
|
| 410 |
+
"familyName": "Dumas"
|
| 411 |
+
},
|
| 412 |
+
{
|
| 413 |
+
"@type":"Person",
|
| 414 |
+
"email":"martin.billinger@tugraz.at",
|
| 415 |
+
"givenName":"",
|
| 416 |
+
"familyName": "Martin"
|
| 417 |
+
},
|
| 418 |
+
{
|
| 419 |
+
"@type":"Person",
|
| 420 |
+
"email":"johann.benerradi@gmail.com",
|
| 421 |
+
"givenName":"Johann",
|
| 422 |
+
"familyName": "Benerradi"
|
| 423 |
+
},
|
| 424 |
+
{
|
| 425 |
+
"@type":"Person",
|
| 426 |
+
"email":"thomas.hartmann@th-ht.de",
|
| 427 |
+
"givenName":"Thomas",
|
| 428 |
+
"familyName": "Hartmann"
|
| 429 |
+
},
|
| 430 |
+
{
|
| 431 |
+
"@type":"Person",
|
| 432 |
+
"email":"eduardxort@gmail.com",
|
| 433 |
+
"givenName":"Eduard",
|
| 434 |
+
"familyName": "Ort"
|
| 435 |
+
},
|
| 436 |
+
{
|
| 437 |
+
"@type":"Person",
|
| 438 |
+
"email":"flkazemakase@gmail.com",
|
| 439 |
+
"givenName":"Martin",
|
| 440 |
+
"familyName": "Billinger"
|
| 441 |
+
},
|
| 442 |
+
{
|
| 443 |
+
"@type":"Person",
|
| 444 |
+
"email":"paul@ppasler.de",
|
| 445 |
+
"givenName":"Paul",
|
| 446 |
+
"familyName": "Pasler"
|
| 447 |
+
},
|
| 448 |
+
{
|
| 449 |
+
"@type":"Person",
|
| 450 |
+
"email":"stefan.repplinger@posteo.net",
|
| 451 |
+
"givenName":"Stefan",
|
| 452 |
+
"familyName": "Repplinger"
|
| 453 |
+
},
|
| 454 |
+
{
|
| 455 |
+
"@type":"Person",
|
| 456 |
+
"email":"alxanderr@gmail.com",
|
| 457 |
+
"givenName":"Alexander",
|
| 458 |
+
"familyName": "Rudiuk"
|
| 459 |
+
},
|
| 460 |
+
{
|
| 461 |
+
"@type":"Person",
|
| 462 |
+
"email":"anaradanovica@gmail.com",
|
| 463 |
+
"givenName":"Ana",
|
| 464 |
+
"familyName": "Radanovic"
|
| 465 |
+
},
|
| 466 |
+
{
|
| 467 |
+
"@type":"Person",
|
| 468 |
+
"email":"bburan@galenea.com",
|
| 469 |
+
"givenName":"Brad",
|
| 470 |
+
"familyName": "Buran"
|
| 471 |
+
},
|
| 472 |
+
{
|
| 473 |
+
"@type":"Person",
|
| 474 |
+
"email":"Woessner.jacob@gmail.com",
|
| 475 |
+
"givenName":"Jacob",
|
| 476 |
+
"familyName": "Woessner"
|
| 477 |
+
},
|
| 478 |
+
{
|
| 479 |
+
"@type":"Person",
|
| 480 |
+
"email":"mathurin.massias@gmail.com",
|
| 481 |
+
"givenName":"Mathurin",
|
| 482 |
+
"familyName": "Massias"
|
| 483 |
+
},
|
| 484 |
+
{
|
| 485 |
+
"@type":"Person",
|
| 486 |
+
"email":"msh@nmr.mgh.harvard.edu",
|
| 487 |
+
"givenName":"Matti",
|
| 488 |
+
"familyName": "Hämäläinen"
|
| 489 |
+
},
|
| 490 |
+
{
|
| 491 |
+
"@type":"Person",
|
| 492 |
+
"email":"pravsripad@gmail.com",
|
| 493 |
+
"givenName":"Praveen",
|
| 494 |
+
"familyName": "Sripad"
|
| 495 |
+
},
|
| 496 |
+
{
|
| 497 |
+
"@type":"Person",
|
| 498 |
+
"email":"vagechirkov@gmail.com",
|
| 499 |
+
"givenName":"Valerii",
|
| 500 |
+
"familyName": "Chirkov"
|
| 501 |
+
},
|
| 502 |
+
{
|
| 503 |
+
"@type":"Person",
|
| 504 |
+
"email":"christopherrmullins@gmail.com",
|
| 505 |
+
"givenName":"Christopher",
|
| 506 |
+
"familyName": "Mullins"
|
| 507 |
+
},
|
| 508 |
+
{
|
| 509 |
+
"@type":"Person",
|
| 510 |
+
"email":"gamaz3ps@gmail.com",
|
| 511 |
+
"givenName":"Félix",
|
| 512 |
+
"familyName": "Raimundo"
|
| 513 |
+
},
|
| 514 |
+
{
|
| 515 |
+
"@type":"Person",
|
| 516 |
+
"email":"",
|
| 517 |
+
"givenName":"Gennadiy",
|
| 518 |
+
"familyName": "Belonosov"
|
| 519 |
+
},
|
| 520 |
+
{
|
| 521 |
+
"@type":"Person",
|
| 522 |
+
"email":"rcmdnk@gmail.com",
|
| 523 |
+
"givenName":"Michiru",
|
| 524 |
+
"familyName": "Kaneda"
|
| 525 |
+
},
|
| 526 |
+
{
|
| 527 |
+
"@type":"Person",
|
| 528 |
+
"email":"phillip.alday@mpi.nl",
|
| 529 |
+
"givenName":"Phillip",
|
| 530 |
+
"familyName": "Alday"
|
| 531 |
+
},
|
| 532 |
+
{
|
| 533 |
+
"@type":"Person",
|
| 534 |
+
"email":"ramsbam@gmail.com",
|
| 535 |
+
"givenName":"Ram",
|
| 536 |
+
"familyName": "Pari"
|
| 537 |
+
},
|
| 538 |
+
{
|
| 539 |
+
"@type":"Person",
|
| 540 |
+
"email":"simon@simonster.com",
|
| 541 |
+
"givenName":"Simon",
|
| 542 |
+
"familyName": "Kornblith"
|
| 543 |
+
},
|
| 544 |
+
{
|
| 545 |
+
"@type":"Person",
|
| 546 |
+
"email":"debian@onerussian.com",
|
| 547 |
+
"givenName":"Yaroslav",
|
| 548 |
+
"familyName": "Halchenko"
|
| 549 |
+
},
|
| 550 |
+
{
|
| 551 |
+
"@type":"Person",
|
| 552 |
+
"email":"yuhanluo1994@gmail.com",
|
| 553 |
+
"givenName":"Yu-Han",
|
| 554 |
+
"familyName": "Luo"
|
| 555 |
+
},
|
| 556 |
+
{
|
| 557 |
+
"@type":"Person",
|
| 558 |
+
"email":"agramfort@fb.com",
|
| 559 |
+
"givenName":"Alexandre",
|
| 560 |
+
"familyName": "Gramfort"
|
| 561 |
+
},
|
| 562 |
+
{
|
| 563 |
+
"@type":"Person",
|
| 564 |
+
"email":"jeythekey@tutanota.com",
|
| 565 |
+
"givenName":"Johannes",
|
| 566 |
+
"familyName": "Kasper"
|
| 567 |
+
},
|
| 568 |
+
{
|
| 569 |
+
"@type":"Person",
|
| 570 |
+
"email":"kd889@nyu.edu",
|
| 571 |
+
"givenName":"Keith",
|
| 572 |
+
"familyName": "Doelling"
|
| 573 |
+
},
|
| 574 |
+
{
|
| 575 |
+
"@type":"Person",
|
| 576 |
+
"email":"mje.mads@gmail.com",
|
| 577 |
+
"givenName":"Mads",
|
| 578 |
+
"familyName": "Jensen"
|
| 579 |
+
},
|
| 580 |
+
{
|
| 581 |
+
"@type":"Person",
|
| 582 |
+
"email":"santeri.ruuskanen@aalto.fi",
|
| 583 |
+
"givenName":"Santeri",
|
| 584 |
+
"familyName": "Ruuskanen"
|
| 585 |
+
},
|
| 586 |
+
{
|
| 587 |
+
"@type":"Person",
|
| 588 |
+
"email":"simon.kern@online.de",
|
| 589 |
+
"givenName":"Simon",
|
| 590 |
+
"familyName": "Kern"
|
| 591 |
+
},
|
| 592 |
+
{
|
| 593 |
+
"@type":"Person",
|
| 594 |
+
"email":"tanaygahlot@gmail.com",
|
| 595 |
+
"givenName":"Tanay",
|
| 596 |
+
"familyName": "Gahlot"
|
| 597 |
+
},
|
| 598 |
+
{
|
| 599 |
+
"@type":"Person",
|
| 600 |
+
"email":"adonay.s.nunes@gmail.com",
|
| 601 |
+
"givenName":"Adonay",
|
| 602 |
+
"familyName": "Nunes"
|
| 603 |
+
},
|
| 604 |
+
{
|
| 605 |
+
"@type":"Person",
|
| 606 |
+
"email":"",
|
| 607 |
+
"givenName":"Dirk",
|
| 608 |
+
"familyName": "Gütlin"
|
| 609 |
+
},
|
| 610 |
+
{
|
| 611 |
+
"@type":"Person",
|
| 612 |
+
"email":"erkkahe@gmail.com",
|
| 613 |
+
"givenName":"Erkka",
|
| 614 |
+
"familyName": "Heinila"
|
| 615 |
+
},
|
| 616 |
+
{
|
| 617 |
+
"@type":"Person",
|
| 618 |
+
"email":"kristijan.armeni@gmail.com",
|
| 619 |
+
"givenName":"Kristijan",
|
| 620 |
+
"familyName": "Armeni"
|
| 621 |
+
},
|
| 622 |
+
{
|
| 623 |
+
"@type":"Person",
|
| 624 |
+
"email":"kjs@llama",
|
| 625 |
+
"givenName":"",
|
| 626 |
+
"familyName": "kjs"
|
| 627 |
+
},
|
| 628 |
+
{
|
| 629 |
+
"@type":"Person",
|
| 630 |
+
"email":"alejandro.weinstein@gmail.com",
|
| 631 |
+
"givenName":"Alejandro",
|
| 632 |
+
"familyName": "Weinstein"
|
| 633 |
+
},
|
| 634 |
+
{
|
| 635 |
+
"@type":"Person",
|
| 636 |
+
"email":"camilo@neurostat.mit.edu",
|
| 637 |
+
"givenName":"Camilo",
|
| 638 |
+
"familyName": "Lamus"
|
| 639 |
+
},
|
| 640 |
+
{
|
| 641 |
+
"@type":"Person",
|
| 642 |
+
"email":"",
|
| 643 |
+
"givenName":"Catalina María",
|
| 644 |
+
"familyName": "Galván"
|
| 645 |
+
},
|
| 646 |
+
{
|
| 647 |
+
"@type":"Person",
|
| 648 |
+
"email":"cmmoenne@gmail.com",
|
| 649 |
+
"givenName":"Cristóbal",
|
| 650 |
+
"familyName": "Moënne-Loccoz"
|
| 651 |
+
},
|
| 652 |
+
{
|
| 653 |
+
"@type":"Person",
|
| 654 |
+
"email":"dm.altukhov@ya.ru",
|
| 655 |
+
"givenName":"Dmitrii",
|
| 656 |
+
"familyName": "Altukhov"
|
| 657 |
+
},
|
| 658 |
+
{
|
| 659 |
+
"@type":"Person",
|
| 660 |
+
"email":"nordme@uw.edu",
|
| 661 |
+
"givenName":"Erica",
|
| 662 |
+
"familyName": "Peterson"
|
| 663 |
+
},
|
| 664 |
+
{
|
| 665 |
+
"@type":"Person",
|
| 666 |
+
"email":"jevri.hanna@gmail.com",
|
| 667 |
+
"givenName":"Jevri",
|
| 668 |
+
"familyName": "Hanna"
|
| 669 |
+
},
|
| 670 |
+
{
|
| 671 |
+
"@type":"Person",
|
| 672 |
+
"email":"jon.houck@gmail.com",
|
| 673 |
+
"givenName":"Jon",
|
| 674 |
+
"familyName": "Houck"
|
| 675 |
+
},
|
| 676 |
+
{
|
| 677 |
+
"@type":"Person",
|
| 678 |
+
"email":"neklein@andrew.cmu.edu",
|
| 679 |
+
"givenName":"Natalie",
|
| 680 |
+
"familyName": "Klein"
|
| 681 |
+
},
|
| 682 |
+
{
|
| 683 |
+
"@type":"Person",
|
| 684 |
+
"email":"paul@roujansky.eu",
|
| 685 |
+
"givenName":"Paul",
|
| 686 |
+
"familyName": "Roujansky"
|
| 687 |
+
},
|
| 688 |
+
{
|
| 689 |
+
"@type":"Person",
|
| 690 |
+
"email":"code@robertluke.net",
|
| 691 |
+
"givenName":"Rob",
|
| 692 |
+
"familyName": "Luke"
|
| 693 |
+
},
|
| 694 |
+
{
|
| 695 |
+
"@type":"Person",
|
| 696 |
+
"email":"antti.rantala90@gmail.com",
|
| 697 |
+
"givenName":"Antti",
|
| 698 |
+
"familyName": "Rantala"
|
| 699 |
+
},
|
| 700 |
+
{
|
| 701 |
+
"@type":"Person",
|
| 702 |
+
"email":"burkhard.maess@arcor.de",
|
| 703 |
+
"givenName":"Burkhard",
|
| 704 |
+
"familyName": "Maess"
|
| 705 |
+
},
|
| 706 |
+
{
|
| 707 |
+
"@type":"Person",
|
| 708 |
+
"email":"carinaforster0611@gmail.com",
|
| 709 |
+
"givenName":"Carina",
|
| 710 |
+
"familyName": "Forster"
|
| 711 |
+
},
|
| 712 |
+
{
|
| 713 |
+
"@type":"Person",
|
| 714 |
+
"email":"christian.oreilly@gmail.com",
|
| 715 |
+
"givenName":"Christian",
|
| 716 |
+
"familyName": "O'Reilly"
|
| 717 |
+
},
|
| 718 |
+
{
|
| 719 |
+
"@type":"Person",
|
| 720 |
+
"email":"dominik.welke@ae.mpg.de",
|
| 721 |
+
"givenName":"Dominik",
|
| 722 |
+
"familyName": "Welke"
|
| 723 |
+
},
|
| 724 |
+
{
|
| 725 |
+
"@type":"Person",
|
| 726 |
+
"email":"dominik.welke@web.de",
|
| 727 |
+
"givenName":"Dominik",
|
| 728 |
+
"familyName": "Welke"
|
| 729 |
+
},
|
| 730 |
+
{
|
| 731 |
+
"@type":"Person",
|
| 732 |
+
"email":"",
|
| 733 |
+
"givenName":"Henrich",
|
| 734 |
+
"familyName": "Kolkhorst"
|
| 735 |
+
},
|
| 736 |
+
{
|
| 737 |
+
"@type":"Person",
|
| 738 |
+
"email":"hubert.jbanville@gmail.com",
|
| 739 |
+
"givenName":"Hubert",
|
| 740 |
+
"familyName": "Banville"
|
| 741 |
+
},
|
| 742 |
+
{
|
| 743 |
+
"@type":"Person",
|
| 744 |
+
"email":"zhangmengyu10@gmail.com",
|
| 745 |
+
"givenName":"Jack",
|
| 746 |
+
"familyName": "Zhang"
|
| 747 |
+
},
|
| 748 |
+
{
|
| 749 |
+
"@type":"Person",
|
| 750 |
+
"email":"makkostya@ukr.net",
|
| 751 |
+
"givenName":"Kostiantyn",
|
| 752 |
+
"familyName": "Maksymenko"
|
| 753 |
+
},
|
| 754 |
+
{
|
| 755 |
+
"@type":"Person",
|
| 756 |
+
"email":"mdclarke@uw.edu",
|
| 757 |
+
"givenName":"Maggie",
|
| 758 |
+
"familyName": "Clarke"
|
| 759 |
+
},
|
| 760 |
+
{
|
| 761 |
+
"@type":"Person",
|
| 762 |
+
"email":"matteo.anelli@aalto.fi",
|
| 763 |
+
"givenName":"Matteo",
|
| 764 |
+
"familyName": "Anelli"
|
| 765 |
+
},
|
| 766 |
+
{
|
| 767 |
+
"@type":"Person",
|
| 768 |
+
"email":"michael.straube.d@gmail.com",
|
| 769 |
+
"givenName":"Michael",
|
| 770 |
+
"familyName": "Straube"
|
| 771 |
+
},
|
| 772 |
+
{
|
| 773 |
+
"@type":"Person",
|
| 774 |
+
"email":"",
|
| 775 |
+
"givenName":"Nikolai",
|
| 776 |
+
"familyName": "Chapochnikov"
|
| 777 |
+
},
|
| 778 |
+
{
|
| 779 |
+
"@type":"Person",
|
| 780 |
+
"email":"pierreantoine.bannier@gmail.com",
|
| 781 |
+
"givenName":"Pierre-Antoine",
|
| 782 |
+
"familyName": "Bannier"
|
| 783 |
+
},
|
| 784 |
+
{
|
| 785 |
+
"@type":"Person",
|
| 786 |
+
"email":"saketkc@gmail.com",
|
| 787 |
+
"givenName":"Saket",
|
| 788 |
+
"familyName": "Choudhary"
|
| 789 |
+
},
|
| 790 |
+
{
|
| 791 |
+
"@type":"Person",
|
| 792 |
+
"email":"victor.ferat@live.Fr",
|
| 793 |
+
"givenName":"Victor",
|
| 794 |
+
"familyName": "Férat"
|
| 795 |
+
},
|
| 796 |
+
{
|
| 797 |
+
"@type":"Person",
|
| 798 |
+
"email":"kimjico@gmail.com",
|
| 799 |
+
"givenName":"Cora",
|
| 800 |
+
"familyName": "Kim"
|
| 801 |
+
},
|
| 802 |
+
{
|
| 803 |
+
"@type":"Person",
|
| 804 |
+
"email":"klotzsche@cbs.mpg.de",
|
| 805 |
+
"givenName":"Felix",
|
| 806 |
+
"familyName": "Klotzsche"
|
| 807 |
+
},
|
| 808 |
+
{
|
| 809 |
+
"@type":"Person",
|
| 810 |
+
"email":"zuxfoucault@gmail.com",
|
| 811 |
+
"givenName":"Fu-Te",
|
| 812 |
+
"familyName": "Wong"
|
| 813 |
+
},
|
| 814 |
+
{
|
| 815 |
+
"@type":"Person",
|
| 816 |
+
"email":"",
|
| 817 |
+
"givenName":"Ivana",
|
| 818 |
+
"familyName": "Kojcic"
|
| 819 |
+
},
|
| 820 |
+
{
|
| 821 |
+
"@type":"Person",
|
| 822 |
+
"email":"jdue@dtu.dk",
|
| 823 |
+
"givenName":"Jesper Duemose",
|
| 824 |
+
"familyName": "Nielsen"
|
| 825 |
+
},
|
| 826 |
+
{
|
| 827 |
+
"@type":"Person",
|
| 828 |
+
"email":"",
|
| 829 |
+
"givenName":"Kaisu",
|
| 830 |
+
"familyName": "Lankinen"
|
| 831 |
+
},
|
| 832 |
+
{
|
| 833 |
+
"@type":"Person",
|
| 834 |
+
"email":"ktavabi@gmail.com",
|
| 835 |
+
"givenName":"Kambiz",
|
| 836 |
+
"familyName": "Tabavi"
|
| 837 |
+
},
|
| 838 |
+
{
|
| 839 |
+
"@type":"Person",
|
| 840 |
+
"email":"louist87@gmail.com",
|
| 841 |
+
"givenName":"Louis",
|
| 842 |
+
"familyName": "Thibault"
|
| 843 |
+
},
|
| 844 |
+
{
|
| 845 |
+
"@type":"Person",
|
| 846 |
+
"email":"",
|
| 847 |
+
"givenName":"Moritz",
|
| 848 |
+
"familyName": "Gerster"
|
| 849 |
+
},
|
| 850 |
+
{
|
| 851 |
+
"@type":"Person",
|
| 852 |
+
"email":"",
|
| 853 |
+
"givenName":"Nabil",
|
| 854 |
+
"familyName": "Alibou"
|
| 855 |
+
},
|
| 856 |
+
{
|
| 857 |
+
"@type":"Person",
|
| 858 |
+
"email":"nathalie.gayraud@inria.fr",
|
| 859 |
+
"givenName":"Nathalie",
|
| 860 |
+
"familyName": "Gayraud"
|
| 861 |
+
},
|
| 862 |
+
{
|
| 863 |
+
"@type":"Person",
|
| 864 |
+
"email":"ward.nickjames@gmail.com",
|
| 865 |
+
"givenName":"Nick",
|
| 866 |
+
"familyName": "Ward"
|
| 867 |
+
},
|
| 868 |
+
{
|
| 869 |
+
"@type":"Person",
|
| 870 |
+
"email":"",
|
| 871 |
+
"givenName":"Qian",
|
| 872 |
+
"familyName": "Chu"
|
| 873 |
+
},
|
| 874 |
+
{
|
| 875 |
+
"@type":"Person",
|
| 876 |
+
"email":"ksherbst@gmail.com",
|
| 877 |
+
"givenName":"Sophie",
|
| 878 |
+
"familyName": "Herbst"
|
| 879 |
+
},
|
| 880 |
+
{
|
| 881 |
+
"@type":"Person",
|
| 882 |
+
"email":"myd7349@gmail.com",
|
| 883 |
+
"givenName":"Tom",
|
| 884 |
+
"familyName": "Ma"
|
| 885 |
+
},
|
| 886 |
+
{
|
| 887 |
+
"@type":"Person",
|
| 888 |
+
"email":"",
|
| 889 |
+
"givenName":"Ana",
|
| 890 |
+
"familyName": "Radanovic"
|
| 891 |
+
},
|
| 892 |
+
{
|
| 893 |
+
"@type":"Person",
|
| 894 |
+
"email":"",
|
| 895 |
+
"givenName":"Andrew",
|
| 896 |
+
"familyName": "Quinn"
|
| 897 |
+
},
|
| 898 |
+
{
|
| 899 |
+
"@type":"Person",
|
| 900 |
+
"email":"antoine.gauthier@ensta.fr",
|
| 901 |
+
"givenName":"Antoine",
|
| 902 |
+
"familyName": "Gauthier"
|
| 903 |
+
},
|
| 904 |
+
{
|
| 905 |
+
"@type":"Person",
|
| 906 |
+
"email":"basile.pinsard@umontreal.ca",
|
| 907 |
+
"givenName":"Basile",
|
| 908 |
+
"familyName": "Pinsard"
|
| 909 |
+
},
|
| 910 |
+
{
|
| 911 |
+
"@type":"Person",
|
| 912 |
+
"email":"emilyps14@gmail.com",
|
| 913 |
+
"givenName":"Emily",
|
| 914 |
+
"familyName": "Stephen"
|
| 915 |
+
},
|
| 916 |
+
{
|
| 917 |
+
"@type":"Person",
|
| 918 |
+
"email":"erik.hornberger@shi-g.com",
|
| 919 |
+
"givenName":"Erik",
|
| 920 |
+
"familyName": "Hornberger"
|
| 921 |
+
},
|
| 922 |
+
{
|
| 923 |
+
"@type":"Person",
|
| 924 |
+
"email":"",
|
| 925 |
+
"givenName":"Evan",
|
| 926 |
+
"familyName": "Hathaway"
|
| 927 |
+
},
|
| 928 |
+
{
|
| 929 |
+
"@type":"Person",
|
| 930 |
+
"email":"e.kalenkovich@gmail.com",
|
| 931 |
+
"givenName":"Evgenii",
|
| 932 |
+
"familyName": "Kalenkovich"
|
| 933 |
+
},
|
| 934 |
+
{
|
| 935 |
+
"@type":"Person",
|
| 936 |
+
"email":"",
|
| 937 |
+
"givenName":"Fahimeh",
|
| 938 |
+
"familyName": "Mamashli"
|
| 939 |
+
},
|
| 940 |
+
{
|
| 941 |
+
"@type":"Person",
|
| 942 |
+
"email":"g.o'neill@ucl.ac.uk",
|
| 943 |
+
"givenName":"George",
|
| 944 |
+
"familyName": "O'Neill"
|
| 945 |
+
},
|
| 946 |
+
{
|
| 947 |
+
"@type":"Person",
|
| 948 |
+
"email":"giorgio.marinato@unitn.it",
|
| 949 |
+
"givenName":"Giorgio",
|
| 950 |
+
"familyName": "Marinato"
|
| 951 |
+
},
|
| 952 |
+
{
|
| 953 |
+
"@type":"Person",
|
| 954 |
+
"email":"hafiza.taj@gmail.com",
|
| 955 |
+
"givenName":"Hafeza",
|
| 956 |
+
"familyName": "Anevar"
|
| 957 |
+
},
|
| 958 |
+
{
|
| 959 |
+
"@type":"Person",
|
| 960 |
+
"email":"hamza.abdelhedii@gmail.com",
|
| 961 |
+
"givenName":"Hamza",
|
| 962 |
+
"familyName": "Abdelhedi"
|
| 963 |
+
},
|
| 964 |
+
{
|
| 965 |
+
"@type":"Person",
|
| 966 |
+
"email":"mail@jan-sosulski.de",
|
| 967 |
+
"givenName":"Jan",
|
| 968 |
+
"familyName": "Sosulski"
|
| 969 |
+
},
|
| 970 |
+
{
|
| 971 |
+
"@type":"Person",
|
| 972 |
+
"email":"stoutjd@nih.gov",
|
| 973 |
+
"givenName":"Jeff",
|
| 974 |
+
"familyName": "Stout"
|
| 975 |
+
},
|
| 976 |
+
{
|
| 977 |
+
"@type":"Person",
|
| 978 |
+
"email":"",
|
| 979 |
+
"givenName":"Joshua",
|
| 980 |
+
"familyName": "Calder-Travis"
|
| 981 |
+
},
|
| 982 |
+
{
|
| 983 |
+
"@type":"Person",
|
| 984 |
+
"email":"",
|
| 985 |
+
"givenName":"Judy D",
|
| 986 |
+
"familyName": "Zhu"
|
| 987 |
+
},
|
| 988 |
+
{
|
| 989 |
+
"@type":"Person",
|
| 990 |
+
"email":"leisenman@wustl.edu",
|
| 991 |
+
"givenName":"Larry",
|
| 992 |
+
"familyName": "Eisenman"
|
| 993 |
+
},
|
| 994 |
+
{
|
| 995 |
+
"@type":"Person",
|
| 996 |
+
"email":"Lorenz.Esch@tu-ilmenau.de",
|
| 997 |
+
"givenName":"Lorenz",
|
| 998 |
+
"familyName": "Esch"
|
| 999 |
+
},
|
| 1000 |
+
{
|
| 1001 |
+
"@type":"Person",
|
| 1002 |
+
"email":"marian.dowgialo@gmail.com",
|
| 1003 |
+
"givenName":"Marian",
|
| 1004 |
+
"familyName": "Dovgialo"
|
| 1005 |
+
},
|
| 1006 |
+
{
|
| 1007 |
+
"@type":"Person",
|
| 1008 |
+
"email":"",
|
| 1009 |
+
"givenName":"Nicolas",
|
| 1010 |
+
"familyName": "Barascud"
|
| 1011 |
+
},
|
| 1012 |
+
{
|
| 1013 |
+
"@type":"Person",
|
| 1014 |
+
"email":"legrand@cyceron.fr",
|
| 1015 |
+
"givenName":"Nicolas",
|
| 1016 |
+
"familyName": "Legrand"
|
| 1017 |
+
},
|
| 1018 |
+
{
|
| 1019 |
+
"@type":"Person",
|
| 1020 |
+
"email":"4dvlup@gmail.com",
|
| 1021 |
+
"givenName":"Nikolai",
|
| 1022 |
+
"familyName": "Kapralov"
|
| 1023 |
+
},
|
| 1024 |
+
{
|
| 1025 |
+
"@type":"Person",
|
| 1026 |
+
"email":"pmolfese@gmail.com",
|
| 1027 |
+
"givenName":"Peter J",
|
| 1028 |
+
"familyName": "Molfese"
|
| 1029 |
+
},
|
| 1030 |
+
{
|
| 1031 |
+
"@type":"Person",
|
| 1032 |
+
"email":"falachrotem@gmail.com",
|
| 1033 |
+
"givenName":"Rotem",
|
| 1034 |
+
"familyName": "Falach"
|
| 1035 |
+
},
|
| 1036 |
+
{
|
| 1037 |
+
"@type":"Person",
|
| 1038 |
+
"email":"sam.deslauriers@gmail.com",
|
| 1039 |
+
"givenName":"Samuel",
|
| 1040 |
+
"familyName": "Deslauriers-Gauthier"
|
| 1041 |
+
},
|
| 1042 |
+
{
|
| 1043 |
+
"@type":"Person",
|
| 1044 |
+
"email":"",
|
| 1045 |
+
"givenName":"Silvia",
|
| 1046 |
+
"familyName": "Cotroneo"
|
| 1047 |
+
},
|
| 1048 |
+
{
|
| 1049 |
+
"@type":"Person",
|
| 1050 |
+
"email":"stevematindi@gmail.com",
|
| 1051 |
+
"givenName":"Steve",
|
| 1052 |
+
"familyName": "Matindi"
|
| 1053 |
+
},
|
| 1054 |
+
{
|
| 1055 |
+
"@type":"Person",
|
| 1056 |
+
"email":"neurolaunch@gmail.copm",
|
| 1057 |
+
"givenName":"Steven",
|
| 1058 |
+
"familyName": "Bierer"
|
| 1059 |
+
},
|
| 1060 |
+
{
|
| 1061 |
+
"@type":"Person",
|
| 1062 |
+
"email":"Theodore.Papadopoulo@inria.fr",
|
| 1063 |
+
"givenName":"Theodore",
|
| 1064 |
+
"familyName": "Papadopoulo"
|
| 1065 |
+
},
|
| 1066 |
+
{
|
| 1067 |
+
"@type":"Person",
|
| 1068 |
+
"email":"t.s.binns@outlook.com",
|
| 1069 |
+
"givenName":"Thomas Samuel",
|
| 1070 |
+
"familyName": "Binns"
|
| 1071 |
+
},
|
| 1072 |
+
{
|
| 1073 |
+
"@type":"Person",
|
| 1074 |
+
"email":"ttstenner@gmail.com",
|
| 1075 |
+
"givenName":"Tristan",
|
| 1076 |
+
"familyName": "Stenner"
|
| 1077 |
+
},
|
| 1078 |
+
{
|
| 1079 |
+
"@type":"Person",
|
| 1080 |
+
"email":"victoriapeterson09@gmail.com",
|
| 1081 |
+
"givenName":"Victoria",
|
| 1082 |
+
"familyName": "Peterson"
|
| 1083 |
+
},
|
| 1084 |
+
{
|
| 1085 |
+
"@type":"Person",
|
| 1086 |
+
"email":"z.baratz@gmail.com",
|
| 1087 |
+
"givenName":"Zvi",
|
| 1088 |
+
"familyName": "Baratz"
|
| 1089 |
+
},
|
| 1090 |
+
{
|
| 1091 |
+
"@type":"Person",
|
| 1092 |
+
"email":"alessandro.tonin@wysscenter.ch",
|
| 1093 |
+
"givenName":"Alessandro",
|
| 1094 |
+
"familyName": "Tonin"
|
| 1095 |
+
},
|
| 1096 |
+
{
|
| 1097 |
+
"@type":"Person",
|
| 1098 |
+
"email":"alexander.kovrig@gmail.com",
|
| 1099 |
+
"givenName":"Alexander",
|
| 1100 |
+
"familyName": "Kovrig"
|
| 1101 |
+
},
|
| 1102 |
+
{
|
| 1103 |
+
"@type":"Person",
|
| 1104 |
+
"email":"a.pascarella@iac.cnr.it",
|
| 1105 |
+
"givenName":"Annalisa",
|
| 1106 |
+
"familyName": "Pascarella"
|
| 1107 |
+
},
|
| 1108 |
+
{
|
| 1109 |
+
"@type":"Person",
|
| 1110 |
+
"email":"",
|
| 1111 |
+
"givenName":"Apoorva",
|
| 1112 |
+
"familyName": "Karekal"
|
| 1113 |
+
},
|
| 1114 |
+
{
|
| 1115 |
+
"@type":"Person",
|
| 1116 |
+
"email":"b.aristimunha@gmail.com",
|
| 1117 |
+
"givenName":"Bruno",
|
| 1118 |
+
"familyName": "Aristimunha"
|
| 1119 |
+
},
|
| 1120 |
+
{
|
| 1121 |
+
"@type":"Person",
|
| 1122 |
+
"email":"",
|
| 1123 |
+
"givenName":"Carlos",
|
| 1124 |
+
"familyName": "de la Torre"
|
| 1125 |
+
},
|
| 1126 |
+
{
|
| 1127 |
+
"@type":"Person",
|
| 1128 |
+
"email":"",
|
| 1129 |
+
"givenName":"Chetan",
|
| 1130 |
+
"familyName": "Gohil"
|
| 1131 |
+
},
|
| 1132 |
+
{
|
| 1133 |
+
"@type":"Person",
|
| 1134 |
+
"email":"zhaotc@uw.edu",
|
| 1135 |
+
"givenName":"Christina",
|
| 1136 |
+
"familyName": "Zhao"
|
| 1137 |
+
},
|
| 1138 |
+
{
|
| 1139 |
+
"@type":"Person",
|
| 1140 |
+
"email":"raymon92@gmail.com",
|
| 1141 |
+
"givenName":"Dominik",
|
| 1142 |
+
"familyName": "Krzemiński"
|
| 1143 |
+
},
|
| 1144 |
+
{
|
| 1145 |
+
"@type":"Person",
|
| 1146 |
+
"email":"dom.mak19@gmail.com",
|
| 1147 |
+
"givenName":"Dominique",
|
| 1148 |
+
"familyName": "Makowski"
|
| 1149 |
+
},
|
| 1150 |
+
{
|
| 1151 |
+
"@type":"Person",
|
| 1152 |
+
"email":"e.mikulan@gmail.com",
|
| 1153 |
+
"givenName":"Ezequiel",
|
| 1154 |
+
"familyName": "Mikulan"
|
| 1155 |
+
},
|
| 1156 |
+
{
|
| 1157 |
+
"@type":"Person",
|
| 1158 |
+
"email":"hofaflo@gmail.com",
|
| 1159 |
+
"givenName":"Florian",
|
| 1160 |
+
"familyName": "Hofer"
|
| 1161 |
+
},
|
| 1162 |
+
{
|
| 1163 |
+
"@type":"Person",
|
| 1164 |
+
"email":"harrison.ritz@gmail.com",
|
| 1165 |
+
"givenName":"Harrison",
|
| 1166 |
+
"familyName": "Ritz"
|
| 1167 |
+
},
|
| 1168 |
+
{
|
| 1169 |
+
"@type":"Person",
|
| 1170 |
+
"email":"jean.baptiste.schiratti@gmail.com",
|
| 1171 |
+
"givenName":"Jean-Baptiste",
|
| 1172 |
+
"familyName": "Schiratti"
|
| 1173 |
+
},
|
| 1174 |
+
{
|
| 1175 |
+
"@type":"Person",
|
| 1176 |
+
"email":"",
|
| 1177 |
+
"givenName":"Jen",
|
| 1178 |
+
"familyName": "Evans"
|
| 1179 |
+
},
|
| 1180 |
+
{
|
| 1181 |
+
"@type":"Person",
|
| 1182 |
+
"email":"johannes@herforth.net",
|
| 1183 |
+
"givenName":"Johannes",
|
| 1184 |
+
"familyName": "Herforth"
|
| 1185 |
+
},
|
| 1186 |
+
{
|
| 1187 |
+
"@type":"Person",
|
| 1188 |
+
"email":"johnv@uchicago.edu",
|
| 1189 |
+
"givenName":"John",
|
| 1190 |
+
"familyName": "Veillette"
|
| 1191 |
+
},
|
| 1192 |
+
{
|
| 1193 |
+
"@type":"Person",
|
| 1194 |
+
"email":"",
|
| 1195 |
+
"givenName":"Jordan",
|
| 1196 |
+
"familyName": "Drew"
|
| 1197 |
+
},
|
| 1198 |
+
{
|
| 1199 |
+
"@type":"Person",
|
| 1200 |
+
"email":"jbtevespro@gmail.com",
|
| 1201 |
+
"givenName":"Joshua",
|
| 1202 |
+
"familyName": "Teves"
|
| 1203 |
+
},
|
| 1204 |
+
{
|
| 1205 |
+
"@type":"Person",
|
| 1206 |
+
"email":"kylemath@gmail.com",
|
| 1207 |
+
"givenName":"Kyle",
|
| 1208 |
+
"familyName": "Mathewson"
|
| 1209 |
+
},
|
| 1210 |
+
{
|
| 1211 |
+
"@type":"Person",
|
| 1212 |
+
"email":"lgwilliams90@gmail.com",
|
| 1213 |
+
"givenName":"Laura",
|
| 1214 |
+
"familyName": "Gwilliams"
|
| 1215 |
+
},
|
| 1216 |
+
{
|
| 1217 |
+
"@type":"Person",
|
| 1218 |
+
"email":"laurent.lementec@gmail.com",
|
| 1219 |
+
"givenName":"Laurent",
|
| 1220 |
+
"familyName": "Lementec"
|
| 1221 |
+
},
|
| 1222 |
+
{
|
| 1223 |
+
"@type":"Person",
|
| 1224 |
+
"email":"",
|
| 1225 |
+
"givenName":"Lenny",
|
| 1226 |
+
"familyName": "Varghese"
|
| 1227 |
+
},
|
| 1228 |
+
{
|
| 1229 |
+
"@type":"Person",
|
| 1230 |
+
"email":"",
|
| 1231 |
+
"givenName":"Liberty",
|
| 1232 |
+
"familyName": "Hamilton"
|
| 1233 |
+
},
|
| 1234 |
+
{
|
| 1235 |
+
"@type":"Person",
|
| 1236 |
+
"email":"lukas.gemein@gmx.de",
|
| 1237 |
+
"givenName":"Lukas",
|
| 1238 |
+
"familyName": "Gemein"
|
| 1239 |
+
},
|
| 1240 |
+
{
|
| 1241 |
+
"@type":"Person",
|
| 1242 |
+
"email":"",
|
| 1243 |
+
"givenName":"Lukas",
|
| 1244 |
+
"familyName": "Hecker"
|
| 1245 |
+
},
|
| 1246 |
+
{
|
| 1247 |
+
"@type":"Person",
|
| 1248 |
+
"email":"capmanip@DESKTOP-TLIFEG1.localdomain",
|
| 1249 |
+
"givenName":"",
|
| 1250 |
+
"familyName": "Lx37"
|
| 1251 |
+
},
|
| 1252 |
+
{
|
| 1253 |
+
"@type":"Person",
|
| 1254 |
+
"email":"mats.vanes@psych.ox.ac.uk",
|
| 1255 |
+
"givenName":"Mats",
|
| 1256 |
+
"familyName": "van Es"
|
| 1257 |
+
},
|
| 1258 |
+
{
|
| 1259 |
+
"@type":"Person",
|
| 1260 |
+
"email":"",
|
| 1261 |
+
"givenName":"Matt",
|
| 1262 |
+
"familyName": "Boggess"
|
| 1263 |
+
},
|
| 1264 |
+
{
|
| 1265 |
+
"@type":"Person",
|
| 1266 |
+
"email":"",
|
| 1267 |
+
"givenName":"Matthias",
|
| 1268 |
+
"familyName": "Eberlein"
|
| 1269 |
+
},
|
| 1270 |
+
{
|
| 1271 |
+
"@type":"Person",
|
| 1272 |
+
"email":"",
|
| 1273 |
+
"givenName":"Michal",
|
| 1274 |
+
"familyName": "Žák"
|
| 1275 |
+
},
|
| 1276 |
+
{
|
| 1277 |
+
"@type":"Person",
|
| 1278 |
+
"email":"molpsychistb@gmail.com",
|
| 1279 |
+
"givenName":"Mohamed",
|
| 1280 |
+
"familyName": "Sherif"
|
| 1281 |
+
},
|
| 1282 |
+
{
|
| 1283 |
+
"@type":"Person",
|
| 1284 |
+
"email":"natakozh22@gmail.com",
|
| 1285 |
+
"givenName":"Nataliia",
|
| 1286 |
+
"familyName": "Kozhemiako"
|
| 1287 |
+
},
|
| 1288 |
+
{
|
| 1289 |
+
"@type":"Person",
|
| 1290 |
+
"email":"",
|
| 1291 |
+
"givenName":"Naveen",
|
| 1292 |
+
"familyName": "Srinivasan"
|
| 1293 |
+
},
|
| 1294 |
+
{
|
| 1295 |
+
"@type":"Person",
|
| 1296 |
+
"email":"niklas.wilming@gmail.com",
|
| 1297 |
+
"givenName":"Niklas",
|
| 1298 |
+
"familyName": "Wilming"
|
| 1299 |
+
},
|
| 1300 |
+
{
|
| 1301 |
+
"@type":"Person",
|
| 1302 |
+
"email":"",
|
| 1303 |
+
"givenName":"Oleh",
|
| 1304 |
+
"familyName": "Kozynets"
|
| 1305 |
+
},
|
| 1306 |
+
{
|
| 1307 |
+
"@type":"Person",
|
| 1308 |
+
"email":"pierreablin@gmail.com",
|
| 1309 |
+
"givenName":"Pierre",
|
| 1310 |
+
"familyName": "Ablin"
|
| 1311 |
+
},
|
| 1312 |
+
{
|
| 1313 |
+
"@type":"Person",
|
| 1314 |
+
"email":"proloy@umd.edu",
|
| 1315 |
+
"givenName":"Proloy",
|
| 1316 |
+
"familyName": "Das"
|
| 1317 |
+
},
|
| 1318 |
+
{
|
| 1319 |
+
"@type":"Person",
|
| 1320 |
+
"email":"quentinbertrand54@gmail.com",
|
| 1321 |
+
"givenName":"Quentin",
|
| 1322 |
+
"familyName": "Bertrand"
|
| 1323 |
+
},
|
| 1324 |
+
{
|
| 1325 |
+
"@type":"Person",
|
| 1326 |
+
"email":"r.shoorangiz@live.com",
|
| 1327 |
+
"givenName":"Reza",
|
| 1328 |
+
"familyName": "Shoorangiz"
|
| 1329 |
+
},
|
| 1330 |
+
{
|
| 1331 |
+
"@type":"Person",
|
| 1332 |
+
"email":"",
|
| 1333 |
+
"givenName":"Richard",
|
| 1334 |
+
"familyName": "Scholz"
|
| 1335 |
+
},
|
| 1336 |
+
{
|
| 1337 |
+
"@type":"Person",
|
| 1338 |
+
"email":"rhubner@gmail.com",
|
| 1339 |
+
"givenName":"Rodrigo",
|
| 1340 |
+
"familyName": "Hübner"
|
| 1341 |
+
},
|
| 1342 |
+
{
|
| 1343 |
+
"@type":"Person",
|
| 1344 |
+
"email":"sommariva@dima.unige.it",
|
| 1345 |
+
"givenName":"Sara",
|
| 1346 |
+
"familyName": "Sommariva"
|
| 1347 |
+
},
|
| 1348 |
+
{
|
| 1349 |
+
"@type":"Person",
|
| 1350 |
+
"email":"",
|
| 1351 |
+
"givenName":"Sena",
|
| 1352 |
+
"familyName": "Er"
|
| 1353 |
+
},
|
| 1354 |
+
{
|
| 1355 |
+
"@type":"Person",
|
| 1356 |
+
"email":"sheraz@nmr.mgh.harvard.edu",
|
| 1357 |
+
"givenName":"Sheraz",
|
| 1358 |
+
"familyName": "Khan"
|
| 1359 |
+
},
|
| 1360 |
+
{
|
| 1361 |
+
"@type":"Person",
|
| 1362 |
+
"email":"",
|
| 1363 |
+
"givenName":"Sumalyo",
|
| 1364 |
+
"familyName": "Datta"
|
| 1365 |
+
},
|
| 1366 |
+
{
|
| 1367 |
+
"@type":"Person",
|
| 1368 |
+
"email":"tdonoghue.research@gmail.com",
|
| 1369 |
+
"givenName":"Thomas",
|
| 1370 |
+
"familyName": "Donoghue"
|
| 1371 |
+
},
|
| 1372 |
+
{
|
| 1373 |
+
"@type":"Person",
|
| 1374 |
+
"email":"",
|
| 1375 |
+
"givenName":"Thomas",
|
| 1376 |
+
"familyName": "Jochmann"
|
| 1377 |
+
},
|
| 1378 |
+
{
|
| 1379 |
+
"@type":"Person",
|
| 1380 |
+
"email":"timon.merk@charite.de",
|
| 1381 |
+
"givenName":"Timon",
|
| 1382 |
+
"familyName": "Merk"
|
| 1383 |
+
},
|
| 1384 |
+
{
|
| 1385 |
+
"@type":"Person",
|
| 1386 |
+
"email":"",
|
| 1387 |
+
"givenName":"Tod",
|
| 1388 |
+
"familyName": "Flak"
|
| 1389 |
+
},
|
| 1390 |
+
{
|
| 1391 |
+
"@type":"Person",
|
| 1392 |
+
"email":"tom.dupre-la-tour@m4x.org",
|
| 1393 |
+
"givenName":"Tom",
|
| 1394 |
+
"familyName": "Dupré la Tour"
|
| 1395 |
+
},
|
| 1396 |
+
{
|
| 1397 |
+
"@type":"Person",
|
| 1398 |
+
"email":"tzionan@mail.tau.ac.il",
|
| 1399 |
+
"givenName":"Tziona",
|
| 1400 |
+
"familyName": "NessAiver"
|
| 1401 |
+
},
|
| 1402 |
+
{
|
| 1403 |
+
"@type":"Person",
|
| 1404 |
+
"email":"akshay0724@gmail.com",
|
| 1405 |
+
"givenName":"",
|
| 1406 |
+
"familyName": "akshay0724"
|
| 1407 |
+
},
|
| 1408 |
+
{
|
| 1409 |
+
"@type":"Person",
|
| 1410 |
+
"email":"sviter33@gmail.com",
|
| 1411 |
+
"givenName":"",
|
| 1412 |
+
"familyName": "sviter"
|
| 1413 |
+
},
|
| 1414 |
+
{
|
| 1415 |
+
"@type":"Person",
|
| 1416 |
+
"email":"Jakdaxter31@gmail.com",
|
| 1417 |
+
"givenName":"Aaron",
|
| 1418 |
+
"familyName": "Earle-Richardson"
|
| 1419 |
+
},
|
| 1420 |
+
{
|
| 1421 |
+
"@type":"Person",
|
| 1422 |
+
"email":"abram.hindle@softwareprocess.es",
|
| 1423 |
+
"givenName":"Abram",
|
| 1424 |
+
"familyName": "Hindle"
|
| 1425 |
+
},
|
| 1426 |
+
{
|
| 1427 |
+
"@type":"Person",
|
| 1428 |
+
"email":"achilleas.k@gmail.com",
|
| 1429 |
+
"givenName":"Achilleas",
|
| 1430 |
+
"familyName": "Koutsou"
|
| 1431 |
+
},
|
| 1432 |
+
{
|
| 1433 |
+
"@type":"Person",
|
| 1434 |
+
"email":"",
|
| 1435 |
+
"givenName":"Adeline",
|
| 1436 |
+
"familyName": "Fecker"
|
| 1437 |
+
},
|
| 1438 |
+
{
|
| 1439 |
+
"@type":"Person",
|
| 1440 |
+
"email":"adina.wagner@t-online.de",
|
| 1441 |
+
"givenName":"Adina",
|
| 1442 |
+
"familyName": "Wagner"
|
| 1443 |
+
},
|
| 1444 |
+
{
|
| 1445 |
+
"@type":"Person",
|
| 1446 |
+
"email":"",
|
| 1447 |
+
"givenName":"Alex",
|
| 1448 |
+
"familyName": "Ciok"
|
| 1449 |
+
},
|
| 1450 |
+
{
|
| 1451 |
+
"@type":"Person",
|
| 1452 |
+
"email":"alex.lepauvre@ae.mpg.de",
|
| 1453 |
+
"givenName":"Alex",
|
| 1454 |
+
"familyName": "Lepauvre"
|
| 1455 |
+
},
|
| 1456 |
+
{
|
| 1457 |
+
"@type":"Person",
|
| 1458 |
+
"email":"",
|
| 1459 |
+
"givenName":"Alexander",
|
| 1460 |
+
"familyName": "Kiefer"
|
| 1461 |
+
},
|
| 1462 |
+
{
|
| 1463 |
+
"@type":"Person",
|
| 1464 |
+
"email":"7andy121@gmail.com",
|
| 1465 |
+
"givenName":"Andy",
|
| 1466 |
+
"familyName": "Gilbert"
|
| 1467 |
+
},
|
| 1468 |
+
{
|
| 1469 |
+
"@type":"Person",
|
| 1470 |
+
"email":"aniket17133@iiitd.ac.in",
|
| 1471 |
+
"givenName":"Aniket",
|
| 1472 |
+
"familyName": "Pradhan"
|
| 1473 |
+
},
|
| 1474 |
+
{
|
| 1475 |
+
"@type":"Person",
|
| 1476 |
+
"email":"anna.padee@gmail.com",
|
| 1477 |
+
"givenName":"Anna",
|
| 1478 |
+
"familyName": "Padee"
|
| 1479 |
+
},
|
| 1480 |
+
{
|
| 1481 |
+
"@type":"Person",
|
| 1482 |
+
"email":"as_dub@hotmail.com",
|
| 1483 |
+
"givenName":"Anne-Sophie",
|
| 1484 |
+
"familyName": "Dubarry"
|
| 1485 |
+
},
|
| 1486 |
+
{
|
| 1487 |
+
"@type":"Person",
|
| 1488 |
+
"email":"contact@antoinecollas.fr",
|
| 1489 |
+
"givenName":"Antoine",
|
| 1490 |
+
"familyName": "Collas"
|
| 1491 |
+
},
|
| 1492 |
+
{
|
| 1493 |
+
"@type":"Person",
|
| 1494 |
+
"email":"",
|
| 1495 |
+
"givenName":"Anton Nikolas",
|
| 1496 |
+
"familyName": "Waniek"
|
| 1497 |
+
},
|
| 1498 |
+
{
|
| 1499 |
+
"@type":"Person",
|
| 1500 |
+
"email":"",
|
| 1501 |
+
"givenName":"Archit",
|
| 1502 |
+
"familyName": "Singhal"
|
| 1503 |
+
},
|
| 1504 |
+
{
|
| 1505 |
+
"@type":"Person",
|
| 1506 |
+
"email":"arokem@gmail.com",
|
| 1507 |
+
"givenName":"Ariel",
|
| 1508 |
+
"familyName": "Rokem"
|
| 1509 |
+
},
|
| 1510 |
+
{
|
| 1511 |
+
"@type":"Person",
|
| 1512 |
+
"email":"arne.pelzer@idmt.fraunhofer.de",
|
| 1513 |
+
"givenName":"Arne",
|
| 1514 |
+
"familyName": "Pelzer"
|
| 1515 |
+
},
|
| 1516 |
+
{
|
| 1517 |
+
"@type":"Person",
|
| 1518 |
+
"email":"mynameisaustinhurst@gmail.com",
|
| 1519 |
+
"givenName":"Austin",
|
| 1520 |
+
"familyName": "Hurst"
|
| 1521 |
+
},
|
| 1522 |
+
{
|
| 1523 |
+
"@type":"Person",
|
| 1524 |
+
"email":"",
|
| 1525 |
+
"givenName":"Beige Jerry",
|
| 1526 |
+
"familyName": "Jin"
|
| 1527 |
+
},
|
| 1528 |
+
{
|
| 1529 |
+
"@type":"Person",
|
| 1530 |
+
"email":"code@musicinmybrain.net",
|
| 1531 |
+
"givenName":"Ben",
|
| 1532 |
+
"familyName": "Beasley"
|
| 1533 |
+
},
|
| 1534 |
+
{
|
| 1535 |
+
"@type":"Person",
|
| 1536 |
+
"email":"bruno.nicenboim@gmail.com",
|
| 1537 |
+
"givenName":"Bruno",
|
| 1538 |
+
"familyName": "Nicenboim"
|
| 1539 |
+
},
|
| 1540 |
+
{
|
| 1541 |
+
"@type":"Person",
|
| 1542 |
+
"email":"ctorre@mailbox.org",
|
| 1543 |
+
"givenName":"Carlos",
|
| 1544 |
+
"familyName": "de la Torre"
|
| 1545 |
+
},
|
| 1546 |
+
{
|
| 1547 |
+
"@type":"Person",
|
| 1548 |
+
"email":"cclauss@me.com",
|
| 1549 |
+
"givenName":"Christian",
|
| 1550 |
+
"familyName": "Clauss"
|
| 1551 |
+
},
|
| 1552 |
+
{
|
| 1553 |
+
"@type":"Person",
|
| 1554 |
+
"email":"cmista@ingenieria.uner.edu.ar",
|
| 1555 |
+
"givenName":"Christian",
|
| 1556 |
+
"familyName": "Mista"
|
| 1557 |
+
},
|
| 1558 |
+
{
|
| 1559 |
+
"@type":"Person",
|
| 1560 |
+
"email":"kechrisc@gmail.com",
|
| 1561 |
+
"givenName":"Christodoulos",
|
| 1562 |
+
"familyName": "Kechris"
|
| 1563 |
+
},
|
| 1564 |
+
{
|
| 1565 |
+
"@type":"Person",
|
| 1566 |
+
"email":"",
|
| 1567 |
+
"givenName":"Chun-Hui",
|
| 1568 |
+
"familyName": "Li"
|
| 1569 |
+
},
|
| 1570 |
+
{
|
| 1571 |
+
"@type":"Person",
|
| 1572 |
+
"email":"claire@guakamole.org",
|
| 1573 |
+
"givenName":"Claire",
|
| 1574 |
+
"familyName": "Braboszcz"
|
| 1575 |
+
},
|
| 1576 |
+
{
|
| 1577 |
+
"@type":"Person",
|
| 1578 |
+
"email":"daniel.c.schad@protonmail.com",
|
| 1579 |
+
"givenName":"Daniel C",
|
| 1580 |
+
"familyName": "Schad"
|
| 1581 |
+
},
|
| 1582 |
+
{
|
| 1583 |
+
"@type":"Person",
|
| 1584 |
+
"email":"danielhasegan@gmail.com",
|
| 1585 |
+
"givenName":"Daniel",
|
| 1586 |
+
"familyName": "Hasegan"
|
| 1587 |
+
},
|
| 1588 |
+
{
|
| 1589 |
+
"@type":"Person",
|
| 1590 |
+
"email":"xiezhibin.0.0.superman@gmail.com",
|
| 1591 |
+
"givenName":"Daniel",
|
| 1592 |
+
"familyName": "Tse"
|
| 1593 |
+
},
|
| 1594 |
+
{
|
| 1595 |
+
"@type":"Person",
|
| 1596 |
+
"email":"darin.sleiter@gmail.com",
|
| 1597 |
+
"givenName":"Darin Erat",
|
| 1598 |
+
"familyName": "Sleiter"
|
| 1599 |
+
},
|
| 1600 |
+
{
|
| 1601 |
+
"@type":"Person",
|
| 1602 |
+
"email":"haslacherdavid@gmail.com",
|
| 1603 |
+
"givenName":"David",
|
| 1604 |
+
"familyName": "Haslacher"
|
| 1605 |
+
},
|
| 1606 |
+
{
|
| 1607 |
+
"@type":"Person",
|
| 1608 |
+
"email":"dav.sabbagh@gmail.com",
|
| 1609 |
+
"givenName":"David",
|
| 1610 |
+
"familyName": "Sabbagh"
|
| 1611 |
+
},
|
| 1612 |
+
{
|
| 1613 |
+
"@type":"Person",
|
| 1614 |
+
"email":"",
|
| 1615 |
+
"givenName":"Demetres",
|
| 1616 |
+
"familyName": "Kostas"
|
| 1617 |
+
},
|
| 1618 |
+
{
|
| 1619 |
+
"@type":"Person",
|
| 1620 |
+
"email":"desislavka@gmail.com",
|
| 1621 |
+
"givenName":"Desislava",
|
| 1622 |
+
"familyName": "Petkova"
|
| 1623 |
+
},
|
| 1624 |
+
{
|
| 1625 |
+
"@type":"Person",
|
| 1626 |
+
"email":"",
|
| 1627 |
+
"givenName":"Dinara",
|
| 1628 |
+
"familyName": "Issagaliyeva"
|
| 1629 |
+
},
|
| 1630 |
+
{
|
| 1631 |
+
"@type":"Person",
|
| 1632 |
+
"email":"",
|
| 1633 |
+
"givenName":"Diptyajit",
|
| 1634 |
+
"familyName": "Das"
|
| 1635 |
+
},
|
| 1636 |
+
{
|
| 1637 |
+
"@type":"Person",
|
| 1638 |
+
"email":"dimonok@web.de",
|
| 1639 |
+
"givenName":"Dominik",
|
| 1640 |
+
"familyName": "Wetzel"
|
| 1641 |
+
},
|
| 1642 |
+
{
|
| 1643 |
+
"@type":"Person",
|
| 1644 |
+
"email":"e.eich@fz-juelich.de",
|
| 1645 |
+
"givenName":"Eberhard",
|
| 1646 |
+
"familyName": "Eich"
|
| 1647 |
+
},
|
| 1648 |
+
{
|
| 1649 |
+
"@type":"Person",
|
| 1650 |
+
"email":"emd222@cornell.edu",
|
| 1651 |
+
"givenName":"Elizabeth",
|
| 1652 |
+
"familyName": "DuPre"
|
| 1653 |
+
},
|
| 1654 |
+
{
|
| 1655 |
+
"@type":"Person",
|
| 1656 |
+
"email":"ellenlau@umd.edu",
|
| 1657 |
+
"givenName":"Ellen",
|
| 1658 |
+
"familyName": "Lau"
|
| 1659 |
+
},
|
| 1660 |
+
{
|
| 1661 |
+
"@type":"Person",
|
| 1662 |
+
"email":"emanuele@relativita.com",
|
| 1663 |
+
"givenName":"Emanuele",
|
| 1664 |
+
"familyName": "Olivetti"
|
| 1665 |
+
},
|
| 1666 |
+
{
|
| 1667 |
+
"@type":"Person",
|
| 1668 |
+
"email":"",
|
| 1669 |
+
"givenName":"Emma",
|
| 1670 |
+
"familyName": "Zhang"
|
| 1671 |
+
},
|
| 1672 |
+
{
|
| 1673 |
+
"@type":"Person",
|
| 1674 |
+
"email":"emmanuelferdman@gmail.com",
|
| 1675 |
+
"givenName":"Emmanuel",
|
| 1676 |
+
"familyName": "Ferdman"
|
| 1677 |
+
},
|
| 1678 |
+
{
|
| 1679 |
+
"@type":"Person",
|
| 1680 |
+
"email":"emrecncelik@gmail.com",
|
| 1681 |
+
"givenName":"Emrecan",
|
| 1682 |
+
"familyName": "Çelik"
|
| 1683 |
+
},
|
| 1684 |
+
{
|
| 1685 |
+
"@type":"Person",
|
| 1686 |
+
"email":"enricovarano@gmail.com",
|
| 1687 |
+
"givenName":"Enrico",
|
| 1688 |
+
"familyName": "Varano"
|
| 1689 |
+
},
|
| 1690 |
+
{
|
| 1691 |
+
"@type":"Person",
|
| 1692 |
+
"email":"enzo.alt@gmail.com",
|
| 1693 |
+
"givenName":"Enzo",
|
| 1694 |
+
"familyName": "Altamiranda"
|
| 1695 |
+
},
|
| 1696 |
+
{
|
| 1697 |
+
"@type":"Person",
|
| 1698 |
+
"email":"eric.brayet@mybraintech.com",
|
| 1699 |
+
"givenName":"Eric",
|
| 1700 |
+
"familyName": "Brayet"
|
| 1701 |
+
},
|
| 1702 |
+
{
|
| 1703 |
+
"@type":"Person",
|
| 1704 |
+
"email":"",
|
| 1705 |
+
"givenName":"Etienne",
|
| 1706 |
+
"familyName": "de Montalivet"
|
| 1707 |
+
},
|
| 1708 |
+
{
|
| 1709 |
+
"@type":"Person",
|
| 1710 |
+
"email":"",
|
| 1711 |
+
"givenName":"Evgeny",
|
| 1712 |
+
"familyName": "Goldstein"
|
| 1713 |
+
},
|
| 1714 |
+
{
|
| 1715 |
+
"@type":"Person",
|
| 1716 |
+
"email":"fmamashli@gmail.com",
|
| 1717 |
+
"givenName":"Fahimeh",
|
| 1718 |
+
"familyName": "Mamashli"
|
| 1719 |
+
},
|
| 1720 |
+
{
|
| 1721 |
+
"@type":"Person",
|
| 1722 |
+
"email":"farzin.negahbani@gmail.com",
|
| 1723 |
+
"givenName":"Farzin",
|
| 1724 |
+
"familyName": "Negahbani"
|
| 1725 |
+
},
|
| 1726 |
+
{
|
| 1727 |
+
"@type":"Person",
|
| 1728 |
+
"email":"",
|
| 1729 |
+
"givenName":"Federico",
|
| 1730 |
+
"familyName": "Zamberlan"
|
| 1731 |
+
},
|
| 1732 |
+
{
|
| 1733 |
+
"@type":"Person",
|
| 1734 |
+
"email":"florinpop@me.com",
|
| 1735 |
+
"givenName":"Florin",
|
| 1736 |
+
"familyName": "Pop"
|
| 1737 |
+
},
|
| 1738 |
+
{
|
| 1739 |
+
"@type":"Person",
|
| 1740 |
+
"email":"",
|
| 1741 |
+
"givenName":"Frederik D",
|
| 1742 |
+
"familyName": "Weber"
|
| 1743 |
+
},
|
| 1744 |
+
{
|
| 1745 |
+
"@type":"Person",
|
| 1746 |
+
"email":"",
|
| 1747 |
+
"givenName":"Gansheng",
|
| 1748 |
+
"familyName": "Tan"
|
| 1749 |
+
},
|
| 1750 |
+
{
|
| 1751 |
+
"@type":"Person",
|
| 1752 |
+
"email":"Geoff.Brookshire@gmail.com",
|
| 1753 |
+
"givenName":"Geoff",
|
| 1754 |
+
"familyName": "Brookshire"
|
| 1755 |
+
},
|
| 1756 |
+
{
|
| 1757 |
+
"@type":"Person",
|
| 1758 |
+
"email":"george.oneill.90@gmail.com",
|
| 1759 |
+
"givenName":"George",
|
| 1760 |
+
"familyName": "O'Neill"
|
| 1761 |
+
},
|
| 1762 |
+
{
|
| 1763 |
+
"@type":"Person",
|
| 1764 |
+
"email":"gack94@gmail.com",
|
| 1765 |
+
"givenName":"",
|
| 1766 |
+
"familyName": "Giulio"
|
| 1767 |
+
},
|
| 1768 |
+
{
|
| 1769 |
+
"@type":"Person",
|
| 1770 |
+
"email":"",
|
| 1771 |
+
"givenName":"Gonzalo",
|
| 1772 |
+
"familyName": "Reina"
|
| 1773 |
+
},
|
| 1774 |
+
{
|
| 1775 |
+
"@type":"Person",
|
| 1776 |
+
"email":"",
|
| 1777 |
+
"givenName":"Hamid",
|
| 1778 |
+
"familyName": "Maymandi"
|
| 1779 |
+
},
|
| 1780 |
+
{
|
| 1781 |
+
"@type":"Person",
|
| 1782 |
+
"email":"hasrat407@gmail.com",
|
| 1783 |
+
"givenName":"Hasrat Ali",
|
| 1784 |
+
"familyName": "Arzoo"
|
| 1785 |
+
},
|
| 1786 |
+
{
|
| 1787 |
+
"@type":"Person",
|
| 1788 |
+
"email":"hermann.sonntag@gmail.com",
|
| 1789 |
+
"givenName":"Hermann",
|
| 1790 |
+
"familyName": "Sonntag"
|
| 1791 |
+
},
|
| 1792 |
+
{
|
| 1793 |
+
"@type":"Person",
|
| 1794 |
+
"email":"rubyyhj@gmail.com",
|
| 1795 |
+
"givenName":"Hongjiang",
|
| 1796 |
+
"familyName": "Ye"
|
| 1797 |
+
},
|
| 1798 |
+
{
|
| 1799 |
+
"@type":"Person",
|
| 1800 |
+
"email":"",
|
| 1801 |
+
"givenName":"Hyonyoung",
|
| 1802 |
+
"familyName": "Shin"
|
| 1803 |
+
},
|
| 1804 |
+
{
|
| 1805 |
+
"@type":"Person",
|
| 1806 |
+
"email":"huseyinorkunelmas@gmail.com",
|
| 1807 |
+
"givenName":"Hüseyin Orkun",
|
| 1808 |
+
"familyName": "Elmas"
|
| 1809 |
+
},
|
| 1810 |
+
{
|
| 1811 |
+
"@type":"Person",
|
| 1812 |
+
"email":"",
|
| 1813 |
+
"givenName":"Ilian",
|
| 1814 |
+
"familyName": "AZZ"
|
| 1815 |
+
},
|
| 1816 |
+
{
|
| 1817 |
+
"@type":"Person",
|
| 1818 |
+
"email":"",
|
| 1819 |
+
"givenName":"Ilias",
|
| 1820 |
+
"familyName": "Machairas"
|
| 1821 |
+
},
|
| 1822 |
+
{
|
| 1823 |
+
"@type":"Person",
|
| 1824 |
+
"email":"ivan.zubarev@aalto.fi",
|
| 1825 |
+
"givenName":"Ivan",
|
| 1826 |
+
"familyName": "Zubarev"
|
| 1827 |
+
},
|
| 1828 |
+
{
|
| 1829 |
+
"@type":"Person",
|
| 1830 |
+
"email":"ivopascal@gmail.com",
|
| 1831 |
+
"givenName":"Ivo",
|
| 1832 |
+
"familyName": "de Jong"
|
| 1833 |
+
},
|
| 1834 |
+
{
|
| 1835 |
+
"@type":"Person",
|
| 1836 |
+
"email":"jacob.phelan.jp@gmail.com",
|
| 1837 |
+
"givenName":"Jacob",
|
| 1838 |
+
"familyName": "Phelan"
|
| 1839 |
+
},
|
| 1840 |
+
{
|
| 1841 |
+
"@type":"Person",
|
| 1842 |
+
"email":"",
|
| 1843 |
+
"givenName":"Jakub",
|
| 1844 |
+
"familyName": "Kaczmarzyk"
|
| 1845 |
+
},
|
| 1846 |
+
{
|
| 1847 |
+
"@type":"Person",
|
| 1848 |
+
"email":"",
|
| 1849 |
+
"givenName":"Jan",
|
| 1850 |
+
"familyName": "Zerfowski"
|
| 1851 |
+
},
|
| 1852 |
+
{
|
| 1853 |
+
"@type":"Person",
|
| 1854 |
+
"email":"japsai@gmail.com",
|
| 1855 |
+
"givenName":"Jasper J F",
|
| 1856 |
+
"familyName": "van den Bosch"
|
| 1857 |
+
},
|
| 1858 |
+
{
|
| 1859 |
+
"@type":"Person",
|
| 1860 |
+
"email":"",
|
| 1861 |
+
"givenName":"Jeroen",
|
| 1862 |
+
"familyName": "Van Der Donckt"
|
| 1863 |
+
},
|
| 1864 |
+
{
|
| 1865 |
+
"@type":"Person",
|
| 1866 |
+
"email":"johanvandermeer@gmail.com",
|
| 1867 |
+
"givenName":"Johan",
|
| 1868 |
+
"familyName": "van der Meer"
|
| 1869 |
+
},
|
| 1870 |
+
{
|
| 1871 |
+
"@type":"Person",
|
| 1872 |
+
"email":"",
|
| 1873 |
+
"givenName":"Johannes",
|
| 1874 |
+
"familyName": "Niediek"
|
| 1875 |
+
},
|
| 1876 |
+
{
|
| 1877 |
+
"@type":"Person",
|
| 1878 |
+
"email":"koen.joshua@gmail.com",
|
| 1879 |
+
"givenName":"Josh",
|
| 1880 |
+
"familyName": "Koen"
|
| 1881 |
+
},
|
| 1882 |
+
{
|
| 1883 |
+
"@type":"Person",
|
| 1884 |
+
"email":"",
|
| 1885 |
+
"givenName":"Joshua J",
|
| 1886 |
+
"familyName": "Bear"
|
| 1887 |
+
},
|
| 1888 |
+
{
|
| 1889 |
+
"@type":"Person",
|
| 1890 |
+
"email":"j.dammers@fz-juelich.de",
|
| 1891 |
+
"givenName":"Juergen",
|
| 1892 |
+
"familyName": "Dammers"
|
| 1893 |
+
},
|
| 1894 |
+
{
|
| 1895 |
+
"@type":"Person",
|
| 1896 |
+
"email":"guiomar.niso@ctb.upm.es",
|
| 1897 |
+
"givenName":"Julia Guiomar Niso",
|
| 1898 |
+
"familyName": "Galán"
|
| 1899 |
+
},
|
| 1900 |
+
{
|
| 1901 |
+
"@type":"Person",
|
| 1902 |
+
"email":"",
|
| 1903 |
+
"givenName":"Julius",
|
| 1904 |
+
"familyName": "Welzel"
|
| 1905 |
+
},
|
| 1906 |
+
{
|
| 1907 |
+
"@type":"Person",
|
| 1908 |
+
"email":"slama@berkeley.edu",
|
| 1909 |
+
"givenName":"Katarina",
|
| 1910 |
+
"familyName": "Slama"
|
| 1911 |
+
},
|
| 1912 |
+
{
|
| 1913 |
+
"@type":"Person",
|
| 1914 |
+
"email":"",
|
| 1915 |
+
"givenName":"Katia",
|
| 1916 |
+
"familyName": "Al-Amir"
|
| 1917 |
+
},
|
| 1918 |
+
{
|
| 1919 |
+
"@type":"Person",
|
| 1920 |
+
"email":"",
|
| 1921 |
+
"givenName":"Katrin",
|
| 1922 |
+
"familyName": "Leinweber"
|
| 1923 |
+
},
|
| 1924 |
+
{
|
| 1925 |
+
"@type":"Person",
|
| 1926 |
+
"email":"laetitia.grabot@gmail.com",
|
| 1927 |
+
"givenName":"Laetitia",
|
| 1928 |
+
"familyName": "Grabot"
|
| 1929 |
+
},
|
| 1930 |
+
{
|
| 1931 |
+
"@type":"Person",
|
| 1932 |
+
"email":"ualsbombe@protonmail.com",
|
| 1933 |
+
"givenName":"Lau Møller",
|
| 1934 |
+
"familyName": "Andersen"
|
| 1935 |
+
},
|
| 1936 |
+
{
|
| 1937 |
+
"@type":"Person",
|
| 1938 |
+
"email":"leorochael@gmail.com",
|
| 1939 |
+
"givenName":"Leonardo Rochael",
|
| 1940 |
+
"familyName": "Almeida"
|
| 1941 |
+
},
|
| 1942 |
+
{
|
| 1943 |
+
"@type":"Person",
|
| 1944 |
+
"email":"lsbarbosa@gmail.com",
|
| 1945 |
+
"givenName":"Leonardo S",
|
| 1946 |
+
"familyName": "Barbosa"
|
| 1947 |
+
},
|
| 1948 |
+
{
|
| 1949 |
+
"@type":"Person",
|
| 1950 |
+
"email":"lorenzo.alfine@gmail.com",
|
| 1951 |
+
"givenName":"Lorenzo",
|
| 1952 |
+
"familyName": "Alfine"
|
| 1953 |
+
},
|
| 1954 |
+
{
|
| 1955 |
+
"@type":"Person",
|
| 1956 |
+
"email":"hejtmy@gmail.com",
|
| 1957 |
+
"givenName":"Lukáš",
|
| 1958 |
+
"familyName": "Hejtmánek"
|
| 1959 |
+
},
|
| 1960 |
+
{
|
| 1961 |
+
"@type":"Person",
|
| 1962 |
+
"email":"mbalatsko@gmail.com",
|
| 1963 |
+
"givenName":"Maksym",
|
| 1964 |
+
"familyName": "Balatsko"
|
| 1965 |
+
},
|
| 1966 |
+
{
|
| 1967 |
+
"@type":"Person",
|
| 1968 |
+
"email":"manfredg@nmr.mgh.harvard.edu",
|
| 1969 |
+
"givenName":"Manfred",
|
| 1970 |
+
"familyName": "Kitzbichler"
|
| 1971 |
+
},
|
| 1972 |
+
{
|
| 1973 |
+
"@type":"Person",
|
| 1974 |
+
"email":"manojkumarsivaraj334@gmail.com",
|
| 1975 |
+
"givenName":"Manoj",
|
| 1976 |
+
"familyName": "Kumar"
|
| 1977 |
+
},
|
| 1978 |
+
{
|
| 1979 |
+
"@type":"Person",
|
| 1980 |
+
"email":"",
|
| 1981 |
+
"givenName":"Manorama",
|
| 1982 |
+
"familyName": "Kadwani"
|
| 1983 |
+
},
|
| 1984 |
+
{
|
| 1985 |
+
"@type":"Person",
|
| 1986 |
+
"email":"manu.sutela@gmail.com",
|
| 1987 |
+
"givenName":"Manu",
|
| 1988 |
+
"familyName": "Sutela"
|
| 1989 |
+
},
|
| 1990 |
+
{
|
| 1991 |
+
"@type":"Person",
|
| 1992 |
+
"email":"koculak.marcin@gmail.com",
|
| 1993 |
+
"givenName":"Marcin",
|
| 1994 |
+
"familyName": "Koculak"
|
| 1995 |
+
},
|
| 1996 |
+
{
|
| 1997 |
+
"@type":"Person",
|
| 1998 |
+
"email":"mah@optoceutics.com",
|
| 1999 |
+
"givenName":"Mark",
|
| 2000 |
+
"familyName": "Henney"
|
| 2001 |
+
},
|
| 2002 |
+
{
|
| 2003 |
+
"@type":"Person",
|
| 2004 |
+
"email":"Martinb.nmb@gmail.com",
|
| 2005 |
+
"givenName":"Martin",
|
| 2006 |
+
"familyName": "BaBer"
|
| 2007 |
+
},
|
| 2008 |
+
{
|
| 2009 |
+
"@type":"Person",
|
| 2010 |
+
"email":"",
|
| 2011 |
+
"givenName":"Martin",
|
| 2012 |
+
"familyName": "Oberg"
|
| 2013 |
+
},
|
| 2014 |
+
{
|
| 2015 |
+
"@type":"Person",
|
| 2016 |
+
"email":"",
|
| 2017 |
+
"givenName":"Martin",
|
| 2018 |
+
"familyName": "van Harmelen"
|
| 2019 |
+
},
|
| 2020 |
+
{
|
| 2021 |
+
"@type":"Person",
|
| 2022 |
+
"email":"mathieu.scheltienne@dandelion.science",
|
| 2023 |
+
"givenName":"Mathieu",
|
| 2024 |
+
"familyName": "Scheltienne"
|
| 2025 |
+
},
|
| 2026 |
+
{
|
| 2027 |
+
"@type":"Person",
|
| 2028 |
+
"email":"",
|
| 2029 |
+
"givenName":"Matt",
|
| 2030 |
+
"familyName": "Courtemanche"
|
| 2031 |
+
},
|
| 2032 |
+
{
|
| 2033 |
+
"@type":"Person",
|
| 2034 |
+
"email":"matt.tucker@nyu.edu",
|
| 2035 |
+
"givenName":"Matt",
|
| 2036 |
+
"familyName": "Tucker"
|
| 2037 |
+
},
|
| 2038 |
+
{
|
| 2039 |
+
"@type":"Person",
|
| 2040 |
+
"email":"matteo.visconti.gr@dartmouth.edu",
|
| 2041 |
+
"givenName":"Matteo",
|
| 2042 |
+
"familyName": "Visconti di Oleggio Castello"
|
| 2043 |
+
},
|
| 2044 |
+
{
|
| 2045 |
+
"@type":"Person",
|
| 2046 |
+
"email":"matthias.dold@gmx.net",
|
| 2047 |
+
"givenName":"Matthias",
|
| 2048 |
+
"familyName": "Dold"
|
| 2049 |
+
},
|
| 2050 |
+
{
|
| 2051 |
+
"@type":"Person",
|
| 2052 |
+
"email":"",
|
| 2053 |
+
"givenName":"Matti",
|
| 2054 |
+
"familyName": "Toivonen"
|
| 2055 |
+
},
|
| 2056 |
+
{
|
| 2057 |
+
"@type":"Person",
|
| 2058 |
+
"email":"",
|
| 2059 |
+
"givenName":"Maureen",
|
| 2060 |
+
"familyName": "Shader"
|
| 2061 |
+
},
|
| 2062 |
+
{
|
| 2063 |
+
"@type":"Person",
|
| 2064 |
+
"email":"",
|
| 2065 |
+
"givenName":"Mauricio",
|
| 2066 |
+
"familyName": "Cespedes"
|
| 2067 |
+
},
|
| 2068 |
+
{
|
| 2069 |
+
"@type":"Person",
|
| 2070 |
+
"email":"krause@mpib-berlin.mpg.de",
|
| 2071 |
+
"givenName":"Michael",
|
| 2072 |
+
"familyName": "Krause"
|
| 2073 |
+
},
|
| 2074 |
+
{
|
| 2075 |
+
"@type":"Person",
|
| 2076 |
+
"email":"kontakt@milanrybar.cz",
|
| 2077 |
+
"givenName":"Milan",
|
| 2078 |
+
"familyName": "Rybář"
|
| 2079 |
+
},
|
| 2080 |
+
{
|
| 2081 |
+
"@type":"Person",
|
| 2082 |
+
"email":"",
|
| 2083 |
+
"givenName":"Mingjian",
|
| 2084 |
+
"familyName": "He"
|
| 2085 |
+
},
|
| 2086 |
+
{
|
| 2087 |
+
"@type":"Person",
|
| 2088 |
+
"email":"",
|
| 2089 |
+
"givenName":"Mohammad",
|
| 2090 |
+
"familyName": "Daneshzand"
|
| 2091 |
+
},
|
| 2092 |
+
{
|
| 2093 |
+
"@type":"Person",
|
| 2094 |
+
"email":"23111220065@m.fudan.edu.cn",
|
| 2095 |
+
"givenName":"",
|
| 2096 |
+
"familyName": "Mojackhak"
|
| 2097 |
+
},
|
| 2098 |
+
{
|
| 2099 |
+
"@type":"Person",
|
| 2100 |
+
"email":"celicolimmo@free.fr",
|
| 2101 |
+
"givenName":"Nicolas",
|
| 2102 |
+
"familyName": "Fourcaud-Trocmé"
|
| 2103 |
+
},
|
| 2104 |
+
{
|
| 2105 |
+
"@type":"Person",
|
| 2106 |
+
"email":"nicolas.gensollen@gmail.com",
|
| 2107 |
+
"givenName":"Nicolas",
|
| 2108 |
+
"familyName": "Gensollen"
|
| 2109 |
+
},
|
| 2110 |
+
{
|
| 2111 |
+
"@type":"Person",
|
| 2112 |
+
"email":"nh.proulx@gmail.com",
|
| 2113 |
+
"givenName":"Nicole",
|
| 2114 |
+
"familyName": "Proulx"
|
| 2115 |
+
},
|
| 2116 |
+
{
|
| 2117 |
+
"@type":"Person",
|
| 2118 |
+
"email":"nfocke@uni-goettingen.de",
|
| 2119 |
+
"givenName":"Niels",
|
| 2120 |
+
"familyName": "Focke"
|
| 2121 |
+
},
|
| 2122 |
+
{
|
| 2123 |
+
"@type":"Person",
|
| 2124 |
+
"email":"nikos.ch01@gmail.com",
|
| 2125 |
+
"givenName":"Nikolas",
|
| 2126 |
+
"familyName": "Chalas"
|
| 2127 |
+
},
|
| 2128 |
+
{
|
| 2129 |
+
"@type":"Person",
|
| 2130 |
+
"email":"",
|
| 2131 |
+
"givenName":"Noah",
|
| 2132 |
+
"familyName": "Markowitz"
|
| 2133 |
+
},
|
| 2134 |
+
{
|
| 2135 |
+
"@type":"Person",
|
| 2136 |
+
"email":"omer.shubi@gmail.com",
|
| 2137 |
+
"givenName":"Omer",
|
| 2138 |
+
"familyName": "Shubi"
|
| 2139 |
+
},
|
| 2140 |
+
{
|
| 2141 |
+
"@type":"Person",
|
| 2142 |
+
"email":"pablomainar.pm@gmail.com",
|
| 2143 |
+
"givenName":"Pablo",
|
| 2144 |
+
"familyName": "Mainar"
|
| 2145 |
+
},
|
| 2146 |
+
{
|
| 2147 |
+
"@type":"Person",
|
| 2148 |
+
"email":"tottochan@gmail.com",
|
| 2149 |
+
"givenName":"Padma",
|
| 2150 |
+
"familyName": "Sundaram"
|
| 2151 |
+
},
|
| 2152 |
+
{
|
| 2153 |
+
"@type":"Person",
|
| 2154 |
+
"email":"",
|
| 2155 |
+
"givenName":"Paul",
|
| 2156 |
+
"familyName": "Anders"
|
| 2157 |
+
},
|
| 2158 |
+
{
|
| 2159 |
+
"@type":"Person",
|
| 2160 |
+
"email":"pedrobnsilva@gmail.com",
|
| 2161 |
+
"givenName":"Pedro",
|
| 2162 |
+
"familyName": "Silva"
|
| 2163 |
+
},
|
| 2164 |
+
{
|
| 2165 |
+
"@type":"Person",
|
| 2166 |
+
"email":"",
|
| 2167 |
+
"givenName":"Pierre",
|
| 2168 |
+
"familyName": "Guetschel"
|
| 2169 |
+
},
|
| 2170 |
+
{
|
| 2171 |
+
"@type":"Person",
|
| 2172 |
+
"email":"glia@dtu.dk",
|
| 2173 |
+
"givenName":"Quanliang",
|
| 2174 |
+
"familyName": "Li"
|
| 2175 |
+
},
|
| 2176 |
+
{
|
| 2177 |
+
"@type":"Person",
|
| 2178 |
+
"email":"q.barthelemy@gmail.com",
|
| 2179 |
+
"givenName":"Quentin",
|
| 2180 |
+
"familyName": "Barthélemy"
|
| 2181 |
+
},
|
| 2182 |
+
{
|
| 2183 |
+
"@type":"Person",
|
| 2184 |
+
"email":"rahuln@cs.washington.edu",
|
| 2185 |
+
"givenName":"Rahul",
|
| 2186 |
+
"familyName": "Nadkarni"
|
| 2187 |
+
},
|
| 2188 |
+
{
|
| 2189 |
+
"@type":"Person",
|
| 2190 |
+
"email":"rmrgatti@gmail.com",
|
| 2191 |
+
"givenName":"Ramiro",
|
| 2192 |
+
"familyName": "Gatti"
|
| 2193 |
+
},
|
| 2194 |
+
{
|
| 2195 |
+
"@type":"Person",
|
| 2196 |
+
"email":"moncho_apa@hotmail.com",
|
| 2197 |
+
"givenName":"Ramonapariciog",
|
| 2198 |
+
"familyName": "Apariciogarcia"
|
| 2199 |
+
},
|
| 2200 |
+
{
|
| 2201 |
+
"@type":"Person",
|
| 2202 |
+
"email":"raagaard97@gmail.com",
|
| 2203 |
+
"givenName":"Rasmus",
|
| 2204 |
+
"familyName": "Aagaard"
|
| 2205 |
+
},
|
| 2206 |
+
{
|
| 2207 |
+
"@type":"Person",
|
| 2208 |
+
"email":"reza@ddpo.ir",
|
| 2209 |
+
"givenName":"Reza",
|
| 2210 |
+
"familyName": "Nasri"
|
| 2211 |
+
},
|
| 2212 |
+
{
|
| 2213 |
+
"@type":"Person",
|
| 2214 |
+
"email":"richard.koehler@outlook.de",
|
| 2215 |
+
"givenName":"Richard",
|
| 2216 |
+
"familyName": "Koehler"
|
| 2217 |
+
},
|
| 2218 |
+
{
|
| 2219 |
+
"@type":"Person",
|
| 2220 |
+
"email":"rie.acad@gmail.com",
|
| 2221 |
+
"givenName":"Riessarius",
|
| 2222 |
+
"familyName": "Stargardsky"
|
| 2223 |
+
},
|
| 2224 |
+
{
|
| 2225 |
+
"@type":"Person",
|
| 2226 |
+
"email":"r.oostenveld@gmail.com",
|
| 2227 |
+
"givenName":"Robert",
|
| 2228 |
+
"familyName": "Oostenveld"
|
| 2229 |
+
},
|
| 2230 |
+
{
|
| 2231 |
+
"@type":"Person",
|
| 2232 |
+
"email":"robbyseymour@gmail.com",
|
| 2233 |
+
"givenName":"Robert",
|
| 2234 |
+
"familyName": "Seymour"
|
| 2235 |
+
},
|
| 2236 |
+
{
|
| 2237 |
+
"@type":"Person",
|
| 2238 |
+
"email":"robintibor@gmail.com",
|
| 2239 |
+
"givenName":"Robin Tibor",
|
| 2240 |
+
"familyName": "Schirrmeister"
|
| 2241 |
+
},
|
| 2242 |
+
{
|
| 2243 |
+
"@type":"Person",
|
| 2244 |
+
"email":"131315c@gmail.com",
|
| 2245 |
+
"givenName":"Rongfei",
|
| 2246 |
+
"familyName": "Jin"
|
| 2247 |
+
},
|
| 2248 |
+
{
|
| 2249 |
+
"@type":"Person",
|
| 2250 |
+
"email":"",
|
| 2251 |
+
"givenName":"Roy Eric",
|
| 2252 |
+
"familyName": "Wieske"
|
| 2253 |
+
},
|
| 2254 |
+
{
|
| 2255 |
+
"@type":"Person",
|
| 2256 |
+
"email":"ryan.law@mpi.nl",
|
| 2257 |
+
"givenName":"Ryan",
|
| 2258 |
+
"familyName": "Law"
|
| 2259 |
+
},
|
| 2260 |
+
{
|
| 2261 |
+
"@type":"Person",
|
| 2262 |
+
"email":"sagung.pai@gmail.com",
|
| 2263 |
+
"givenName":"Sagun",
|
| 2264 |
+
"familyName": "Pai"
|
| 2265 |
+
},
|
| 2266 |
+
{
|
| 2267 |
+
"@type":"Person",
|
| 2268 |
+
"email":"u1265119@unimail.hud.ac.uk",
|
| 2269 |
+
"givenName":"Sam",
|
| 2270 |
+
"familyName": "Perry"
|
| 2271 |
+
},
|
| 2272 |
+
{
|
| 2273 |
+
"@type":"Person",
|
| 2274 |
+
"email":"",
|
| 2275 |
+
"givenName":"Samuel",
|
| 2276 |
+
"familyName": "Louviot"
|
| 2277 |
+
},
|
| 2278 |
+
{
|
| 2279 |
+
"@type":"Person",
|
| 2280 |
+
"email":"santiaguzz@gmail.com",
|
| 2281 |
+
"givenName":"Santi",
|
| 2282 |
+
"familyName": "Martínez"
|
| 2283 |
+
},
|
| 2284 |
+
{
|
| 2285 |
+
"@type":"Person",
|
| 2286 |
+
"email":"",
|
| 2287 |
+
"givenName":"Sawradip",
|
| 2288 |
+
"familyName": "Saha"
|
| 2289 |
+
},
|
| 2290 |
+
{
|
| 2291 |
+
"@type":"Person",
|
| 2292 |
+
"email":"s.mathot@cogsci.nl",
|
| 2293 |
+
"givenName":"Sebastiaan",
|
| 2294 |
+
"familyName": "Mathot"
|
| 2295 |
+
},
|
| 2296 |
+
{
|
| 2297 |
+
"@type":"Person",
|
| 2298 |
+
"email":"",
|
| 2299 |
+
"givenName":"Sebastian",
|
| 2300 |
+
"familyName": "Jentschke"
|
| 2301 |
+
},
|
| 2302 |
+
{
|
| 2303 |
+
"@type":"Person",
|
| 2304 |
+
"email":"",
|
| 2305 |
+
"givenName":"Sebastian",
|
| 2306 |
+
"familyName": "Major"
|
| 2307 |
+
},
|
| 2308 |
+
{
|
| 2309 |
+
"@type":"Person",
|
| 2310 |
+
"email":"sfox@riseup.net",
|
| 2311 |
+
"givenName":"Sebastien",
|
| 2312 |
+
"familyName": "Treguer"
|
| 2313 |
+
},
|
| 2314 |
+
{
|
| 2315 |
+
"@type":"Person",
|
| 2316 |
+
"email":"sebastian.castano@blbt.uni-freiburg.de",
|
| 2317 |
+
"givenName":"Sebastián",
|
| 2318 |
+
"familyName": "Castaño"
|
| 2319 |
+
},
|
| 2320 |
+
{
|
| 2321 |
+
"@type":"Person",
|
| 2322 |
+
"email":"",
|
| 2323 |
+
"givenName":"Senwen",
|
| 2324 |
+
"familyName": "Deng"
|
| 2325 |
+
},
|
| 2326 |
+
{
|
| 2327 |
+
"@type":"Person",
|
| 2328 |
+
"email":"s.antopolsky@gmail.com",
|
| 2329 |
+
"givenName":"Sergey",
|
| 2330 |
+
"familyName": "Antopolskiy"
|
| 2331 |
+
},
|
| 2332 |
+
{
|
| 2333 |
+
"@type":"Person",
|
| 2334 |
+
"email":"shirazi@ieee.org",
|
| 2335 |
+
"givenName":"Seyed (Yahya)",
|
| 2336 |
+
"familyName": "Shirazi"
|
| 2337 |
+
},
|
| 2338 |
+
{
|
| 2339 |
+
"@type":"Person",
|
| 2340 |
+
"email":"kesharishresth5@gmail.com",
|
| 2341 |
+
"givenName":"Shresth",
|
| 2342 |
+
"familyName": "Keshari"
|
| 2343 |
+
},
|
| 2344 |
+
{
|
| 2345 |
+
"@type":"Person",
|
| 2346 |
+
"email":"baral.shristi@gmail.com",
|
| 2347 |
+
"givenName":"Shristi",
|
| 2348 |
+
"familyName": "Baral"
|
| 2349 |
+
},
|
| 2350 |
+
{
|
| 2351 |
+
"@type":"Person",
|
| 2352 |
+
"email":"baralshristi@gmail.com",
|
| 2353 |
+
"givenName":"Shristi",
|
| 2354 |
+
"familyName": "Baral"
|
| 2355 |
+
},
|
| 2356 |
+
{
|
| 2357 |
+
"@type":"Person",
|
| 2358 |
+
"email":"",
|
| 2359 |
+
"givenName":"Simeon",
|
| 2360 |
+
"familyName": "Wong"
|
| 2361 |
+
},
|
| 2362 |
+
{
|
| 2363 |
+
"@type":"Person",
|
| 2364 |
+
"email":"",
|
| 2365 |
+
"givenName":"Simeon",
|
| 2366 |
+
"familyName": "Wong"
|
| 2367 |
+
},
|
| 2368 |
+
{
|
| 2369 |
+
"@type":"Person",
|
| 2370 |
+
"email":"",
|
| 2371 |
+
"givenName":"Simon M",
|
| 2372 |
+
"familyName": "Hofmann"
|
| 2373 |
+
},
|
| 2374 |
+
{
|
| 2375 |
+
"@type":"Person",
|
| 2376 |
+
"email":"",
|
| 2377 |
+
"givenName":"Simon-Shlomo",
|
| 2378 |
+
"familyName": "Poil"
|
| 2379 |
+
},
|
| 2380 |
+
{
|
| 2381 |
+
"@type":"Person",
|
| 2382 |
+
"email":"sondre.foslien@gmail.com",
|
| 2383 |
+
"givenName":"Sondre",
|
| 2384 |
+
"familyName": "Foslien"
|
| 2385 |
+
},
|
| 2386 |
+
{
|
| 2387 |
+
"@type":"Person",
|
| 2388 |
+
"email":"",
|
| 2389 |
+
"givenName":"Sourav",
|
| 2390 |
+
"familyName": "Singh"
|
| 2391 |
+
},
|
| 2392 |
+
{
|
| 2393 |
+
"@type":"Person",
|
| 2394 |
+
"email":"stan.chambon@gmail.com",
|
| 2395 |
+
"givenName":"Stanislas",
|
| 2396 |
+
"familyName": "Chambon"
|
| 2397 |
+
},
|
| 2398 |
+
{
|
| 2399 |
+
"@type":"Person",
|
| 2400 |
+
"email":"",
|
| 2401 |
+
"givenName":"Steinn Hauser",
|
| 2402 |
+
"familyName": "Magnússon"
|
| 2403 |
+
},
|
| 2404 |
+
{
|
| 2405 |
+
"@type":"Person",
|
| 2406 |
+
"email":"bethard@email.arizona.edu",
|
| 2407 |
+
"givenName":"Steven",
|
| 2408 |
+
"familyName": "Bethard"
|
| 2409 |
+
},
|
| 2410 |
+
{
|
| 2411 |
+
"@type":"Person",
|
| 2412 |
+
"email":"s.m.gutstein@gmail.com",
|
| 2413 |
+
"givenName":"Steven M",
|
| 2414 |
+
"familyName": "Gutstein"
|
| 2415 |
+
},
|
| 2416 |
+
{
|
| 2417 |
+
"@type":"Person",
|
| 2418 |
+
"email":"",
|
| 2419 |
+
"givenName":"Svea Marie",
|
| 2420 |
+
"familyName": "Meyer"
|
| 2421 |
+
},
|
| 2422 |
+
{
|
| 2423 |
+
"@type":"Person",
|
| 2424 |
+
"email":"twang5@swarthmore.edu",
|
| 2425 |
+
"givenName":"T",
|
| 2426 |
+
"familyName": "Wang"
|
| 2427 |
+
},
|
| 2428 |
+
{
|
| 2429 |
+
"@type":"Person",
|
| 2430 |
+
"email":"tharupahanjayawardana@gmail.com",
|
| 2431 |
+
"givenName":"Tharupahan",
|
| 2432 |
+
"familyName": "Jayawardana"
|
| 2433 |
+
},
|
| 2434 |
+
{
|
| 2435 |
+
"@type":"Person",
|
| 2436 |
+
"email":"thomas.moreau.2010@gmail.com",
|
| 2437 |
+
"givenName":"Thomas",
|
| 2438 |
+
"familyName": "Moreau"
|
| 2439 |
+
},
|
| 2440 |
+
{
|
| 2441 |
+
"@type":"Person",
|
| 2442 |
+
"email":"radman.thomas@gmail.com",
|
| 2443 |
+
"givenName":"Thomas",
|
| 2444 |
+
"familyName": "Radman"
|
| 2445 |
+
},
|
| 2446 |
+
{
|
| 2447 |
+
"@type":"Person",
|
| 2448 |
+
"email":"tim.gates@iress.com",
|
| 2449 |
+
"givenName":"Timothy",
|
| 2450 |
+
"familyName": "Gates"
|
| 2451 |
+
},
|
| 2452 |
+
{
|
| 2453 |
+
"@type":"Person",
|
| 2454 |
+
"email":"TASTONE@mgh.harvard.edu",
|
| 2455 |
+
"givenName":"Tom",
|
| 2456 |
+
"familyName": "Stone"
|
| 2457 |
+
},
|
| 2458 |
+
{
|
| 2459 |
+
"@type":"Person",
|
| 2460 |
+
"email":"",
|
| 2461 |
+
"givenName":"Tommy",
|
| 2462 |
+
"familyName": "Clausner"
|
| 2463 |
+
},
|
| 2464 |
+
{
|
| 2465 |
+
"@type":"Person",
|
| 2466 |
+
"email":"toomaserikanijarv@gmail.com",
|
| 2467 |
+
"givenName":"Toomas Erik",
|
| 2468 |
+
"familyName": "Anijärv"
|
| 2469 |
+
},
|
| 2470 |
+
{
|
| 2471 |
+
"@type":"Person",
|
| 2472 |
+
"email":"",
|
| 2473 |
+
"givenName":"Velu Prabhakar",
|
| 2474 |
+
"familyName": "Kumaravel"
|
| 2475 |
+
},
|
| 2476 |
+
{
|
| 2477 |
+
"@type":"Person",
|
| 2478 |
+
"email":"weixu@mail.bnu.edu.cn",
|
| 2479 |
+
"givenName":"Wei",
|
| 2480 |
+
"familyName": "Xu"
|
| 2481 |
+
},
|
| 2482 |
+
{
|
| 2483 |
+
"@type":"Person",
|
| 2484 |
+
"email":"williamfrancisturner@gmail.com",
|
| 2485 |
+
"givenName":"Will",
|
| 2486 |
+
"familyName": "Turner"
|
| 2487 |
+
},
|
| 2488 |
+
{
|
| 2489 |
+
"@type":"Person",
|
| 2490 |
+
"email":"xabier@zuazo.org",
|
| 2491 |
+
"givenName":"Xabier de",
|
| 2492 |
+
"familyName": "Zuazo"
|
| 2493 |
+
},
|
| 2494 |
+
{
|
| 2495 |
+
"@type":"Person",
|
| 2496 |
+
"email":"xia@xiaokai.me",
|
| 2497 |
+
"givenName":"Xiaokai",
|
| 2498 |
+
"familyName": "Xia"
|
| 2499 |
+
},
|
| 2500 |
+
{
|
| 2501 |
+
"@type":"Person",
|
| 2502 |
+
"email":"frostime@foxmail.com",
|
| 2503 |
+
"givenName":"Yiping",
|
| 2504 |
+
"familyName": "Zuo"
|
| 2505 |
+
},
|
| 2506 |
+
{
|
| 2507 |
+
"@type":"Person",
|
| 2508 |
+
"email":"",
|
| 2509 |
+
"givenName":"Yixiao",
|
| 2510 |
+
"familyName": "Shen"
|
| 2511 |
+
},
|
| 2512 |
+
{
|
| 2513 |
+
"@type":"Person",
|
| 2514 |
+
"email":"",
|
| 2515 |
+
"givenName":"Young",
|
| 2516 |
+
"familyName": "Truong"
|
| 2517 |
+
},
|
| 2518 |
+
{
|
| 2519 |
+
"@type":"Person",
|
| 2520 |
+
"email":"850734033@qq.com",
|
| 2521 |
+
"givenName":"Zhi",
|
| 2522 |
+
"familyName": "Zhang"
|
| 2523 |
+
},
|
| 2524 |
+
{
|
| 2525 |
+
"@type":"Person",
|
| 2526 |
+
"email":"ziyizeng@link.cuhk.edu.cn",
|
| 2527 |
+
"givenName":"Ziyi",
|
| 2528 |
+
"familyName": "ZENG"
|
| 2529 |
+
},
|
| 2530 |
+
{
|
| 2531 |
+
"@type":"Person",
|
| 2532 |
+
"email":"btk.codedev@gmail.com",
|
| 2533 |
+
"givenName":"",
|
| 2534 |
+
"familyName": "btkcodedev"
|
| 2535 |
+
},
|
| 2536 |
+
{
|
| 2537 |
+
"@type":"Person",
|
| 2538 |
+
"email":"",
|
| 2539 |
+
"givenName":"",
|
| 2540 |
+
"familyName": "buildqa"
|
| 2541 |
+
},
|
| 2542 |
+
{
|
| 2543 |
+
"@type":"Person",
|
| 2544 |
+
"email":"",
|
| 2545 |
+
"givenName":"",
|
| 2546 |
+
"familyName": "luzpaz"
|
| 2547 |
+
},
|
| 2548 |
+
{
|
| 2549 |
+
"@type":"Person",
|
| 2550 |
+
"email":"",
|
| 2551 |
+
"givenName":"",
|
| 2552 |
+
"familyName": "user27182"
|
| 2553 |
+
}
|
| 2554 |
+
]
|
| 2555 |
+
}
|
mne-python/source/doc/Makefile
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Makefile for Sphinx documentation
|
| 2 |
+
#
|
| 3 |
+
|
| 4 |
+
# You can set these variables from the command line.
|
| 5 |
+
SPHINXOPTS = -nWT --keep-going
|
| 6 |
+
SPHINXBUILD = sphinx-build
|
| 7 |
+
MPROF = SG_STAMP_STARTS=true mprof run -E --python sphinx
|
| 8 |
+
|
| 9 |
+
# Internal variables.
|
| 10 |
+
ALLSPHINXOPTS = -d _build/doctrees $(SPHINXOPTS) .
|
| 11 |
+
|
| 12 |
+
.PHONY: help clean html html-noplot html-pattern linkcheck linkcheck-grep doctest
|
| 13 |
+
|
| 14 |
+
# make with no arguments will build the first target by default, i.e., build standalone HTML files
|
| 15 |
+
first_target: html-noplot
|
| 16 |
+
|
| 17 |
+
help:
|
| 18 |
+
@echo "Please use \`make <target>' where <target> is one of"
|
| 19 |
+
@echo " html to make standalone HTML files"
|
| 20 |
+
@echo " html-memory to make standalone HTML files while monitoring memory usage"
|
| 21 |
+
@echo " html-pattern to make standalone HTML files for a specific filename pattern"
|
| 22 |
+
@echo " html-front to make standalone HTML files with only the frontpage examples"
|
| 23 |
+
@echo " html-noplot to make standalone HTML files without plotting"
|
| 24 |
+
@echo " clean to clean HTML files"
|
| 25 |
+
@echo " linkcheck to check all external links for integrity"
|
| 26 |
+
@echo " linkcheck-grep to grep the linkcheck result"
|
| 27 |
+
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
| 28 |
+
@echo " view to view the built HTML"
|
| 29 |
+
|
| 30 |
+
clean:
|
| 31 |
+
-rm -rf _build sg_execution_times.rst auto_examples auto_tutorials generated *.stc *.fif *.nii.gz
|
| 32 |
+
|
| 33 |
+
html:
|
| 34 |
+
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
|
| 35 |
+
@echo
|
| 36 |
+
@echo "Build finished. The HTML pages are in _build/html."
|
| 37 |
+
|
| 38 |
+
html-memory:
|
| 39 |
+
$(MPROF) -b html $(ALLSPHINXOPTS) _build/html
|
| 40 |
+
@echo
|
| 41 |
+
@echo "Build finished. The HTML pages are in _build/html."
|
| 42 |
+
|
| 43 |
+
html-pattern:
|
| 44 |
+
$(SPHINXBUILD) -D sphinx_gallery_conf.filename_pattern=$(PATTERN) -D sphinx_gallery_conf.run_stale_examples=True -b html $(ALLSPHINXOPTS) _build/html
|
| 45 |
+
@echo
|
| 46 |
+
@echo "Build finished. The HTML pages are in _build/html"
|
| 47 |
+
|
| 48 |
+
html-pattern-memory:
|
| 49 |
+
$(MPROF) -D sphinx_gallery_conf.filename_pattern=$(PATTERN) -D sphinx_gallery_conf.run_stale_examples=True -b html $(ALLSPHINXOPTS) _build/html
|
| 50 |
+
@echo
|
| 51 |
+
@echo "Build finished. The HTML pages are in _build/html"
|
| 52 |
+
|
| 53 |
+
html-noplot:
|
| 54 |
+
$(SPHINXBUILD) -D plot_gallery=0 -b html $(ALLSPHINXOPTS) _build/html
|
| 55 |
+
@echo
|
| 56 |
+
@echo "Build finished. The HTML pages are in _build/html."
|
| 57 |
+
|
| 58 |
+
html-front:
|
| 59 |
+
@PATTERN="\(30_mne_dspm_loreta.py\|50_decoding.py\|30_strf.py\|20_cluster_1samp_spatiotemporal.py\|20_visualize_evoked.py\)" make html-pattern
|
| 60 |
+
|
| 61 |
+
# Aliases for old methods
|
| 62 |
+
html_dev-pattern-memory: html-pattern-memory
|
| 63 |
+
html_dev-pattern: html-pattern
|
| 64 |
+
html_dev-noplot: html-noplot
|
| 65 |
+
html_dev-front: html-front
|
| 66 |
+
|
| 67 |
+
linkcheck:
|
| 68 |
+
@$(SPHINXBUILD) -b linkcheck -D nitpicky=0 -q -D plot_gallery=0 -D exclude_patterns="cited.rst,whats_new.rst,configure_git.rst,_includes,changes/dev" -d _build/doctrees . _build/linkcheck
|
| 69 |
+
|
| 70 |
+
doctest:
|
| 71 |
+
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
|
| 72 |
+
@echo "Testing of doctests in the sources finished, look at the " \
|
| 73 |
+
"results in _build/doctest/output.txt."
|
| 74 |
+
|
| 75 |
+
view:
|
| 76 |
+
@python -c "import webbrowser; webbrowser.open_new_tab('file://$(PWD)/_build/html/sg_execution_times.html')"
|
| 77 |
+
|
| 78 |
+
show: view
|
| 79 |
+
|
| 80 |
+
serve:
|
| 81 |
+
python -m http.server -d _build/html
|
mne-python/source/doc/_includes/bem_model.rst
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Creating the BEM meshes
|
| 4 |
+
=======================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 7 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 8 |
+
to :ref:`bem-model` to link to that section of the implementation.rst page.
|
| 9 |
+
The next line is a target for :start-after: so we can omit the title from
|
| 10 |
+
the include:
|
| 11 |
+
bem-begin-content
|
| 12 |
+
|
| 13 |
+
.. _bem_watershed_algorithm:
|
| 14 |
+
|
| 15 |
+
Using the watershed algorithm
|
| 16 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 17 |
+
|
| 18 |
+
The watershed algorithm [Segonne *et al.*,
|
| 19 |
+
2004] is part of the FreeSurfer software.
|
| 20 |
+
The name of the program is mri_watershed_.
|
| 21 |
+
Its use in the MNE environment is facilitated by the script
|
| 22 |
+
:ref:`mne watershed_bem`.
|
| 23 |
+
|
| 24 |
+
After ``mne watershed_bem`` has completed, the following files appear in the
|
| 25 |
+
subject's :file:`bem/watershed` directory:
|
| 26 |
+
|
| 27 |
+
- :file:`{<subject>}_brain_surface` contains the brain surface triangulation.
|
| 28 |
+
|
| 29 |
+
- :file:`{<subject>}_inner_skull_surface` contains the inner skull
|
| 30 |
+
triangulation.
|
| 31 |
+
|
| 32 |
+
- :file:`{<subject>}_outer_skull_surface` contains the outer skull
|
| 33 |
+
triangulation.
|
| 34 |
+
|
| 35 |
+
- :file:`{<subject>}_outer_skin_surface` contains the scalp triangulation.
|
| 36 |
+
|
| 37 |
+
All of these surfaces are in the FreeSurfer format. In addition, there will be
|
| 38 |
+
a file called :file:`bem/watershed/ws.mgz` which contains the brain MRI
|
| 39 |
+
volume. Furthermore, ``mne watershed_bem`` script converts the scalp surface to
|
| 40 |
+
fif format and saves the result to :file:`bem/{<subject>}-head.fif`.
|
| 41 |
+
|
| 42 |
+
.. _bem_flash_algorithm:
|
| 43 |
+
|
| 44 |
+
Using FLASH images
|
| 45 |
+
~~~~~~~~~~~~~~~~~~
|
| 46 |
+
|
| 47 |
+
This method depends on the availablily of MRI data acquired with a multi-echo
|
| 48 |
+
FLASH sequence at two flip angles (5 and 30 degrees). These data can be
|
| 49 |
+
acquired separately from the MPRAGE data employed in FreeSurfer cortical
|
| 50 |
+
reconstructions but it is strongly recommended that they are collected at the
|
| 51 |
+
same time with the MPRAGEs or at least with the same scanner. For easy
|
| 52 |
+
co-registration, the images should have FOV, matrix, slice thickness, gap, and
|
| 53 |
+
slice orientation as the MPRAGE data. For information on suitable pulse
|
| 54 |
+
sequences, see :footcite:t:`FischlEtAl2004`.
|
| 55 |
+
|
| 56 |
+
Creation of the BEM meshes using this method involves the following steps:
|
| 57 |
+
|
| 58 |
+
- Creating a synthetic 5-degree flip angle FLASH volume, register
|
| 59 |
+
it with the MPRAGE data, and run the segmentation and meshing program.
|
| 60 |
+
This step is accomplished by running the script :ref:`mne flash_bem`.
|
| 61 |
+
|
| 62 |
+
- Inspecting the meshes with tkmedit, see :ref:`inspecting-meshes`.
|
| 63 |
+
|
| 64 |
+
.. note:: Different methods can be employed for the creation of the
|
| 65 |
+
individual surfaces. For example, it may turn out that the
|
| 66 |
+
watershed algorithm produces are better quality skin surface than
|
| 67 |
+
the segmentation approach based on the FLASH images. If this is
|
| 68 |
+
the case, ``outer_skin.surf`` can set to point to the corresponding
|
| 69 |
+
watershed output file while the other surfaces can be picked from
|
| 70 |
+
the FLASH segmentation data.
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
Organizing MRI data into directories
|
| 74 |
+
------------------------------------
|
| 75 |
+
|
| 76 |
+
Since all images comprising the multi-echo FLASH data are contained in a single
|
| 77 |
+
series, it is necessary to organize the images according to the echoes before
|
| 78 |
+
proceeding to the BEM surface reconstruction. This can be accomplished by using
|
| 79 |
+
`dcm2niix <https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage>`__
|
| 80 |
+
or the MNE-C tool ``mne_organize_dicom`` if necessary, then use
|
| 81 |
+
:func:`mne.bem.convert_flash_mris`.
|
| 82 |
+
|
| 83 |
+
Creating the surface tessellations
|
| 84 |
+
----------------------------------
|
| 85 |
+
|
| 86 |
+
The BEM surface segmentation and tessellation is automated with the script
|
| 87 |
+
:ref:`mne flash_bem`. It assumes that a FreeSurfer reconstruction for this
|
| 88 |
+
subject is already in place.
|
| 89 |
+
|
| 90 |
+
Before running :ref:`mne flash_bem` do the following:
|
| 91 |
+
|
| 92 |
+
- Create symbolic links from the directories containing the 5-degree and
|
| 93 |
+
30-degree flip angle FLASH series to ``flash05`` and ``flash30``,
|
| 94 |
+
respectively:
|
| 95 |
+
|
| 96 |
+
- :samp:`ln -s {<FLASH 5 series dir>} flash05`
|
| 97 |
+
|
| 98 |
+
- :samp:`ln -s {<FLASH 30 series dir>} flash30`
|
| 99 |
+
|
| 100 |
+
- Some partition formats (e.g. FAT32) do not support symbolic links. In this
|
| 101 |
+
case, copy the file to the appropriate series:
|
| 102 |
+
|
| 103 |
+
- :samp:`cp {<FLASH 5 series dir>} flash05`
|
| 104 |
+
|
| 105 |
+
- :samp:`cp {<FLASH 30 series dir>} flash30`
|
| 106 |
+
|
| 107 |
+
- Set the ``SUBJECTS_DIR`` and ``SUBJECT`` environment variables or pass
|
| 108 |
+
the ``--subjects-dir`` and ``--subject`` options to ``mne flash_bem``
|
| 109 |
+
|
| 110 |
+
.. note:: If ``mne flash_bem`` is run with the ``--noflash30`` option, the
|
| 111 |
+
:file:`flash30` directory is not needed, *i.e.*, only the 5-degree flip
|
| 112 |
+
angle flash data are employed.
|
| 113 |
+
|
| 114 |
+
It may take a while for ``mne flash_bem`` to complete. It uses the FreeSurfer
|
| 115 |
+
directory structure under ``$SUBJECTS_DIR/$SUBJECT``. The script encapsulates
|
| 116 |
+
the following processing steps:
|
| 117 |
+
|
| 118 |
+
- It creates an mgz file corresponding to each of the eight echoes in each of
|
| 119 |
+
the FLASH directories in ``mri/flash``. The files will be called
|
| 120 |
+
:file:`mef {<flip-angle>}_{<echo-number>}.mgz`.
|
| 121 |
+
|
| 122 |
+
- If the ``unwarp=True`` option is specified, run grad_unwarp and produce
|
| 123 |
+
files :file:`mef {<flip-angle>}_{<echo-number>}u.mgz`. These files will be
|
| 124 |
+
then used in the following steps.
|
| 125 |
+
|
| 126 |
+
- It creates parameter maps in :file:`mri/flash/parameter_maps` using
|
| 127 |
+
``mri_ms_fitparms``.
|
| 128 |
+
|
| 129 |
+
- It creates a synthetic 5-degree flip angle volume in
|
| 130 |
+
:file:`mri/flash/parameter_maps/flash5.mgz` using ``mri_synthesize``.
|
| 131 |
+
|
| 132 |
+
- Using ``fsl_rigid_register``, it creates a registered 5-degree flip angle
|
| 133 |
+
volume ``mri/flash/parameter_maps/flash5_reg.mgz`` by registering
|
| 134 |
+
:file:`mri/flash/parameter_maps/flash5.mgz` to the *T1* volume under ``mri``.
|
| 135 |
+
|
| 136 |
+
- Using ``mri_convert``, it converts the flash5_reg volume to COR format under
|
| 137 |
+
``mri/flash5``. If necessary, the T1 and brain volumes are also converted
|
| 138 |
+
into the COR format.
|
| 139 |
+
|
| 140 |
+
- It runs ``mri_make_bem_surfaces`` to create the BEM surface tessellations.
|
| 141 |
+
|
| 142 |
+
- It creates the directory :file:`bem/flash`, moves the tri-format
|
| 143 |
+
tringulations there and creates the corresponding FreeSurfer surface files
|
| 144 |
+
in the same directory.
|
| 145 |
+
|
| 146 |
+
- The COR format volumes created by ``mne flash_bem`` are removed.
|
| 147 |
+
|
| 148 |
+
If the ``--noflash30`` option is specified to ``mne flash_bem``,
|
| 149 |
+
steps 3 and 4 in the above are replaced by averaging over the different
|
| 150 |
+
echo times in 5-degree flip angle data.
|
| 151 |
+
|
| 152 |
+
.. _inspecting-meshes:
|
| 153 |
+
|
| 154 |
+
Inspecting the meshes
|
| 155 |
+
---------------------
|
| 156 |
+
|
| 157 |
+
It is advisable to check the validity of the BEM meshes before
|
| 158 |
+
using them. This can be done with:
|
| 159 |
+
|
| 160 |
+
- the ``--view`` option of :ref:`mne flash_bem`
|
| 161 |
+
- calling :func:`mne.viz.plot_bem` directly
|
| 162 |
+
- Using FreeSurfer tools ``tkmedit`` or ``freeview``
|
mne-python/source/doc/_includes/channel_interpolation.rst
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Bad channel repair via interpolation
|
| 4 |
+
====================================
|
| 5 |
+
|
| 6 |
+
Spherical spline interpolation (EEG)
|
| 7 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 8 |
+
|
| 9 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 10 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 11 |
+
to :ref:`channel-interpolation` to link to that section of the
|
| 12 |
+
implementation.rst page. The next line is a target for :start-after: so we
|
| 13 |
+
can omit the title from the include:
|
| 14 |
+
channel-interpolation-begin-content
|
| 15 |
+
|
| 16 |
+
In short, data repair using spherical spline interpolation :footcite:`PerrinEtAl1989` consists of the following steps:
|
| 17 |
+
|
| 18 |
+
* Project the good and bad electrodes onto a unit sphere
|
| 19 |
+
* Compute a mapping matrix that maps :math:`N` good channels to :math:`M` bad channels
|
| 20 |
+
* Use this mapping matrix to compute interpolated data in the bad channels
|
| 21 |
+
|
| 22 |
+
Spherical splines assume that the potential :math:`V(\boldsymbol{r_i})` at any point :math:`\boldsymbol{r_i}` on the surface of the sphere can be represented by:
|
| 23 |
+
|
| 24 |
+
.. math:: V(\boldsymbol{r_i}) = c_0 + \sum_{j=1}^{N}c_{i}g_{m}(cos(\boldsymbol{r_i}, \boldsymbol{r_{j}}))
|
| 25 |
+
:name: model
|
| 26 |
+
|
| 27 |
+
where the :math:`C = (c_{1}, ..., c_{N})^{T}` are constants which must be estimated. The function :math:`g_{m}(\cdot)` of order :math:`m` is given by:
|
| 28 |
+
|
| 29 |
+
.. math:: g_{m}(x) = \frac{1}{4 \pi}\sum_{n=1}^{\infty} \frac{2n + 1}{(n(n + 1))^m}P_{n}(x)
|
| 30 |
+
|
| 31 |
+
where :math:`P_{n}(x)` are `Legendre polynomials`_ of order :math:`n`.
|
| 32 |
+
|
| 33 |
+
.. _Legendre polynomials: https://en.wikipedia.org/wiki/Legendre_polynomials
|
| 34 |
+
|
| 35 |
+
To estimate the constants :math:`C`, we must solve the following two equations simultaneously:
|
| 36 |
+
|
| 37 |
+
.. math:: G_{ss}C + T_{s}c_0 = X
|
| 38 |
+
:name: matrix_form
|
| 39 |
+
|
| 40 |
+
.. math:: {T_s}^{T}C = 0
|
| 41 |
+
:name: constraint
|
| 42 |
+
|
| 43 |
+
where :math:`G_{ss} \in R^{N \times N}` is a matrix whose entries are :math:`G_{ss}[i, j] = g_{m}(cos(\boldsymbol{r_i}, \boldsymbol{r_j}))` and :math:`X \in R^{N \times 1}` are the potentials :math:`V(\boldsymbol{r_i})` measured at the good channels. :math:`T_{s} = (1, 1, ..., 1)^\top` is a column vector of dimension :math:`N`. Equation :eq:`matrix_form` is the matrix formulation of Equation :eq:`model` and equation :eq:`constraint` is like applying an average reference to the data. From equation :eq:`matrix_form` and :eq:`constraint`, we get:
|
| 44 |
+
|
| 45 |
+
.. math:: \begin{bmatrix} c_0 \\ C \end{bmatrix} = {\begin{bmatrix} {T_s}^{T} && 0 \\ T_s && G_{ss} \end{bmatrix}}^{-1} \begin{bmatrix} 0 \\ X \end{bmatrix} = C_{i}X
|
| 46 |
+
:name: estimate_constant
|
| 47 |
+
|
| 48 |
+
:math:`C_{i}` is the same as matrix :math:`{\begin{bmatrix} {T_s}^{T} && 0 \\ T_s && G_{ss} \end{bmatrix}}^{-1}` but with its first column deleted, therefore giving a matrix of dimension :math:`(N + 1) \times N`.
|
| 49 |
+
|
| 50 |
+
Now, to estimate the potentials :math:`\hat{X} \in R^{M \times 1}` at the bad channels, we have to do:
|
| 51 |
+
|
| 52 |
+
.. math:: \hat{X} = G_{ds}C + T_{d}c_0
|
| 53 |
+
:name: estimate_data
|
| 54 |
+
|
| 55 |
+
where :math:`G_{ds} \in R^{M \times N}` computes :math:`g_{m}(\boldsymbol{r_i}, \boldsymbol{r_j})` between the bad and good channels. :math:`T_{d} = (1, 1, ..., 1)^\top` is a column vector of dimension :math:`M`. Plugging in equation :eq:`estimate_constant` in :eq:`estimate_data`, we get
|
| 56 |
+
|
| 57 |
+
.. math:: \hat{X} = \begin{bmatrix} T_d && G_{ds} \end{bmatrix} \begin{bmatrix} c_0 \\ C \end{bmatrix} = \underbrace{\begin{bmatrix} T_d && G_{ds} \end{bmatrix} C_{i}}_\text{mapping matrix}X
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
To interpolate bad channels, one can simply do:
|
| 61 |
+
|
| 62 |
+
>>> evoked.interpolate_bads(reset_bads=False) # doctest: +SKIP
|
| 63 |
+
|
| 64 |
+
and the bad channel will be fixed.
|
| 65 |
+
|
| 66 |
+
.. target for :end-before: channel-interpolation-end-content
|
| 67 |
+
|
| 68 |
+
.. topic:: Examples:
|
| 69 |
+
|
| 70 |
+
* :ref:`ex-interpolate-bad-channels`
|
mne-python/source/doc/_includes/channel_types.rst
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Supported channel types
|
| 4 |
+
=======================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 7 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 8 |
+
to :ref:`channel-types` to link to that section of the implementation.rst
|
| 9 |
+
page. The next line is a target for :start-after: so we can omit the title
|
| 10 |
+
from the include:
|
| 11 |
+
channel-types-begin-content
|
| 12 |
+
|
| 13 |
+
.. NOTE: In the future, this table should be automatically synchronized with
|
| 14 |
+
the sensor types listed in the glossary. Perhaps a table showing data type
|
| 15 |
+
channels as well as non-data type channels should be added to the glossary
|
| 16 |
+
and displayed here too.
|
| 17 |
+
|
| 18 |
+
Channel types are represented in MNE-Python with shortened or abbreviated
|
| 19 |
+
names. This page lists all supported channel types, their abbreviated names,
|
| 20 |
+
and the measurement unit used to represent data of that type. Where channel
|
| 21 |
+
types occur in two or more sub-types, the sub-type abbreviations are given in
|
| 22 |
+
parentheses. More information about measurement units is given in the
|
| 23 |
+
:ref:`units` section.
|
| 24 |
+
|
| 25 |
+
.. NOTE: To include only the table, here's a different target for :start-after:
|
| 26 |
+
channel-types-begin-table
|
| 27 |
+
|
| 28 |
+
.. cssclass:: table-bordered
|
| 29 |
+
.. rst-class:: midvalign
|
| 30 |
+
|
| 31 |
+
================= ========================================= =================
|
| 32 |
+
Channel type Description Measurement unit
|
| 33 |
+
================= ========================================= =================
|
| 34 |
+
eeg scalp electroencephalography (EEG) Volts
|
| 35 |
+
|
| 36 |
+
meg (mag) Magnetoencephalography (magnetometers) Teslas
|
| 37 |
+
|
| 38 |
+
meg (grad) Magnetoencephalography (gradiometers) Teslas/meter
|
| 39 |
+
|
| 40 |
+
ecg Electrocardiography (ECG) Volts
|
| 41 |
+
|
| 42 |
+
seeg Stereotactic EEG channels Volts
|
| 43 |
+
|
| 44 |
+
dbs Deep brain stimulation (DBS) Volts
|
| 45 |
+
|
| 46 |
+
ecog Electrocorticography (ECoG) Volts
|
| 47 |
+
|
| 48 |
+
fnirs (hbo) Functional near-infrared spectroscopy Moles/liter
|
| 49 |
+
(oxyhemoglobin)
|
| 50 |
+
|
| 51 |
+
fnirs (hbr) Functional near-infrared spectroscopy Moles/liter
|
| 52 |
+
(deoxyhemoglobin)
|
| 53 |
+
|
| 54 |
+
emg Electromyography (EMG) Volts
|
| 55 |
+
|
| 56 |
+
eog Electrooculography (EOG) Volts
|
| 57 |
+
|
| 58 |
+
bio Miscellaneous biological channels (e.g., Arbitrary units
|
| 59 |
+
skin conductance)
|
| 60 |
+
|
| 61 |
+
stim stimulus (a.k.a. trigger) channels Arbitrary units
|
| 62 |
+
|
| 63 |
+
resp respiration monitoring channel Volts
|
| 64 |
+
|
| 65 |
+
chpi continuous head position indicator Teslas
|
| 66 |
+
(HPI) coil channels
|
| 67 |
+
|
| 68 |
+
exci Flux excitation channel
|
| 69 |
+
|
| 70 |
+
ias Internal Active Shielding data
|
| 71 |
+
(Triux systems only?)
|
| 72 |
+
|
| 73 |
+
syst System status channel information
|
| 74 |
+
(Triux systems only)
|
| 75 |
+
|
| 76 |
+
temperature Temperature Degrees Celsius
|
| 77 |
+
|
| 78 |
+
gsr Galvanic skin response Siemens
|
| 79 |
+
|
| 80 |
+
ref_meg Reference Magnetometers Teslas
|
| 81 |
+
|
| 82 |
+
dipole Dipole amplitude Amperes
|
| 83 |
+
|
| 84 |
+
gof Goodness of fit (GOF) Goodness-of-fit
|
| 85 |
+
|
| 86 |
+
cw-nirs (amp) Continuous-wave functional near-infrared Volts
|
| 87 |
+
spectroscopy (CW-fNIRS) (CW amplitude)
|
| 88 |
+
|
| 89 |
+
fd-nirs (ac amp) Frequency-domain near-infrared Volts
|
| 90 |
+
spectroscopy (FD-NIRS AC amplitude)
|
| 91 |
+
|
| 92 |
+
fd-nirs (phase) Frequency-domain near-infrared Radians
|
| 93 |
+
spectroscopy (FD-NIRS phase)
|
| 94 |
+
|
| 95 |
+
fnirs (od) Functional near-infrared spectroscopy Volts
|
| 96 |
+
(optical density)
|
| 97 |
+
|
| 98 |
+
csd Current source density Volts per square
|
| 99 |
+
meter
|
| 100 |
+
|
| 101 |
+
eyegaze Eye-tracking (gaze position) Arbitrary units
|
| 102 |
+
|
| 103 |
+
pupil Eye-tracking (pupil size) Arbitrary units
|
| 104 |
+
================= ========================================= =================
|
mne-python/source/doc/_includes/data_formats.rst
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Supported data formats
|
| 4 |
+
======================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 7 |
+
Changes here are reflected there. If you want to link to this content,
|
| 8 |
+
link to :ref:`data-formats`. The next line is
|
| 9 |
+
a target for :start-after: so we can omit the title above:
|
| 10 |
+
data-formats-begin-content
|
| 11 |
+
|
| 12 |
+
When MNE-Python loads sensor data, the data are stored in a Python object of
|
| 13 |
+
type :class:`mne.io.Raw`. Specialized loading functions are provided for the
|
| 14 |
+
raw data file formats from a variety of equipment manufacturers. All raw data
|
| 15 |
+
input/output functions in MNE-Python are found in :mod:`mne.io` and start
|
| 16 |
+
with :samp:`read_raw_{*}`; see the documentation for each reader function for
|
| 17 |
+
more info on reading specific file types.
|
| 18 |
+
|
| 19 |
+
As seen in the table below, there are also a few formats defined by other
|
| 20 |
+
neuroimaging analysis software packages that are supported (EEGLAB,
|
| 21 |
+
FieldTrip). Like the equipment-specific loading functions, these will also
|
| 22 |
+
return an object of class :class:`~mne.io.Raw`; additional functions are
|
| 23 |
+
available for reading data that has already been epoched or averaged (see
|
| 24 |
+
table).
|
| 25 |
+
|
| 26 |
+
.. NOTE: To include only the table, here's a different target for :start-after:
|
| 27 |
+
data-formats-begin-table
|
| 28 |
+
|
| 29 |
+
.. cssclass:: table-bordered
|
| 30 |
+
.. rst-class:: midvalign
|
| 31 |
+
|
| 32 |
+
============ ============================================ ========= ===================================
|
| 33 |
+
Data type File format Extension MNE-Python function
|
| 34 |
+
============ ============================================ ========= ===================================
|
| 35 |
+
MEG :ref:`Artemis123 <import-artemis>` .bin :func:`mne.io.read_raw_artemis123`
|
| 36 |
+
|
| 37 |
+
MEG :ref:`4-D Neuroimaging / BTi <import-bti>` <dir> :func:`mne.io.read_raw_bti`
|
| 38 |
+
|
| 39 |
+
MEG :ref:`CTF <import-ctf>` <dir> :func:`mne.io.read_raw_ctf`
|
| 40 |
+
|
| 41 |
+
MEG and EEG :ref:`Elekta Neuromag <import-neuromag>` .fif :func:`mne.io.read_raw_fif`
|
| 42 |
+
|
| 43 |
+
MEG :ref:`FIL OPM MEG <import-fil>` .bin :func:`mne.io.read_raw_fil`
|
| 44 |
+
|
| 45 |
+
MEG :ref:`KIT <import-kit>` .sqd :func:`mne.io.read_raw_kit`,
|
| 46 |
+
:func:`mne.read_epochs_kit`
|
| 47 |
+
|
| 48 |
+
MEG and EEG :ref:`FieldTrip <import-fieldtrip>` .mat :func:`mne.io.read_raw_fieldtrip`,
|
| 49 |
+
:func:`mne.read_epochs_fieldtrip`,
|
| 50 |
+
:func:`mne.read_evoked_fieldtrip`
|
| 51 |
+
|
| 52 |
+
EEG :ref:`Brainvision <import-bv>` .vhdr :func:`mne.io.read_raw_brainvision`
|
| 53 |
+
|
| 54 |
+
EEG :ref:`Biosemi data format <import-biosemi>` .bdf :func:`mne.io.read_raw_bdf`
|
| 55 |
+
|
| 56 |
+
EEG :ref:`Neuroscan CNT <import-cnt>` .cnt :func:`mne.io.read_raw_cnt`
|
| 57 |
+
|
| 58 |
+
EEG :ref:`European data format <import-edf>` .edf :func:`mne.io.read_raw_edf`
|
| 59 |
+
|
| 60 |
+
EEG :ref:`EEGLAB <import-set>` .set :func:`mne.io.read_raw_eeglab`,
|
| 61 |
+
:func:`mne.read_epochs_eeglab`
|
| 62 |
+
|
| 63 |
+
EEG :ref:`EGI simple binary <import-egi>` .egi :func:`mne.io.read_raw_egi`
|
| 64 |
+
|
| 65 |
+
EEG :ref:`EGI MFF format <import-mff>` .mff :func:`mne.io.read_raw_egi`
|
| 66 |
+
|
| 67 |
+
EEG :ref:`eXimia <import-nxe>` .nxe :func:`mne.io.read_raw_eximia`
|
| 68 |
+
|
| 69 |
+
EEG :ref:`General data format <import-gdf>` .gdf :func:`mne.io.read_raw_gdf`
|
| 70 |
+
|
| 71 |
+
EEG :ref:`Nicolet <import-nicolet>` .data :func:`mne.io.read_raw_nicolet`
|
| 72 |
+
|
| 73 |
+
EEG :ref:`Persyst <import-persyst>` .lay :func:`mne.io.read_raw_persyst`
|
| 74 |
+
|
| 75 |
+
NIRS :ref:`NIRx <import-nirx>` directory :func:`mne.io.read_raw_nirx`
|
| 76 |
+
|
| 77 |
+
NIRS :ref:`BOXY <import-boxy>` directory :func:`mne.io.read_raw_boxy`
|
| 78 |
+
|
| 79 |
+
EYETRACK SR eyelink ASCII files .asc :func:`mne.io.read_raw_eyelink`
|
| 80 |
+
|
| 81 |
+
iEEG MEF3 .mefd :func:`mne.io.read_raw_mef`
|
| 82 |
+
|
| 83 |
+
============ ============================================ ========= ===================================
|
| 84 |
+
|
| 85 |
+
More details are provided in the tutorials in the :ref:`tut-data-formats`
|
| 86 |
+
section.
|
mne-python/source/doc/_includes/dig_formats.rst
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
.. _dig-formats:
|
| 4 |
+
|
| 5 |
+
Supported formats for digitized 3D locations
|
| 6 |
+
============================================
|
| 7 |
+
|
| 8 |
+
.. NOTE: If you want to link to this content, link to :ref:`dig-formats`
|
| 9 |
+
for the implementation page. The next line is
|
| 10 |
+
a target for :start-after: so we can omit the title above:
|
| 11 |
+
dig-formats-begin-content
|
| 12 |
+
|
| 13 |
+
MNE-Python can load 3D point locations obtained by digitization systems.
|
| 14 |
+
Such files allow to obtain a :class:`montage <mne.channels.DigMontage>`
|
| 15 |
+
that can then be added to :class:`~mne.io.Raw` objects with the
|
| 16 |
+
:meth:`~mne.io.Raw.set_montage`. See the documentation for each reader
|
| 17 |
+
function for more info on reading specific file types.
|
| 18 |
+
|
| 19 |
+
.. NOTE: To include only the table, here's a different target for :start-after:
|
| 20 |
+
dig-formats-begin-table
|
| 21 |
+
|
| 22 |
+
.. cssclass:: table-bordered
|
| 23 |
+
.. rst-class:: midvalign
|
| 24 |
+
|
| 25 |
+
===================== ================ ==============================================
|
| 26 |
+
Vendor Extension(s) MNE-Python function
|
| 27 |
+
===================== ================ ==============================================
|
| 28 |
+
Neuromag .fif :func:`mne.channels.read_dig_fif`
|
| 29 |
+
|
| 30 |
+
Polhemus ISOTRAK .hsp, .elp, .eeg :func:`mne.channels.read_dig_polhemus_isotrak`
|
| 31 |
+
|
| 32 |
+
EGI .xml :func:`mne.channels.read_dig_egi`
|
| 33 |
+
|
| 34 |
+
MNE-C .hpts :func:`mne.channels.read_dig_hpts`
|
| 35 |
+
|
| 36 |
+
Brain Products .bvct :func:`mne.channels.read_dig_captrak`
|
| 37 |
+
|
| 38 |
+
Compumedics .dat, .cdt :func:`mne.channels.read_dig_curry`
|
| 39 |
+
|
| 40 |
+
Compumedics (legacy) .dat :func:`mne.channels.read_dig_dat`
|
| 41 |
+
===================== ================ ==============================================
|
| 42 |
+
|
| 43 |
+
To load Polhemus FastSCAN files you can use
|
| 44 |
+
:func:`montage <mne.channels.read_polhemus_fastscan>`.
|
| 45 |
+
|
| 46 |
+
It is also possible to make a :class:`montage <mne.channels.DigMontage>`
|
| 47 |
+
from arrays with :func:`mne.channels.make_dig_montage`.
|
mne-python/source/doc/_includes/forward.rst
ADDED
|
@@ -0,0 +1,726 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
The forward solution
|
| 4 |
+
====================
|
| 5 |
+
|
| 6 |
+
This page covers the definitions of different coordinate systems employed in
|
| 7 |
+
MNE software and FreeSurfer, the details of the computation of the forward
|
| 8 |
+
solutions, and the associated low-level utilities.
|
| 9 |
+
|
| 10 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 11 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 12 |
+
to :ref:`ch_forward` to link to that section of the implementation.rst page.
|
| 13 |
+
The next line is a target for :start-after: so we can omit the title from
|
| 14 |
+
the include:
|
| 15 |
+
forward-begin-content
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
.. _coordinate_systems:
|
| 19 |
+
|
| 20 |
+
MEG/EEG and MRI coordinate systems
|
| 21 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 22 |
+
|
| 23 |
+
.. note:: Coordinate systems in MNE-Python
|
| 24 |
+
:class: sidebar
|
| 25 |
+
|
| 26 |
+
In some MNE-Python objects (e.g., :class:`~mne.Forward`,
|
| 27 |
+
:class:`~mne.SourceSpaces`, etc), information about the coordinate frame is
|
| 28 |
+
encoded as a constant integer value. The meaning of those integers is
|
| 29 |
+
determined `in the source code
|
| 30 |
+
<https://github.com/mne-tools/mne-python/blob/079c868240a898204bf82b2f1bf0e04cdee75da1/mne/_fiff/constants.py#L263-L275>`__.
|
| 31 |
+
|
| 32 |
+
The coordinate systems used in MNE software (and FreeSurfer) and their
|
| 33 |
+
relationships are depicted in :ref:`coordinate_system_figure`. Except for the
|
| 34 |
+
*sensor coordinates*, all of the coordinate systems are Cartesian and have the
|
| 35 |
+
"RAS" (Right-Anterior-Superior) orientation, *i.e.*, the :math:`x` axis points
|
| 36 |
+
to the right, the :math:`y` axis to the front, and the :math:`z` axis up.
|
| 37 |
+
|
| 38 |
+
.. _coordinate_system_figure:
|
| 39 |
+
|
| 40 |
+
.. figure:: ../_static/CoordinateSystems.png
|
| 41 |
+
:alt: MEG/EEG and MRI coordinate systems
|
| 42 |
+
|
| 43 |
+
MEG/EEG and MRI coordinate systems
|
| 44 |
+
|
| 45 |
+
The coordinate transforms present in the fif files in MNE and the
|
| 46 |
+
FreeSurfer files as well as those set to fixed values are indicated with
|
| 47 |
+
:math:`T_x`, where :math:`x` identifies the transformation.
|
| 48 |
+
|
| 49 |
+
The coordinate systems related to MEG/EEG data are:
|
| 50 |
+
|
| 51 |
+
**Head coordinates**
|
| 52 |
+
|
| 53 |
+
This is a coordinate system defined with help of the fiducial landmarks
|
| 54 |
+
(nasion and the two auricular points). In fif files, EEG electrode
|
| 55 |
+
locations are given in this coordinate system. In addition, the head
|
| 56 |
+
digitization data acquired in the beginning of an MEG, MEG/EEG, or EEG
|
| 57 |
+
acquisition are expressed in head coordinates. For details, see
|
| 58 |
+
:ref:`coordinate_systems`.
|
| 59 |
+
|
| 60 |
+
**Device coordinates**
|
| 61 |
+
|
| 62 |
+
This is a coordinate system tied to the MEG device. The relationship of the
|
| 63 |
+
Device and Head coordinates is determined during an MEG measurement by
|
| 64 |
+
feeding current to three to five head-position indicator (HPI) coils and by
|
| 65 |
+
determining their locations with respect to the MEG sensor array from the
|
| 66 |
+
magnetic fields they generate.
|
| 67 |
+
|
| 68 |
+
**Sensor coordinates**
|
| 69 |
+
|
| 70 |
+
Each MEG sensor has a local coordinate system defining the orientation and
|
| 71 |
+
location of the sensor. With help of this coordinate system, the numerical
|
| 72 |
+
integration data needed for the computation of the magnetic field can be
|
| 73 |
+
expressed conveniently as discussed in :ref:`coil_geometry_information`.
|
| 74 |
+
The channel information data in the fif files contain the information to
|
| 75 |
+
specify the coordinate transformation between the coordinates of each
|
| 76 |
+
sensor and the MEG device coordinates.
|
| 77 |
+
|
| 78 |
+
The coordinate systems related to MRI data are:
|
| 79 |
+
|
| 80 |
+
**Surface RAS coordinates**
|
| 81 |
+
|
| 82 |
+
The FreeSurfer surface data are expressed in this coordinate system. The
|
| 83 |
+
origin of this coordinate system is at the center of the conformed
|
| 84 |
+
FreeSurfer MRI volumes (usually 256 x 256 x 256 isotropic 1-mm3 voxels)
|
| 85 |
+
and the axes are oriented along the axes of this volume. The BEM surface
|
| 86 |
+
and the locations of the sources in the source space are usually expressed
|
| 87 |
+
in this coordinate system in the fif files. In this manual, the *Surface
|
| 88 |
+
RAS coordinates* are usually referred to as *MRI coordinates* unless there
|
| 89 |
+
is need to specifically discuss the different MRI-related coordinate
|
| 90 |
+
systems.
|
| 91 |
+
|
| 92 |
+
**RAS coordinates**
|
| 93 |
+
|
| 94 |
+
This coordinate system has axes identical to the Surface RAS coordinates
|
| 95 |
+
but the location of the origin is different and defined by the original MRI
|
| 96 |
+
data, i.e. , the origin is in a scanner-dependent location. There is hardly
|
| 97 |
+
any need to refer to this coordinate system explicitly in the analysis with
|
| 98 |
+
the MNE software. However, since the Talairach coordinates, discussed
|
| 99 |
+
below, are defined with respect to *RAS coordinates* rather than the
|
| 100 |
+
*Surface RAS coordinates*, the RAS coordinate system is implicitly involved
|
| 101 |
+
in the transformation between Surface RAS coordinates and the two
|
| 102 |
+
*Talairach* coordinate systems.
|
| 103 |
+
|
| 104 |
+
**MNI Talairach coordinates**
|
| 105 |
+
|
| 106 |
+
The definition of this coordinate system is discussed, e.g., in
|
| 107 |
+
https://imaging.mrc-cbu.cam.ac.uk/imaging/MniTalairach. This transformation
|
| 108 |
+
is determined during the FreeSurfer reconstruction process. These
|
| 109 |
+
coordinates are in MNI305 space.
|
| 110 |
+
|
| 111 |
+
**FreeSurfer Talairach coordinates**
|
| 112 |
+
|
| 113 |
+
The problem with the MNI Talairach coordinates is that the linear MNI
|
| 114 |
+
Talairach transform does not match the brains completely to the Talairach
|
| 115 |
+
brain. This is probably because the Talairach atlas brain is a rather odd
|
| 116 |
+
shape, and as a result, it is difficult to match a standard brain to the
|
| 117 |
+
atlas brain using an affine transform. As a result, the MNI brains are
|
| 118 |
+
slightly larger (in particular higher, deeper and longer) than the
|
| 119 |
+
Talairach brain. The differences are larger as you get further from the
|
| 120 |
+
middle of the brain, towards the outside. The FreeSurfer Talairach
|
| 121 |
+
coordinates mitigate this problem by additing a an additional
|
| 122 |
+
transformation, defined separately for negative and positive MNI Talairach
|
| 123 |
+
:math:`z` coordinates. These two transformations, denoted by :math:`T_-`
|
| 124 |
+
and :math:`T_+` in :ref:`coordinate_system_figure`, are fixed as discussed in
|
| 125 |
+
https://imaging.mrc-cbu.cam.ac.uk/imaging/MniTalairach (*Approach 2*).
|
| 126 |
+
|
| 127 |
+
The different coordinate systems are related by coordinate transformations
|
| 128 |
+
depicted in :ref:`coordinate_system_figure`. The arrows and coordinate
|
| 129 |
+
transformation symbols (:math:`T_x`) indicate the transformations actually
|
| 130 |
+
present in the FreeSurfer files. Generally,
|
| 131 |
+
|
| 132 |
+
.. math:: \begin{bmatrix}
|
| 133 |
+
x_2 \\
|
| 134 |
+
y_2 \\
|
| 135 |
+
z_2 \\
|
| 136 |
+
1
|
| 137 |
+
\end{bmatrix} = T_{12} \begin{bmatrix}
|
| 138 |
+
x_1 \\
|
| 139 |
+
y_1 \\
|
| 140 |
+
z_1 \\
|
| 141 |
+
1
|
| 142 |
+
\end{bmatrix} = \begin{bmatrix}
|
| 143 |
+
R_{11} & R_{12} & R_{13} & x_0 \\
|
| 144 |
+
R_{21} & R_{22} & R_{23} & y_0 \\
|
| 145 |
+
R_{31} & R_{32} & R_{33} & z_0 \\
|
| 146 |
+
0 & 0 & 0 & 1
|
| 147 |
+
\end{bmatrix} \begin{bmatrix}
|
| 148 |
+
x_1 \\
|
| 149 |
+
y_1 \\
|
| 150 |
+
z_1 \\
|
| 151 |
+
1
|
| 152 |
+
\end{bmatrix}\ ,
|
| 153 |
+
|
| 154 |
+
where :math:`x_k`, :math:`y_k`,and :math:`z_k` are the location coordinates in
|
| 155 |
+
two coordinate systems, :math:`T_{12}` is the coordinate transformation from
|
| 156 |
+
coordinate system "1" to "2", :math:`x_0`, :math:`y_0`, and :math:`z_0` is the
|
| 157 |
+
location of the origin of coordinate system "1" in coordinate system "2", and
|
| 158 |
+
:math:`R_{jk}` are the elements of the rotation matrix relating the two
|
| 159 |
+
coordinate systems. The coordinate transformations are present in different
|
| 160 |
+
files produced by FreeSurfer and MNE.
|
| 161 |
+
The fixed transformations :math:`T_-` and :math:`T_+` are:
|
| 162 |
+
|
| 163 |
+
.. math:: T_{-} = \begin{bmatrix}
|
| 164 |
+
0.99 & 0 & 0 & 0 \\
|
| 165 |
+
0 & 0.9688 & 0.042 & 0 \\
|
| 166 |
+
0 & -0.0485 & 0.839 & 0 \\
|
| 167 |
+
0 & 0 & 0 & 1
|
| 168 |
+
\end{bmatrix}
|
| 169 |
+
|
| 170 |
+
and
|
| 171 |
+
|
| 172 |
+
.. math:: T_{+} = \begin{bmatrix}
|
| 173 |
+
0.99 & 0 & 0 & 0 \\
|
| 174 |
+
0 & 0.9688 & 0.046 & 0 \\
|
| 175 |
+
0 & -0.0485 & 0.9189 & 0 \\
|
| 176 |
+
0 & 0 & 0 & 1
|
| 177 |
+
\end{bmatrix}
|
| 178 |
+
|
| 179 |
+
.. note::
|
| 180 |
+
This section does not discuss the transformation between the MRI voxel
|
| 181 |
+
indices and the different MRI coordinates. However, it is important to note
|
| 182 |
+
that in FreeSurfer, MNE, as well as in Neuromag software an integer voxel
|
| 183 |
+
coordinate corresponds to the location of the center of a voxel. Detailed
|
| 184 |
+
information on the FreeSurfer MRI systems can be found at
|
| 185 |
+
https://surfer.nmr.mgh.harvard.edu/fswiki/CoordinateSystems.
|
| 186 |
+
The symbols :math:`T_x` are defined in :ref:`coordinate_system_figure`.
|
| 187 |
+
|
| 188 |
+
.. tabularcolumns:: |p{0.2\linewidth}|p{0.3\linewidth}|p{0.5\linewidth}|
|
| 189 |
+
.. table:: Coordinate transformations in FreeSurfer and MNE software packages
|
| 190 |
+
|
| 191 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 192 |
+
| Transformation | FreeSurfer | MNE |
|
| 193 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 194 |
+
| :math:`T_1` | Not present | | Measurement data files |
|
| 195 |
+
| | | | Forward solution files (``*fwd.fif``) |
|
| 196 |
+
| | | | Inverse operator files (``*inv.fif``) |
|
| 197 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 198 |
+
| :math:`T_{s_1}\dots T_{s_n}` | Not present | Channel information in files |
|
| 199 |
+
| | | containing :math:`T_1`. |
|
| 200 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 201 |
+
| :math:`T_2` | Not present | | MRI description filesSeparate |
|
| 202 |
+
| | | | Separate ``-trans.fif`` files |
|
| 203 |
+
| | | | from :ref:`mne coreg` |
|
| 204 |
+
| | | | Forward solution files |
|
| 205 |
+
| | | | Inverse operator files |
|
| 206 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 207 |
+
| :math:`T_3` | ``mri/*mgz`` files | :class:`nibabel.freesurfer.mghformat.MGHImage` |
|
| 208 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 209 |
+
| :math:`T_4` | mri/transforms/talairach.xfm | Internal reading |
|
| 210 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 211 |
+
| :math:`T_-` | Hardcoded in software | Hardcoded in software. |
|
| 212 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 213 |
+
| :math:`T_+` | Hardcoded in software | Hardcoded in software. |
|
| 214 |
+
+------------------------------+-------------------------------+-------------------------------------------------+
|
| 215 |
+
|
| 216 |
+
.. _head_device_coords:
|
| 217 |
+
|
| 218 |
+
The head and device coordinate systems
|
| 219 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 220 |
+
|
| 221 |
+
.. figure:: ../_static/HeadCS.png
|
| 222 |
+
:alt: Head coordinate system
|
| 223 |
+
|
| 224 |
+
The head coordinate system
|
| 225 |
+
|
| 226 |
+
The MEG/EEG head coordinate system employed in the MNE software is a
|
| 227 |
+
right-handed Cartesian coordinate system. The direction of :math:`x` axis is
|
| 228 |
+
from left to right, that of :math:`y` axis to the front, and the :math:`z` axis
|
| 229 |
+
thus points up.
|
| 230 |
+
|
| 231 |
+
The :math:`x` axis of the head coordinate system passes through the two
|
| 232 |
+
periauricular or preauricular points digitized before acquiring the data with
|
| 233 |
+
positive direction to the right. The :math:`y` axis passes through the nasion
|
| 234 |
+
and is normal to the :math:`x` axis. The :math:`z` axis points up according to
|
| 235 |
+
the right-hand rule and is normal to the :math:`xy` plane.
|
| 236 |
+
|
| 237 |
+
The origin of the MEG device coordinate system is device dependent. Its origin
|
| 238 |
+
is located approximately at the center of a sphere which fits the occipital
|
| 239 |
+
section of the MEG helmet best with :math:`x` axis axis going from left to
|
| 240 |
+
right and :math:`y` axis pointing front. The :math:`z` axis is, again, normal
|
| 241 |
+
to the :math:`xy` plane with positive direction up.
|
| 242 |
+
|
| 243 |
+
.. note::
|
| 244 |
+
The above definition is identical to that of the Neuromag MEG/EEG (head)
|
| 245 |
+
coordinate system. However, in 4-D Neuroimaging and CTF MEG systems the head
|
| 246 |
+
coordinate frame definition is different. The origin of the coordinate
|
| 247 |
+
system is at the midpoint of the left and right auricular points. The
|
| 248 |
+
:math:`x` axis passes through the nasion and the origin with positive
|
| 249 |
+
direction to the front. The :math:`y` axis is perpendicular to the :math:`x`
|
| 250 |
+
axis on the and lies in the plane defined by the three fiducial landmarks,
|
| 251 |
+
positive direction from right to left. The :math:`z` axis is normal to the
|
| 252 |
+
plane of the landmarks, pointing up. Note that in this convention the
|
| 253 |
+
auricular points are not necessarily located on :math:`y` coordinate axis.
|
| 254 |
+
The file conversion utilities take care of these idiosyncrasies and convert
|
| 255 |
+
all coordinate information to the MNE software head coordinate frame.
|
| 256 |
+
|
| 257 |
+
Creating a surface-based source space
|
| 258 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 259 |
+
|
| 260 |
+
The fif format source space files containing the dipole locations and
|
| 261 |
+
orientations are created with :func:`mne.setup_source_space`.
|
| 262 |
+
|
| 263 |
+
Creating a volumetric or discrete source space
|
| 264 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 265 |
+
|
| 266 |
+
In addition to source spaces confined to a surface, the MNE software provides
|
| 267 |
+
some support for three-dimensional source spaces bounded by a surface as well
|
| 268 |
+
as source spaces comprised of discrete, arbitrarily located source points. The
|
| 269 |
+
:func:`mne.setup_volume_source_space` utility assists in generating such source
|
| 270 |
+
spaces.
|
| 271 |
+
|
| 272 |
+
Creating the BEM meshes
|
| 273 |
+
~~~~~~~~~~~~~~~~~~~~~~~
|
| 274 |
+
|
| 275 |
+
See :ref:`bem-model`.
|
| 276 |
+
|
| 277 |
+
Topology checks
|
| 278 |
+
---------------
|
| 279 |
+
|
| 280 |
+
The following topology checks are performed during the creation of BEM models:
|
| 281 |
+
|
| 282 |
+
- The completeness of each surface is confirmed by calculating the total solid
|
| 283 |
+
angle subtended by all triangles from a point inside the triangulation. The
|
| 284 |
+
result should be very close to :math:`4 \pi`. If the result is :math:`-4 \pi`
|
| 285 |
+
instead, it is conceivable that the ordering of the triangle vertices is
|
| 286 |
+
incorrect and the ``--swap`` option should be specified.
|
| 287 |
+
|
| 288 |
+
- The correct ordering of the surfaces is verified by checking that the
|
| 289 |
+
surfaces are inside each other as expected. This is accomplished by checking
|
| 290 |
+
that the sum solid angles subtended by triangles of a surface :math:`S_k` at
|
| 291 |
+
all vertices of another surface :math:`S_p` which is supposed to be inside it
|
| 292 |
+
equals :math:`4 \pi`. Naturally, this check is applied only if the model has
|
| 293 |
+
more than one surface. Since the surface relations are transitive, it is
|
| 294 |
+
enough to check that the outer skull surface is inside the skin surface and
|
| 295 |
+
that the inner skull surface is inside the outer skull one.
|
| 296 |
+
|
| 297 |
+
- The extent of each of the triangulated volumes is checked. If the extent is
|
| 298 |
+
smaller than 50mm, an error is reported. This may indicate that the vertex
|
| 299 |
+
coordinates have been specified in meters instead of millimeters.
|
| 300 |
+
|
| 301 |
+
|
| 302 |
+
Computing the BEM geometry data
|
| 303 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 304 |
+
|
| 305 |
+
The utility :func:`mne.make_bem_solution` computes the geometry information for
|
| 306 |
+
BEM.
|
| 307 |
+
|
| 308 |
+
.. _coil_geometry_information:
|
| 309 |
+
|
| 310 |
+
Coil geometry information
|
| 311 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 312 |
+
|
| 313 |
+
This Section explains the presentation of MEG detection coil geometry
|
| 314 |
+
information the approximations used for different detection coils in MNE
|
| 315 |
+
software. Two pieces of information are needed to characterize the detectors:
|
| 316 |
+
|
| 317 |
+
- The location and orientation a local coordinate system for each detector.
|
| 318 |
+
|
| 319 |
+
- A unique identifier, which has an one-to-one correspondence to the
|
| 320 |
+
geometrical description of the coil.
|
| 321 |
+
|
| 322 |
+
.. note:: MNE ships with several coil geometry configurations. They can be
|
| 323 |
+
found in ``mne/data``. See :ref:`ex-plot-meg-sensors` for a
|
| 324 |
+
comparison between different coil geometries, and
|
| 325 |
+
:ref:`implemented_coil_geometries` for detailed information regarding
|
| 326 |
+
the files describing Neuromag coil geometries.
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
The sensor coordinate system
|
| 330 |
+
----------------------------
|
| 331 |
+
|
| 332 |
+
The sensor coordinate system is completely characterized by the location of its
|
| 333 |
+
origin and the direction cosines of three orthogonal unit vectors pointing to
|
| 334 |
+
the directions of the x, y, and z axis. In fact, the unit vectors contain
|
| 335 |
+
redundant information because the orientation can be uniquely defined with
|
| 336 |
+
three angles. The measurement fif files list these data in MEG device
|
| 337 |
+
coordinates. Transformation to the MEG head coordinate frame can be easily
|
| 338 |
+
accomplished by applying the device-to-head coordinate transformation matrix
|
| 339 |
+
available in the data files provided that the head-position indicator was used.
|
| 340 |
+
Optionally, the MNE software forward calculation applies another coordinate
|
| 341 |
+
transformation to the head-coordinate data to bring the coil locations and
|
| 342 |
+
orientations to the MRI coordinate system.
|
| 343 |
+
|
| 344 |
+
If :math:`r_0` is a row vector for the origin of the local sensor coordinate
|
| 345 |
+
system and :math:`e_x`, :math:`e_y`, and :math:`e_z` are the row vectors for
|
| 346 |
+
the three orthogonal unit vectors, all given in device coordinates, a location
|
| 347 |
+
of a point :math:`r_C` in sensor coordinates is transformed to device
|
| 348 |
+
coordinates (:math:`r_D`) by
|
| 349 |
+
|
| 350 |
+
.. math:: [r_D 1] = [r_C 1] T_{CD}\ ,
|
| 351 |
+
|
| 352 |
+
where
|
| 353 |
+
|
| 354 |
+
.. math:: T = \begin{bmatrix}
|
| 355 |
+
e_x & 0 \\
|
| 356 |
+
e_y & 0 \\
|
| 357 |
+
e_z & 0 \\
|
| 358 |
+
r_{0D} & 1
|
| 359 |
+
\end{bmatrix}\ .
|
| 360 |
+
|
| 361 |
+
Calculation of the magnetic field
|
| 362 |
+
---------------------------------
|
| 363 |
+
|
| 364 |
+
The forward calculation in the MNE software computes the signals detected by
|
| 365 |
+
each MEG sensor for three orthogonal dipoles at each source space location.
|
| 366 |
+
This requires specification of the conductor model, the location and
|
| 367 |
+
orientation of the dipoles, and the location and orientation of each MEG sensor
|
| 368 |
+
as well as its coil geometry.
|
| 369 |
+
|
| 370 |
+
The output of each SQUID sensor is a weighted sum of the magnetic fluxes
|
| 371 |
+
threading the loops comprising the detection coil. Since the flux threading a
|
| 372 |
+
coil loop is an integral of the magnetic field component normal to the coil
|
| 373 |
+
plane, the output of the k :sup:`th` MEG channel, :math:`b_k` can be
|
| 374 |
+
approximated by:
|
| 375 |
+
|
| 376 |
+
.. math:: b_k = \sum_{p = 1}^{N_k} {w_{kp} B(r_{kp}) \cdot n_{kp}}
|
| 377 |
+
|
| 378 |
+
where :math:`r_{kp}` are a set of :math:`N_k` integration points covering the
|
| 379 |
+
pickup coil loops of the sensor, :math:`B(r_{kp})` is the magnetic field due to
|
| 380 |
+
the current sources calculated at :math:`r_{kp}`, :math:`n_{kp}` are the coil
|
| 381 |
+
normal directions at these points, and :math:`w_{kp}` are the weights
|
| 382 |
+
associated to the integration points. This formula essentially presents
|
| 383 |
+
numerical integration of the magnetic field over the pickup loops of sensor
|
| 384 |
+
:math:`k`.
|
| 385 |
+
|
| 386 |
+
There are three accuracy levels for the numerical integration expressed above.
|
| 387 |
+
The *simple* accuracy means the simplest description of the coil. This accuracy
|
| 388 |
+
is not used in the MNE forward calculations. The *normal* or *recommended*
|
| 389 |
+
accuracy typically uses two integration points for planar gradiometers, one in
|
| 390 |
+
each half of the pickup coil and four evenly distributed integration points for
|
| 391 |
+
magnetometers. This is the default accuracy used by MNE. If the ``--accurate``
|
| 392 |
+
option is specified, the forward calculation typically employs a total of eight
|
| 393 |
+
integration points for planar gradiometers and sixteen for magnetometers.
|
| 394 |
+
Detailed information about the integration points is given in the next section.
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
.. _implemented_coil_geometries:
|
| 398 |
+
|
| 399 |
+
Implemented coil geometries
|
| 400 |
+
---------------------------
|
| 401 |
+
|
| 402 |
+
This section describes the coil geometries currently implemented
|
| 403 |
+
in MNE. The coil types fall in two general categories:
|
| 404 |
+
|
| 405 |
+
- Axial gradiometers and planar gradiometers
|
| 406 |
+
and
|
| 407 |
+
|
| 408 |
+
- Planar magnetometers.
|
| 409 |
+
|
| 410 |
+
For axial sensors, the *z* axis of the local coordinate system is parallel to
|
| 411 |
+
the field component detected, *i.e.*, normal to the coil plane.For circular
|
| 412 |
+
coils, the orientation of the *x* and *y* axes on the plane normal to the z
|
| 413 |
+
axis is irrelevant. In the square coils employed in the Vectorview (TM) system
|
| 414 |
+
the *x* axis is chosen to be parallel to one of the sides of the magnetometer
|
| 415 |
+
coil. For planar sensors, the *z* axis is likewise normal to the coil plane and
|
| 416 |
+
the x axis passes through the centerpoints of the two coil loops so that the
|
| 417 |
+
detector gives a positive signal when the normal field component increases
|
| 418 |
+
along the *x* axis.
|
| 419 |
+
|
| 420 |
+
:ref:`normal_coil_descriptions` lists the parameters of the *normal* coil
|
| 421 |
+
geometry descriptions :ref:`accurate_coil_descriptions` lists the *accurate*
|
| 422 |
+
descriptions. For simple accuracy, please consult the coil definition file, see
|
| 423 |
+
:ref:`coil_definition_file`. The columns of the tables contain the following
|
| 424 |
+
data:
|
| 425 |
+
|
| 426 |
+
- The number identifying the coil id.
|
| 427 |
+
This number is used in the coil descriptions found in the FIF files.
|
| 428 |
+
|
| 429 |
+
- Description of the coil.
|
| 430 |
+
|
| 431 |
+
- Number of integration points used
|
| 432 |
+
|
| 433 |
+
- The locations of the integration points in sensor coordinates.
|
| 434 |
+
|
| 435 |
+
- Weights assigned to the field values at the integration points.
|
| 436 |
+
Some formulas are listed instead of the numerical values to demonstrate
|
| 437 |
+
the principle of the calculation. For example, in the normal coil
|
| 438 |
+
descriptions of the planar gradiometers the weights are inverses
|
| 439 |
+
of the baseline of the gradiometer to show that the output is in
|
| 440 |
+
T/m.
|
| 441 |
+
|
| 442 |
+
.. note:: The coil geometry information is stored in the file
|
| 443 |
+
:file:`mne/data/coil_def.dat`, which is
|
| 444 |
+
automatically created by the MNE-C utility ``mne_list_coil_def``.
|
| 445 |
+
|
| 446 |
+
.. tabularcolumns:: |p{0.1\linewidth}|p{0.3\linewidth}|p{0.1\linewidth}|p{0.25\linewidth}|p{0.2\linewidth}|
|
| 447 |
+
.. table:: Normal coil descriptions
|
| 448 |
+
:name: normal_coil_descriptions
|
| 449 |
+
|
| 450 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 451 |
+
| Id | Description | n | r/mm | w |
|
| 452 |
+
+======+=========================+====+==================================+======================+
|
| 453 |
+
| 2 | Neuromag-122 | 2 | (+/-8.1, 0, 0) mm | +/-1 ⁄ 16.2mm |
|
| 454 |
+
| | planar gradiometer | | | |
|
| 455 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 456 |
+
| 2000 | A point magnetometer | 1 | (0, 0, 0)mm | 1 |
|
| 457 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 458 |
+
| 3012 | Vectorview type 1 | 2 | (+/-8.4, 0, 0.3) mm | +/-1 ⁄ 16.8mm |
|
| 459 |
+
| | planar gradiometer | | | |
|
| 460 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 461 |
+
| 3013 | Vectorview type 2 | 2 | (+/-8.4, 0, 0.3) mm | +/-1 ⁄ 16.8mm |
|
| 462 |
+
| | planar gradiometer | | | |
|
| 463 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 464 |
+
| 3022 | Vectorview type 1 | 4 | (+/-6.45, +/-6.45, 0.3)mm | 1/4 |
|
| 465 |
+
| | magnetometer | | | |
|
| 466 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 467 |
+
| 3023 | Vectorview type 2 | 4 | (+/-6.45, +/-6.45, 0.3)mm | 1/4 |
|
| 468 |
+
| | magnetometer | | | |
|
| 469 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 470 |
+
| 3024 | Vectorview type 3 | 4 | (+/-5.25, +/-5.25, 0.3)mm | 1/4 |
|
| 471 |
+
| | magnetometer | | | |
|
| 472 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 473 |
+
| 2000 | An ideal point | 1 | (0.0, 0.0, 0.0)mm | 1 |
|
| 474 |
+
| | magnetometer | | | |
|
| 475 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 476 |
+
| 4001 | Magnes WH | 4 | (+/-5.75, +/-5.75, 0.0)mm | 1/4 |
|
| 477 |
+
| | magnetometer | | | |
|
| 478 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 479 |
+
| 4002 | Magnes WH 3600 | 8 | (+/-4.5, +/-4.5, 0.0)mm | 1/4 |
|
| 480 |
+
| | axial gradiometer | | (+/-4.5, +/-4.5, 50.0)mm | -1/4 |
|
| 481 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 482 |
+
| 4003 | Magnes reference | 4 | (+/-7.5, +/-7.5, 0.0)mm | 1/4 |
|
| 483 |
+
| | magnetometer | | | |
|
| 484 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 485 |
+
| 4004 | Magnes reference | 8 | (+/-20, +/-20, 0.0)mm | 1/4 |
|
| 486 |
+
| | gradiometer measuring | | (+/-20, +/-20, 135)mm | -1/4 |
|
| 487 |
+
| | diagonal gradients | | | |
|
| 488 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 489 |
+
| 4005 | Magnes reference | 8 | (87.5, +/-20, 0.0)mm | 1/4 |
|
| 490 |
+
| | gradiometer measuring | | (47.5, +/-20, 0.0)mm | -1/4 |
|
| 491 |
+
| | off-diagonal gradients | | (-87.5, +/-20, 0.0)mm | 1/4 |
|
| 492 |
+
| | | | (-47.5, +/-20, 0.0)mm | -1/4 |
|
| 493 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 494 |
+
| 5001 | CTF 275 axial | 8 | (+/-4.5, +/-4.5, 0.0)mm | 1/4 |
|
| 495 |
+
| | gradiometer | | (+/-4.5, +/-4.5, 50.0)mm | -1/4 |
|
| 496 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 497 |
+
| 5002 | CTF reference | 4 | (+/-4, +/-4, 0.0)mm | 1/4 |
|
| 498 |
+
| | magnetometer | | | |
|
| 499 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 500 |
+
| 5003 | CTF reference | 8 | (+/-8.6, +/-8.6, 0.0)mm | 1/4 |
|
| 501 |
+
| | gradiometer measuring | | (+/-8.6, +/-8.6, 78.6)mm | -1/4 |
|
| 502 |
+
| | diagonal gradients | | | |
|
| 503 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 504 |
+
|
| 505 |
+
.. note:: If a plus-minus sign occurs in several coordinates, all possible
|
| 506 |
+
combinations have to be included.
|
| 507 |
+
|
| 508 |
+
.. tabularcolumns:: |p{0.1\linewidth}|p{0.3\linewidth}|p{0.05\linewidth}|p{0.25\linewidth}|p{0.15\linewidth}|
|
| 509 |
+
.. table:: Accurate coil descriptions
|
| 510 |
+
:name: accurate_coil_descriptions
|
| 511 |
+
|
| 512 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 513 |
+
| Id | Description | n | r/mm | w |
|
| 514 |
+
+======+=========================+====+==================================+======================+
|
| 515 |
+
| 2 | Neuromag-122 planar | 8 | +/-(8.1, 0, 0) mm | +/-1 ⁄ 16.2mm |
|
| 516 |
+
| | gradiometer | | | |
|
| 517 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 518 |
+
| 2000 | A point magnetometer | 1 | (0, 0, 0) mm | 1 |
|
| 519 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 520 |
+
| 3012 | Vectorview type 1 | 2 | (+/-8.4, 0, 0.3) mm | +/-1 ⁄ 16.8mm |
|
| 521 |
+
| | planar gradiometer | | | |
|
| 522 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 523 |
+
| 3013 | Vectorview type 2 | 2 | (+/-8.4, 0, 0.3) mm | +/-1 ⁄ 16.8mm |
|
| 524 |
+
| | planar gradiometer | | | |
|
| 525 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 526 |
+
| 3022 | Vectorview type 1 | 4 | (+/-6.45, +/-6.45, 0.3)mm | 1/4 |
|
| 527 |
+
| | magnetometer | | | |
|
| 528 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 529 |
+
| 3023 | Vectorview type 2 | 4 | (+/-6.45, +/-6.45, 0.3)mm | 1/4 |
|
| 530 |
+
| | magnetometer | | | |
|
| 531 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 532 |
+
| 3024 | Vectorview type 3 | 4 | (+/-5.25, +/-5.25, 0.3)mm | 1/4 |
|
| 533 |
+
| | magnetometer | | | |
|
| 534 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 535 |
+
| 4001 | Magnes WH magnetometer | 4 | (+/-5.75, +/-5.75, 0.0)mm | 1/4 |
|
| 536 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 537 |
+
| 4002 | Magnes WH 3600 | 4 | (+/-4.5, +/-4.5, 0.0)mm | 1/4 |
|
| 538 |
+
| | axial gradiometer | | (+/-4.5, +/-4.5, 0.0)mm | -1/4 |
|
| 539 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 540 |
+
| 4004 | Magnes reference | 8 | (+/-20, +/-20, 0.0)mm | 1/4 |
|
| 541 |
+
| | gradiometer measuring | | (+/-20, +/-20, 135)mm | -1/4 |
|
| 542 |
+
| | diagonal gradients | | | |
|
| 543 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 544 |
+
| 4005 | Magnes reference | 8 | (87.5, +/-20, 0.0)mm | 1/4 |
|
| 545 |
+
| | gradiometer measuring | | (47.5, +/-20, 0.0)mm | -1/4 |
|
| 546 |
+
| | off-diagonal gradients | | (-87.5, +/-20, 0.0)mm | 1/4 |
|
| 547 |
+
| | | | (-47.5, +/-20, 0.0)mm | -1/4 |
|
| 548 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 549 |
+
| 5001 | CTF 275 axial | 8 | (+/-4.5, +/-4.5, 0.0)mm | 1/4 |
|
| 550 |
+
| | gradiometer | | (+/-4.5, +/-4.5, 50.0)mm | -1/4 |
|
| 551 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 552 |
+
| 5002 | CTF reference | 4 | (+/-4, +/-4, 0.0)mm | 1/4 |
|
| 553 |
+
| | magnetometer | | | |
|
| 554 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 555 |
+
| 5003 | CTF 275 reference | 8 | (+/-8.6, +/-8.6, 0.0)mm | 1/4 |
|
| 556 |
+
| | gradiometer measuring | | (+/-8.6, +/-8.6, 78.6)mm | -1/4 |
|
| 557 |
+
| | diagonal gradients | | | |
|
| 558 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 559 |
+
| 5004 | CTF 275 reference | 8 | (47.8, +/-8.5, 0.0)mm | 1/4 |
|
| 560 |
+
| | gradiometer measuring | | (30.8, +/-8.5, 0.0)mm | -1/4 |
|
| 561 |
+
| | off-diagonal gradients | | (-47.8, +/-8.5, 0.0)mm | 1/4 |
|
| 562 |
+
| | | | (-30.8, +/-8.5, 0.0)mm | -1/4 |
|
| 563 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 564 |
+
| 6001 | MIT KIT system axial | 8 | (+/-3.875, +/-3.875, 0.0)mm | 1/4 |
|
| 565 |
+
| | gradiometer | | (+/-3.875, +/-3.875, 0.0)mm | -1/4 |
|
| 566 |
+
+------+-------------------------+----+----------------------------------+----------------------+
|
| 567 |
+
|
| 568 |
+
|
| 569 |
+
.. _coil_definition_file:
|
| 570 |
+
|
| 571 |
+
The coil definition file
|
| 572 |
+
------------------------
|
| 573 |
+
|
| 574 |
+
The coil geometry information is stored in the text file
|
| 575 |
+
:file:`{$MNE_ROOT}/share/mne/coil_def.dat`. In this file, any lines starting
|
| 576 |
+
with the pound sign (#) are comments. A coil definition starts with a
|
| 577 |
+
description line containing the following fields:
|
| 578 |
+
|
| 579 |
+
- :samp:`{<class>}`: A number indicating class of this coil.
|
| 580 |
+
|
| 581 |
+
- :samp:`{<id>}`: Coil ID value. This value is listed in the first column of
|
| 582 |
+
Tables :ref:`normal_coil_descriptions` and :ref:`accurate_coil_descriptions`.
|
| 583 |
+
|
| 584 |
+
- :samp:`{<accuracy>}`: The coil representation accuracy. Possible values and
|
| 585 |
+
their meanings are listed in :ref:`coil_accuracies`.
|
| 586 |
+
|
| 587 |
+
- :samp:`{<np>}`: Number of integration points in this representation.
|
| 588 |
+
|
| 589 |
+
- :samp:`{<size/m>}`: The size of the coil. For circular coils this is the
|
| 590 |
+
diameter of the coil and for square ones the side length of the square. This
|
| 591 |
+
information is mainly included to facilitate drawing of the coil geometry. It
|
| 592 |
+
should not be employed to infer a coil approximation for the forward
|
| 593 |
+
calculations.
|
| 594 |
+
|
| 595 |
+
- :samp:`{<baseline/m>}`: The baseline of a this kind of a coil. This will be
|
| 596 |
+
zero for magnetometer coils. This information is mainly included to
|
| 597 |
+
facilitate drawing of the coil geometry. It should not be employed to infer
|
| 598 |
+
a coil approximation for the forward calculations.
|
| 599 |
+
|
| 600 |
+
- :samp:`{<description>}`: Short description of this kind of a coil. If the
|
| 601 |
+
description contains several words, it is enclosed in quotes.
|
| 602 |
+
|
| 603 |
+
|
| 604 |
+
.. tabularcolumns:: |p{0.1\linewidth}|p{0.5\linewidth}|
|
| 605 |
+
.. table:: Coil representation accuracies
|
| 606 |
+
:name: coil_accuracies
|
| 607 |
+
|
| 608 |
+
======= ====================================================================================
|
| 609 |
+
Value Meaning
|
| 610 |
+
======= ====================================================================================
|
| 611 |
+
1 The simplest representation available
|
| 612 |
+
2 The standard or *normal* representation (see :ref:`normal_coil_descriptions`)
|
| 613 |
+
3 The most *accurate* representation available (see :ref:`accurate_coil_descriptions`)
|
| 614 |
+
======= ====================================================================================
|
| 615 |
+
|
| 616 |
+
Each coil description line is followed by one or more integration point lines,
|
| 617 |
+
consisting of seven numbers:
|
| 618 |
+
|
| 619 |
+
- :samp:`{<weight>}`: Gives the weight for this integration point (last column
|
| 620 |
+
in Tables :ref:`normal_coil_descriptions` and
|
| 621 |
+
:ref:`accurate_coil_descriptions`).
|
| 622 |
+
|
| 623 |
+
- :samp:`{<x/m>} {<y/m>} {<z/m>}`: Indicates the location of the integration
|
| 624 |
+
point (fourth column in Tables :ref:`normal_coil_descriptions` and
|
| 625 |
+
:ref:`accurate_coil_descriptions`).
|
| 626 |
+
|
| 627 |
+
- :samp:`{<nx>} {<ny>} {<nz>}`: Components of a unit vector indicating the
|
| 628 |
+
field component to be selected. Note that listing a separate unit vector for
|
| 629 |
+
each integration points allows the implementation of curved coils and coils
|
| 630 |
+
with the gradiometer loops tilted with respect to each other.
|
| 631 |
+
|
| 632 |
+
|
| 633 |
+
Computing the forward solution
|
| 634 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 635 |
+
|
| 636 |
+
Purpose
|
| 637 |
+
-------
|
| 638 |
+
|
| 639 |
+
Examples on how to compute the forward solution in MNE-Python using
|
| 640 |
+
:func:`mne.make_forward_solution` can be found
|
| 641 |
+
:ref:`plot_forward_compute_forward_solution` and
|
| 642 |
+
:ref:`computing_the_forward_solution`.
|
| 643 |
+
|
| 644 |
+
Implementation of software gradient compensation
|
| 645 |
+
------------------------------------------------
|
| 646 |
+
|
| 647 |
+
Accounting for noise cancellation in MNE-Python is accomplished in
|
| 648 |
+
:meth:`mne.io.Raw.apply_gradient_compensation`. See
|
| 649 |
+
:ref:`plot_brainstorm_phantom_ctf` for an example.
|
| 650 |
+
|
| 651 |
+
CTF and 4D Neuroimaging data may have been subjected to noise cancellation
|
| 652 |
+
employing the data from the reference sensor array. Even though these sensor
|
| 653 |
+
are rather far away from the brain sources, :func:`mne.make_forward_solution`
|
| 654 |
+
takes them into account in the computations. If the data file has software
|
| 655 |
+
gradient compensation activated, it computes the field of at the reference
|
| 656 |
+
sensors in addition to the main MEG sensor array and computes a compensated
|
| 657 |
+
forward solution.
|
| 658 |
+
|
| 659 |
+
The EEG sphere model definition file
|
| 660 |
+
------------------------------------
|
| 661 |
+
|
| 662 |
+
In MNE-Python, different sphere models can be specified through
|
| 663 |
+
:func:`mne.make_sphere_model`. The default model has the following structure:
|
| 664 |
+
|
| 665 |
+
.. tabularcolumns:: |p{0.1\linewidth}|p{0.25\linewidth}|p{0.2\linewidth}|
|
| 666 |
+
.. table:: Structure of the default EEG model
|
| 667 |
+
|
| 668 |
+
======== ======================= =======================
|
| 669 |
+
Layer Relative outer radius :math:`\sigma` (S/m)
|
| 670 |
+
======== ======================= =======================
|
| 671 |
+
Head 1.0 0.33
|
| 672 |
+
Skull 0.97 0.04
|
| 673 |
+
CSF 0.92 1.0
|
| 674 |
+
Brain 0.90 0.33
|
| 675 |
+
======== ======================= =======================
|
| 676 |
+
|
| 677 |
+
Although it is not BEM model per se the ``sphere`` structure describes the head
|
| 678 |
+
geometry so it can be passed as ``bem`` parameter in MNE-Python functions such
|
| 679 |
+
as :func:`mne.fit_dipole`, :func:`mne.viz.plot_alignment` or
|
| 680 |
+
:func:`mne.make_forward_solution`.
|
| 681 |
+
|
| 682 |
+
.. _eeg_sphere_model:
|
| 683 |
+
|
| 684 |
+
EEG forward solution in the sphere model
|
| 685 |
+
----------------------------------------
|
| 686 |
+
|
| 687 |
+
.. note:: Sphere-model examples in MNE-Python
|
| 688 |
+
:class: sidebar
|
| 689 |
+
|
| 690 |
+
For examples of using the sphere model when computing the forward model
|
| 691 |
+
(using :func:`mne.make_forward_solution`), see :ref:`Brainstorm CTF phantom
|
| 692 |
+
dataset tutorial <plt_brainstorm_phantom_ctf_eeg_sphere_geometry>`,
|
| 693 |
+
:ref:`Brainstorm Elekta phantom dataset tutorial
|
| 694 |
+
<plt_brainstorm_phantom_elekta_eeg_sphere_geometry>`, and
|
| 695 |
+
:ref:`tut-source-alignment-without-mri`.
|
| 696 |
+
|
| 697 |
+
When the sphere model is employed, the computation of the EEG solution can be
|
| 698 |
+
substantially accelerated by using approximation methods described by Mosher
|
| 699 |
+
:footcite:`MosherEtAl1999`, Zhang :footcite:`Zhang1995`, and Berg
|
| 700 |
+
:footcite:`BergScherg1994`.
|
| 701 |
+
:func:`mne.make_forward_solution` approximates the solution with three dipoles
|
| 702 |
+
in a homogeneous sphere whose locations and amplitudes are determined by
|
| 703 |
+
minimizing the cost function:
|
| 704 |
+
|
| 705 |
+
.. math::
|
| 706 |
+
S(r_1,\dotsc,r_m\ ,\ \mu_1,\dotsc,\mu_m) = \int_{scalp} {(V_{true} - V_{approx})}\,dS
|
| 707 |
+
|
| 708 |
+
where :math:`r_1,\dotsc,r_m` and :math:`\mu_1,\dotsc,\mu_m` are the locations
|
| 709 |
+
and amplitudes of the approximating dipoles and :math:`V_{true}` and
|
| 710 |
+
:math:`V_{approx}` are the potential distributions given by the true and
|
| 711 |
+
approximative formulas, respectively. It can be shown that this integral can be
|
| 712 |
+
expressed in closed form using an expansion of the potentials in spherical
|
| 713 |
+
harmonics. The formula is evaluated for the most superficial dipoles, *i.e.*,
|
| 714 |
+
those lying just inside the inner skull surface.
|
| 715 |
+
|
| 716 |
+
Averaging forward solutions
|
| 717 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 718 |
+
|
| 719 |
+
One possibility to make a grand average over several runs of a experiment is to
|
| 720 |
+
average the data across runs and average the forward solutions accordingly. For
|
| 721 |
+
this purpose, :func:`mne.average_forward_solutions` computes a weighted average
|
| 722 |
+
of several forward solutions. The function averages both MEG and EEG forward
|
| 723 |
+
solutions. Usually the EEG forward solution is identical across runs because
|
| 724 |
+
the electrode locations do not change.
|
| 725 |
+
|
| 726 |
+
.. target for :end-before: forward-end-content
|
mne-python/source/doc/_includes/ged.rst
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Generalized eigendecomposition in decoding
|
| 4 |
+
==========================================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 7 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 8 |
+
to :ref:`ged` to link to that section of the implementation.rst page.
|
| 9 |
+
The next line is a target for :start-after: so we can omit the title from
|
| 10 |
+
the include:
|
| 11 |
+
ged-begin-content
|
| 12 |
+
|
| 13 |
+
This section describes the mathematical formulation and application of
|
| 14 |
+
Generalized Eigendecomposition (GED), often used in spatial filtering
|
| 15 |
+
and source separation algorithms, such as :class:`mne.decoding.CSP`,
|
| 16 |
+
:class:`mne.decoding.SPoC`, :class:`mne.decoding.SSD` and
|
| 17 |
+
:class:`mne.decoding.XdawnTransformer`.
|
| 18 |
+
|
| 19 |
+
The core principle of GED is to find a set of channel weights (spatial filter)
|
| 20 |
+
that maximizes the ratio of signal power between two data features.
|
| 21 |
+
These features are defined by the researcher and are represented by two covariance matrices:
|
| 22 |
+
a "signal" matrix :math:`S` and a "reference" matrix :math:`R`.
|
| 23 |
+
For example, :math:`S` could be the covariance of data from a task time interval,
|
| 24 |
+
and :math:`S` could be the covariance from a baseline time interval. For more details see :footcite:`Cohen2022`.
|
| 25 |
+
|
| 26 |
+
Algebraic formulation of GED
|
| 27 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 28 |
+
|
| 29 |
+
A few definitions first:
|
| 30 |
+
Let :math:`n \in \mathbb{N}^+` be a number of channels.
|
| 31 |
+
Let :math:`\text{Symm}_n(\mathbb{R}) \subset M_n(\mathbb{R})` be a vector space of real symmetric matrices.
|
| 32 |
+
Let :math:`S^n_+, S^n_{++} \subset \text{Symm}_n(\mathbb{R})` be sets of real positive semidefinite and positive definite matrices, respectively.
|
| 33 |
+
Let :math:`S, R \in S^n_+` be covariance matrices estimated from electrophysiological data :math:`X_S \in M_{n \times t_S}(\mathbb{R})` and :math:`X_R \in M_{n \times t_R}(\mathbb{R})`.
|
| 34 |
+
|
| 35 |
+
GED (or simultaneous diagonalization by congruence) of :math:`S` and :math:`R`
|
| 36 |
+
is possible when :math:`R` is full rank (and thus :math:`R \in S^n_{++}`):
|
| 37 |
+
|
| 38 |
+
.. math::
|
| 39 |
+
|
| 40 |
+
SW = RWD,
|
| 41 |
+
|
| 42 |
+
where :math:`W \in M_n(\mathbb{R})` is an invertible matrix of eigenvectors
|
| 43 |
+
of :math:`(S, R)` and :math:`D` is a diagonal matrix of eigenvalues :math:`\lambda_i`.
|
| 44 |
+
|
| 45 |
+
Each eigenvector :math:`\mathbf{w} \in W` is a spatial filter that solves
|
| 46 |
+
an optimization problem of the form:
|
| 47 |
+
|
| 48 |
+
.. math::
|
| 49 |
+
|
| 50 |
+
\operatorname{argmax}_{\mathbf{w}} \frac{\mathbf{w}^t S \mathbf{w}}{\mathbf{w}^t R \mathbf{w}}
|
| 51 |
+
|
| 52 |
+
That is, using spatial filters :math:`W` on time-series :math:`X \in M_{n \times t}(\mathbb{R})`:
|
| 53 |
+
|
| 54 |
+
.. math::
|
| 55 |
+
|
| 56 |
+
\mathbf{A} = W^t X,
|
| 57 |
+
|
| 58 |
+
results in "activation" time-series :math:`A` of the estimated "sources",
|
| 59 |
+
such that the ratio of their variances,
|
| 60 |
+
:math:`\frac{\text{Var}(\mathbf{w}^T X_S)}{\text{Var}(\mathbf{w}^T X_R)} = \frac{\mathbf{w}^T S \mathbf{w}}{\mathbf{w}^T R \mathbf{w}}`,
|
| 61 |
+
is sequentially maximized spatial filters :math:`\mathbf{w}_i`, sorted according to :math:`\lambda_i`.
|
| 62 |
+
|
| 63 |
+
GED in the principal subspace
|
| 64 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 65 |
+
Unfortunately, :math:`R` might not be full rank depending on the data :math:`X_R` (for example due to average reference, removed PCA/ICA components, etc.).
|
| 66 |
+
In such cases, GED can be performed on :math:`S` and :math:`R` in the principal subspace :math:`Q = \operatorname{Im}(C_{ref}) \subset \mathbb{R}^n` of some reference
|
| 67 |
+
covariance :math:`C_{ref}` (in Common Spatial Pattern (CSP) algorithm, for example, :math:`C_{ref}=\frac{1}{2}(S+R)` and GED is performed on S and R'=S+R).
|
| 68 |
+
|
| 69 |
+
More formally:
|
| 70 |
+
Let :math:`r \leq n` be a rank of :math:`C \in S^n_+`.
|
| 71 |
+
Let :math:`Q=\operatorname{Im}(C_{ref})` be a principal subspace of :math:`C_{ref}`.
|
| 72 |
+
Let :math:`P \in M_{n \times r}(\mathbb{R})` be an isometry formed by orthonormal basis of :math:`Q`.
|
| 73 |
+
Let :math:`f:S^n_+ \to S^r_+`, :math:`A \mapsto P^t A P` be a "restricting" map, that restricts quadratic form
|
| 74 |
+
:math:`q_A:\mathbb{R}^n \to \mathbb{R}` to :math:`q_{A|_Q}:\mathbb{R}^n \to \mathbb{R}` (in practical terms, :math:`q_A` maps
|
| 75 |
+
spatial filters to variance of the spatially filtered data :math:`X_A`).
|
| 76 |
+
|
| 77 |
+
Then, the GED of :math:`S` and :math:`R` in the principal subspace :math:`Q` of :math:`C_{ref}` is performed as follows:
|
| 78 |
+
|
| 79 |
+
1. :math:`S` and :math:`R` are transformed to :math:`S_Q = f(S) = P^t S P` and :math:`R_Q = f(R) = P^t R P`,
|
| 80 |
+
such that :math:`S_Q` and :math:`R_Q` are matrix representations of restricted :math:`q_{S|_Q}` and :math:`q_{R|_Q}`.
|
| 81 |
+
2. GED is performed on :math:`S_Q` and :math:`R_Q`: :math:`S_Q W_Q = R_Q W_Q D`.
|
| 82 |
+
3. Eigenvectors :math:`W_Q` of :math:`(S_Q, R_Q)` are transformed back to :math:`\mathbb{R}^n`
|
| 83 |
+
by :math:`W = P W_Q \in \mathbb{R}^{n \times r}` to obtain :math:`r` spatial filters.
|
| 84 |
+
|
| 85 |
+
Note that the solution to the original optimization problem is preserved:
|
| 86 |
+
|
| 87 |
+
.. math::
|
| 88 |
+
|
| 89 |
+
\frac{\mathbf{w_Q}^t S_Q \mathbf{w_Q}}{\mathbf{w_Q}^t R_Q \mathbf{w_Q}}= \frac{\mathbf{w_Q}^t (P^t S P) \mathbf{w_Q}}{\mathbf{w_Q}^t (P^t R P)
|
| 90 |
+
\mathbf{w_Q}} = \frac{\mathbf{w}^t S \mathbf{w}}{\mathbf{w}^t R \mathbf{w}} = \lambda
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
In addition to restriction, :math:`q_S` and :math:`q_R` can be rescaled based on the whitened :math:`C_{ref}`.
|
| 94 |
+
In this case the whitening map :math:`f_{wh}:S^n_+ \to S^r_+`,
|
| 95 |
+
:math:`A \mapsto P_{wh}^t A P_{wh}` transforms :math:`A` into matrix representation of :math:`q_{A|Q}` rescaled according to :math:`\Lambda^{-1/2}`,
|
| 96 |
+
where :math:`\Lambda` is a diagonal matrix of eigenvalues of :math:`C_{ref}` and so :math:`P_{wh} = P \Lambda^{-1/2}`.
|
| 97 |
+
|
| 98 |
+
In MNE-Python, the matrix :math:`P` of the restricting map can be obtained using
|
| 99 |
+
::
|
| 100 |
+
|
| 101 |
+
_, ref_evecs, mask = mne.cov._smart_eigh(C_ref, ..., proj_subspace=True, ...)
|
| 102 |
+
restr_mat = ref_evecs[mask]
|
| 103 |
+
|
| 104 |
+
while :math:`P_{wh}` using:
|
| 105 |
+
::
|
| 106 |
+
|
| 107 |
+
restr_mat = compute_whitener(C_ref, ..., pca=True, ...)
|
mne-python/source/doc/_includes/institutional-partners.rst
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Institutional partners
|
| 4 |
+
----------------------
|
| 5 |
+
|
| 6 |
+
.. NOTE: this file is included in doc/funding.rst and doc/overview/people.rst.
|
| 7 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 8 |
+
to :ref:`supporting-institutions` to link to that section of the funding.rst
|
| 9 |
+
page. The next line is a target for :start-after: so we can omit the title
|
| 10 |
+
from the include:
|
| 11 |
+
institutional-partners-begin-content
|
| 12 |
+
|
| 13 |
+
Current partners
|
| 14 |
+
~~~~~~~~~~~~~~~~
|
| 15 |
+
|
| 16 |
+
- `Aalto-yliopiston perustieteiden korkeakoulu <https://sci.aalto.fi/>`_
|
| 17 |
+
- `Donders Institute for Brain, Cognition and Behaviour at Radboud University <https://www.ru.nl/donders/>`_
|
| 18 |
+
- `Karl-Franzens-Universität Graz <https://www.uni-graz.at/>`_
|
| 19 |
+
- `University of Washington <https://www.washington.edu/>`_
|
| 20 |
+
|
| 21 |
+
Former partners
|
| 22 |
+
~~~~~~~~~~~~~~~
|
| 23 |
+
|
| 24 |
+
- `Aarhus Universitet <https://www.au.dk/>`_
|
| 25 |
+
- `AE Studio <https://ae.studio/>`_
|
| 26 |
+
- `Athinoula A. Martinos Center for Biomedical Imaging <https://martinos.org/>`_
|
| 27 |
+
- `Berkeley Institute for Data Science <https://bids.berkeley.edu/>`_
|
| 28 |
+
- `Boston University <https://www.bu.edu/>`_
|
| 29 |
+
- `Children’s Hospital of Philadelphia Research Institute <https://www.research.chop.edu/imaging/>`_
|
| 30 |
+
- `Commissariat à l’énergie atomique et aux énergies alternatives <https://www.cea.fr/>`_
|
| 31 |
+
- `Fondation Campus Biotech Geneva <https://fcbg.ch/>`_
|
| 32 |
+
- `Forschungszentrum Jülich <https://www.fz-juelich.de/>`_
|
| 33 |
+
- `Harvard Medical School <https://hms.harvard.edu/>`_
|
| 34 |
+
- `Institut du Cerveau et de la Moelle épinière <https://icm-institute.org/>`_
|
| 35 |
+
- `Institut national de la santé et de la recherche médicale <https://www.inserm.fr/>`_
|
| 36 |
+
- `Institut national de recherche en informatique et en automatique <https://www.inria.fr/>`_
|
| 37 |
+
- `Massachusetts General Hospital <https://www.massgeneral.org/>`_
|
| 38 |
+
- `Massachusetts Institute of Technology <https://web.mit.edu/>`_
|
| 39 |
+
- `Max-Planck-Institut für Bildungsforschung <https://www.mpib-berlin.mpg.de/>`_
|
| 40 |
+
- `Macquarie University <https://www.mq.edu.au/>`_
|
| 41 |
+
- `New York University <https://www.nyu.edu/>`_
|
| 42 |
+
- `SWPS Uniwersytet Humanistycznospołeczny <https://www.swps.pl/>`_
|
| 43 |
+
- `Technische Universität Ilmenau <https://www.tu-ilmenau.de/>`_
|
| 44 |
+
- `Télécom ParisTech <https://www.telecom-paris.fr/>`_
|
mne-python/source/doc/_includes/inverse.rst
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.. _ch_mne:
|
| 2 |
+
|
| 3 |
+
The minimum-norm current estimates
|
| 4 |
+
==================================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 7 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 8 |
+
to :ref:`ch_mne` to link to that section of the implementation.rst page.
|
| 9 |
+
The next line is a target for :start-after: so we can omit the title from
|
| 10 |
+
the include:
|
| 11 |
+
inverse-begin-content
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
This section describes the mathematical details of the calculation of
|
| 15 |
+
minimum-norm estimates. In Bayesian sense, the ensuing current distribution is
|
| 16 |
+
the maximum a posteriori (MAP) estimate under the following assumptions:
|
| 17 |
+
|
| 18 |
+
- The viable locations of the currents are constrained to the cortex.
|
| 19 |
+
Optionally, the current orientations can be fixed to be normal to the
|
| 20 |
+
cortical mantle.
|
| 21 |
+
|
| 22 |
+
- The amplitudes of the currents have a Gaussian prior distribution with a
|
| 23 |
+
known source covariance matrix.
|
| 24 |
+
|
| 25 |
+
- The measured data contain additive noise with a Gaussian distribution with a
|
| 26 |
+
known covariance matrix. The noise is not correlated over time.
|
| 27 |
+
|
| 28 |
+
Computing the inverse operator is accomplished using
|
| 29 |
+
:func:`mne.minimum_norm.make_inverse_operator` and
|
| 30 |
+
:func:`mne.minimum_norm.apply_inverse`. The use of these functions is presented
|
| 31 |
+
in the tutorial :ref:`tut-inverse-methods`.
|
| 32 |
+
|
| 33 |
+
The linear inverse operator
|
| 34 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 35 |
+
|
| 36 |
+
The measured data in the source estimation procedure consists of MEG and EEG
|
| 37 |
+
data, recorded on a total of N channels. The task is to estimate a total of
|
| 38 |
+
:math:`Q`
|
| 39 |
+
strengths of sources located on the cortical mantle. If the number of source
|
| 40 |
+
locations is :math:`P`, :math:`Q = P` for fixed-orientation sources and
|
| 41 |
+
:math:`Q = 3P` if the source
|
| 42 |
+
orientations are unconstrained. The regularized linear inverse operator
|
| 43 |
+
following from regularized maximal likelihood of the above probabilistic model
|
| 44 |
+
is given by the :math:`Q \times N` matrix
|
| 45 |
+
|
| 46 |
+
.. math:: M = R' G^\top (G R' G^\top + C)^{-1}\ ,
|
| 47 |
+
|
| 48 |
+
where :math:`G` is the gain matrix relating the source strengths to the measured
|
| 49 |
+
MEG/EEG data, :math:`C` is the data noise-covariance matrix and :math:`R'` is
|
| 50 |
+
the source covariance matrix. The dimensions of these matrices are :math:`N
|
| 51 |
+
\times Q`, :math:`N \times N`, and :math:`Q \times Q`, respectively. The
|
| 52 |
+
:math:`Q \times 1` source-strength vector is obtained by multiplying the
|
| 53 |
+
:math:`Q \times 1` data vector by :math:`Q`.
|
| 54 |
+
|
| 55 |
+
The expected value of the current amplitudes at time *t* is then given by
|
| 56 |
+
:math:`\hat{j}(t) = Mx(t)`, where :math:`x(t)` is a vector containing the
|
| 57 |
+
measured MEG and EEG data values at time *t*.
|
| 58 |
+
|
| 59 |
+
For computational convenience, the linear inverse operator is
|
| 60 |
+
not computed explicitly. See :ref:`mne_solution` for mathematical
|
| 61 |
+
details, and :ref:`CIHCFJEI` for a detailed example.
|
| 62 |
+
|
| 63 |
+
.. _mne_regularization:
|
| 64 |
+
|
| 65 |
+
Regularization
|
| 66 |
+
~~~~~~~~~~~~~~
|
| 67 |
+
|
| 68 |
+
The a priori variance of the currents is, in practice, unknown. We can express
|
| 69 |
+
this by writing :math:`R' = R/ \lambda^2 = R \lambda^{-2}`, which yields the
|
| 70 |
+
inverse operator
|
| 71 |
+
|
| 72 |
+
.. math::
|
| 73 |
+
:name: inv_m
|
| 74 |
+
|
| 75 |
+
M &= R' G^\top (G R' G^\top + C)^{-1} \\
|
| 76 |
+
&= R \lambda^{-2} G^\top (G R \lambda^{-2} G^\top + C)^{-1} \\
|
| 77 |
+
&= R \lambda^{-2} G^\top \lambda^2 (G R G^\top + \lambda^2 C)^{-1} \\
|
| 78 |
+
&= R G^\top (G R G^\top + \lambda^2 C)^{-1}\ ,
|
| 79 |
+
|
| 80 |
+
where the unknown current amplitude is now interpreted in terms of the
|
| 81 |
+
regularization parameter :math:`\lambda^2`. Larger :math:`\lambda^2` values
|
| 82 |
+
correspond to spatially smoother and weaker current amplitudes, whereas smaller
|
| 83 |
+
:math:`\lambda^2` values lead to the opposite.
|
| 84 |
+
|
| 85 |
+
We can arrive at the regularized linear inverse operator also by minimizing a
|
| 86 |
+
cost function :math:`S` with respect to the estimated current :math:`\hat{j}`
|
| 87 |
+
(given the measurement vector :math:`x` at any given time :math:`t`) as
|
| 88 |
+
|
| 89 |
+
.. math::
|
| 90 |
+
|
| 91 |
+
\min_\hat{j} \Bigl\{ S \Bigr\} &= \min_\hat{j} \Bigl\{ \tilde{e}^\top \tilde{e} + \lambda^2 \hat{j}^\top R^{-1} \hat{j} \Bigr\} \\
|
| 92 |
+
&= \min_\hat{j} \Bigl\{ (x - G\hat{j})^\top C^{-1} (x - G\hat{j}) + \lambda^2 \hat{j}^\top R^{-1} \hat{j} \Bigr\} \,
|
| 93 |
+
|
| 94 |
+
where the first term consists of the difference between the whitened measured
|
| 95 |
+
data (see :ref:`whitening_and_scaling`) and those predicted by the model while the
|
| 96 |
+
second term is a weighted-norm of the current estimate. It is seen that, with
|
| 97 |
+
increasing :math:`\lambda^2`, the source term receive more weight and larger
|
| 98 |
+
discrepancy between the measured and predicted data is tolerable.
|
| 99 |
+
|
| 100 |
+
.. _whitening_and_scaling:
|
| 101 |
+
|
| 102 |
+
Whitening and scaling
|
| 103 |
+
~~~~~~~~~~~~~~~~~~~~~
|
| 104 |
+
|
| 105 |
+
The MNE software employs data whitening so that a 'whitened' inverse operator
|
| 106 |
+
assumes the form
|
| 107 |
+
|
| 108 |
+
.. math:: \tilde{M} = M C^{^1/_2} = R \tilde{G}^\top (\tilde{G} R \tilde{G}^\top + \lambda^2 I)^{-1}\ ,
|
| 109 |
+
:name: inv_m_tilde
|
| 110 |
+
|
| 111 |
+
where
|
| 112 |
+
|
| 113 |
+
.. math:: \tilde{G} = C^{-^1/_2}G
|
| 114 |
+
:name: inv_g_tilde
|
| 115 |
+
|
| 116 |
+
is the spatially whitened gain matrix. We arrive at the whitened inverse
|
| 117 |
+
operator equation :eq:`inv_m_tilde` by making the substitution for
|
| 118 |
+
:math:`G` from :eq:`inv_g_tilde` in :eq:`inv_m` as
|
| 119 |
+
|
| 120 |
+
.. math::
|
| 121 |
+
|
| 122 |
+
\tilde{M} = M C^{^1/_2} &= R G^\top (G R G^\top + \lambda^2 C)^{-1} C^{^1/_2} \\
|
| 123 |
+
&= R \tilde{G}^\top C^{^1/_2} (C^{^1/_2} \tilde{G} R \tilde{G}^\top C^{^1/_2} + \lambda^2 C)^{-1} C^{^1/_2} \\
|
| 124 |
+
&= R \tilde{G}^\top C^{^1/_2} (C^{^1/_2} (\tilde{G} R \tilde{G}^\top + \lambda^2 I) C^{^1/_2})^{-1} C^{^1/_2} \\
|
| 125 |
+
&= R \tilde{G}^\top C^{^1/_2} C^{-^1/_2} (\tilde{G} R \tilde{G}^\top + \lambda^2 I)^{-1} C^{-^1/_2} C^{^1/_2} \\
|
| 126 |
+
&= R \tilde{G}^\top (\tilde{G} R \tilde{G}^\top + \lambda^2 I)^{-1}\ .
|
| 127 |
+
|
| 128 |
+
The expected current values are
|
| 129 |
+
|
| 130 |
+
.. math::
|
| 131 |
+
:name: inv_j_hat_t
|
| 132 |
+
|
| 133 |
+
\hat{j}(t) &= Mx(t) \\
|
| 134 |
+
&= M C^{^1/_2} C^{-^1/_2} x(t) \\
|
| 135 |
+
&= \tilde{M} \tilde{x}(t)
|
| 136 |
+
|
| 137 |
+
knowing :eq:`inv_m_tilde` and taking
|
| 138 |
+
|
| 139 |
+
.. math::
|
| 140 |
+
:name: inv_tilde_x_t
|
| 141 |
+
|
| 142 |
+
\tilde{x}(t) = C^{-^1/_2}x(t)
|
| 143 |
+
|
| 144 |
+
as the whitened measurement vector at time *t*. The spatial
|
| 145 |
+
whitening operator :math:`C^{-^1/_2}` is obtained with the help of the
|
| 146 |
+
eigenvalue decomposition
|
| 147 |
+
:math:`C = U_C \Lambda_C^2 U_C^\top` as :math:`C^{-^1/_2} = \Lambda_C^{-1} U_C^\top`.
|
| 148 |
+
In the MNE software the noise-covariance matrix is stored as the one applying
|
| 149 |
+
to raw data. To reflect the decrease of noise due to averaging, this matrix,
|
| 150 |
+
:math:`C_0`, is scaled by the number of averages, :math:`L`, *i.e.*, :math:`C =
|
| 151 |
+
C_0 / L`.
|
| 152 |
+
|
| 153 |
+
.. note::
|
| 154 |
+
When EEG data are included, the gain matrix :math:`G` needs to be average referenced when computing the linear inverse operator :math:`M`. This is incorporated during creating the spatial whitening operator :math:`C^{-^1/_2}`, which includes any projectors on the data. EEG data average reference (using a projector) is mandatory for source modeling and is checked when calculating the inverse operator.
|
| 155 |
+
|
| 156 |
+
As shown above, regularization of the inverse solution is equivalent to a
|
| 157 |
+
change in the variance of the current amplitudes in the Bayesian *a priori*
|
| 158 |
+
distribution.
|
| 159 |
+
|
| 160 |
+
A convenient choice for the source-covariance matrix :math:`R` is such that
|
| 161 |
+
:math:`\text{trace}(\tilde{G} R \tilde{G}^\top) / \text{trace}(I) = 1`. With this
|
| 162 |
+
choice we can approximate :math:`\lambda^2 \sim 1/\rm{SNR}^2`, where SNR is the
|
| 163 |
+
(amplitude) signal-to-noise ratio of the whitened data.
|
| 164 |
+
|
| 165 |
+
.. note::
|
| 166 |
+
The definition of the signal to noise-ratio/ :math:`\lambda^2` relationship
|
| 167 |
+
given above works nicely for the whitened forward solution. In the
|
| 168 |
+
un-whitened case scaling with the trace ratio :math:`\text{trace}(GRG^\top) /
|
| 169 |
+
\text{trace}(C)` does not make sense, since the diagonal elements summed
|
| 170 |
+
have, in general, different units of measure. For example, the MEG data are
|
| 171 |
+
expressed in T or T/m whereas the unit of EEG is Volts.
|
| 172 |
+
|
| 173 |
+
See :ref:`tut-compute-covariance` for example of noise covariance computation
|
| 174 |
+
and whitening.
|
| 175 |
+
|
| 176 |
+
.. _cov_regularization_math:
|
| 177 |
+
|
| 178 |
+
Regularization of the noise-covariance matrix
|
| 179 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 180 |
+
|
| 181 |
+
Since finite amount of data is usually available to compute an estimate of the
|
| 182 |
+
noise-covariance matrix :math:`C`, the smallest eigenvalues of its estimate are
|
| 183 |
+
usually inaccurate and smaller than the true eigenvalues. Depending on the
|
| 184 |
+
seriousness of this problem, the following quantities can be affected:
|
| 185 |
+
|
| 186 |
+
- The model data predicted by the current estimate,
|
| 187 |
+
|
| 188 |
+
- Estimates of signal-to-noise ratios, which lead to estimates of the required
|
| 189 |
+
regularization, see :ref:`mne_regularization`,
|
| 190 |
+
|
| 191 |
+
- The estimated current values, and
|
| 192 |
+
|
| 193 |
+
- The noise-normalized estimates, see :ref:`noise_normalization`.
|
| 194 |
+
|
| 195 |
+
Fortunately, the latter two are least likely to be affected due to
|
| 196 |
+
regularization of the estimates. However, in some cases especially the EEG part
|
| 197 |
+
of the noise-covariance matrix estimate can be deficient, *i.e.*, it may
|
| 198 |
+
possess very small eigenvalues and thus regularization of the noise-covariance
|
| 199 |
+
matrix is advisable.
|
| 200 |
+
|
| 201 |
+
Historically, the MNE software accomplishes the regularization by replacing a
|
| 202 |
+
noise-covariance matrix estimate :math:`C` with
|
| 203 |
+
|
| 204 |
+
.. math:: C' = C + \sum_k {\varepsilon_k \bar{\sigma_k}^2 I^{(k)}}\ ,
|
| 205 |
+
|
| 206 |
+
where the index :math:`k` goes across the different channel groups (MEG planar
|
| 207 |
+
gradiometers, MEG axial gradiometers and magnetometers, and EEG),
|
| 208 |
+
:math:`\varepsilon_k` are the corresponding regularization factors,
|
| 209 |
+
:math:`\bar{\sigma_k}` are the average variances across the channel groups, and
|
| 210 |
+
:math:`I^{(k)}` are diagonal matrices containing ones at the positions
|
| 211 |
+
corresponding to the channels contained in each channel group.
|
| 212 |
+
|
| 213 |
+
See :ref:`plot_compute_covariance_howto` for details on computing and
|
| 214 |
+
regularizing the channel covariance matrix.
|
| 215 |
+
|
| 216 |
+
.. _mne_solution:
|
| 217 |
+
|
| 218 |
+
Computation of the solution
|
| 219 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 220 |
+
|
| 221 |
+
The most straightforward approach to calculate the MNE is to employ the
|
| 222 |
+
expression of the original or whitened inverse operator directly. However, for
|
| 223 |
+
computational convenience we prefer to take another route, which employs the
|
| 224 |
+
singular-value decomposition (SVD) of the matrix
|
| 225 |
+
|
| 226 |
+
.. math::
|
| 227 |
+
:name: inv_a
|
| 228 |
+
|
| 229 |
+
A &= \tilde{G} R^{^1/_2} \\
|
| 230 |
+
&= U \Lambda V^\top
|
| 231 |
+
|
| 232 |
+
where the superscript :math:`^1/_2` indicates a square root of :math:`R`. For a
|
| 233 |
+
diagonal matrix, one simply takes the square root of :math:`R` while in the
|
| 234 |
+
more general case one can use the Cholesky factorization :math:`R = R_C R_C^\top`
|
| 235 |
+
and thus :math:`R^{^1/_2} = R_C`.
|
| 236 |
+
|
| 237 |
+
Combining the SVD from :eq:`inv_a` with the inverse equation :eq:`inv_m` it is
|
| 238 |
+
easy to show that
|
| 239 |
+
|
| 240 |
+
.. math::
|
| 241 |
+
:name: inv_m_tilde_svd
|
| 242 |
+
|
| 243 |
+
\tilde{M} &= R \tilde{G}^\top (\tilde{G} R \tilde{G}^\top + \lambda^2 I)^{-1} \\
|
| 244 |
+
&= R^{^1/_2} A^\top (A A^\top + \lambda^2 I)^{-1} \\
|
| 245 |
+
&= R^{^1/_2} V \Lambda U^\top (U \Lambda V^\top V \Lambda U^\top + \lambda^2 I)^{-1} \\
|
| 246 |
+
&= R^{^1/_2} V \Lambda U^\top (U (\Lambda^2 + \lambda^2 I) U^\top)^{-1} \\
|
| 247 |
+
&= R^{^1/_2} V \Lambda U^\top U (\Lambda^2 + \lambda^2 I)^{-1} U^\top \\
|
| 248 |
+
&= R^{^1/_2} V \Lambda (\Lambda^2 + \lambda^2 I)^{-1} U^\top \\
|
| 249 |
+
&= R^{^1/_2} V \Gamma U^\top
|
| 250 |
+
|
| 251 |
+
where the elements of the diagonal matrix :math:`\Gamma` are simply
|
| 252 |
+
|
| 253 |
+
.. `reginv` in our code:
|
| 254 |
+
|
| 255 |
+
.. math::
|
| 256 |
+
:name: inv_gamma_k
|
| 257 |
+
|
| 258 |
+
\gamma_k = \frac{\lambda_k}{\lambda_k^2 + \lambda^2}\ .
|
| 259 |
+
|
| 260 |
+
From our expected current equation :eq:`inv_j_hat_t` and our whitened
|
| 261 |
+
measurement equation :eq:`inv_tilde_x_t`, if we take
|
| 262 |
+
|
| 263 |
+
.. math::
|
| 264 |
+
:name: inv_w_t
|
| 265 |
+
|
| 266 |
+
w(t) &= U^\top \tilde{x}(t) \\
|
| 267 |
+
&= U^\top C^{-^1/_2} x(t)\ ,
|
| 268 |
+
|
| 269 |
+
we can see that the expression for the expected current is just
|
| 270 |
+
|
| 271 |
+
.. math::
|
| 272 |
+
:name: inv_j_hat_t_svd
|
| 273 |
+
|
| 274 |
+
\hat{j}(t) &= R^{^1/_2} V \Gamma w(t) \\
|
| 275 |
+
&= \sum_k {\bar{v_k} \gamma_k w_k(t)}\ ,
|
| 276 |
+
|
| 277 |
+
where :math:`\bar{v_k} = R^{^1/_2} v_k`, with :math:`v_k` being the
|
| 278 |
+
:math:`k` th column of :math:`V`. It is thus seen that the current estimate is
|
| 279 |
+
a weighted sum of the "weighted" eigenleads :math:`v_k`.
|
| 280 |
+
|
| 281 |
+
It is easy to see that :math:`w(t) \propto \sqrt{L}`. To maintain the relation
|
| 282 |
+
:math:`(\tilde{G} R \tilde{G}^\top) / \text{trace}(I) = 1` when :math:`L` changes
|
| 283 |
+
we must have :math:`R \propto 1/L`. With this approach, :math:`\lambda_k` is
|
| 284 |
+
independent of :math:`L` and, for fixed :math:`\lambda`, we see directly that
|
| 285 |
+
:math:`j(t)` is independent of :math:`L`.
|
| 286 |
+
|
| 287 |
+
The minimum-norm estimate is computed using this procedure in
|
| 288 |
+
:func:`mne.minimum_norm.make_inverse_operator`, and its usage is illustrated
|
| 289 |
+
in :ref:`CIHCFJEI`.
|
| 290 |
+
|
| 291 |
+
|
| 292 |
+
.. _noise_normalization:
|
| 293 |
+
|
| 294 |
+
Noise normalization
|
| 295 |
+
~~~~~~~~~~~~~~~~~~~
|
| 296 |
+
|
| 297 |
+
Noise normalization serves three purposes:
|
| 298 |
+
|
| 299 |
+
- It converts the expected current value into a dimensionless statistical test
|
| 300 |
+
variable. Thus the resulting time and location dependent values are often
|
| 301 |
+
referred to as dynamic statistical parameter maps (dSPM).
|
| 302 |
+
|
| 303 |
+
- It reduces the location bias of the estimates. In particular, the tendency of
|
| 304 |
+
the MNE to prefer superficial currents is eliminated.
|
| 305 |
+
|
| 306 |
+
- The width of the point-spread function becomes less dependent on the source
|
| 307 |
+
location on the cortical mantle. The point-spread is defined as the MNE
|
| 308 |
+
resulting from the signals coming from a point current source (a current
|
| 309 |
+
dipole) located at a certain point on the cortex.
|
| 310 |
+
|
| 311 |
+
In practice, noise normalization is implemented as a division by the square
|
| 312 |
+
root of the estimated variance of each voxel. In computing these noise
|
| 313 |
+
normalization factors, it's convenient to reuse our "weighted eigenleads"
|
| 314 |
+
definition from equation :eq:`inv_j_hat_t` in matrix form as
|
| 315 |
+
|
| 316 |
+
.. math::
|
| 317 |
+
:name: inv_eigenleads_weighted
|
| 318 |
+
|
| 319 |
+
\bar{V} = R^{^1/_2} V\ .
|
| 320 |
+
|
| 321 |
+
dSPM
|
| 322 |
+
----
|
| 323 |
+
|
| 324 |
+
Noise-normalized linear estimates introduced by Dale et al.
|
| 325 |
+
:footcite:`DaleEtAl1999` require division of the expected current amplitude by
|
| 326 |
+
its variance. In practice, this requires the computation of the diagonal
|
| 327 |
+
elements of the following matrix, using SVD equation :eq:`inv_m_tilde` and
|
| 328 |
+
:eq:`inv_eigenleads_weighted`:
|
| 329 |
+
|
| 330 |
+
.. math::
|
| 331 |
+
|
| 332 |
+
M C M^\top &= M C^{^1/_2} C^{^1/_2} M^\top \\
|
| 333 |
+
&= \tilde{M} \tilde{M}^\top \\
|
| 334 |
+
&= R^{^1/_2} V \Gamma U^\top U \Gamma V^\top R^{^1/_2} \\
|
| 335 |
+
&= \bar{V} \Gamma^2 \bar{V}^\top\ .
|
| 336 |
+
|
| 337 |
+
Because we only care about the diagonal entries here, we can find the
|
| 338 |
+
variances for each source as
|
| 339 |
+
|
| 340 |
+
.. math::
|
| 341 |
+
|
| 342 |
+
\sigma_k^2 = \gamma_k^2
|
| 343 |
+
|
| 344 |
+
Under the conditions expressed at the end of :ref:`mne_solution`, it
|
| 345 |
+
follows that the *t*-statistic values associated with fixed-orientation
|
| 346 |
+
sources) are thus proportional to :math:`\sqrt{L}` while the *F*-statistic
|
| 347 |
+
employed with free-orientation sources is proportional to :math:`L`,
|
| 348 |
+
correspondingly.
|
| 349 |
+
|
| 350 |
+
.. note::
|
| 351 |
+
The MNE software usually computes the *square roots* of the F-statistic to
|
| 352 |
+
be displayed on the inflated cortical surfaces. These are also proportional
|
| 353 |
+
to :math:`\sqrt{L}`.
|
| 354 |
+
|
| 355 |
+
sLORETA
|
| 356 |
+
-------
|
| 357 |
+
sLORETA :footcite:`Pascual-Marqui2002` estimates the current variances as the
|
| 358 |
+
diagonal entries of the
|
| 359 |
+
resolution matrix, which is the product of the inverse and forward operators.
|
| 360 |
+
In other words, the diagonal entries of (using :eq:`inv_m_tilde_svd`,
|
| 361 |
+
:eq:`inv_g_tilde`, and :eq:`inv_a`)
|
| 362 |
+
|
| 363 |
+
.. math::
|
| 364 |
+
|
| 365 |
+
M G &= M C^{^1/_2} C^{-^1/_2} G \\
|
| 366 |
+
&= \tilde{M} \tilde{G} \\
|
| 367 |
+
&= R^{^1/_2} V \Gamma U^\top \tilde{G} R^{^1/_2} R^{-^1/_2} \\
|
| 368 |
+
&= R^{^1/_2} V \Gamma U^\top U \Lambda V^\top R^{-^1/_2} \\
|
| 369 |
+
&= R^{^1/_2} V \Gamma U^\top U \Lambda V^\top R^{^1/_2} R^{-1} \\
|
| 370 |
+
&= \bar{V} \Gamma U^\top U \Lambda \bar{V}^\top R^{-1} \\
|
| 371 |
+
&= \bar{V} \Gamma \Lambda \bar{V}^\top R^{-1}\ .
|
| 372 |
+
|
| 373 |
+
Because :math:`R` is diagonal and we only care about the diagonal entries,
|
| 374 |
+
we can find our variance estimates as
|
| 375 |
+
|
| 376 |
+
.. math::
|
| 377 |
+
|
| 378 |
+
\sigma_k^2 &= \gamma_k \lambda_k R_{k,k}^{-1} \\
|
| 379 |
+
&= \left(\frac{\lambda_k}{(\lambda_k^2 + \lambda^2)}\right) \left(\frac{\lambda_k}{1}\right) \left(\frac{1}{\lambda^2}\right) \\
|
| 380 |
+
&= \frac{\lambda_k^2}{(\lambda_k^2 + \lambda^2) \lambda^2} \\
|
| 381 |
+
&= \left(\frac{\lambda_k^2}{(\lambda_k^2 + \lambda^2)^2}\right) \left(\frac{\lambda^2 + \lambda_k^2}{\lambda^2}\right) \\
|
| 382 |
+
&= \left(\frac{\lambda_k}{\lambda_k^2 + \lambda^2}\right)^2 \left(1 + \frac{\lambda_k^2}{\lambda^2}\right) \\
|
| 383 |
+
&= \gamma_k^2 \left(1 + \frac{\lambda_k^2}{\lambda^2}\right)\ .
|
| 384 |
+
|
| 385 |
+
eLORETA
|
| 386 |
+
~~~~~~~
|
| 387 |
+
While dSPM and sLORETA solve for noise normalization weights
|
| 388 |
+
:math:`\sigma^2_k` that are applied to standard minimum-norm estimates
|
| 389 |
+
:math:`\hat{j}(t)`, eLORETA :footcite:`Pascual-Marqui2011` instead solves for
|
| 390 |
+
a source covariance
|
| 391 |
+
matrix :math:`R` that achieves zero localization bias. For fixed-orientation
|
| 392 |
+
solutions the resulting matrix :math:`R` will be a diagonal matrix, and for
|
| 393 |
+
free-orientation solutions it will be a block-diagonal matrix with
|
| 394 |
+
:math:`3 \times 3` blocks.
|
| 395 |
+
|
| 396 |
+
.. In https://royalsocietypublishing.org/doi/full/10.1098/rsta.2011.0081
|
| 397 |
+
.. eq. 2.10 (classical min norm), their values map onto our values as:
|
| 398 |
+
..
|
| 399 |
+
.. - α=λ²
|
| 400 |
+
.. - W=R⁻¹ (pos semidef weight matrix)
|
| 401 |
+
.. - K=G
|
| 402 |
+
.. - ϕ=x
|
| 403 |
+
.. - C=H
|
| 404 |
+
..
|
| 405 |
+
|
| 406 |
+
In :footcite:`Pascual-Marqui2011` eq. 2.13 states that the following system
|
| 407 |
+
of equations can be used to find the weights, :math:`\forall i \in {1, ..., P}`
|
| 408 |
+
(note that here we represent the equations from that paper using our notation):
|
| 409 |
+
|
| 410 |
+
.. math:: r_i = \left[ G_i^\top \left( GRG^\top + \lambda^2C \right)^{-1} G_i \right] ^{-^1/_2}
|
| 411 |
+
|
| 412 |
+
And an iterative algorithm can be used to find the values for the weights
|
| 413 |
+
:math:`r_i` that satisfy these equations as:
|
| 414 |
+
|
| 415 |
+
1. Initialize identity weights.
|
| 416 |
+
2. Compute :math:`N= \left( GRG^\top + \lambda^2C \right)^{-1}`.
|
| 417 |
+
3. Holding :math:`N` fixed, compute new weights :math:`r_i = \left[ G_i^\top N G_i \right]^{-^1/_2}`.
|
| 418 |
+
4. Using new weights, go to step (2) until convergence.
|
| 419 |
+
|
| 420 |
+
In particular, for step (2) we can use our substitution from :eq:`inv_g_tilde`
|
| 421 |
+
as:
|
| 422 |
+
|
| 423 |
+
.. math::
|
| 424 |
+
|
| 425 |
+
N &= (G R G^\top + \lambda^2 C)^{-1} \\
|
| 426 |
+
&= (C^{^1/_2} \tilde{G} R \tilde{G}^\top C^{^1/_2} + \lambda^2 C)^{-1} \\
|
| 427 |
+
&= (C^{^1/_2} (\tilde{G} R \tilde{G}^\top + \lambda^2 I) C^{^1/_2})^{-1} \\
|
| 428 |
+
&= C^{-^1/_2} (\tilde{G} R \tilde{G}^\top + \lambda^2 I)^{-1} C^{-^1/_2} \\
|
| 429 |
+
&= C^{-^1/_2} (\tilde{G} R \tilde{G}^\top + \lambda^2 I)^{-1} C^{-^1/_2}\ .
|
| 430 |
+
|
| 431 |
+
Then defining :math:`\tilde{N}` as the whitened version of :math:`N`, i.e.,
|
| 432 |
+
the regularized pseudoinverse of :math:`\tilde{G}R\tilde{G}^\top`, we can
|
| 433 |
+
compute :math:`N` as:
|
| 434 |
+
|
| 435 |
+
.. math::
|
| 436 |
+
|
| 437 |
+
N &= C^{-^1/_2} (U_{\tilde{G}R\tilde{G}^\top} \Lambda_{\tilde{G}R\tilde{G}^\top} V_{\tilde{G}R\tilde{G}^\top}^\top + \lambda^2 I)^{-1} C^{-^1/_2} \\
|
| 438 |
+
&= C^{-^1/_2} (U_{\tilde{G}R\tilde{G}^\top} (\Lambda_{\tilde{G}R\tilde{G}^\top} + \lambda^2 I) V_{\tilde{G}R\tilde{G}^\top}^\top)^{-1} C^{-^1/_2} \\
|
| 439 |
+
&= C^{-^1/_2} V_{\tilde{G}R\tilde{G}^\top} (\Lambda_{\tilde{G}R\tilde{G}^\top} + \lambda^2 I)^{-1} U_{\tilde{G}R\tilde{G}^\top}^\top C^{-^1/_2} \\
|
| 440 |
+
&= C^{-^1/_2} \tilde{N} C^{-^1/_2}\ .
|
| 441 |
+
|
| 442 |
+
In step (3) we left and right multiply with subsets of :math:`G`, but making
|
| 443 |
+
the substitution :eq:`inv_g_tilde` we see that we equivalently compute:
|
| 444 |
+
|
| 445 |
+
.. math::
|
| 446 |
+
|
| 447 |
+
r_i &= \left[ G_i^\top N G_i \right]^{-^1/_2} \\
|
| 448 |
+
&= \left[ (C^{^1/_2} \tilde{G}_i)^\top N C^{^1/_2} \tilde{G}_i \right]^{-^1/_2} \\
|
| 449 |
+
&= \left[ \tilde{G}_i^\top C^{^1/_2} N C^{^1/_2} \tilde{G}_i \right]^{-^1/_2} \\
|
| 450 |
+
&= \left[ \tilde{G}_i^\top C^{^1/_2} C^{-^1/_2} \tilde{N} C^{-^1/_2} C^{^1/_2} \tilde{G}_i \right]^{-^1/_2} \\
|
| 451 |
+
&= \left[ \tilde{G}_i^\top \tilde{N} \tilde{G}_i \right]^{-^1/_2}\ .
|
| 452 |
+
|
| 453 |
+
For convenience, we thus never need to compute :math:`N` itself but can instead
|
| 454 |
+
compute the whitened version :math:`\tilde{N}`.
|
| 455 |
+
|
| 456 |
+
Predicted data
|
| 457 |
+
~~~~~~~~~~~~~~
|
| 458 |
+
|
| 459 |
+
Under noiseless conditions the SNR is infinite and thus leads to
|
| 460 |
+
:math:`\lambda^2 = 0` and the minimum-norm estimate explains the measured data
|
| 461 |
+
perfectly. Under realistic conditions, however, :math:`\lambda^2 > 0` and there
|
| 462 |
+
is a misfit between measured data and those predicted by the MNE. Comparison of
|
| 463 |
+
the predicted data, here denoted by :math:`x(t)`, and measured one can give
|
| 464 |
+
valuable insight on the correctness of the regularization applied.
|
| 465 |
+
|
| 466 |
+
In the SVD approach we easily find
|
| 467 |
+
|
| 468 |
+
.. math:: \hat{x}(t) = G \hat{j}(t) = C^{^1/_2} U \Pi w(t)\ ,
|
| 469 |
+
|
| 470 |
+
where the diagonal matrix :math:`\Pi` has elements :math:`\pi_k = \lambda_k
|
| 471 |
+
\gamma_k` The predicted data is thus expressed as the weighted sum of the
|
| 472 |
+
'recolored eigenfields' in :math:`C^{^1/_2} U`.
|
| 473 |
+
|
| 474 |
+
Cortical patch statistics
|
| 475 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 476 |
+
|
| 477 |
+
If the ``add_dists=True`` option was used in source space creation,
|
| 478 |
+
the source space file will contain
|
| 479 |
+
Cortical Patch Statistics (CPS) for each vertex of the cortical surface. The
|
| 480 |
+
CPS provide information about the source space point closest to it as well as
|
| 481 |
+
the distance from the vertex to this source space point. The vertices for which
|
| 482 |
+
a given source space point is the nearest one define the cortical patch
|
| 483 |
+
associated with with the source space point. Once these data are available, it
|
| 484 |
+
is straightforward to compute the following cortical patch statistics for each
|
| 485 |
+
source location :math:`d`:
|
| 486 |
+
|
| 487 |
+
- The average over the normals of at the vertices in a patch,
|
| 488 |
+
:math:`\bar{n_d}`,
|
| 489 |
+
|
| 490 |
+
- The areas of the patches, :math:`A_d`, and
|
| 491 |
+
|
| 492 |
+
- The average deviation of the vertex normals in a patch from their average,
|
| 493 |
+
:math:`\sigma_d`, given in degrees.
|
| 494 |
+
|
| 495 |
+
``use_cps`` parameter in :func:`mne.convert_forward_solution`, and
|
| 496 |
+
:func:`mne.minimum_norm.make_inverse_operator` controls whether to use
|
| 497 |
+
cortical patch statistics (CPS) to define normal orientations or not (see
|
| 498 |
+
:ref:`CHDBBCEJ`).
|
| 499 |
+
|
| 500 |
+
.. _inverse_orientation_constraints:
|
| 501 |
+
|
| 502 |
+
Orientation constraints
|
| 503 |
+
~~~~~~~~~~~~~~~~~~~~~~~
|
| 504 |
+
|
| 505 |
+
The principal sources of MEG and EEG signals are generally believed to be
|
| 506 |
+
postsynaptic currents in the cortical pyramidal neurons. Since the net primary
|
| 507 |
+
current associated with these microscopic events is oriented normal to the
|
| 508 |
+
cortical mantle, it is reasonable to use the cortical normal orientation as a
|
| 509 |
+
constraint in source estimation. In addition to allowing completely free source
|
| 510 |
+
orientations, the MNE software implements three orientation constraints based
|
| 511 |
+
of the surface normal data:
|
| 512 |
+
|
| 513 |
+
- Source orientation can be rigidly fixed to the surface normal direction by
|
| 514 |
+
specifying ``fixed=True`` in :func:`mne.minimum_norm.make_inverse_operator`.
|
| 515 |
+
If cortical patch statistics are available the average
|
| 516 |
+
normal over each patch, :math:`\bar{n_d}`, are used to define the source
|
| 517 |
+
orientation. Otherwise, the vertex normal at the source space location is
|
| 518 |
+
employed.
|
| 519 |
+
|
| 520 |
+
- A *location independent or fixed loose orientation constraint* (fLOC) can be
|
| 521 |
+
employed by specifying ``fixed=False`` and ``loose=1.0`` when
|
| 522 |
+
calling :func:`mne.minimum_norm.make_inverse_operator` (see
|
| 523 |
+
:ref:`plot_dipole_orientations_fLOC_orientations`).
|
| 524 |
+
In this approach, a source coordinate
|
| 525 |
+
system based on the local surface orientation at the source location is
|
| 526 |
+
employed. By default, the three columns of the gain matrix G, associated with
|
| 527 |
+
a given source location, are the fields of unit dipoles pointing to the
|
| 528 |
+
directions of the :math:`x`, :math:`y`, and :math:`z` axis of the coordinate
|
| 529 |
+
system employed in the forward calculation (usually the :ref:`MEG head
|
| 530 |
+
coordinate frame <head_device_coords>`). For LOC the orientation is changed so
|
| 531 |
+
that the first two source components lie in the plane normal to the surface
|
| 532 |
+
normal at the source location and the third component is aligned with it.
|
| 533 |
+
Thereafter, the variance of the source components tangential to the cortical
|
| 534 |
+
surface are reduced by a factor defined by the ``--loose`` option.
|
| 535 |
+
|
| 536 |
+
- A *variable loose orientation constraint* (vLOC) can be employed by
|
| 537 |
+
specifying ``fixed=False`` and ``loose`` parameters when calling
|
| 538 |
+
:func:`mne.minimum_norm.make_inverse_operator` (see
|
| 539 |
+
:ref:`plot_dipole_orientations_vLOC_orientations`). This
|
| 540 |
+
is similar to *fLOC* except that the value given with the ``loose``
|
| 541 |
+
parameter will be multiplied by :math:`\sigma_d`, defined above.
|
| 542 |
+
|
| 543 |
+
Depth weighting
|
| 544 |
+
~~~~~~~~~~~~~~~
|
| 545 |
+
|
| 546 |
+
The minimum-norm estimates have a bias towards superficial currents. This
|
| 547 |
+
tendency can be alleviated by adjusting the source covariance matrix :math:`R`
|
| 548 |
+
to favor deeper source locations. In the depth weighting scheme employed in MNE
|
| 549 |
+
analyze, the elements of :math:`R` corresponding to the :math:`p` th source
|
| 550 |
+
location are be scaled by a factor
|
| 551 |
+
|
| 552 |
+
.. math:: f_p = (g_{1p}^\top g_{1p} + g_{2p}^\top g_{2p} + g_{3p}^\top g_{3p})^{-\gamma}\ ,
|
| 553 |
+
|
| 554 |
+
where :math:`g_{1p}`, :math:`g_{2p}`, and :math:`g_{3p}` are the three columns
|
| 555 |
+
of :math:`G` corresponding to source location :math:`p` and :math:`\gamma` is
|
| 556 |
+
the order of the depth weighting, which is specified via the ``depth`` option
|
| 557 |
+
in :func:`mne.minimum_norm.make_inverse_operator`.
|
| 558 |
+
|
| 559 |
+
Effective number of averages
|
| 560 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 561 |
+
|
| 562 |
+
It is often the case that the epoch to be analyzed is a linear combination over
|
| 563 |
+
conditions rather than one of the original averages computed. As stated above,
|
| 564 |
+
the noise-covariance matrix computed is originally one corresponding to raw
|
| 565 |
+
data. Therefore, it has to be scaled correctly to correspond to the actual or
|
| 566 |
+
effective number of epochs in the condition to be analyzed. In general, we have
|
| 567 |
+
|
| 568 |
+
.. math:: C = C_0 / L_{eff}
|
| 569 |
+
|
| 570 |
+
where :math:`L_{eff}` is the effective number of averages. To calculate
|
| 571 |
+
:math:`L_{eff}` for an arbitrary linear combination of conditions
|
| 572 |
+
|
| 573 |
+
.. math:: y(t) = \sum_{i = 1}^n {w_i x_i(t)}
|
| 574 |
+
|
| 575 |
+
we make use of the the fact that the noise-covariance matrix
|
| 576 |
+
|
| 577 |
+
.. math:: C_y = \sum_{i = 1}^n {w_i^2 C_{x_i}} = C_0 \sum_{i = 1}^n {w_i^2 / L_i}
|
| 578 |
+
|
| 579 |
+
which leads to
|
| 580 |
+
|
| 581 |
+
.. math:: 1 / L_{eff} = \sum_{i = 1}^n {w_i^2 / L_i}
|
| 582 |
+
|
| 583 |
+
An important special case of the above is a weighted average, where
|
| 584 |
+
|
| 585 |
+
.. math:: w_i = L_i / \sum_{i = 1}^n {L_i}
|
| 586 |
+
|
| 587 |
+
and, therefore
|
| 588 |
+
|
| 589 |
+
.. math:: L_{eff} = \sum_{i = 1}^n {L_i}
|
| 590 |
+
|
| 591 |
+
Instead of a weighted average, one often computes a weighted sum, a simplest
|
| 592 |
+
case being a difference or sum of two categories. For a difference :math:`w_1 =
|
| 593 |
+
1` and :math:`w_2 = -1` and thus
|
| 594 |
+
|
| 595 |
+
.. math:: 1 / L_{eff} = 1 / L_1 + 1 / L_2
|
| 596 |
+
|
| 597 |
+
or
|
| 598 |
+
|
| 599 |
+
.. math:: L_{eff} = \frac{L_1 L_2}{L_1 + L_2}
|
| 600 |
+
|
| 601 |
+
Interestingly, the same holds for a sum, where :math:`w_1 = w_2 = 1`.
|
| 602 |
+
Generalizing, for any combination of sums and differences, where :math:`w_i =
|
| 603 |
+
1` or :math:`w_i = -1`, :math:`i = 1 \dotso n`, we have
|
| 604 |
+
|
| 605 |
+
.. math:: 1 / L_{eff} = \sum_{i = 1}^n {1/{L_i}}
|
| 606 |
+
|
| 607 |
+
.. target for :end-before: inverse-end-content
|
mne-python/source/doc/_includes/memory.rst
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Memory-efficient I/O
|
| 4 |
+
====================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 7 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 8 |
+
to :ref:`memory` to link to that section of the implementation.rst
|
| 9 |
+
page. The next line is a target for :start-after: so we can omit the title
|
| 10 |
+
from the include:
|
| 11 |
+
memory-begin-content
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
Preloading continuous (raw) data
|
| 15 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 16 |
+
|
| 17 |
+
MNE-Python can read data on-demand using the ``preload`` option provided in
|
| 18 |
+
raw reading functions. For example::
|
| 19 |
+
|
| 20 |
+
from mne import io
|
| 21 |
+
from mne.datasets import sample
|
| 22 |
+
data_path = sample.data_path()
|
| 23 |
+
raw_fname = data_path / 'MEG' / 'sample' / 'sample_audvis_filt-0-40_raw.fif'
|
| 24 |
+
raw = io.read_raw_fif(raw_fname, preload=False)
|
| 25 |
+
|
| 26 |
+
.. note:: Filtering, resampling and dropping or selecting channels does not
|
| 27 |
+
work with ``preload=False``.
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
Preloading epoched data
|
| 31 |
+
~~~~~~~~~~~~~~~~~~~~~~~
|
| 32 |
+
|
| 33 |
+
Similarly, epochs can also be be read from disk on-demand. For example::
|
| 34 |
+
|
| 35 |
+
import mne
|
| 36 |
+
events = mne.find_events(raw)
|
| 37 |
+
event_id, tmin, tmax = 1, -0.2, 0.5
|
| 38 |
+
picks = mne.pick_types(raw.info, meg=True, eeg=True, stim=False, eog=True)
|
| 39 |
+
epochs = mne.Epochs(raw, events, event_id, tmin, tmax, picks=picks,
|
| 40 |
+
baseline=(None, 0), reject=dict(eeg=80e-6, eog=150e-6),
|
| 41 |
+
preload=False)
|
| 42 |
+
|
| 43 |
+
When ``preload=False``, the epochs data is loaded from the disk on-demand. Note
|
| 44 |
+
that ``preload=False`` for epochs will work even if the ``raw`` object has been
|
| 45 |
+
loaded with ``preload=True``. Preloading is also supported for
|
| 46 |
+
:func:`mne.read_epochs`.
|
| 47 |
+
|
| 48 |
+
.. warning:: This comes with a caveat. When ``preload=False``, data rejection
|
| 49 |
+
based on peak-to-peak thresholds is executed when the data is
|
| 50 |
+
loaded from disk, *not* when the ``Epochs`` object is created.
|
| 51 |
+
|
| 52 |
+
To explicitly reject artifacts with ``preload=False``, use the function :func:`mne.Epochs.drop_bad`.
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
Loading data explicitly
|
| 56 |
+
~~~~~~~~~~~~~~~~~~~~~~~
|
| 57 |
+
|
| 58 |
+
To load the data if ``preload=False`` was initially selected, use the functions :func:`mne.io.Raw.load_data` and :func:`mne.Epochs.load_data`.
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
Accessing data as NumPy arrays
|
| 62 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 63 |
+
|
| 64 |
+
If you just want your raw data as a :class:`Numpy array <numpy.ndarray>` to
|
| 65 |
+
work with it in a different framework you can use slicing syntax::
|
| 66 |
+
|
| 67 |
+
first_channel_data, times = raw[0, :]
|
| 68 |
+
channels_3_and_4, times = raw[3:5, :]
|
mne-python/source/doc/_includes/morph.rst
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Morphing and averaging source estimates
|
| 4 |
+
=======================================
|
| 5 |
+
|
| 6 |
+
The spherical morphing of BEM surfaces accomplished by FreeSurfer can be
|
| 7 |
+
employed to bring data from different subjects into a common anatomical frame.
|
| 8 |
+
This page describes utilities which make use of the spherical :term:`morphing`
|
| 9 |
+
procedure. :func:`mne.morph_labels` morphs label files between subjects
|
| 10 |
+
allowing the definition of labels in a one brain and transforming them to
|
| 11 |
+
anatomically analogous labels in another. :meth:`mne.SourceMorph.apply` offers
|
| 12 |
+
the capability to transform all subject data to the same space and,
|
| 13 |
+
e.g., compute averages of data across subjects.
|
| 14 |
+
|
| 15 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 16 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 17 |
+
to :ref:`ch_morph` to link to that section of the implementation.rst page.
|
| 18 |
+
The next line is a target for :start-after: so we can omit the title from
|
| 19 |
+
the include:
|
| 20 |
+
morph-begin-content
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
Why morphing?
|
| 24 |
+
~~~~~~~~~~~~~
|
| 25 |
+
|
| 26 |
+
.. note:: Morphing examples in MNE-Python
|
| 27 |
+
:class: sidebar
|
| 28 |
+
|
| 29 |
+
Examples of morphing in MNE-Python include :ref:`this tutorial
|
| 30 |
+
<tut-mne-fixed-free>` on surface source estimation or these examples on
|
| 31 |
+
:ref:`surface <ex-morph-surface>` and :ref:`volumetric <ex-morph-volume>`
|
| 32 |
+
source estimation.
|
| 33 |
+
|
| 34 |
+
Modern neuroimaging techniques, such as source reconstruction or fMRI analyses,
|
| 35 |
+
make use of advanced mathematical models and hardware to map brain activity
|
| 36 |
+
patterns into a subject-specific anatomical brain space. This enables the study
|
| 37 |
+
of spatio-temporal brain activity. The representation of spatio-temporal brain
|
| 38 |
+
data is often mapped onto the anatomical brain structure to relate functional
|
| 39 |
+
and anatomical maps. Thereby activity patterns are overlaid with anatomical
|
| 40 |
+
locations that supposedly produced the activity. Anatomical MR images are often
|
| 41 |
+
used as such or are transformed into an inflated surface representations to
|
| 42 |
+
serve as "canvas" for the visualization.
|
| 43 |
+
|
| 44 |
+
In order to compute group-level statistics, data representations across
|
| 45 |
+
subjects must be morphed to a common frame, such that anatomically and
|
| 46 |
+
functional similar structures are represented at the same spatial location for
|
| 47 |
+
*all subjects equally*. Since brains vary, :term:`morphing` comes into play to
|
| 48 |
+
tell us how the data produced by subject A would be represented on the brain of
|
| 49 |
+
subject B (and vice-versa).
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
The morphing maps
|
| 53 |
+
~~~~~~~~~~~~~~~~~
|
| 54 |
+
|
| 55 |
+
The MNE software accomplishes morphing with help of morphing maps.
|
| 56 |
+
The morphing is performed with help of the registered
|
| 57 |
+
spherical surfaces (``lh.sphere.reg`` and ``rh.sphere.reg`` ) which must be
|
| 58 |
+
produced in FreeSurfer. A morphing map is a linear mapping from cortical
|
| 59 |
+
surface values in subject A (:math:`x^{(A)}`) to those in another subject B
|
| 60 |
+
(:math:`x^{(B)}`)
|
| 61 |
+
|
| 62 |
+
.. math:: x^{(B)} = M^{(AB)} x^{(A)}\ ,
|
| 63 |
+
|
| 64 |
+
where :math:`M^{(AB)}` is a sparse matrix with at most three nonzero elements
|
| 65 |
+
on each row. These elements are determined as follows. First, using the aligned
|
| 66 |
+
spherical surfaces, for each vertex :math:`x_j^{(B)}`, find the triangle
|
| 67 |
+
:math:`T_j^{(A)}` on the spherical surface of subject A which contains the
|
| 68 |
+
location :math:`x_j^{(B)}`. Next, find the numbers of the vertices of this
|
| 69 |
+
triangle and set the corresponding elements on the *j* th row of
|
| 70 |
+
:math:`M^{(AB)}` so that :math:`x_j^{(B)}` will be a linear interpolation
|
| 71 |
+
between the triangle vertex values reflecting the location :math:`x_j^{(B)}`
|
| 72 |
+
within the triangle :math:`T_j^{(A)}`.
|
| 73 |
+
|
| 74 |
+
It follows from the above definition that in general
|
| 75 |
+
|
| 76 |
+
.. math:: M^{(AB)} \neq (M^{(BA)})^{-1}\ ,
|
| 77 |
+
|
| 78 |
+
*i.e.*,
|
| 79 |
+
|
| 80 |
+
.. math:: x_{(A)} \neq M^{(BA)} M^{(AB)} x^{(A)}\ ,
|
| 81 |
+
|
| 82 |
+
even if
|
| 83 |
+
|
| 84 |
+
.. math:: x^{(A)} \approx M^{(BA)} M^{(AB)} x^{(A)}\ ,
|
| 85 |
+
|
| 86 |
+
*i.e.*, the mapping is *almost* a bijection.
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
About smoothing
|
| 90 |
+
~~~~~~~~~~~~~~~
|
| 91 |
+
|
| 92 |
+
The current estimates are normally defined only in a decimated grid which is a
|
| 93 |
+
sparse subset of the vertices in the triangular tessellation of the cortical
|
| 94 |
+
surface. Therefore, any sparse set of values is distributed to neighboring
|
| 95 |
+
vertices to make the visualized results easily understandable. This procedure
|
| 96 |
+
has been traditionally called smoothing but a more appropriate name might be
|
| 97 |
+
smudging or blurring in accordance with similar operations in image processing
|
| 98 |
+
programs.
|
| 99 |
+
|
| 100 |
+
In MNE software terms, smoothing of the vertex data is an iterative procedure,
|
| 101 |
+
which produces a blurred image :math:`x^{(N)}` from the original sparse image
|
| 102 |
+
:math:`x^{(0)}` by applying in each iteration step a sparse blurring matrix:
|
| 103 |
+
|
| 104 |
+
.. math:: x^{(p)} = S^{(p)} x^{(p - 1)}\ .
|
| 105 |
+
|
| 106 |
+
On each row :math:`j` of the matrix :math:`S^{(p)}` there are :math:`N_j^{(p -
|
| 107 |
+
1)}` nonzero entries whose values equal :math:`1/N_j^{(p - 1)}`. Here
|
| 108 |
+
:math:`N_j^{(p - 1)}` is the number of immediate neighbors of vertex :math:`j`
|
| 109 |
+
which had non-zero values at iteration step :math:`p - 1`. Matrix
|
| 110 |
+
:math:`S^{(p)}` thus assigns the average of the non-zero neighbors as the new
|
| 111 |
+
value for vertex :math:`j`. One important feature of this procedure is that it
|
| 112 |
+
tends to preserve the amplitudes while blurring the surface image.
|
| 113 |
+
|
| 114 |
+
Once the indices non-zero vertices in :math:`x^{(0)}` and the topology of the
|
| 115 |
+
triangulation are fixed the matrices :math:`S^{(p)}` are fixed and independent
|
| 116 |
+
of the data. Therefore, it would be in principle possible to construct a
|
| 117 |
+
composite blurring matrix
|
| 118 |
+
|
| 119 |
+
.. math:: S^{(N)} = \prod_{p = 1}^N {S^{(p)}}\ .
|
| 120 |
+
|
| 121 |
+
However, it turns out to be computationally more effective to do blurring with
|
| 122 |
+
an iteration. The above formula for :math:`S^{(N)}` also shows that the
|
| 123 |
+
smudging (smoothing) operation is linear.
|
mne-python/source/doc/_includes/precision.rst
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Floating-point precision
|
| 4 |
+
========================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/manual/io.rst and
|
| 7 |
+
doc/overview/implementation.rst. Changes here are reflected there. If you
|
| 8 |
+
want to link to this content, link to :ref:`manual-precision` for the manual
|
| 9 |
+
or :ref:`precision` for the implementation page. The next line is a target
|
| 10 |
+
for :start-after: so we can omit the title above:
|
| 11 |
+
precision-begin-content
|
| 12 |
+
|
| 13 |
+
MNE-Python performs all computation in memory using the double-precision 64-bit
|
| 14 |
+
floating point format. This means that the data is typecast into float64 format
|
| 15 |
+
as soon as it is read into memory. The reason for this is that operations such
|
| 16 |
+
as filtering and preprocessing are more accurate when using the 64-bit format.
|
| 17 |
+
However, for backward compatibility, MNE-Python writes :file:`.fif` files in a
|
| 18 |
+
32-bit format by default. This reduces file size when saving data to disk, but
|
| 19 |
+
beware that *saving intermediate results to disk and re-loading them from disk
|
| 20 |
+
later may lead to loss in precision*. If you would like to ensure 64-bit
|
| 21 |
+
precision, there are two possibilities:
|
| 22 |
+
|
| 23 |
+
- Chain the operations in memory and avoid saving intermediate results.
|
| 24 |
+
|
| 25 |
+
- Save intermediate results but change the :class:`~numpy.dtype` used for
|
| 26 |
+
saving, by using the ``fmt`` parameter of :meth:`mne.io.Raw.save` (or
|
| 27 |
+
:meth:`mne.Epochs.save`, etc). However, note that this may render the
|
| 28 |
+
:file:`.fif` files unreadable in software packages other than MNE-Python.
|
mne-python/source/doc/_includes/ssp.rst
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
The Signal-Space Projection (SSP) method
|
| 4 |
+
========================================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/overview/implementation.rst.
|
| 7 |
+
Changes here are reflected there. If you want to link to this content, link
|
| 8 |
+
to :ref:`ssp-method` to link to that section of the implementation.rst
|
| 9 |
+
page. The next line is a target for :start-after: so we can omit the title
|
| 10 |
+
from the include:
|
| 11 |
+
ssp-begin-content
|
| 12 |
+
|
| 13 |
+
The Signal-Space Projection (SSP) is one approach to rejection of external
|
| 14 |
+
disturbances in software. The section presents some relevant details of this
|
| 15 |
+
method. For practical examples of how to use SSP for artifact rejection, see
|
| 16 |
+
:ref:`tut-artifact-ssp`.
|
| 17 |
+
|
| 18 |
+
General concepts
|
| 19 |
+
~~~~~~~~~~~~~~~~
|
| 20 |
+
|
| 21 |
+
Unlike many other noise-cancellation approaches, SSP does not require
|
| 22 |
+
additional reference sensors to record the disturbance fields. Instead, SSP
|
| 23 |
+
relies on the fact that the magnetic field distributions generated by the
|
| 24 |
+
sources in the brain have spatial distributions sufficiently different from
|
| 25 |
+
those generated by external noise sources. Furthermore, it is implicitly
|
| 26 |
+
assumed that the linear space spanned by the significant external noise patterns
|
| 27 |
+
has a low dimension.
|
| 28 |
+
|
| 29 |
+
Without loss of generality we can always decompose any :math:`n`-channel
|
| 30 |
+
measurement :math:`b(t)` into its signal and noise components as
|
| 31 |
+
|
| 32 |
+
.. math:: b(t) = b_s(t) + b_n(t)
|
| 33 |
+
:name: additive_model
|
| 34 |
+
|
| 35 |
+
Further, if we know that :math:`b_n(t)` is well characterized by a few field
|
| 36 |
+
patterns :math:`b_1 \dotso b_m`, we can express the disturbance as
|
| 37 |
+
|
| 38 |
+
.. math:: b_n(t) = Uc_n(t) + e(t)\ ,
|
| 39 |
+
:name: pca
|
| 40 |
+
|
| 41 |
+
where the columns of :math:`U` constitute an orthonormal basis for :math:`b_1
|
| 42 |
+
\dotso b_m`, :math:`c_n(t)` is an :math:`m`-component column vector, and the
|
| 43 |
+
error term :math:`e(t)` is small and does not exhibit any consistent spatial
|
| 44 |
+
distributions over time, *i.e.*, :math:`C_e = E \{e e^\top\} = I`. Subsequently,
|
| 45 |
+
we will call the column space of :math:`U` the noise subspace. The basic idea
|
| 46 |
+
of SSP is that we can actually find a small basis set :math:`b_1 \dotso b_m`
|
| 47 |
+
such that the conditions described above are satisfied. We can now construct
|
| 48 |
+
the orthogonal complement operator
|
| 49 |
+
|
| 50 |
+
.. math:: P_{\perp} = I - UU^\top
|
| 51 |
+
:name: projector
|
| 52 |
+
|
| 53 |
+
and apply it to :math:`b(t)` in Equation :eq:`additive_model` yielding
|
| 54 |
+
|
| 55 |
+
.. math:: b_{s}(t) \approx P_{\perp}b(t)\ ,
|
| 56 |
+
:name: result
|
| 57 |
+
|
| 58 |
+
since :math:`P_{\perp}b_n(t) = P_{\perp}(Uc_n(t) + e(t)) \approx 0` and
|
| 59 |
+
:math:`P_{\perp}b_{s}(t) \approx b_{s}(t)`. The projection operator
|
| 60 |
+
:math:`P_{\perp}` is called the **signal-space projection operator** and
|
| 61 |
+
generally provides considerable rejection of noise, suppressing external
|
| 62 |
+
disturbances by a factor of 10 or more. The effectiveness of SSP depends on two
|
| 63 |
+
factors:
|
| 64 |
+
|
| 65 |
+
- The basis set :math:`b_1 \dotso b_m` should be able to characterize the
|
| 66 |
+
disturbance field patterns completely and
|
| 67 |
+
|
| 68 |
+
- The angles between the noise subspace space spanned by :math:`b_1 \dotso b_m`
|
| 69 |
+
and the signal vectors :math:`b_s(t)` should be as close to :math:`\pi / 2`
|
| 70 |
+
as possible.
|
| 71 |
+
|
| 72 |
+
If the first requirement is not satisfied, some noise will leak through because
|
| 73 |
+
:math:`P_{\perp}b_n(t) \neq 0`. If the any of the brain signal vectors
|
| 74 |
+
:math:`b_s(t)` is close to the noise subspace not only the noise but also the
|
| 75 |
+
signal will be attenuated by the application of :math:`P_{\perp}` and,
|
| 76 |
+
consequently, there might by little gain in signal-to-noise ratio.
|
| 77 |
+
|
| 78 |
+
Since the signal-space projection modifies the signal vectors originating in
|
| 79 |
+
the brain, it is necessary to apply the projection to the forward solution in
|
| 80 |
+
the course of inverse computations.
|
| 81 |
+
|
| 82 |
+
For more information on SSP, please consult the references listed in
|
| 83 |
+
:footcite:t:`TescheEtAl1995,UusitaloIlmoniemi1997`.
|
| 84 |
+
|
| 85 |
+
Estimation of the noise subspace
|
| 86 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 87 |
+
|
| 88 |
+
As described above, application of SSP requires the estimation of the signal
|
| 89 |
+
vectors :math:`b_1 \dotso b_m` constituting the noise subspace. The most common
|
| 90 |
+
approach, also implemented in :func:`mne.compute_proj_raw`
|
| 91 |
+
is to compute a covariance matrix
|
| 92 |
+
of empty room data, compute its eigenvalue decomposition, and employ the
|
| 93 |
+
eigenvectors corresponding to the highest eigenvalues as basis for the noise
|
| 94 |
+
subspace. It is also customary to use a separate set of vectors for
|
| 95 |
+
magnetometers and gradiometers in the Vectorview system.
|
| 96 |
+
|
| 97 |
+
EEG average electrode reference
|
| 98 |
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 99 |
+
|
| 100 |
+
The EEG average reference is the mean signal over all the sensors. It is
|
| 101 |
+
typical in EEG analysis to subtract the average reference from all the sensor
|
| 102 |
+
signals :math:`b^{1}(t), ..., b^{n}(t)`. That is:
|
| 103 |
+
|
| 104 |
+
.. math:: {b}^{j}_{s}(t) = b^{j}(t) - \frac{1}{n}\sum_{k}{b^k(t)}
|
| 105 |
+
:name: eeg_proj
|
| 106 |
+
|
| 107 |
+
where the noise term :math:`b_{n}^{j}(t)` is given by
|
| 108 |
+
|
| 109 |
+
.. math:: b_{n}^{j}(t) = \frac{1}{n}\sum_{k}{b^k(t)}
|
| 110 |
+
:name: noise_term
|
| 111 |
+
|
| 112 |
+
Thus, the projector vector :math:`P_{\perp}` will be given by
|
| 113 |
+
:math:`P_{\perp}=\frac{1}{n}[1, 1, ..., 1]`
|
| 114 |
+
|
| 115 |
+
.. warning::
|
| 116 |
+
When applying SSP, the signal of interest can also be sometimes removed.
|
| 117 |
+
Therefore, it's always a good idea to check how much the effect of interest
|
| 118 |
+
is reduced by applying SSP. SSP might remove *both* the artifact and signal
|
| 119 |
+
of interest.
|
mne-python/source/doc/_includes/units.rst
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:orphan:
|
| 2 |
+
|
| 3 |
+
Internal representation (units)
|
| 4 |
+
===============================
|
| 5 |
+
|
| 6 |
+
.. NOTE: part of this file is included in doc/manual/io.rst and
|
| 7 |
+
doc/overview/implementation.rst. Changes here are reflected there. If you
|
| 8 |
+
want to link to this content, link to :ref:`manual-units` for the manual or
|
| 9 |
+
:ref:`units` for the implementation page. The next line is a target for
|
| 10 |
+
:start-after: so we can omit what's above:
|
| 11 |
+
units-begin-content
|
| 12 |
+
|
| 13 |
+
Irrespective of the units used in your manufacturer's format, when importing
|
| 14 |
+
data, MNE-Python will always convert measurements to the same standard units.
|
| 15 |
+
Thus the in-memory representation of data are always in:
|
| 16 |
+
|
| 17 |
+
- Volts (eeg, eog, seeg, emg, ecg, bio, ecog, dbs)
|
| 18 |
+
- Teslas (magnetometers)
|
| 19 |
+
- Teslas/meter (gradiometers)
|
| 20 |
+
- Amperes*meter (dipole fits, minimum-norm estimates, etc.)
|
| 21 |
+
- Moles/liter ("molar"; fNIRS data: oxyhemoglobin (hbo), deoxyhemoglobin (hbr))
|
| 22 |
+
- Arbitrary units (various derived unitless quantities)
|
| 23 |
+
|
| 24 |
+
.. NOTE: this is a target for :end-before: units-end-of-list
|
| 25 |
+
|
| 26 |
+
Note, however, that most MNE-Python plotting functions will scale the data when
|
| 27 |
+
plotted to yield nice-looking axis annotations in a sensible range; for
|
| 28 |
+
example, :meth:`mne.io.Raw.plot_psd` will convert teslas to femtoteslas (fT)
|
| 29 |
+
and volts to microvolts (µV) when plotting MEG and EEG data.
|
| 30 |
+
|
| 31 |
+
The units used in internal data representation are particularly important to
|
| 32 |
+
remember when extracting data from MNE-Python objects and manipulating it
|
| 33 |
+
outside MNE-Python (e.g., when using methods like :meth:`~mne.io.Raw.get_data`
|
| 34 |
+
or :meth:`~mne.Epochs.to_data_frame` to convert data to :class:`NumPy arrays
|
| 35 |
+
<numpy.ndarray>` or :class:`Pandas DataFrames <pandas.DataFrame>` for analysis
|
| 36 |
+
or plotting with other Python modules).
|
mne-python/source/doc/_static/CoordinateSystems.png
ADDED
|
mne-python/source/doc/_static/HeadCS.png
ADDED
|
mne-python/source/doc/_static/blender_import_obj/blender_import_obj1.jpg
ADDED
|
Git LFS Details
|
mne-python/source/doc/_static/blender_import_obj/blender_import_obj2.jpg
ADDED
|