ncrf 0.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. ncrf-0.5/.git_archival.txt +3 -0
  2. ncrf-0.5/.gitattributes +1 -0
  3. ncrf-0.5/.github/labeler.yaml +3 -0
  4. ncrf-0.5/.github/workflows/auto-label.yaml +18 -0
  5. ncrf-0.5/.github/workflows/code-quality.yml +25 -0
  6. ncrf-0.5/.github/workflows/doc.yaml +63 -0
  7. ncrf-0.5/.github/workflows/test-posix.yml +59 -0
  8. ncrf-0.5/.github/workflows/test-windows.yml +32 -0
  9. ncrf-0.5/.github/workflows/wheels.yml +89 -0
  10. ncrf-0.5/.gitignore +22 -0
  11. ncrf-0.5/.pre-commit-config.yaml +29 -0
  12. ncrf-0.5/LICENSE.txt +7 -0
  13. ncrf-0.5/PKG-INFO +133 -0
  14. ncrf-0.5/README.md +76 -0
  15. ncrf-0.5/conftest.py +14 -0
  16. ncrf-0.5/docs/Makefile +36 -0
  17. ncrf-0.5/docs/_static/custom.css +123 -0
  18. ncrf-0.5/docs/api.rst +67 -0
  19. ncrf-0.5/docs/architecture.rst +151 -0
  20. ncrf-0.5/docs/changes.rst +176 -0
  21. ncrf-0.5/docs/conf.py +154 -0
  22. ncrf-0.5/docs/development.rst +42 -0
  23. ncrf-0.5/docs/guide.rst +111 -0
  24. ncrf-0.5/docs/index.rst +33 -0
  25. ncrf-0.5/docs/installing.rst +32 -0
  26. ncrf-0.5/docs/links.inc +12 -0
  27. ncrf-0.5/docs/make.bat +35 -0
  28. ncrf-0.5/docs/references.bib +41 -0
  29. ncrf-0.5/docs/references.rst +6 -0
  30. ncrf-0.5/docs/templates/autosummary/class.rst +38 -0
  31. ncrf-0.5/docs/templates/autosummary/module.rst +3 -0
  32. ncrf-0.5/docs/templates/class_nomethods.rst +5 -0
  33. ncrf-0.5/env-dev.yml +17 -0
  34. ncrf-0.5/examples/00_example-vol-src.py +409 -0
  35. ncrf-0.5/examples/01_example-surf-src.py +297 -0
  36. ncrf-0.5/examples/GALLERY_HEADER.rst +4 -0
  37. ncrf-0.5/ncrf/__init__.py +34 -0
  38. ncrf-0.5/ncrf/_crossvalidation.py +290 -0
  39. ncrf-0.5/ncrf/_data.py +635 -0
  40. ncrf-0.5/ncrf/_fastac.py +279 -0
  41. ncrf-0.5/ncrf/_forward.py +205 -0
  42. ncrf-0.5/ncrf/_initialization.py +115 -0
  43. ncrf-0.5/ncrf/_linalg.py +105 -0
  44. ncrf-0.5/ncrf/_metrics.py +65 -0
  45. ncrf-0.5/ncrf/_model.py +593 -0
  46. ncrf-0.5/ncrf/_ncrf.py +240 -0
  47. ncrf-0.5/ncrf/_penalties.py +147 -0
  48. ncrf-0.5/ncrf/_pickle.py +19 -0
  49. ncrf-0.5/ncrf/_repr.py +30 -0
  50. ncrf-0.5/ncrf/_solvers/__init__.py +3 -0
  51. ncrf-0.5/ncrf/_solvers/base.py +160 -0
  52. ncrf-0.5/ncrf/_solvers/champ_lasso.py +768 -0
  53. ncrf-0.5/ncrf/_trf_design.py +274 -0
  54. ncrf-0.5/ncrf/_typing.py +22 -0
  55. ncrf-0.5/ncrf/tests/__init__.py +5 -0
  56. ncrf-0.5/ncrf/tests/fetch.py +112 -0
  57. ncrf-0.5/ncrf/tests/test_crossvalidation.py +246 -0
  58. ncrf-0.5/ncrf/tests/test_linalg.py +61 -0
  59. ncrf-0.5/ncrf/tests/test_model.py +767 -0
  60. ncrf-0.5/ncrf/tests/test_ncrf.py +241 -0
  61. ncrf-0.5/ncrf/tests/test_penalties.py +41 -0
  62. ncrf-0.5/ncrf.egg-info/PKG-INFO +133 -0
  63. ncrf-0.5/ncrf.egg-info/SOURCES.txt +70 -0
  64. ncrf-0.5/ncrf.egg-info/dependency_links.txt +1 -0
  65. ncrf-0.5/ncrf.egg-info/requires.txt +36 -0
  66. ncrf-0.5/ncrf.egg-info/scm_file_list.json +67 -0
  67. ncrf-0.5/ncrf.egg-info/scm_version.json +8 -0
  68. ncrf-0.5/ncrf.egg-info/top_level.txt +1 -0
  69. ncrf-0.5/pyproject.toml +104 -0
  70. ncrf-0.5/setup.cfg +23 -0
  71. ncrf-0.5/windows-explicit.conda.lock +232 -0
@@ -0,0 +1,3 @@
1
+ node: $Format:%H$
2
+ node-date: $Format:%cI$
3
+ describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$
@@ -0,0 +1 @@
1
+ .git_archival.txt export-subst
@@ -0,0 +1,3 @@
1
+ 📓 doc:
2
+ - changed-files:
3
+ - any-glob-to-any-file: ['docs/*']
@@ -0,0 +1,18 @@
1
+ name: auto-label
2
+ concurrency:
3
+ group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }}
4
+ cancel-in-progress: true
5
+ on: # yamllint disable-line rule:truthy
6
+ - pull_request_target
7
+
8
+ jobs:
9
+ labeler:
10
+ permissions:
11
+ issues: write
12
+ contents: read
13
+ pull-requests: write
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/labeler@v5
17
+ with:
18
+ configuration-path: .github/labeler.yaml
@@ -0,0 +1,25 @@
1
+ name: Lint with pre-commit
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ pre-commit:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - name: Checkout code
10
+ uses: actions/checkout@v7
11
+ with:
12
+ fetch-depth: 0
13
+
14
+ - name: Set up Python
15
+ uses: actions/setup-python@v6.2.0
16
+ with:
17
+ python-version: '3.12'
18
+
19
+ - name: Install dependencies
20
+ run: |
21
+ pip install pre-commit
22
+
23
+ - name: Run pre-commit hooks
24
+ run: |
25
+ pre-commit run --all-files
@@ -0,0 +1,63 @@
1
+ name: doc
2
+ concurrency:
3
+ group: ${{ github.workflow }}-${{ github.event.number }}-${{ github.event.ref }}
4
+ cancel-in-progress: true
5
+ on: # yamllint disable-line rule:truthy
6
+ pull_request:
7
+ push:
8
+ branches:
9
+ - master
10
+ - doc*
11
+ workflow_dispatch:
12
+
13
+ jobs:
14
+ build:
15
+ timeout-minutes: 30
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 0
21
+ - run: sudo apt update && sudo apt install -y optipng
22
+ - name: Install Miniconda
23
+ uses: conda-incubator/setup-miniconda@v3
24
+ with:
25
+ auto-update-conda: true
26
+ miniforge-version: latest
27
+ environment-file: env-dev.yml
28
+ activate-environment: ncrf
29
+ auto-activate-base: false
30
+ - name: build Neuro-currentRF and doc
31
+ shell: bash -el {0}
32
+ run: |
33
+ python -m pip install -e .[doc]
34
+ python -c "import ncrf"
35
+ make -C docs html
36
+ - name: Prune sphinx environment
37
+ run: rm -R ./docs/_build/html/.doctrees
38
+ - uses: actions/upload-artifact@v4
39
+ with:
40
+ name: doc-dev
41
+ path: ./docs/_build/html
42
+
43
+ deploy:
44
+ if: github.event_name == 'push'
45
+ needs: build
46
+ timeout-minutes: 10
47
+ runs-on: ubuntu-latest
48
+ permissions:
49
+ contents: write
50
+ steps:
51
+ - uses: actions/checkout@v4
52
+ - uses: actions/download-artifact@v4
53
+ with:
54
+ name: doc-dev
55
+ path: ./doc-dev
56
+ - uses: JamesIves/github-pages-deploy-action@v4
57
+ with:
58
+ folder: doc-dev
59
+ # target-folder: ./neuro-currentRF
60
+ git-config-name: 'github-actions[bot]'
61
+ git-config-email: 'github-actions[bot]@users.noreply.github.com'
62
+ single-commit: true
63
+ force: true
@@ -0,0 +1,59 @@
1
+ name: Python Package using Conda on linux and macos
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ - maint*
8
+ pull_request:
9
+ branches: [ "master" ]
10
+
11
+ jobs:
12
+ build-posix:
13
+ name: build-${{ matrix.os }}
14
+ runs-on: ${{ matrix.os }}
15
+ # runs-on: ubuntu-latest
16
+ strategy:
17
+ max-parallel: 5
18
+ matrix:
19
+ os: [ubuntu-latest, macos-latest]
20
+ python-version: ['3.12'] # oldest Python with conda builds of Eelbrain pre-releases
21
+ include:
22
+ - os: ubuntu-latest
23
+ cv: 1
24
+ - os: macos-latest
25
+ cc: 1
26
+
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ with:
30
+ fetch-depth: 0
31
+ - name: Install Miniconda
32
+ uses: conda-incubator/setup-miniconda@v3
33
+ with:
34
+ auto-update-conda: true
35
+ miniforge-version: latest
36
+ python-version: ${{ matrix.python-version }}
37
+ environment-file: env-dev.yml
38
+ activate-environment: ncrf
39
+ auto-activate-base: false
40
+ - name: build Neuro-currentRF
41
+ shell: bash -el {0}
42
+ run: |
43
+ python -m pip install .[test]
44
+ rm -rf ncrf
45
+ - if: ${{ matrix.cc }}
46
+ name: Test with pytest and code-cov
47
+ shell: bash -el {0}
48
+ run: |
49
+ pytest --cov --cov-report=xml --pyargs ncrf # namespace vs module import?
50
+ - if: ${{ matrix.cc }}
51
+ name: Upload coverage to Codecov
52
+ uses: codecov/codecov-action@v4
53
+ with:
54
+ token: ${{ secrets.CODECOV_TOKEN }}
55
+ - if: ${{ matrix.cv }}
56
+ name: Test with pytest and cv
57
+ shell: bash -el {0}
58
+ run: |
59
+ pytest --crossvalidation=True --pyargs ncrf
@@ -0,0 +1,32 @@
1
+ name: Python Package using Conda on windows
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ - maint*
8
+ pull_request:
9
+ branches: [ "master" ]
10
+
11
+ jobs:
12
+ build-windows-latest:
13
+ runs-on: windows-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+ - name: Install Miniconda
20
+ uses: conda-incubator/setup-miniconda@v3
21
+ with:
22
+ auto-update-conda: false
23
+ environment-file: env-dev.yml
24
+ activate-environment: ncrf
25
+ - name: build Neuro-currentRF
26
+ shell: bash -el {0}
27
+ run: |
28
+ pip install -e .[test]
29
+ - name: Test with pytest
30
+ shell: bash -el {0}
31
+ run: |
32
+ pytest --crossvalidation=True
@@ -0,0 +1,89 @@
1
+ name: Build wheels
2
+
3
+ # Adapted from Eelbrain
4
+
5
+ on:
6
+ push:
7
+ branches:
8
+ - master
9
+ tags:
10
+ - "v*"
11
+ pull_request:
12
+ branches:
13
+ - master
14
+
15
+ concurrency:
16
+ group: ${{ github.workflow }}-${{ github.ref }}
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ build:
21
+ name: Build sdist and wheel
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v7
25
+ with:
26
+ fetch-depth: 0
27
+ - name: Build sdist and wheel
28
+ run: pipx run build
29
+ - uses: actions/upload-artifact@v7
30
+ with:
31
+ name: dist
32
+ path: ./dist/*
33
+
34
+ test-sdist:
35
+ name: Test sdist
36
+ needs: [build]
37
+ runs-on: ubuntu-latest
38
+ steps:
39
+ - uses: actions/checkout@v7 # for env-dev.yml
40
+ - uses: actions/download-artifact@v8
41
+ with:
42
+ name: dist
43
+ path: ./dist
44
+ - name: Install Miniconda
45
+ uses: conda-incubator/setup-miniconda@v3
46
+ with:
47
+ auto-update-conda: true
48
+ miniforge-version: latest
49
+ environment-file: env-dev.yml
50
+ activate-environment: ncrf
51
+ auto-activate-base: false
52
+ - name: Install sdist
53
+ shell: bash -el {0}
54
+ run: |
55
+ pip install "$(ls dist/*.tar.gz)[test]"
56
+ rm -rf ncrf
57
+ - name: Check version
58
+ shell: bash -el {0}
59
+ run: |
60
+ python -c "import ncrf; v = ncrf.__version__; assert v != '0.0.0' and v[0].isdigit(), f'Bad version: {v!r}'"
61
+ - name: Run tests
62
+ shell: bash -el {0}
63
+ run: pytest -m "not slow" -rsx -v --pyargs ncrf
64
+
65
+ pre-publish:
66
+ runs-on: ubuntu-latest
67
+ needs: [test-sdist]
68
+ steps:
69
+ - uses: actions/download-artifact@v8
70
+ with:
71
+ name: dist
72
+ path: dist/
73
+ - run: ls -lR dist/
74
+ - run: pipx run twine check dist/*
75
+
76
+ publish:
77
+ runs-on: ubuntu-latest
78
+ environment: "Package deployment"
79
+ permissions:
80
+ id-token: write # for trusted publishing
81
+ needs: [pre-publish]
82
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
83
+ steps:
84
+ - uses: actions/download-artifact@v8
85
+ with:
86
+ name: dist
87
+ path: dist/
88
+ - run: ls -lR dist/
89
+ - uses: pypa/gh-action-pypi-publish@release/v1
ncrf-0.5/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ docs/_build
2
+ docs/generated
3
+ docs/auto_examples
4
+ docs/sg_execution_times.rst
5
+ ncrf.egg-info
6
+ fit_ncrf/*.log
7
+ *.out
8
+ *.so
9
+ fit_ncrf/*.pickled
10
+ *egg-info
11
+ .idea/
12
+ build/
13
+ dist/
14
+ __pycache__/
15
+ ncrf/__pycache__/
16
+ ncrf-testing-data
17
+ *.html
18
+ ncrf_data
19
+ .pytest_cache
20
+ .DS_Store
21
+ *.ipynb
22
+ */.ipynb_checkpoints/*
@@ -0,0 +1,29 @@
1
+ repos:
2
+ - repo: https://github.com/asottile/pyupgrade
3
+ rev: v3.19.1
4
+ hooks:
5
+ - id: pyupgrade
6
+ args: [--py310-plus]
7
+ - repo: https://github.com/PyCQA/autoflake
8
+ rev: v2.3.3
9
+ hooks:
10
+ - id: autoflake
11
+ args:
12
+ - --remove-all-unused-imports
13
+ - --in-place
14
+ - --remove-unused-variables
15
+ - --ignore-init-module-imports
16
+ - repo: https://github.com/ikamensh/flynt/
17
+ rev: 1.0.6
18
+ hooks:
19
+ - id: flynt
20
+ - repo: https://github.com/hhatto/autopep8
21
+ rev: v2.3.2
22
+ hooks:
23
+ - id: autopep8
24
+ files: 'ncrf/'
25
+ - repo: https://github.com/PyCQA/flake8
26
+ rev: 7.3.0
27
+ hooks:
28
+ - id: flake8
29
+ files: 'ncrf/'
ncrf-0.5/LICENSE.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2019-2025, Proloy Das
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ncrf-0.5/PKG-INFO ADDED
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.4
2
+ Name: ncrf
3
+ Version: 0.5
4
+ Summary: add-on module to eelbrain for neural current RF estimation
5
+ Author-email: Proloy Das <proloyd94@gmail.com>
6
+ Maintainer: Christian Brodbeck
7
+ Maintainer-email: Proloy Das <proloyd94@gmail.com>
8
+ License-Expression: MIT
9
+ Project-URL: documentation, https://proloyd.github.io/neuro-currentRF
10
+ Project-URL: homepage, https://github.com/proloyd/neuro-currentRF
11
+ Project-URL: source, https://github.com/proloyd/neuro-currentRF
12
+ Project-URL: tracker, https://github.com/proloyd/neuro-currentRF/issues
13
+ Keywords: meg,eeg,source localization,python
14
+ Classifier: Natural Language :: English
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: Unix
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE.txt
25
+ Requires-Dist: eelbrain>=0.43.0b3
26
+ Requires-Dist: numpy<3,>=1.23
27
+ Provides-Extra: all
28
+ Requires-Dist: ncrf[style]; extra == "all"
29
+ Requires-Dist: ncrf[test]; extra == "all"
30
+ Requires-Dist: ncrf[doc]; extra == "all"
31
+ Provides-Extra: full
32
+ Requires-Dist: ncrf[all]; extra == "full"
33
+ Provides-Extra: style
34
+ Requires-Dist: codespell[toml]>=2.2.4; extra == "style"
35
+ Requires-Dist: ruff>=0.6.0; extra == "style"
36
+ Requires-Dist: toml-sort; extra == "style"
37
+ Requires-Dist: yamllint; extra == "style"
38
+ Provides-Extra: doc
39
+ Requires-Dist: dipy; extra == "doc"
40
+ Requires-Dist: numpydoc; extra == "doc"
41
+ Requires-Dist: furo; extra == "doc"
42
+ Requires-Dist: matplotlib; extra == "doc"
43
+ Requires-Dist: sphinx-copybutton; extra == "doc"
44
+ Requires-Dist: sphinx-design; extra == "doc"
45
+ Requires-Dist: sphinx-gallery; extra == "doc"
46
+ Requires-Dist: sphinx-issues; extra == "doc"
47
+ Requires-Dist: sphinxcontrib-bibtex; extra == "doc"
48
+ Requires-Dist: intersphinx_registry; extra == "doc"
49
+ Requires-Dist: memory-profiler; extra == "doc"
50
+ Provides-Extra: test
51
+ Requires-Dist: flake8; extra == "test"
52
+ Requires-Dist: pytest-cov; extra == "test"
53
+ Requires-Dist: pytest<8.1.1,>=8.0; extra == "test"
54
+ Requires-Dist: pytest-faulthandler; extra == "test"
55
+ Requires-Dist: seaborn; extra == "test"
56
+ Dynamic: license-file
57
+
58
+ # Build Status
59
+ ![test-posix](https://github.com/proloyd/neuro-currentRF/actions/workflows/test-posix.yml/badge.svg)
60
+
61
+ ![test-windows](https://github.com/proloyd/neuro-currentRF/actions/workflows/test-windows.yml/badge.svg)
62
+
63
+
64
+ # NCRF
65
+ The magnetoencephalography (MEG) response to continuous auditory stimuli, such as speech, is commonly described using a linear filter, the auditory temporal response function (TRF). Though components of the sensor level TRFs have been well characterized, the cortical distributions of the underlying neural responses are not well-understood. In our recent work, we provide a unified framework for determining the TRFs of neural sources directly from the MEG data, by integrating the TRF and distributed forward source models into one, and casting the joint estimation task as a Bayesian optimization problem. Though the resulting problem emerges as non-convex, we propose efficient solutions that leverage recent advances in evidence maximization. For more details please refer to [1], [2].
66
+
67
+ This repository contains the implementation of our direct TRF estimation algorithm in Python.
68
+
69
+ For code examples using real datasets, see the [Example gallery](https://eelbrain.github.io/neuro-currentRF/auto_examples/index.html).
70
+
71
+ The optimization algorithm is configurable independently of the forward model.
72
+ For a prepared `RegressionData` dataset, the lower-level API is:
73
+
74
+ ```python
75
+ from ncrf import ChampLasso, NCRFEstimator
76
+
77
+ estimator = NCRFEstimator.from_lead_field(lead_field, noise_covariance)
78
+ solver = ChampLasso(mu='auto', n_iter=30, n_iterc=10, n_iterf=100)
79
+ result = estimator.fit(data, solver)
80
+ ```
81
+
82
+ All solvers return a common predictive `NCRF` in `result.model`; training explained variance
83
+ is available as `result.scores['explained_variance']`. To score other data,
84
+ `result.model.evaluate(data, [explained_variance, l2_error])` predicts once and
85
+ returns all requested metrics. Solver-specific state is available as
86
+ `result.solver_fit`.
87
+
88
+
89
+ ## How to use:
90
+ run
91
+ ```python
92
+ result = fit_ncrf(meg, stim, lead_field, noise_covariance, mu='auto', tstop=1.0, basis_stride=2, n_splits=3, scale='l1')
93
+ ```
94
+ to perform a 3-fold cross-validation and then construct the model for 1s long TRF with the regularization weight among the given range that gives least generalization error. The signature of the ``meg`` and ``stim`` could be as follows:
95
+
96
+ [ megA (case, sensor, time), megB (case, sensor, time), ...]
97
+ [[featA1 (case, time), featA2 (case, time), ...], [featB1 (case, time), featB2 (case, time), ...], ...]
98
+
99
+ For more options, please look at the docstring. The learned TRF, `h` can be retrieved using:
100
+ ```python
101
+ h = result.model.h
102
+ ```
103
+
104
+ ## Results
105
+ We applied the algorithm on a subset of MEG data collected from 17 adults (aged 18-27 years) under an auditory task described in the papers. In short, during the task, the participants listened to `1 min` long segments from an audio-book recording of [The Legend of Sleepy Hollow by Washington Irving](https://librivox.org/the-legend-of-sleepy-hollow-by-washington-irving/), narrated by a male speaker. We consider localizing the TRFs using a total of `6 min` data from each participant. MNE-python 0.14 was used in pre-processing the raw data to automatically detect and discard flat channels, remove extraneous artifacts, and to band-pass filter the data in the range `1 - 80 Hz`. The six `1 min` long data epochs were then down-sampled to `200 Hz`. As the stimulus variable, we used the speech envelope reflecting the momentary acoustic power, by averaging the auditory spectrogram representation (generated using a model of the
106
+ auditory periphery) across the frequency bands, sampled at `200 Hz`. A volume source space for individual subjects was defined on a 3D regular grid with a resolution of `7 mm` in each direction. The lead-field matrix was then computed by placing free orientation virtual dipoles on the resulting `3322` grid points. The consistent components of our estimated `1 s`-long 3D TRFs across all `17` subjects looks like following:
107
+
108
+ ![Demo](https://user-images.githubusercontent.com/28169943/49410670-bf51c500-f733-11e8-9894-43880aa8d49e.gif)
109
+
110
+ Isn't that cool? Do expect to see something like that with any other source localization method? If you realize you could use this method on your data, please feel free to use the codes. You can reach me at proloy@umd.edu if you have any issues with the codes. And don't forget to go over the papers/ posters before applying the algorithm.
111
+
112
+ ## Versioning and releases
113
+ The version is derived from git tags by [setuptools_scm](https://setuptools-scm.readthedocs.io); it is not stored in the source. A commit tagged `v0.5.0` builds as `0.5.0`; later commits build as a development version of the next release, e.g. `0.5.1.dev3+g1a2b3c4`. The installed version is available as `ncrf.__version__`.
114
+
115
+ To release, [create a release on GitHub](https://github.com/Eelbrain/neuro-currentRF/releases/new) with a new tag of the form `v0.5.0`. Publishing the release creates the tag and triggers the `wheels` workflow, which builds and tests the sdist and wheel and publishes them to [PyPI](https://pypi.org/project/ncrf/). Clones need the tags for the version to resolve (`git fetch --tags`); `pip install -e .` must be re-run for `ncrf.__version__` to reflect new tags.
116
+
117
+ The files involved:
118
+
119
+ - `pyproject.toml`: declares the version as dynamic and enables setuptools_scm (`[tool.setuptools_scm]`), which computes it from git at build time.
120
+ - `ncrf/__init__.py`: reads the version of the installed package from its metadata into `ncrf.__version__`.
121
+ - `.git_archival.txt` and `.gitattributes`: let GitHub archive downloads (`.zip`/`.tar.gz`), which have no git history, still carry the tag information.
122
+ - `.github/workflows/wheels.yml`: builds, tests and publishes the sdist and wheel; the other workflows check out the full history (`fetch-depth: 0`) so tags are available.
123
+ - `docs/conf.py`: takes the documentation version from `ncrf.__version__`.
124
+
125
+ ## References
126
+ [1] P. Das, C. Brodbeck, J. Z. Simon, B. Babadi, [Direct Cortical Localization of the MEG Auditory Temporal Response
127
+ Function: a Non-Convex Optimization Approach](https://isr.umd.edu/Labs/CSSL/simonlab/pubs/SFN2018.pdf); Proceedings
128
+ of the 47th Annual Neuroscience Meeting (SfN 2018), Nov. 2-7, San Diego, CA.
129
+
130
+ [2] P. Das, C. Brodbeck, J. Z. Simon, B. Babadi, [Cortical Localization of the Auditory Temporal Response Function from
131
+ MEG via Non-Convex Optimization](https://isr.umd.edu/Labs/CSSL/simonlab/pubs/Asilomar2018.pdf); 2018 Asilomar Conference
132
+ on Signals, Systems, and Computers, Oct. 28–31, Pacific Grove, CA (invited)
133
+
ncrf-0.5/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Build Status
2
+ ![test-posix](https://github.com/proloyd/neuro-currentRF/actions/workflows/test-posix.yml/badge.svg)
3
+
4
+ ![test-windows](https://github.com/proloyd/neuro-currentRF/actions/workflows/test-windows.yml/badge.svg)
5
+
6
+
7
+ # NCRF
8
+ The magnetoencephalography (MEG) response to continuous auditory stimuli, such as speech, is commonly described using a linear filter, the auditory temporal response function (TRF). Though components of the sensor level TRFs have been well characterized, the cortical distributions of the underlying neural responses are not well-understood. In our recent work, we provide a unified framework for determining the TRFs of neural sources directly from the MEG data, by integrating the TRF and distributed forward source models into one, and casting the joint estimation task as a Bayesian optimization problem. Though the resulting problem emerges as non-convex, we propose efficient solutions that leverage recent advances in evidence maximization. For more details please refer to [1], [2].
9
+
10
+ This repository contains the implementation of our direct TRF estimation algorithm in Python.
11
+
12
+ For code examples using real datasets, see the [Example gallery](https://eelbrain.github.io/neuro-currentRF/auto_examples/index.html).
13
+
14
+ The optimization algorithm is configurable independently of the forward model.
15
+ For a prepared `RegressionData` dataset, the lower-level API is:
16
+
17
+ ```python
18
+ from ncrf import ChampLasso, NCRFEstimator
19
+
20
+ estimator = NCRFEstimator.from_lead_field(lead_field, noise_covariance)
21
+ solver = ChampLasso(mu='auto', n_iter=30, n_iterc=10, n_iterf=100)
22
+ result = estimator.fit(data, solver)
23
+ ```
24
+
25
+ All solvers return a common predictive `NCRF` in `result.model`; training explained variance
26
+ is available as `result.scores['explained_variance']`. To score other data,
27
+ `result.model.evaluate(data, [explained_variance, l2_error])` predicts once and
28
+ returns all requested metrics. Solver-specific state is available as
29
+ `result.solver_fit`.
30
+
31
+
32
+ ## How to use:
33
+ run
34
+ ```python
35
+ result = fit_ncrf(meg, stim, lead_field, noise_covariance, mu='auto', tstop=1.0, basis_stride=2, n_splits=3, scale='l1')
36
+ ```
37
+ to perform a 3-fold cross-validation and then construct the model for 1s long TRF with the regularization weight among the given range that gives least generalization error. The signature of the ``meg`` and ``stim`` could be as follows:
38
+
39
+ [ megA (case, sensor, time), megB (case, sensor, time), ...]
40
+ [[featA1 (case, time), featA2 (case, time), ...], [featB1 (case, time), featB2 (case, time), ...], ...]
41
+
42
+ For more options, please look at the docstring. The learned TRF, `h` can be retrieved using:
43
+ ```python
44
+ h = result.model.h
45
+ ```
46
+
47
+ ## Results
48
+ We applied the algorithm on a subset of MEG data collected from 17 adults (aged 18-27 years) under an auditory task described in the papers. In short, during the task, the participants listened to `1 min` long segments from an audio-book recording of [The Legend of Sleepy Hollow by Washington Irving](https://librivox.org/the-legend-of-sleepy-hollow-by-washington-irving/), narrated by a male speaker. We consider localizing the TRFs using a total of `6 min` data from each participant. MNE-python 0.14 was used in pre-processing the raw data to automatically detect and discard flat channels, remove extraneous artifacts, and to band-pass filter the data in the range `1 - 80 Hz`. The six `1 min` long data epochs were then down-sampled to `200 Hz`. As the stimulus variable, we used the speech envelope reflecting the momentary acoustic power, by averaging the auditory spectrogram representation (generated using a model of the
49
+ auditory periphery) across the frequency bands, sampled at `200 Hz`. A volume source space for individual subjects was defined on a 3D regular grid with a resolution of `7 mm` in each direction. The lead-field matrix was then computed by placing free orientation virtual dipoles on the resulting `3322` grid points. The consistent components of our estimated `1 s`-long 3D TRFs across all `17` subjects looks like following:
50
+
51
+ ![Demo](https://user-images.githubusercontent.com/28169943/49410670-bf51c500-f733-11e8-9894-43880aa8d49e.gif)
52
+
53
+ Isn't that cool? Do expect to see something like that with any other source localization method? If you realize you could use this method on your data, please feel free to use the codes. You can reach me at proloy@umd.edu if you have any issues with the codes. And don't forget to go over the papers/ posters before applying the algorithm.
54
+
55
+ ## Versioning and releases
56
+ The version is derived from git tags by [setuptools_scm](https://setuptools-scm.readthedocs.io); it is not stored in the source. A commit tagged `v0.5.0` builds as `0.5.0`; later commits build as a development version of the next release, e.g. `0.5.1.dev3+g1a2b3c4`. The installed version is available as `ncrf.__version__`.
57
+
58
+ To release, [create a release on GitHub](https://github.com/Eelbrain/neuro-currentRF/releases/new) with a new tag of the form `v0.5.0`. Publishing the release creates the tag and triggers the `wheels` workflow, which builds and tests the sdist and wheel and publishes them to [PyPI](https://pypi.org/project/ncrf/). Clones need the tags for the version to resolve (`git fetch --tags`); `pip install -e .` must be re-run for `ncrf.__version__` to reflect new tags.
59
+
60
+ The files involved:
61
+
62
+ - `pyproject.toml`: declares the version as dynamic and enables setuptools_scm (`[tool.setuptools_scm]`), which computes it from git at build time.
63
+ - `ncrf/__init__.py`: reads the version of the installed package from its metadata into `ncrf.__version__`.
64
+ - `.git_archival.txt` and `.gitattributes`: let GitHub archive downloads (`.zip`/`.tar.gz`), which have no git history, still carry the tag information.
65
+ - `.github/workflows/wheels.yml`: builds, tests and publishes the sdist and wheel; the other workflows check out the full history (`fetch-depth: 0`) so tags are available.
66
+ - `docs/conf.py`: takes the documentation version from `ncrf.__version__`.
67
+
68
+ ## References
69
+ [1] P. Das, C. Brodbeck, J. Z. Simon, B. Babadi, [Direct Cortical Localization of the MEG Auditory Temporal Response
70
+ Function: a Non-Convex Optimization Approach](https://isr.umd.edu/Labs/CSSL/simonlab/pubs/SFN2018.pdf); Proceedings
71
+ of the 47th Annual Neuroscience Meeting (SfN 2018), Nov. 2-7, San Diego, CA.
72
+
73
+ [2] P. Das, C. Brodbeck, J. Z. Simon, B. Babadi, [Cortical Localization of the Auditory Temporal Response Function from
74
+ MEG via Non-Convex Optimization](https://isr.umd.edu/Labs/CSSL/simonlab/pubs/Asilomar2018.pdf); 2018 Asilomar Conference
75
+ on Signals, Systems, and Computers, Oct. 28–31, Pacific Grove, CA (invited)
76
+
ncrf-0.5/conftest.py ADDED
@@ -0,0 +1,14 @@
1
+ import pytest
2
+
3
+ _Dict = {'True': True, 'False': False}
4
+
5
+ # decide on cross-validation test from command line
6
+ def pytest_addoption(parser):
7
+ parser.addoption(
8
+ "--crossvalidation", action="store", default="False", help="run crossvalidation? True or False"
9
+ )
10
+
11
+
12
+ @pytest.fixture
13
+ def cmdopt(request):
14
+ return _Dict.get(request.config.getoption("--crossvalidation"), None)
ncrf-0.5/docs/Makefile ADDED
@@ -0,0 +1,36 @@
1
+ # Minimal makefile for Sphinx documentation
2
+ #
3
+
4
+ SPHINXOPTS ?= -nWT --keep-going
5
+ SPHINXBUILD ?= sphinx-build
6
+
7
+ .PHONY: help Makefile clean html html-noplot linkcheck linkcheck-grep view
8
+
9
+ first_target: help
10
+
11
+ help:
12
+ @echo "Please use \`make <target>' where <target> is one of"
13
+ @echo " html to make standalone HTML files"
14
+ @echo " html-noplot to make standalone HTML files without plotting"
15
+ @echo " clean to clean HTML files"
16
+ @echo " linkcheck to check all external links for integrity"
17
+ @echo " linkcheck-grep to grep the linkcheck result"
18
+ @echo " view to view the built HTML"
19
+
20
+ html:
21
+ $(SPHINXBUILD) . _build/html -b html $(SPHINXOPTS)
22
+
23
+ html-noplot:
24
+ $(SPHINXBUILD) . _build/html -b html $(SPHINXOPTS) -D plot_gallery=0
25
+
26
+ clean:
27
+ rm -rf _build generated
28
+
29
+ linkcheck:
30
+ $(SPHINXBUILD) . _build/linkcheck -b linkcheck -D plot_gallery=0
31
+
32
+ linkcheck-grep:
33
+ @! grep -h "^.*:.*: \[\(\(local\)\|\(broken\)\)\]" _build/linkcheck/output.txt
34
+
35
+ view:
36
+ @python -c "import webbrowser; webbrowser.open_new_tab('file://$(PWD)/_build/html/index.html')"