Skip to content

Commit 3e60a9a

Browse files
massichagramfort
authored andcommitted
Deprecate parts of read_dig_montage (#6712)
* WIP: deprecate FIF, and let codecov reveal the dead code. * WIP: deprecate EGI and branvision in `read_dig_montage` * WIP: add alternative to the warning msg * wip * WIP: remove dead code * ups * forgot whatsnew
1 parent b97cfbe commit 3e60a9a

7 files changed

Lines changed: 79 additions & 86 deletions

File tree

doc/changes/latest.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ Bug
131131
API
132132
~~~
133133
134+
- Deprecate passing ``np.arrays`` as ``hsp``, ``hpi`` or ``elp`` parameters to ``mne.channels.read_dig_montage`` by `Joan Massich`_.
135+
136+
- Deprecate ``fif`` and ``egi`` parameters in ``mne.channels.read_dig_montage`` by `Joan Massich`_.
137+
134138
- Deprecate ``mne.evoked.grand_average`` in favor of :func:`mne.grand_average` (which works on both :class:`~mne.Evoked` and :class:`~mne.time_frequency.AverageTFR`) by `Daniel McCloy`_
135139
136140
- Deprecate ``exclude`` parameter in :func:`mne.viz.plot_ica_sources` and :meth:`mne.preprocessing.ICA.plot_sources`, instead always use the ``exclude`` attribute of the ICA object by `Daniel McCloy`_.

mne/channels/_dig_montage_utils.py

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
from ..transforms import apply_trans, get_ras_to_neuromag_trans
1919

2020
from ..io.constants import FIFF
21-
from ..io.open import fiff_open
22-
from .._digitization._utils import _read_dig_fif
2321
from ..utils import _check_fname, Bunch, warn
2422

2523

@@ -96,60 +94,6 @@ def _transform_to_head_call(data):
9694
}
9795

9896

99-
def _read_dig_montage_fif(
100-
fname,
101-
_raise_transform_err,
102-
_all_data_kwargs_are_none,
103-
):
104-
from .montage import _check_frame # circular dep
105-
106-
if _raise_transform_err:
107-
raise ValueError('transform must be True and dev_head_t must be '
108-
'False for FIF dig montage')
109-
if not _all_data_kwargs_are_none:
110-
raise ValueError('hsp, hpi, elp, point_names, egi must all be '
111-
'None if fif is not None')
112-
113-
_check_fname(fname, overwrite='read', must_exist=True)
114-
# Load the dig data
115-
f, tree = fiff_open(fname)[:2]
116-
with f as fid:
117-
dig = _read_dig_fif(fid, tree)
118-
119-
# Split up the dig points by category
120-
hsp = list()
121-
hpi = list()
122-
elp = list()
123-
point_names = list()
124-
fids = dict()
125-
dig_ch_pos = dict()
126-
for d in dig:
127-
if d['kind'] == FIFF.FIFFV_POINT_CARDINAL:
128-
_check_frame(d, 'head')
129-
fids[_cardinal_ident_mapping[d['ident']]] = d['r']
130-
elif d['kind'] == FIFF.FIFFV_POINT_HPI:
131-
_check_frame(d, 'head')
132-
hpi.append(d['r'])
133-
elp.append(d['r'])
134-
point_names.append('HPI%03d' % d['ident'])
135-
elif d['kind'] == FIFF.FIFFV_POINT_EXTRA:
136-
_check_frame(d, 'head')
137-
hsp.append(d['r'])
138-
elif d['kind'] == FIFF.FIFFV_POINT_EEG:
139-
_check_frame(d, 'head')
140-
dig_ch_pos['EEG%03d' % d['ident']] = d['r']
141-
142-
return Bunch(
143-
nasion=fids['nasion'], lpa=fids['lpa'], rpa=fids['rpa'],
144-
hsp=np.array(hsp) if len(hsp) else None,
145-
hpi=hpi, # XXX: why this is returned as empty list instead of None?
146-
elp=np.array(elp) if len(elp) else None,
147-
point_names=point_names,
148-
dig_ch_pos=dig_ch_pos,
149-
coord_frame='head',
150-
)
151-
152-
15397
def _read_dig_montage_egi(
15498
fname,
15599
_scaling,

mne/channels/montage.py

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from ..viz import plot_montage
2323
from .channels import _contains_ch_type
2424
from ..transforms import (apply_trans, get_ras_to_neuromag_trans, _sph_to_cart,
25-
_topo_to_sph, _str_to_frame, _frame_to_str)
25+
_topo_to_sph, _frame_to_str)
2626
from .._digitization import Digitization
2727
from .._digitization._utils import (_make_dig_points, _read_dig_points,
2828
write_dig, _read_dig_fif)
@@ -34,7 +34,7 @@
3434
_check_fname)
3535

3636
from .layout import _pol_to_cart, _cart_to_sph
37-
from ._dig_montage_utils import _transform_to_head_call, _read_dig_montage_fif
37+
from ._dig_montage_utils import _transform_to_head_call
3838
from ._dig_montage_utils import _read_dig_montage_egi, _read_dig_montage_bvct
3939
from ._dig_montage_utils import _foo_get_data_from_dig
4040
from ._dig_montage_utils import _fix_data_fiducials
@@ -764,13 +764,6 @@ def nasion(self):
764764
return _foo_get_data_from_dig(self.dig).nasion
765765

766766

767-
def _check_frame(d, frame_str):
768-
"""Check coordinate frames."""
769-
if d['coord_frame'] != _str_to_frame[frame_str]:
770-
raise RuntimeError('dig point must be in %s coordinate frame, got %s'
771-
% (frame_str, _frame_to_str[d['coord_frame']]))
772-
773-
774767
def _get_scaling(unit, scale):
775768
if unit not in scale:
776769
raise ValueError("Unit needs to be one of %s, not %r" %
@@ -821,6 +814,41 @@ def transform_to_head(montage):
821814
return montage
822815

823816

817+
def _read_dig_montage_deprecation_warning_helper(**kwargs):
818+
if kwargs.pop('fif') is not None:
819+
warn('Using "read_dig_montage" with "fif" not None'
820+
' is deprecated and will be removed in v0.20'
821+
' Please use read_dig_fif instead.', DeprecationWarning)
822+
return
823+
if kwargs.pop('egi') is not None:
824+
warn('Using "read_dig_montage" with "egi" not None'
825+
' is deprecated and will be removed in v0.20'
826+
' Please use read_dig_egi instead.', DeprecationWarning)
827+
return
828+
if kwargs.pop('bvct') is not None:
829+
warn('Using "read_dig_montage" with "bvct" not None'
830+
' is deprecated and will be removed in v0.20.'
831+
' Please use read_dig_captrack instead.', DeprecationWarning)
832+
return
833+
834+
# XXX: for now we only have implemented the case where hsp, hpi and elp
835+
# are np.arrays. we need read_dig_polhemus for the str cases. Plus,
836+
# we need to make sure that we can handle a mix of arrays and str. The
837+
# mixed case is not in our code-base but there was nothing preventing
838+
# a user to do so.
839+
#
840+
# we can assume that whatever is not None or np.array is path-like
841+
# therefore str.
842+
if [kk for kk in ('hsp', 'hpi', 'elp') if isinstance(kwargs[kk],
843+
np.ndarray)]:
844+
warn('Passing "np.arrays" to "hsp", "hpi" or "elp" in'
845+
' "read_dig_montage" is deprecated and will be removed in v0.20.'
846+
' Please use "make_dig_montage" instead.', DeprecationWarning)
847+
return
848+
849+
pass # noqa # XXX: will grow with issue-6461
850+
851+
824852
def read_dig_montage(hsp=None, hpi=None, elp=None,
825853
point_names=None, unit='auto', fif=None, egi=None,
826854
bvct=None, transform=True, dev_head_t=False, ):
@@ -911,15 +939,25 @@ def read_dig_montage(hsp=None, hpi=None, elp=None,
911939
EGI_SCALE = dict(mm=1e-3, cm=1e-2, auto=1e-2, m=1)
912940
NUMPY_DATA_SCALE = dict(mm=1e-3, cm=1e-2, auto=1e-3, m=1)
913941

942+
_read_dig_montage_deprecation_warning_helper(
943+
hsp=hsp, hpi=hpi, elp=elp, fif=fif, egi=egi, bvct=bvct,
944+
)
945+
914946
if fif is not None:
915947
_raise_transform_err = True if dev_head_t or not transform else False
916-
data = _read_dig_montage_fif(
917-
fname=fif,
918-
_raise_transform_err=_raise_transform_err,
919-
_all_data_kwargs_are_none=all(
920-
x is None for x in (hsp, hpi, elp, point_names, egi, bvct))
948+
_all_data_kwargs_are_none = all(
949+
x is None for x in (hsp, hpi, elp, point_names, egi, bvct)
921950
)
922951

952+
if _raise_transform_err:
953+
raise ValueError('transform must be True and dev_head_t must be'
954+
' False for FIF dig montage')
955+
if not _all_data_kwargs_are_none:
956+
raise ValueError('hsp, hpi, elp, point_names, egi must all be'
957+
' None if fif is not None')
958+
959+
return read_dig_fif(fname=fif)
960+
923961
elif egi is not None:
924962
data = _read_dig_montage_egi(
925963
fname=egi,

mne/channels/tests/test_montage.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,12 @@ def test_read_dig_montage():
407407
assert_allclose(montage.dev_head_t, EXPECTED_DEV_HEAD_T, atol=1e-7)
408408

409409
# Digitizer as array
410-
m2 = read_dig_montage(hsp_points, hpi_points, elp_points, names, unit='m')
411410
with pytest.deprecated_call():
411+
m2 = read_dig_montage(hsp_points, hpi_points, elp_points, names,
412+
unit='m')
412413
assert_array_equal(m2.hsp, montage.hsp)
413-
m3 = read_dig_montage(hsp_points * 1000, hpi_points, elp_points * 1000,
414-
names)
414+
m3 = read_dig_montage(hsp_points * 1000, hpi_points, elp_points * 1000,
415+
names)
415416
with pytest.deprecated_call():
416417
assert_allclose(m3.hsp, montage.hsp)
417418

@@ -460,7 +461,8 @@ def test_set_dig_montage():
460461
temp_dir = _TempDir()
461462
fname_temp = op.join(temp_dir, 'test.fif')
462463
montage.save(fname_temp)
463-
montage_read = read_dig_montage(fif=fname_temp)
464+
with pytest.deprecated_call():
465+
montage_read = read_dig_montage(fif=fname_temp)
464466
for use_mon in (montage, montage_read):
465467
info = create_info(['Test Ch'], 1e3, ['eeg'])
466468
with pytest.warns(None): # warns on one run about not all positions
@@ -489,7 +491,8 @@ def test_set_dig_montage():
489491
@testing.requires_testing_data
490492
def test_fif_dig_montage():
491493
"""Test FIF dig montage support."""
492-
dig_montage = read_dig_montage(fif=fif_dig_montage_fname)
494+
with pytest.deprecated_call():
495+
dig_montage = read_dig_montage(fif=fif_dig_montage_fname)
493496

494497
# test round-trip IO
495498
temp_dir = _TempDir()
@@ -535,7 +538,8 @@ def test_fif_dig_montage():
535538
_check_roundtrip(montage, fname_temp)
536539

537540
# Test old way matches new way
538-
dig_montage = read_dig_montage(fif=fif_dig_montage_fname)
541+
with pytest.deprecated_call():
542+
dig_montage = read_dig_montage(fif=fif_dig_montage_fname)
539543
dig_montage_fif = read_dig_fif(fif_dig_montage_fname)
540544
assert dig_montage.dig == dig_montage_fif.dig
541545
assert object_diff(dig_montage.ch_names, dig_montage_fif.ch_names) == ''
@@ -544,7 +548,8 @@ def test_fif_dig_montage():
544548
@testing.requires_testing_data
545549
def test_egi_dig_montage():
546550
"""Test EGI MFF XML dig montage support."""
547-
dig_montage = read_dig_montage(egi=egi_dig_montage_fname, unit='m')
551+
with pytest.deprecated_call():
552+
dig_montage = read_dig_montage(egi=egi_dig_montage_fname, unit='m')
548553

549554
# # test round-trip IO
550555
temp_dir = _TempDir()
@@ -575,7 +580,8 @@ def test_egi_dig_montage():
575580
assert_dig_allclose(raw_egi.info, test_raw_egi.info)
576581

577582
# Test old way matches new way
578-
dig_montage = read_dig_montage(egi=egi_dig_montage_fname, unit='m')
583+
with pytest.deprecated_call():
584+
dig_montage = read_dig_montage(egi=egi_dig_montage_fname, unit='m')
579585
dig_montage_egi = read_dig_egi(egi_dig_montage_fname)
580586
dig_montage_egi = transform_to_head(dig_montage_egi)
581587
assert dig_montage.dig == dig_montage_egi.dig
@@ -588,7 +594,8 @@ def test_bvct_dig_montage_old_api(): # XXX: to remove in 0.20
588594
with pytest.warns(RuntimeWarning, match='Using "m" as unit for BVCT file'):
589595
read_dig_montage(bvct=bvct_dig_montage_fname, unit='m')
590596

591-
dig_montage = read_dig_montage(bvct=bvct_dig_montage_fname)
597+
with pytest.deprecated_call():
598+
dig_montage = read_dig_montage(bvct=bvct_dig_montage_fname)
592599

593600
# test round-trip IO
594601
temp_dir = _TempDir()
@@ -682,7 +689,7 @@ def _check_roundtrip(montage, fname):
682689
with pytest.deprecated_call():
683690
assert_equal(montage.coord_frame, 'head')
684691
montage.save(fname)
685-
montage_read = read_dig_montage(fif=fname)
692+
montage_read = read_dig_fif(fname=fname)
686693
assert_equal(str(montage), str(montage_read))
687694
with pytest.deprecated_call():
688695
for kind in ('elp', 'hsp', 'nasion', 'lpa', 'rpa'):

mne/gui/_file_traits.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
create_default_subject)
3030
from ..utils import get_config, set_config
3131
from ..viz._3d import _fiducial_coords
32-
from ..channels import read_dig_montage, DigMontage
32+
from ..channels import read_dig_fif, DigMontage
3333

3434

3535
fid_wildcard = "*.fif"
@@ -300,7 +300,7 @@ def _get__info(self):
300300
if len(dir_tree_find(tree, FIFF.FIFFB_MEAS_INFO)) > 0:
301301
info = read_info(self.file, verbose=False)
302302
elif len(dir_tree_find(tree, FIFF.FIFFB_ISOTRAK)) > 0:
303-
info = read_dig_montage(fif=self.file, transform=True)
303+
info = read_dig_fif(fname=self.file)
304304

305305
if isinstance(info, DigMontage):
306306
dig = info.dig

mne/gui/tests/test_file_traits.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from mne.datasets import testing
1313
from mne.io.tests import data_dir as fiff_data_dir
1414
from mne.utils import _TempDir, requires_mayavi, run_tests_if_main, traits_test
15-
from mne.channels import read_dig_montage
15+
from mne.channels import read_dig_fif
1616

1717
data_path = testing.data_path(download=False)
1818
subjects_dir = op.join(data_path, 'subjects')
@@ -77,7 +77,7 @@ def test_inst_source():
7777
assert_allclose(inst.nasion, nasion)
7878
assert_allclose(inst.rpa, rpa)
7979

80-
montage = read_dig_montage(fif=inst_path) # test reading DigMontage
80+
montage = read_dig_fif(inst_path) # test reading DigMontage
8181
montage_path = op.join(tempdir, 'temp_montage.fif')
8282
montage.save(montage_path)
8383
inst.file = montage_path

mne/viz/tests/test_montage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import pytest
1111
import matplotlib.pyplot as plt
1212

13-
from mne.channels import read_montage, read_dig_montage
13+
from mne.channels import read_montage, read_dig_montage, read_dig_fif
1414

1515
p_dir = op.join(op.dirname(__file__), '..', '..', 'io', 'kit', 'tests', 'data')
1616
elp = op.join(p_dir, 'test_elp.txt')
@@ -38,7 +38,7 @@ def test_plot_montage():
3838
assert '0 channels' in repr(d)
3939
with pytest.raises(RuntimeError, match='No valid channel positions'):
4040
d.plot()
41-
d = read_dig_montage(fif=fif_fname)
41+
d = read_dig_fif(fname=fif_fname)
4242
assert '61 channels' in repr(d)
4343
# XXX this is broken; dm.point_names is used. Sometimes we say this should
4444
# Just contain the HPI coils, other times that it's all channels (e.g.,

0 commit comments

Comments
 (0)