-
-
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
Changes from 11 commits
e0f8cc6
2159fb3
44cbe02
5dae7fa
e55859a
cebdf10
9064883
4091332
9bbf7a8
d65d8f8
7428812
599bbfd
b77459c
801c27f
28ff382
69bc74c
eef41f3
0a35722
03e6944
8033643
c04ad5c
059ae2f
7fc5db9
7e00eb5
a47743e
4675c64
4fb7463
27b8123
d60f88e
e465a1e
b7cfe66
9a4db53
e4ed607
acc71eb
e3a6c7b
28e2a50
11c30ee
4d4a80c
c990c8b
9228a01
e971fe8
5fac262
2640d12
2b17fb0
1ffa727
227fc24
717f2e6
4690830
726e282
20aa229
de264a0
bade068
c695f04
0ea038a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| MNI Coordinates | ||
|
|
||
| Brain Atlas Coordinate System Projection Method | ||
| MNI ICBM 152 nonlinear asymmetric 2009a MNI Coordinate System Scalp Projection | ||
|
|
||
| Fiducial x-Coordinate y-Coordinate z-Coordinate | ||
| Nz -4.62 82.33 -45.74 | ||
| Iz -4.90 -115.92 -31.92 | ||
| RPA 79.66 -18.72 -45.89 | ||
| LPA -81.41 -17.18 -45.56 | ||
| Cz 2.81 -12.59 96.67 | ||
|
|
||
| Optode x-Coordinate y-Coordinate z-Coordinate | ||
| Rx1 65.18 27.28 35.31 | ||
| Rx2 48.62 59.71 22.68 | ||
| Rx3 18.95 72.41 38.32 | ||
| Rx4 -3.97 79.74 30.28 | ||
| Rx5 -25.96 72.19 35.16 | ||
| Rx6 -52.51 60.53 14.54 | ||
| Rx7 -66.37 32.04 31.08 | ||
|
|
||
| Optode x-Coordinate y-Coordinate z-Coordinate | ||
| Tx1 76.10 -0.29 31.24 | ||
| Tx2 65.61 -0.26 56.15 | ||
| Tx3 64.93 42.43 8.29 | ||
| Tx4 43.32 46.36 50.77 | ||
| Tx5 21.58 82.45 1.06 | ||
| Tx6 -2.91 59.57 61.59 | ||
| Tx7 -29.62 79.35 2.38 | ||
| Tx8 -48.13 44.76 49.15 | ||
| Tx9 -67.68 43.26 -3.18 | ||
| Tx10 -65.37 4.89 56.36 | ||
| Tx11 -77.24 5.88 27.58 | ||
|
|
||
| Channel x-Coordinate y-Coordinate z-Coordinate | ||
| Rx1-Tx1 70.71 14.91 34.96 | ||
| Rx1-Tx2 65.96 11.27 48.41 | ||
| Rx1-Tx3 65.53 36.16 21.42 | ||
| Rx1-Tx4 55.49 36.06 44.50 | ||
| Rx2-Tx3 57.64 52.09 13.64 | ||
| Rx2-Tx4 46.47 52.98 38.87 | ||
| Rx2-Tx5 36.77 72.78 13.84 | ||
| Rx3-Tx4 34.91 59.03 45.54 | ||
| Rx3-Tx5 20.83 78.65 22.34 | ||
| Rx3-Tx6 7.44 68.09 50.48 | ||
| Rx4-Tx5 8.37 83.62 17.02 | ||
| Rx4-Tx6 -3.95 71.80 45.98 | ||
| Rx4-Tx7 -16.94 82.98 14.76 | ||
| Rx5-Tx6 -18.12 67.26 48.34 | ||
| Rx5-Tx7 -29.46 77.35 17.29 | ||
| Rx5-Tx8 -38.28 58.97 44.13 | ||
| Rx6-Tx7 -43.67 70.05 8.04 | ||
| Rx6-Tx8 -51.14 53.07 33.96 | ||
| Rx6-Tx9 -61.17 52.21 6.64 | ||
| Rx7-Tx8 -57.77 39.15 40.61 | ||
| Rx7-Tx9 -68.49 37.56 14.92 | ||
| Rx7-Tx10 -67.44 19.36 42.90 | ||
| Rx7-Tx11 -73.47 16.23 31.14 | ||
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| MNI Coordinates | ||
|
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. Once we are sure the elc file is correct we can delete these. Must be done before merge. |
||
|
|
||
| Brain Atlas Coordinate System Projection Method | ||
| MNI ICBM 152 nonlinear asymmetric 2009a MNI Coordinate System Scalp Projection | ||
|
|
||
| Fiducial x-Coordinate y-Coordinate z-Coordinate | ||
| Nz 0.96 83.56 -48.63 | ||
| Iz 0.33 -115.25 -34.65 | ||
| RPA 80.25 -19.67 -43.88 | ||
| LPA -82.58 -20.09 -43.10 | ||
| Cz 0.65 -12.86 96.78 | ||
|
|
||
| Optode x-Coordinate y-Coordinate z-Coordinate | ||
| Rx1 47.77 65.28 7.28 | ||
| Rx2 -46.45 67.76 8.81 | ||
|
|
||
| Optode x-Coordinate y-Coordinate z-Coordinate | ||
| Tx1 63.88 34.84 28.34 | ||
| Tx2 64.96 45.02 -10.31 | ||
| Tx3 22.07 74.86 31.03 | ||
| Tx4 17.84 84.96 -10.84 | ||
| Tx5 -10.81 77.96 32.10 | ||
| Tx6 -15.96 85.24 -7.41 | ||
| Tx7 -61.78 40.78 29.92 | ||
| Tx8 -65.28 48.14 -10.73 | ||
|
|
||
| Channel x-Coordinate y-Coordinate z-Coordinate | ||
| Rx1-Tx1 57.00 50.56 19.33 | ||
| Rx1-Tx2 57.12 56.10 1.26 | ||
| Rx1-Tx3 38.41 70.37 19.56 | ||
| Rx1-Tx4 32.83 76.89 -0.91 | ||
| Rx2-Tx5 -31.45 75.44 21.04 | ||
| Rx2-Tx6 -33.04 77.66 0.59 | ||
| Rx2-Tx7 -56.11 54.37 19.49 | ||
| Rx2-Tx8 -55.73 60.39 -1.00 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,7 +32,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, | ||
|
|
@@ -51,7 +51,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' | ||
| ] | ||
|
|
||
|
|
||
|
|
@@ -666,6 +667,35 @@ def _get_montage_in_head(montage): | |
| return transform_to_head(montage.copy()) | ||
|
|
||
|
|
||
| def _set_montage_fnirs(info, montage): | ||
| """ | ||
| Sets 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. | ||
| """ | ||
| # Modify info['chs'][_]['loc'] in place | ||
| num_ficiduals = len(montage.dig) - len(montage.ch_names) | ||
| picks = _picks_to_idx(info, 'fnirs', exclude=[], allow_empty=True) | ||
| for ch_idx in picks: | ||
| ch = info['ch_names'][ch_idx] | ||
| 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'): | ||
|
|
@@ -803,6 +833,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'] | ||
| # XXX info['chs'][_]['loc'] modified in place | ||
| _loc_view[:6] = _backcompat_value(ch_pos_use[use], eeg_ref_pos) | ||
|
|
||
| del ch_pos_use | ||
|
|
@@ -831,14 +862,22 @@ def _backcompat_value(pos, ref_pos): | |
| # in the old dig | ||
| if ref_dig_point in old_dig: | ||
| digpoints.append(ref_dig_point) | ||
| # XXX info['dig'] modified in place | ||
|
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. As above |
||
| info['dig'] = _format_dig_points(digpoints, enforce_order=True) | ||
|
|
||
| if mnt_head.dev_head_t is not None: | ||
| # XXX info['dev_head_t'] modified in place | ||
| info['dev_head_t'] = Transform('meg', 'head', mnt_head.dev_head_t) | ||
|
|
||
| fnirs_picks = _picks_to_idx(info, 'fnirs', allow_empty=True) | ||
| if len(fnirs_picks) > 0: | ||
| info = _set_montage_fnirs(info, montage) | ||
|
Member
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. To avoid the pain of the next person errantly using |
||
|
|
||
| else: # None case | ||
| # XXX info['dig'] modified in place | ||
|
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. As above |
||
| info['dig'] = None | ||
| for ch in info['chs']: | ||
| # XXX info['chs'][_]['loc'] modified in place | ||
| ch['loc'] = np.full(12, np.nan) | ||
|
|
||
|
|
||
|
|
@@ -1297,6 +1336,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 Brite 23 fNIRS (11 sources, 7 detectors) | ||
| =================== ===================================================== | ||
|
|
||
| .. versionadded:: 0.19.0 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once we are sure the elc file is correct we can delete this. Must be done before merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For those playing along at home...
In MNE we use the terminology source (S) and detector (D). These artinis files use the terminology transmitter (Tx) and receiver (Rx).