Skip to content

Commit

Permalink
BUG: Fix bug with fNIRS reordering (mne-tools#10630)
Browse files Browse the repository at this point in the history
* BUG: Fix bug with ordering

* DOC: Document temporary status
  • Loading branch information
larsoner authored May 16, 2022
1 parent 7f5b0f1 commit fd3112e
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 69 deletions.
2 changes: 1 addition & 1 deletion doc/overview/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ References
.. _`the most current version`: https://github.com/mne-tools/mne-python/releases/latest
.. _`minimal working example`: https://en.wikipedia.org/wiki/Minimal_Working_Example
.. _mri_watershed: https://freesurfer.net/fswiki/mri_watershed
.. _mri_watershed: https://surfer.nmr.mgh.harvard.edu/fswiki/mri_watershed
.. _mri_normalize: https://surfer.nmr.mgh.harvard.edu/fswiki/mri_normalize
.. _freeview: https://surfer.nmr.mgh.harvard.edu/fswiki/FreeviewGuide/FreeviewIntroduction
.. _`FreeSurfer listserv`: https://www.mail-archive.com/[email protected]/
Expand Down
2 changes: 1 addition & 1 deletion mne/channels/tests/test_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,6 @@ def test_interpolation_nirs():
assert bad_0_std_pre_interp > np.std(raw_od._data[bad_0])
raw_haemo = beer_lambert_law(raw_od, ppf=6)
raw_haemo.info['bads'] = raw_haemo.ch_names[2:4]
assert raw_haemo.info['bads'] == ['S10_D11 hbo', 'S10_D11 hbr']
assert raw_haemo.info['bads'] == ['S1_D2 hbo', 'S1_D2 hbr']
raw_haemo.interpolate_bads()
assert raw_haemo.info['bads'] == []
23 changes: 20 additions & 3 deletions mne/io/nirx/nirx.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from ..utils import _mult_cal_one
from ..constants import FIFF
from ..meas_info import create_info, _format_dig_points
from ..pick import pick_types
from ...annotations import Annotations
from ..._freesurfer import get_mni_fiducials
from ...transforms import apply_trans, _get_trans
Expand Down Expand Up @@ -458,9 +459,7 @@ def __init__(self, fname, saturated, preload=False, verbose=None):
ch_names.append(list())
annot = Annotations(onset, duration, description, ch_names=ch_names)
self.set_annotations(annot)

sort_idx = np.argsort(self.ch_names)
self.pick(picks=sort_idx)
self.pick(picks=_nirs_sort_idx(self.info))

def _read_segment_file(self, data, idx, fi, start, stop, cals, mult):
"""Read a segment of data from a file.
Expand Down Expand Up @@ -513,3 +512,21 @@ def _convert_fnirs_to_head(trans, fro, to, src_locs, det_locs, ch_locs):
det_locs = apply_trans(mri_head_t, det_locs)
ch_locs = apply_trans(mri_head_t, ch_locs)
return src_locs, det_locs, ch_locs, mri_head_t


def _nirs_sort_idx(info):
# TODO: Remove any actual reordering that is done and just use this
# function to get picks to operate on in an ordered way. This should be
# done by refactoring mne.preprocessing.nirs.nirs._check_channels_ordered
# and this function to make sure the picks we obtain here are in the
# correct order.
nirs_picks = pick_types(info, fnirs=True, exclude=())
other_picks = np.setdiff1d(np.arange(info['nchan']), nirs_picks)
prefixes = [info['ch_names'][pick].split()[0] for pick in nirs_picks]
nirs_names = [info['ch_names'][pick] for pick in nirs_picks]
nirs_sorted = sorted(nirs_names,
key=lambda name: (prefixes.index(name.split()[0]),
name.split(maxsplit=1)[1]))
nirs_picks = nirs_picks[
[nirs_names.index(name) for name in nirs_sorted]]
return np.concatenate((nirs_picks, other_picks))
106 changes: 64 additions & 42 deletions mne/io/nirx/tests/test_nirx.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def test_nirsport_v2_matches_snirf(fname_nirx, fname_snirf):
"""Test NIRSport2 raw files return same data as snirf."""
raw = read_raw_nirx(fname_nirx, preload=True)
raw_snirf = read_raw_snirf(fname_snirf, preload=True)
assert raw.ch_names == raw_snirf.ch_names

assert_allclose(raw._data, raw_snirf._data)

Expand Down Expand Up @@ -119,9 +120,9 @@ def test_nirsport_v2():
assert_allclose(
mni_locs[2], [-0.0841, -0.0138, 0.0248], atol=allowed_dist_error)

assert raw.info['ch_names'][13][3:5] == 'D5'
assert raw.info['ch_names'][34][3:5] == 'D5'
assert_allclose(
mni_locs[13], [0.0845, -0.0451, -0.0123], atol=allowed_dist_error)
mni_locs[34], [0.0845, -0.0451, -0.0123], atol=allowed_dist_error)

# Test location of sensors
# The locations of sensors can be seen in the second
Expand All @@ -141,7 +142,7 @@ def test_nirsport_v2():

assert raw.info['ch_names'][39][:2] == 'S8'
assert_allclose(
mni_locs[39], [0.0828, -0.046, 0.0285], atol=allowed_dist_error)
mni_locs[34], [0.0828, -0.046, 0.0285], atol=allowed_dist_error)

assert len(raw.annotations) == 3
assert raw.annotations.description[0] == '1.0'
Expand Down Expand Up @@ -291,7 +292,7 @@ def test_nirx_15_2_short():
# Test channel naming
assert raw.info['ch_names'][:4] == ["S1_D1 760", "S1_D1 850",
"S1_D9 760", "S1_D9 850"]
assert raw.info['ch_names'][24:26] == ["S5_D8 760", "S5_D8 850"]
assert raw.info['ch_names'][24:26] == ["S5_D13 760", "S5_D13 850"]

# Test frequency encoding
assert raw.info['chs'][0]['loc'][9] == 760
Expand Down Expand Up @@ -319,7 +320,7 @@ def test_nirx_15_2_short():
# These are the ones marked as red at
# https://github.com/mne-tools/mne-testing-data/pull/51 step 4 figure 2
is_short = short_channels(raw.info)
assert_array_equal(is_short[:9:2], [False, True, True, False, True])
assert_array_equal(is_short[:9:2], [False, True, False, True, False])
is_short = short_channels(raw.info, threshold=0.003)
assert_array_equal(is_short[:3:2], [False, False])
is_short = short_channels(raw.info, threshold=50)
Expand All @@ -346,29 +347,29 @@ def test_nirx_15_2_short():
assert_allclose(
mni_locs[0], [-0.0841, -0.0464, -0.0129], atol=allowed_dist_error)

assert raw.info['ch_names'][6][3:5] == 'D3'
assert raw.info['ch_names'][4][3:5] == 'D3'
assert_allclose(
mni_locs[6], [0.0846, -0.0142, -0.0156], atol=allowed_dist_error)
mni_locs[4], [0.0846, -0.0142, -0.0156], atol=allowed_dist_error)

assert raw.info['ch_names'][10][3:5] == 'D2'
assert raw.info['ch_names'][8][3:5] == 'D2'
assert_allclose(
mni_locs[10], [0.0207, -0.1062, 0.0484], atol=allowed_dist_error)
mni_locs[8], [0.0207, -0.1062, 0.0484], atol=allowed_dist_error)

assert raw.info['ch_names'][14][3:5] == 'D4'
assert raw.info['ch_names'][12][3:5] == 'D4'
assert_allclose(
mni_locs[14], [-0.0196, 0.0821, 0.0275], atol=allowed_dist_error)
mni_locs[12], [-0.0196, 0.0821, 0.0275], atol=allowed_dist_error)

assert raw.info['ch_names'][18][3:5] == 'D5'
assert raw.info['ch_names'][16][3:5] == 'D5'
assert_allclose(
mni_locs[18], [-0.0360, 0.0276, 0.0778], atol=allowed_dist_error)
mni_locs[16], [-0.0360, 0.0276, 0.0778], atol=allowed_dist_error)

assert raw.info['ch_names'][20][3:5] == 'D6'
assert raw.info['ch_names'][19][3:5] == 'D6'
assert_allclose(
mni_locs[20], [0.0352, 0.0283, 0.0780], atol=allowed_dist_error)
mni_locs[19], [0.0352, 0.0283, 0.0780], atol=allowed_dist_error)

assert raw.info['ch_names'][23][3:5] == 'D7'
assert raw.info['ch_names'][21][3:5] == 'D7'
assert_allclose(
mni_locs[23], [0.0388, -0.0477, 0.0932], atol=allowed_dist_error)
mni_locs[21], [0.0388, -0.0477, 0.0932], atol=allowed_dist_error)


@requires_testing_data
Expand All @@ -383,7 +384,7 @@ def test_nirx_15_3_short():
# Test channel naming
assert raw.info['ch_names'][:4] == ["S1_D2 760", "S1_D2 850",
"S1_D9 760", "S1_D9 850"]
assert raw.info['ch_names'][24:26] == ["S5_D8 760", "S5_D8 850"]
assert raw.info['ch_names'][24:26] == ["S5_D13 760", "S5_D13 850"]

# Test frequency encoding
assert raw.info['chs'][0]['loc'][9] == 760
Expand Down Expand Up @@ -411,7 +412,7 @@ def test_nirx_15_3_short():
# These are the ones marked as red at
# https://github.com/mne-tools/mne-testing-data/pull/72
is_short = short_channels(raw.info)
assert_array_equal(is_short[:9:2], [False, True, False, True, True])
assert_array_equal(is_short[:9:2], [False, True, False, True, False])
is_short = short_channels(raw.info, threshold=0.003)
assert_array_equal(is_short[:3:2], [False, False])
is_short = short_channels(raw.info, threshold=50)
Expand All @@ -438,25 +439,25 @@ def test_nirx_15_3_short():
assert_allclose(
mni_locs[4], [0.0846, -0.0142, -0.0156], atol=allowed_dist_error)

assert raw.info['ch_names'][10][3:5] == 'D3'
assert raw.info['ch_names'][8][3:5] == 'D3'
assert_allclose(
mni_locs[10], [0.0207, -0.1062, 0.0484], atol=allowed_dist_error)
mni_locs[8], [0.0207, -0.1062, 0.0484], atol=allowed_dist_error)

assert raw.info['ch_names'][14][3:5] == 'D4'
assert raw.info['ch_names'][12][3:5] == 'D4'
assert_allclose(
mni_locs[14], [-0.0196, 0.0821, 0.0275], atol=allowed_dist_error)
mni_locs[12], [-0.0196, 0.0821, 0.0275], atol=allowed_dist_error)

assert raw.info['ch_names'][18][3:5] == 'D5'
assert raw.info['ch_names'][16][3:5] == 'D5'
assert_allclose(
mni_locs[18], [-0.0360, 0.0276, 0.0778], atol=allowed_dist_error)
mni_locs[16], [-0.0360, 0.0276, 0.0778], atol=allowed_dist_error)

assert raw.info['ch_names'][20][3:5] == 'D6'
assert raw.info['ch_names'][19][3:5] == 'D6'
assert_allclose(
mni_locs[20], [0.0388, -0.0477, 0.0932], atol=allowed_dist_error)
mni_locs[19], [0.0388, -0.0477, 0.0932], atol=allowed_dist_error)

assert raw.info['ch_names'][22][3:5] == 'D7'
assert raw.info['ch_names'][21][3:5] == 'D7'
assert_allclose(
mni_locs[22], [-0.0394, -0.0483, 0.0928], atol=allowed_dist_error)
mni_locs[21], [-0.0394, -0.0483, 0.0928], atol=allowed_dist_error)


@requires_testing_data
Expand Down Expand Up @@ -504,8 +505,8 @@ def test_nirx_15_2():
tzinfo=dt.timezone.utc)

# Test channel naming
assert raw.info['ch_names'][:4] == ["S10_D10 760", "S10_D10 850",
"S10_D9 760", "S10_D9 850"]
assert raw.info['ch_names'][:4] == ["S1_D1 760", "S1_D1 850",
"S1_D10 760", "S1_D10 850"]

# Test info import
assert raw.info['subject_info'] == dict(sex=1, first_name="TestRecording",
Expand All @@ -522,13 +523,13 @@ def test_nirx_15_2():
head_mri_t, _ = _get_trans('fsaverage', 'head', 'mri')
mni_locs = apply_trans(head_mri_t, locs)

assert raw.info['ch_names'][28][3:5] == 'D1'
assert raw.info['ch_names'][0][3:5] == 'D1'
assert_allclose(
mni_locs[28], [-0.0292, 0.0852, -0.0142], atol=allowed_dist_error)
mni_locs[0], [-0.0292, 0.0852, -0.0142], atol=allowed_dist_error)

assert raw.info['ch_names'][42][3:5] == 'D4'
assert raw.info['ch_names'][15][3:5] == 'D4'
assert_allclose(
mni_locs[42], [-0.0739, -0.0756, -0.0075], atol=allowed_dist_error)
mni_locs[15], [-0.0739, -0.0756, -0.0075], atol=allowed_dist_error)

# Old name aliases for backward compat
assert 'fnirs_cw_amplitude' in raw
Expand All @@ -552,12 +553,12 @@ def test_nirx_15_0():
tzinfo=dt.timezone.utc)

# Test channel naming
assert raw.info['ch_names'][:12] == ["S10_D10 760", "S10_D10 850",
"S1_D1 760", "S1_D1 850",
assert raw.info['ch_names'][:12] == ["S1_D1 760", "S1_D1 850",
"S2_D2 760", "S2_D2 850",
"S3_D3 760", "S3_D3 850",
"S4_D4 760", "S4_D4 850",
"S5_D5 760", "S5_D5 850"]
"S5_D5 760", "S5_D5 850",
"S6_D6 760", "S6_D6 850"]

# Test info import
assert raw.info['subject_info'] == {'birthday': (2004, 10, 27),
Expand All @@ -575,13 +576,13 @@ def test_nirx_15_0():
head_mri_t, _ = _get_trans('fsaverage', 'head', 'mri')
mni_locs = apply_trans(head_mri_t, locs)

assert raw.info['ch_names'][2][3:5] == 'D1'
assert raw.info['ch_names'][0][3:5] == 'D1'
assert_allclose(
mni_locs[2], [0.0287, -0.1143, -0.0332], atol=allowed_dist_error)
mni_locs[0], [0.0287, -0.1143, -0.0332], atol=allowed_dist_error)

assert raw.info['ch_names'][17][3:5] == 'D8'
assert raw.info['ch_names'][15][3:5] == 'D8'
assert_allclose(
mni_locs[17], [-0.0693, -0.0480, 0.0657], atol=allowed_dist_error)
mni_locs[15], [-0.0693, -0.0480, 0.0657], atol=allowed_dist_error)

# Test distance between optodes matches values from
allowed_distance_error = 0.0002
Expand All @@ -605,3 +606,24 @@ def test_nirx_standard(fname, boundary_decimal):
"""Test standard operations."""
_test_raw_reader(read_raw_nirx, fname=fname,
boundary_decimal=boundary_decimal) # low fs


# Below are the native (on-disk) orders, which should be preserved
@requires_testing_data
@pytest.mark.parametrize('fname, want_order', [
(fname_nirx_15_0, ['S1_D1', 'S2_D2', 'S3_D3', 'S4_D4', 'S5_D5', 'S6_D6', 'S7_D7', 'S8_D8', 'S9_D9', 'S10_D10']), # noqa: E501
(fname_nirx_15_2, ['S1_D1', 'S1_D10', 'S2_D1', 'S2_D2', 'S3_D2', 'S3_D3', 'S4_D3', 'S4_D4', 'S5_D4', 'S5_D5', 'S6_D5', 'S6_D6', 'S7_D6', 'S7_D7', 'S8_D7', 'S8_D8', 'S9_D8', 'S9_D9', 'S10_D9', 'S10_D10', 'S11_D11', 'S11_D12', 'S12_D12', 'S12_D13', 'S13_D13', 'S13_D14', 'S14_D14', 'S14_D15', 'S15_D15', 'S15_D16', 'S16_D11', 'S16_D16']), # noqa: E501
(fname_nirx_15_2_short, ['S1_D1', 'S1_D9', 'S2_D3', 'S2_D10', 'S3_D2', 'S3_D11', 'S4_D4', 'S4_D12', 'S5_D5', 'S5_D6', 'S5_D7', 'S5_D8', 'S5_D13']), # noqa: E501
(fname_nirx_15_3_short, ['S1_D2', 'S1_D9', 'S2_D1', 'S2_D10', 'S3_D3', 'S3_D11', 'S4_D4', 'S4_D12', 'S5_D5', 'S5_D6', 'S5_D7', 'S5_D8', 'S5_D13']), # noqa: E501
(nirsport1_wo_sat, ['S1_D4', 'S1_D5', 'S1_D6', 'S2_D5', 'S2_D6', 'S3_D5', 'S4_D1', 'S4_D3', 'S4_D4', 'S5_D1', 'S5_D2', 'S6_D1', 'S6_D3']), # noqa: E501
(nirsport2, ['S1_D1', 'S1_D6', 'S1_D9', 'S2_D2', 'S2_D10', 'S3_D5', 'S3_D7', 'S3_D11', 'S4_D8', 'S4_D12', 'S5_D3', 'S5_D13', 'S6_D4', 'S6_D14', 'S7_D1', 'S7_D6', 'S7_D15', 'S8_D5', 'S8_D7', 'S8_D16']), # noqa: E501
(nirsport2_2021_9, ['S1_D1', 'S1_D3', 'S2_D1', 'S2_D2', 'S2_D4', 'S3_D2', 'S3_D5', 'S4_D1', 'S4_D3', 'S4_D4', 'S4_D6', 'S5_D2', 'S5_D4', 'S5_D5', 'S5_D7', 'S6_D3', 'S6_D6', 'S7_D4', 'S7_D6', 'S7_D7', 'S8_D5', 'S8_D7']), # noqa: E501
])
def test_channel_order(fname, want_order):
"""Test that logical channel order is preserved."""
raw = read_raw_nirx(fname)
ch_names = raw.ch_names
prefixes = [ch_name.split()[0] for ch_name in ch_names]
assert prefixes[::2] == prefixes[1::2]
prefixes = prefixes[::2]
assert prefixes == want_order
5 changes: 2 additions & 3 deletions mne/io/snirf/_snirf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from ..constants import FIFF
from .._digitization import _make_dig_points
from ...transforms import _frame_to_str, apply_trans
from ..nirx.nirx import _convert_fnirs_to_head
from ..nirx.nirx import _convert_fnirs_to_head, _nirs_sort_idx
from ..._freesurfer import get_mni_fiducials


Expand Down Expand Up @@ -411,8 +411,7 @@ def natural_keys(text):

# MNE requires channels are paired as alternating wavelengths
if len(_validate_nirs_info(self.info, throw_errors=False)) == 0:
sort_idx = np.argsort(self.ch_names)
self.pick(picks=sort_idx)
self.pick(picks=_nirs_sort_idx(self.info))

# Validate that the fNIRS info is correctly formatted
_validate_nirs_info(self.info)
Expand Down
31 changes: 27 additions & 4 deletions mne/io/snirf/tests/test_snirf.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,24 @@ def test_snirf_gowerlabs():
assert raw.info['dig'][0]['coord_frame'] == FIFF.FIFFV_COORD_HEAD
assert len(raw.ch_names) == 216
assert_allclose(raw.info['sfreq'], 10.0)
# we don't force them to be sorted according to a naive split
# (but we do force them to be interleaved, which is tested by beer_lambert
# above)
assert raw.ch_names != sorted(raw.ch_names)
# ... and this file does have a nice logical ordering already
assert raw.ch_names == sorted(
raw.ch_names, # use a key which is (source int, detector int)
key=lambda name: (int(name.split()[0].split('_')[0][1:]),
int(name.split()[0].split('_')[1][1:])))
prefixes = [name.split()[0] for name in raw.ch_names]
# TODO: This is actually not the order on disk -- we reorder to ravel as
# S-D then freq, but gowerlabs order is freq then S-D. So hopefully soon
# we can change these lines to check that the first half of prefixes
# matches the second half of prefixes, rather than every-other matching the
# other every-other
assert prefixes[::2] == prefixes[1::2]
prefixes = prefixes[::2]
assert prefixes == ['S1_D1', 'S1_D2', 'S1_D3', 'S1_D4', 'S1_D5', 'S1_D6', 'S1_D7', 'S1_D8', 'S1_D9', 'S1_D10', 'S1_D11', 'S1_D12', 'S2_D1', 'S2_D2', 'S2_D3', 'S2_D4', 'S2_D5', 'S2_D6', 'S2_D7', 'S2_D8', 'S2_D9', 'S2_D10', 'S2_D11', 'S2_D12', 'S3_D1', 'S3_D2', 'S3_D3', 'S3_D4', 'S3_D5', 'S3_D6', 'S3_D7', 'S3_D8', 'S3_D9', 'S3_D10', 'S3_D11', 'S3_D12', 'S4_D1', 'S4_D2', 'S4_D3', 'S4_D4', 'S4_D5', 'S4_D6', 'S4_D7', 'S4_D8', 'S4_D9', 'S4_D10', 'S4_D11', 'S4_D12', 'S5_D1', 'S5_D2', 'S5_D3', 'S5_D4', 'S5_D5', 'S5_D6', 'S5_D7', 'S5_D8', 'S5_D9', 'S5_D10', 'S5_D11', 'S5_D12', 'S6_D1', 'S6_D2', 'S6_D3', 'S6_D4', 'S6_D5', 'S6_D6', 'S6_D7', 'S6_D8', 'S6_D9', 'S6_D10', 'S6_D11', 'S6_D12', 'S7_D1', 'S7_D2', 'S7_D3', 'S7_D4', 'S7_D5', 'S7_D6', 'S7_D7', 'S7_D8', 'S7_D9', 'S7_D10', 'S7_D11', 'S7_D12', 'S8_D1', 'S8_D2', 'S8_D3', 'S8_D4', 'S8_D5', 'S8_D6', 'S8_D7', 'S8_D8', 'S8_D9', 'S8_D10', 'S8_D11', 'S8_D12', 'S9_D1', 'S9_D2', 'S9_D3', 'S9_D4', 'S9_D5', 'S9_D6', 'S9_D7', 'S9_D8', 'S9_D9', 'S9_D10', 'S9_D11', 'S9_D12'] # noqa: E501


@requires_testing_data
Expand All @@ -106,6 +124,7 @@ def test_snirf_basic():
# Test channel naming
assert raw.info['ch_names'][:4] == ["S1_D1 760", "S1_D1 850",
"S1_D9 760", "S1_D9 850"]
assert raw.info['ch_names'][24:26] == ["S5_D13 760", "S5_D13 850"]

# Test frequency encoding
assert raw.info['chs'][0]['loc'][9] == 760
Expand Down Expand Up @@ -206,9 +225,9 @@ def test_snirf_nirsport2():
assert_almost_equal(raw.info['sfreq'], 7.6, decimal=1)

# Test channel naming
assert raw.info['ch_names'][:4] == ['S10_D3 760', 'S10_D3 850',
'S10_D9 760', 'S10_D9 850']
assert raw.info['ch_names'][24:26] == ['S15_D11 760', 'S15_D11 850']
assert raw.info['ch_names'][:4] == ['S1_D1 760', 'S1_D1 850',
'S1_D3 760', 'S1_D3 850']
assert raw.info['ch_names'][24:26] == ['S6_D4 760', 'S6_D4 850']

# Test frequency encoding
assert raw.info['chs'][0]['loc'][9] == 760
Expand Down Expand Up @@ -246,7 +265,7 @@ def test_snirf_nirsport2_w_positions():
# Test channel naming
assert raw.info['ch_names'][:4] == ['S1_D1 760', 'S1_D1 850',
'S1_D6 760', 'S1_D6 850']
assert raw.info['ch_names'][24:26] == ['S6_D14 760', 'S6_D14 850']
assert raw.info['ch_names'][24:26] == ['S6_D4 760', 'S6_D4 850']

# Test frequency encoding
assert raw.info['chs'][0]['loc'][9] == 760
Expand Down Expand Up @@ -282,6 +301,10 @@ def test_snirf_nirsport2_w_positions():
assert_allclose(
mni_locs[2], [-0.0841, -0.0138, 0.0248], atol=allowed_dist_error)

assert raw.info['ch_names'][34][3:5] == 'D5'
assert_allclose(
mni_locs[34], [0.0845, -0.0451, -0.0123], atol=allowed_dist_error)

# Test location of sensors
# The locations of sensors can be seen in the second
# figure on this page...
Expand Down
Loading

0 comments on commit fd3112e

Please sign in to comment.