-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
WIP: Adds support for fNIRS data to set_montage and new standard artinis montage #9141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
e0f8cc6
Add raw montage files sent by Artinis
HanBnrd 2159fb3
Initial pseudo code
rob-luke 44cbe02
Tweaks
rob-luke 5dae7fa
Draft _set_montage_fnirs
HanBnrd e55859a
Tweaks
rob-luke cebdf10
Example with optode montage as elc file
HanBnrd 9064883
Clean up and add Brite 23
HanBnrd 4091332
Merge branch 'main' into artinis-montages
HanBnrd 9bbf7a8
Tweak skeleton code and push example
rob-luke d65d8f8
Add TODOs
HanBnrd 7428812
Update also dig
HanBnrd 599bbfd
Fix optodes in the brain
HanBnrd b77459c
Add fetch_fsaverage
HanBnrd 801c27f
Merge branch 'main' into artinis-montages
HanBnrd 28ff382
Set montage with str in tutorial
HanBnrd 69bc74c
Add example of how to load unstructured data [ci skip]
rob-luke eef41f3
Typo [skip github] [azp skip]
rob-luke 0a35722
More typos [skip github] [azp skip]
rob-luke 03e6944
Typos [skip github] [azp skip]
rob-luke 8033643
Merge remote-tracking branch 'upstream/main' into artinis-montages
rob-luke c04ad5c
Fix linking [azp skip] [skip github]
rob-luke 059ae2f
Small doc tweaks [azp skip] [github skip]
rob-luke 7fc5db9
Add tests. More needed
rob-luke 7e00eb5
More tests
rob-luke a47743e
Update doc and tests
HanBnrd 4675c64
Fix pydocstyle
HanBnrd 4fb7463
Add more warning and limitations
rob-luke 27b8123
added wrong file
rob-luke d60f88e
Fix reverted source and detector
HanBnrd e465a1e
Merge branch 'artinis-montages' of https://github.com/HanBnrd/mne-pyt…
HanBnrd b7cfe66
Typo
rob-luke 9a4db53
More warnings
rob-luke e4ed607
Check fNIRS ch_names and add wavelength
HanBnrd acc71eb
Merge branch 'main' into artinis-montages
HanBnrd e3a6c7b
No modification of wavelength
HanBnrd 28e2a50
Test Brite, intensity, OD
HanBnrd 11c30ee
Merge branch 'main' into artinis-montages
HanBnrd 4d4a80c
Use _check_channels_ordered with new API
HanBnrd c990c8b
Merge branch 'main' into artinis-montages
HanBnrd 9228a01
Simplify _set_montage_fnirs
HanBnrd e971fe8
Add tests for channel variations
HanBnrd 5fac262
TST: Test rough equivalent with fsaverage
larsoner 2640d12
Test 2 more built in montages (OctaMon & Brite 23)
HanBnrd 2b17fb0
Update tutorial
HanBnrd 1ffa727
Merge branch 'main' into artinis-montages
HanBnrd 227fc24
Describe changes
HanBnrd 717f2e6
Update latest
HanBnrd 4690830
Apply suggestions from code review
HanBnrd 726e282
Merge branch 'main' into artinis-montages
HanBnrd 20aa229
Fix ref
HanBnrd de264a0
Update in-line comments
HanBnrd bade068
Merge branch 'main' into artinis-montages
HanBnrd c695f04
Fix refs
HanBnrd 0ea038a
Move channel info and add read_custom_montage
HanBnrd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # ASA optode file | ||
| ReferenceLabel avg | ||
| UnitPosition mm | ||
| NumberPositions= 21 | ||
| Positions | ||
| -4.62 82.33 -45.74 | ||
| 79.66 -18.72 -45.89 | ||
| -81.41 -17.18 -45.56 | ||
| 65.18 27.28 35.31 | ||
| 48.62 59.71 22.68 | ||
| 18.95 72.41 38.32 | ||
| -3.97 79.74 30.28 | ||
| -25.96 72.19 35.16 | ||
| -52.51 60.53 14.54 | ||
| -66.37 32.04 31.08 | ||
| 76.10 -0.29 31.24 | ||
| 65.61 -0.26 56.15 | ||
| 64.93 42.43 8.29 | ||
| 43.32 46.36 50.77 | ||
| 21.58 82.45 1.06 | ||
| -2.91 59.57 61.59 | ||
| -29.62 79.35 2.38 | ||
| -48.13 44.76 49.15 | ||
| -67.68 43.26 -3.18 | ||
| -65.37 4.89 56.36 | ||
| -77.24 5.88 27.58 | ||
| Labels | ||
| Nz | ||
| RPA | ||
| LPA | ||
| D1 | ||
| D2 | ||
| D3 | ||
| D4 | ||
| D5 | ||
| D6 | ||
| D7 | ||
| S1 | ||
| S2 | ||
| S3 | ||
| S4 | ||
| S5 | ||
| S6 | ||
| S7 | ||
| S8 | ||
| S9 | ||
| S10 | ||
| S11 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # ASA optode file | ||
| ReferenceLabel avg | ||
| UnitPosition mm | ||
| NumberPositions= 13 | ||
| Positions | ||
| 0.96 83.56 -48.63 | ||
| 80.25 -19.67 -43.88 | ||
| -82.58 -20.09 -43.10 | ||
| 47.77 65.28 7.28 | ||
| -46.45 67.76 8.81 | ||
| 63.88 34.84 28.34 | ||
| 64.96 45.02 -10.31 | ||
| 22.07 74.86 31.03 | ||
| 17.84 84.96 -10.84 | ||
| -10.81 77.96 32.10 | ||
| -15.96 85.24 -7.41 | ||
| -61.78 40.78 29.92 | ||
| -65.28 48.14 -10.73 | ||
| Labels | ||
| Nz | ||
| RPA | ||
| LPA | ||
| D1 | ||
| D2 | ||
| S1 | ||
| S2 | ||
| S3 | ||
| S4 | ||
| S5 | ||
| S6 | ||
| S7 | ||
| S8 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -33,7 +33,7 @@ | |||||||
| _get_data_as_dict_from_dig) | ||||||||
| from ..io.meas_info import create_info | ||||||||
| from ..io.open import fiff_open | ||||||||
| from ..io.pick import pick_types | ||||||||
| from ..io.pick import pick_types, _picks_to_idx | ||||||||
| from ..io.constants import FIFF, CHANNEL_LOC_ALIASES | ||||||||
| from ..utils import (warn, copy_function_doc_to_method_doc, _pl, verbose, | ||||||||
| _check_option, _validate_type, _check_fname, _on_missing, | ||||||||
|
|
@@ -52,7 +52,8 @@ | |||||||
| 'easycap-M1', 'easycap-M10', | ||||||||
| 'mgh60', 'mgh70', | ||||||||
| 'standard_1005', 'standard_1020', 'standard_alphabetic', | ||||||||
| 'standard_postfixed', 'standard_prefixed', 'standard_primed' | ||||||||
| 'standard_postfixed', 'standard_prefixed', 'standard_primed', | ||||||||
| 'artinis-octamon', 'artinis-brite23' | ||||||||
| ] | ||||||||
|
|
||||||||
|
|
||||||||
|
|
@@ -725,6 +726,47 @@ def _get_montage_in_head(montage): | |||||||
| return transform_to_head(montage.copy()) | ||||||||
|
|
||||||||
|
|
||||||||
| def _set_montage_fnirs(info, montage): | ||||||||
| """Set the montage for fNIRS data. | ||||||||
|
|
||||||||
| This needs to be different to electrodes as each channel has three | ||||||||
| coordinates that need to be set. For each channel there is a source optode | ||||||||
| location, a detector optode location, and a channel midpoint that must be | ||||||||
| stored. This function modifies info['chs'][#]['loc'] and info['dig'] in | ||||||||
| place. | ||||||||
| """ | ||||||||
| from ..preprocessing.nirs import (_channel_frequencies, | ||||||||
| _channel_chromophore, | ||||||||
| _check_channels_ordered) | ||||||||
| # Validate that the fNIRS info is correctly formatted | ||||||||
| freqs = np.unique(_channel_frequencies(info)) | ||||||||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| if freqs.size > 0: | ||||||||
| picks = _check_channels_ordered(info, freqs) | ||||||||
| else: | ||||||||
| picks = _check_channels_ordered(info, | ||||||||
| np.unique(_channel_chromophore(info))) | ||||||||
|
|
||||||||
| # Modify info['chs'][#]['loc'] in place | ||||||||
| num_ficiduals = len(montage.dig) - len(montage.ch_names) | ||||||||
| for ch_idx in picks: | ||||||||
| ch = info['chs'][ch_idx]['ch_name'] | ||||||||
| source, detector = ch.split(' ')[0].split('_') | ||||||||
| source_pos = montage.dig[montage.ch_names.index(source) | ||||||||
| + num_ficiduals]['r'] | ||||||||
| detector_pos = montage.dig[montage.ch_names.index(detector) | ||||||||
| + num_ficiduals]['r'] | ||||||||
|
|
||||||||
| info['chs'][ch_idx]['loc'][3:6] = source_pos | ||||||||
| info['chs'][ch_idx]['loc'][6:9] = detector_pos | ||||||||
| midpoint = (source_pos + detector_pos) / 2 | ||||||||
| info['chs'][ch_idx]['loc'][:3] = midpoint | ||||||||
|
|
||||||||
| # Modify info['dig'] in place | ||||||||
| info['dig'] = montage.dig | ||||||||
|
|
||||||||
| return info | ||||||||
|
|
||||||||
|
|
||||||||
| @fill_doc | ||||||||
| def _set_montage(info, montage, match_case=True, match_alias=False, | ||||||||
| on_missing='raise'): | ||||||||
|
|
@@ -758,6 +800,7 @@ def _set_montage(info, montage, match_case=True, match_alias=False, | |||||||
|
|
||||||||
| if isinstance(montage, DigMontage): | ||||||||
| mnt_head = _get_montage_in_head(montage) | ||||||||
| del montage | ||||||||
larsoner marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
|
||||||||
| def _backcompat_value(pos, ref_pos): | ||||||||
| if any(np.isnan(pos)): | ||||||||
|
|
@@ -862,6 +905,7 @@ def _backcompat_value(pos, ref_pos): | |||||||
|
|
||||||||
| for name, use in zip(info_names, info_names_use): | ||||||||
| _loc_view = info['chs'][info['ch_names'].index(name)]['loc'] | ||||||||
| # Next line modifies info['chs'][#]['loc'] in place | ||||||||
| _loc_view[:6] = _backcompat_value(ch_pos_use[use], eeg_ref_pos) | ||||||||
|
|
||||||||
| del ch_pos_use | ||||||||
|
|
@@ -890,14 +934,23 @@ def _backcompat_value(pos, ref_pos): | |||||||
| # in the old dig | ||||||||
| if ref_dig_point in old_dig: | ||||||||
| digpoints.append(ref_dig_point) | ||||||||
| # Next line modifies info['dig'] in place | ||||||||
| info['dig'] = _format_dig_points(digpoints, enforce_order=True) | ||||||||
|
|
||||||||
| if mnt_head.dev_head_t is not None: | ||||||||
| # Next line modifies info['dev_head_t'] in place | ||||||||
| info['dev_head_t'] = Transform('meg', 'head', mnt_head.dev_head_t) | ||||||||
|
|
||||||||
| # Handle fNIRS with source, detector and channel | ||||||||
| fnirs_picks = _picks_to_idx(info, 'fnirs', allow_empty=True) | ||||||||
| if len(fnirs_picks) > 0: | ||||||||
| info = _set_montage_fnirs(info, mnt_head) | ||||||||
|
|
||||||||
| else: # None case | ||||||||
| # Next line modifies info['dig'] in place | ||||||||
| info['dig'] = None | ||||||||
| for ch in info['chs']: | ||||||||
| # Next line modifies info['chs'][#]['loc'] in place | ||||||||
| ch['loc'] = np.full(12, np.nan) | ||||||||
|
|
||||||||
|
|
||||||||
|
|
@@ -1361,6 +1414,10 @@ def make_standard_montage(kind, head_size=HEAD_SIZE_DEFAULT): | |||||||
| MGH (60+3 locations) | ||||||||
| mgh70 The (newer) 70-channel BrainVision cap used at | ||||||||
| MGH (70+3 locations) | ||||||||
|
|
||||||||
| artinis-octamon Artinis OctaMon fNIRS (8 sources, 2 detectors) | ||||||||
|
|
||||||||
| artinis-brite23 Artinis Brite23 fNIRS (11 sources, 7 detectors) | ||||||||
| =================== ===================================================== | ||||||||
|
|
||||||||
| .. versionadded:: 0.19.0 | ||||||||
|
|
||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.