Skip to content

Commit

Permalink
FIX: Fix ELP coords
Browse files Browse the repository at this point in the history
  • Loading branch information
larsoner committed Nov 27, 2016
1 parent 23575dd commit 9e49e4a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 44 deletions.
2 changes: 1 addition & 1 deletion mne/channels/montage.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def read_montage(kind, ch_names=None, path=None, unit='m', transform=False):
az = data['f2']
horiz = data['f3']
radius = np.abs(az / 180.)
az = np.deg2rad(np.array([90. - h if a >= 0. else -90. - h
az = np.deg2rad(np.array([h if a >= 0. else 180 + h
for h, a in zip(horiz, az)]))
pol = radius * np.pi
pos = _sph_to_cart(np.array([np.ones(len(az)) * 85., az, pol]).T)
Expand Down
107 changes: 64 additions & 43 deletions mne/channels/tests/test_montage.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,68 +40,90 @@
def test_montage():
"""Test making montages."""
tempdir = _TempDir()
# no pep8
input_str = [
'FidNz 0.00000 10.56381 -2.05108\nFidT9 -7.82694 0.45386 -3.76056\n'
'very_very_very_long_name 7.82694 0.45386 -3.76056\nDmy 7.0 0.0 1.0',
'// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa: E501
'// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa: E501
'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa: E501
'E2 44.600 -0.880 1.000 0.7119 0.7021 -0.0154 0.00000000000000000\n' # noqa: E501
'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000\n' # noqa: E501
'E4 52.700 12.000 1.000 0.7084 0.7504 0.1508 0.00000000000000000', # noqa: E501; dummy line
'# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n'
'NumberPositions= 68\nPositions\n-86.0761 -19.9897 -47.9860\n'
'85.7939 -20.0093 -48.0310\n0.0083 86.8110 -39.9830\n'
'85 -20 -48\n'
'Labels\nLPA\nRPA\nNz\nDummy\n',
'# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n'
'NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n'
'.0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n'
'.08 -.02 -.04\n'
'Labels\nLPA\nRPA\nNz\nDummy\n',
'Site Theta Phi\nFp1 -92 -72\nFp2 92 72\n'
'very_very_very_long_name -60 -51\n'
'dummy -60 -52\n',
'346\n'
'EEG\t F3\t -62.027\t -50.053\t 85\n'
'EEG\t Fz\t 45.608\t 90\t 85\n'
'EEG\t F4\t 62.01\t 50.103\t 85\n'
'EEG\t FCz\t 68.01\t 58.103\t 85\n',
'eeg Fp1 -95.0 -3. -3.\neeg AF7 -1 -1 -3\neeg A3 -2 -2 2\neeg A 0 0 0'
]

kinds = ['test.sfp', 'test.csd', 'test_mm.elc', 'test_m.elc', 'test.txt',
'test.elp', 'test.hpts']
for kind, text in zip(kinds, input_str):
fname = op.join(tempdir, kind)
inputs = dict(
sfp='FidNz 0 9.071585155 -2.359754454\n'
'FidT9 -6.711765 0.040402876 -3.251600355\n'
'very_very_very_long_name -5.831241498 -4.494821698 4.955347697\n'
'Cz 0 0 8.899186843',
csd='// MatLab Sphere coordinates [degrees] Cartesian coordinates\n' # noqa: E501
'// Label Theta Phi Radius X Y Z off sphere surface\n' # noqa: E501
'E1 37.700 -14.000 1.000 0.7677 0.5934 -0.2419 -0.00000000000000011\n' # noqa: E501
'E3 51.700 11.000 1.000 0.6084 0.7704 0.1908 0.00000000000000000\n' # noqa: E501
'E31 90.000 -11.000 1.000 0.0000 0.9816 -0.1908 0.00000000000000000\n' # noqa: E501
'E61 158.000 -17.200 1.000 -0.8857 0.3579 -0.2957 -0.00000000000000022', # noqa: E501
mm_elc='# ASA electrode file\nReferenceLabel avg\nUnitPosition mm\n' # noqa:E501
'NumberPositions= 68\n'
'Positions\n'
'-86.0761 -19.9897 -47.9860\n'
'85.7939 -20.0093 -48.0310\n'
'0.0083 86.8110 -39.9830\n'
'-86.0761 -24.9897 -67.9860\n'
'Labels\nLPA\nRPA\nNz\nDummy\n',
m_elc='# ASA electrode file\nReferenceLabel avg\nUnitPosition m\n'
'NumberPositions= 68\nPositions\n-.0860761 -.0199897 -.0479860\n' # noqa:E501
'.0857939 -.0200093 -.0480310\n.0000083 .00868110 -.0399830\n'
'.08 -.02 -.04\n'
'Labels\nLPA\nRPA\nNz\nDummy\n',
txt='Site Theta Phi\n'
'Fp1 -92 -72\n'
'Fp2 92 72\n'
'very_very_very_long_name -92 72\n'
'O2 92 -90\n',
elp='346\n'
'EEG\t F3\t -62.027\t -50.053\t 85\n'
'EEG\t Fz\t 45.608\t 90\t 85\n'
'EEG\t F4\t 62.01\t 50.103\t 85\n'
'EEG\t FCz\t 68.01\t 58.103\t 85\n',
hpts='eeg Fp1 -95.0 -3. -3.\n'
'eeg AF7 -1 -1 -3\n'
'eeg A3 -2 -2 2\n'
'eeg A 0 0 0',
)
# Get actual positions and save them for checking
# csd comes from the string above, all others come from commit 2fa35d4
poss = dict(
sfp=[[0.0, 9.07159, -2.35975], [-6.71176, 0.0404, -3.2516],
[-5.83124, -4.49482, 4.95535], [0.0, 0.0, 8.89919]],
mm_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803],
[1e-05, 0.08681, -0.03998], [-0.08608, -0.02499, -0.06799]],
m_elc=[[-0.08608, -0.01999, -0.04799], [0.08579, -0.02001, -0.04803],
[1e-05, 0.00868, -0.03998], [0.08, -0.02, -0.04]],
txt=[[-26.25044, 80.79056, -2.96646], [26.25044, 80.79056, -2.96646],
[-26.25044, -80.79056, -2.96646], [0.0, -84.94822, -2.96646]],
elp=[[-48.20043, 57.55106, 39.86971], [0.0, 60.73848, 59.4629],
[48.1426, 57.58403, 39.89198], [41.64599, 66.91489, 31.8278]],
hpts=[[-95, -3, -3], [-1, -1., -3.], [-2, -2, 2.], [0, 0, 0]],
)
for key, text in inputs.items():
kind = key.split('_')[-1]
fname = op.join(tempdir, 'test.' + kind)
with open(fname, 'w') as fid:
fid.write(text)
montage = read_montage(fname)
if ".sfp" in kind or ".txt" in kind:
if kind in ('sfp', 'txt'):
assert_true('very_very_very_long_name' in montage.ch_names)
assert_equal(len(montage.ch_names), 4)
assert_equal(len(montage.ch_names), len(montage.pos))
assert_equal(montage.pos.shape, (4, 3))
assert_equal(montage.kind, op.splitext(kind)[0])
if kind.endswith('csd'):
assert_equal(montage.kind, 'test')
if kind == 'csd':
dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'),
('radius', 'f8'), ('x', 'f8'), ('y', 'f8'), ('z', 'f8'),
('off_sph', 'f8')]
try:
table = np.loadtxt(fname, skip_header=2, dtype=dtype)
except TypeError:
table = np.loadtxt(fname, skiprows=2, dtype=dtype)
pos2 = np.c_[table['x'], table['y'], table['z']]
assert_array_almost_equal(pos2[:-1, :], montage.pos[:-1, :], 4)
if kind.endswith('elc'):
poss['csd'] = np.c_[table['x'], table['y'], table['z']]
if kind == 'elc':
# Make sure points are reasonable distance from geometric centroid
centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0]
distance_from_centroid = np.apply_along_axis(
np.linalg.norm, 1,
montage.pos - centroid)
assert_array_less(distance_from_centroid, 0.2)
assert_array_less(0.01, distance_from_centroid)
assert_array_almost_equal(poss[key], montage.pos, 4, err_msg=key)

# Test reading in different letter case.
ch_names = ["F3", "FZ", "F4", "FC3", "FCz", "FC4", "C3", "CZ", "C4", "CP3",
Expand All @@ -118,8 +140,7 @@ def test_montage():
cardinal 1 0 -91 -42
cardinal 3 0 91 -42
"""
kind = 'test_fid.hpts'
fname = op.join(tempdir, kind)
fname = op.join(tempdir, 'test_fid.hpts')
with open(fname, 'w') as fid:
fid.write(input_str)
montage = read_montage(op.join(tempdir, 'test_fid.hpts'), transform=True)
Expand Down

0 comments on commit 9e49e4a

Please sign in to comment.