Repository: mne-tools/mne-python

Issue:
#3613 causes problems with loading .elps
After #3613, loading a normal .elp file, I get

```
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-11-eab9d558a983> in <module>()
      1 fname = fnames[2]
----> 2 mne.io.read_raw_brainvision(fname, montage=montage, preload=True, eog=[])

/home/FB/fb05/sassenha/tools/mne-python/mne/io/brainvision/brainvision.py in read_raw_brainvision(vhdr_fname, montage, eog, misc, scale, preload, response_trig_shift, event_id, verbose)
    689                           misc=misc, scale=scale, preload=preload,
    690                           response_trig_shift=response_trig_shift,
--> 691                           event_id=event_id, verbose=verbose)

/home/FB/fb05/sassenha/tools/mne-python/mne/io/brainvision/brainvision.py in __init__(self, vhdr_fname, montage, eog, misc, scale, preload, response_trig_shift, event_id, verbose)

/home/FB/fb05/sassenha/tools/mne-python/mne/utils.py in verbose(function, *args, **kwargs)
    682         with use_log_level(verbose_level):
    683             return function(*args, **kwargs)
--> 684     return function(*args, **kwargs)
    685 
    686 

/home/FB/fb05/sassenha/tools/mne-python/mne/io/brainvision/brainvision.py in __init__(self, vhdr_fname, montage, eog, misc, scale, preload, response_trig_shift, event_id, verbose)
     83             vhdr_fname, eog, misc, scale, montage)
     84         events = _read_vmrk_events(mrk_fname, event_id, response_trig_shift)
---> 85         _check_update_montage(info, montage)
     86         with open(info['filename'], 'rb') as f:
     87             f.seek(0, os.SEEK_END)

/home/FB/fb05/sassenha/tools/mne-python/mne/io/base.py in _check_update_montage(info, montage, path, update_ch_names)
   2246         if montage is not None:
   2247             if isinstance(montage, string_types):
-> 2248                 montage = read_montage(montage, path=path)
   2249             _set_montage(info, montage, update_ch_names=update_ch_names)
   2250 

/home/FB/fb05/sassenha/tools/mne-python/mne/channels/montage.py in read_montage(kind, ch_names, path, unit, transform)
    267                                   for h, a in zip(horiz, az)]))
    268         pol = radius * np.pi
--> 269         pos = _sph_to_cart(np.array([np.ones(len(az)) * 85., az, pol])).T
    270     elif ext == '.hpts':
    271         # MNE-C specified format for generic digitizer data

/home/FB/fb05/sassenha/tools/mne-python/mne/transforms.py in _sph_to_cart(sph)
    583 def _sph_to_cart(sph):
    584     """Convert spherical coordinates to Cartesion coordinates."""
--> 585     assert sph.ndim == 2 and sph.shape[1] == 3
    586     sph = np.atleast_2d(sph)
    587     out = np.empty((len(sph), 3))

AssertionError: 
```

The problem is that the input to `_sph_to_cart` has shape (3, 368), but the second dimension should be 3, not the first. There should have been a test for this ...

@Eric89GXL 



Discussion:

Resolving patch:
diff --git a/mne/channels/montage.py b/mne/channels/montage.py
--- a/mne/channels/montage.py
+++ b/mne/channels/montage.py
@@ -266,7 +266,7 @@ def read_montage(kind, ch_names=None, path=None, unit='m', transform=False):
         az = np.deg2rad(np.array([90. - h if a >= 0. else -90. - 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
+        pos = _sph_to_cart(np.array([np.ones(len(az)) * 85., az, pol]).T)
     elif ext == '.hpts':
         # MNE-C specified format for generic digitizer data
         dtype = [('type', 'S8'), ('name', 'S8'),


Test patch:
diff --git a/mne/channels/tests/test_montage.py b/mne/channels/tests/test_montage.py
--- a/mne/channels/tests/test_montage.py
+++ b/mne/channels/tests/test_montage.py
@@ -43,28 +43,34 @@ def test_montage():
     # 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',
+        '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',  # 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'
-        'Labels\nLPA\nRPA\nNz\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'
-        'Labels\nLPA\nRPA\nNz\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',
+        '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 Fp1 -95.0 -31.0 -3.0\neeg AF7 -81 -59 -3\neeg AF3 -87 -41 28\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):
@@ -74,9 +80,9 @@ def test_montage():
         montage = read_montage(fname)
         if ".sfp" in kind or ".txt" in kind:
             assert_true('very_very_very_long_name' in montage.ch_names)
-        assert_equal(len(montage.ch_names), 3)
+        assert_equal(len(montage.ch_names), 4)
         assert_equal(len(montage.ch_names), len(montage.pos))
-        assert_equal(montage.pos.shape, (3, 3))
+        assert_equal(montage.pos.shape, (4, 3))
         assert_equal(montage.kind, op.splitext(kind)[0])
         if kind.endswith('csd'):
             dtype = [('label', 'S4'), ('theta', 'f8'), ('phi', 'f8'),
@@ -87,7 +93,7 @@ def test_montage():
             except TypeError:
                 table = np.loadtxt(fname, skiprows=2, dtype=dtype)
             pos2 = np.c_[table['x'], table['y'], table['z']]
-            assert_array_almost_equal(pos2, montage.pos, 4)
+            assert_array_almost_equal(pos2[:-1, :], montage.pos[:-1, :], 4)
         if kind.endswith('elc'):
             # Make sure points are reasonable distance from geometric centroid
             centroid = np.sum(montage.pos, axis=0) / montage.pos.shape[0]