Skip to content

Commit 73bd194

Browse files
author
Joan Massich
committed
MAINT: remove io.meas_info duplicates in digitization._utils
1 parent 0c94c97 commit 73bd194

11 files changed

Lines changed: 27 additions & 231 deletions

File tree

mne/channels/montage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
from .channels import _contains_ch_type
2121
from ..transforms import (apply_trans, get_ras_to_neuromag_trans, _sph_to_cart,
2222
_topo_to_sph, _str_to_frame, _frame_to_str)
23-
from ..io.meas_info import (_make_dig_points, _read_dig_points, _read_dig_fif,
24-
write_dig)
23+
from ..digitization._utils import (_make_dig_points, _read_dig_points,
24+
_read_dig_fif, write_dig)
2525
from ..io.pick import pick_types
2626
from ..io.open import fiff_open
2727
from ..io.constants import FIFF

mne/digitization/_mess.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
# Things that should be common to every reader
88

99
# from ..io.meas_info import _empty_info
10-
from ..io.meas_info import _read_dig_points
11-
from ..io.meas_info import _make_dig_points
10+
from ._utils import _read_dig_points
11+
from ._utils import _make_dig_points
1212
from ..transforms import apply_trans
1313
from ..transforms import als_ras_trans
1414
from ..transforms import get_ras_to_neuromag_trans

mne/digitization/_utils.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from mne.utils import warn
2626
from mne.utils.check import _check_option
2727
from mne import __version__
28-
from .base import _format_dig_points
28+
from .base import _format_dig_points, Digitization
2929

3030
b = bytes # alias
3131

@@ -173,6 +173,7 @@ def _write_dig_points(fname, dig_points):
173173
raise ValueError(msg)
174174

175175

176+
# XXX: all points are supposed to be in FIFFV_COORD_HEAD
176177
def _make_dig_points(nasion=None, lpa=None, rpa=None, hpi=None,
177178
extra_points=None, dig_ch_pos=None):
178179
"""Construct digitizer info for the info.
@@ -194,8 +195,8 @@ def _make_dig_points(nasion=None, lpa=None, rpa=None, hpi=None,
194195
195196
Returns
196197
-------
197-
dig : list
198-
List of digitizer points to be added to the info['dig'].
198+
dig : Digitization
199+
A container of DigPoints to be added to the info['dig'].
199200
"""
200201
dig = []
201202
if lpa is not None:
@@ -250,4 +251,5 @@ def _make_dig_points(nasion=None, lpa=None, rpa=None, hpi=None,
250251
dig.append({'r': dig_ch_pos[key], 'ident': ident,
251252
'kind': FIFF.FIFFV_POINT_EEG,
252253
'coord_frame': FIFF.FIFFV_COORD_HEAD})
253-
return _format_dig_points(dig)
254+
255+
return Digitization(_format_dig_points(dig))

mne/gui/_kit2fiff_gui.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from scipy.linalg import inv
1414
from threading import Thread
1515

16-
from ..io.meas_info import _read_dig_points, _make_dig_points
16+
from ..digitization._utils import _read_dig_points, _make_dig_points
1717
from ..utils import get_config, set_config, logger, warn
1818

1919
from mayavi.core.ui.mayavi_scene import MayaviScene

mne/gui/_marker_gui.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from ..transforms import apply_trans, rotation, translation
2121
from ..coreg import fit_matched_points
2222
from ..io.kit import read_mrk
23-
from ..io.meas_info import _write_dig_points
23+
from ..digitization._utils import _write_dig_points
2424
from ._viewer import PointObject
2525
from ._backend import _check_pyface_backend
2626

mne/io/artemis123/artemis123.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
from ...utils import logger, warn, verbose
1212
from ..utils import _read_segments_file
1313
from ..base import BaseRaw
14-
from ..meas_info import _empty_info, _make_dig_points
14+
from ..meas_info import _empty_info
15+
from ...digitization._utils import _make_dig_points
1516
from ..constants import FIFF
1617
from ...chpi import _fit_device_hpi_positions, _fit_coil_order_dev_head_trans
1718
from ...transforms import get_ras_to_neuromag_trans, apply_trans, Transform

mne/io/kit/coreg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import numpy as np
1313

1414
from .constants import KIT
15-
from ..meas_info import _read_dig_points
15+
from ...digitization._utils import _read_dig_points
1616

1717

1818
def read_mrk(fname):

mne/io/kit/tests/test_coreg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from numpy.testing import assert_array_equal
1111

1212
from mne.io.kit import read_mrk
13-
from mne.io.meas_info import _write_dig_points
13+
from mne.digitization._utils import _write_dig_points
1414
from mne.utils import _TempDir
1515

1616

mne/io/meas_info.py

Lines changed: 7 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import datetime
1212
from io import BytesIO
1313
import operator
14-
import os.path as op
15-
import re
1614

1715
import numpy as np
1816
from scipy import linalg
@@ -29,16 +27,15 @@
2927
write_coord_trans, write_ch_info, write_name_list,
3028
write_julian, write_float_matrix, write_id, DATE_NONE)
3129
from .proc_history import _read_proc_history, _write_proc_history
32-
from ..transforms import _to_const, invert_transform
33-
from ..utils import (logger, verbose, warn, object_diff, _validate_type,
34-
_check_option)
35-
from .. import __version__
30+
from ..transforms import invert_transform
31+
from ..utils import logger, verbose, warn, object_diff, _validate_type
3632
from ..digitization.base import _format_dig_points
3733
from ..digitization import Digitization
3834
from .compensator import get_current_comp
3935

4036
# XXX: most probably the functions needing this, should go somewhere else
4137
from ..digitization.base import _dig_kind_proper, _dig_kind_rev, _dig_kind_ints
38+
from ..digitization._utils import _read_dig_fif
4239

4340
b = bytes # alias
4441

@@ -661,7 +658,8 @@ def write_fiducials(fname, pts, coord_frame=FIFF.FIFFV_COORD_UNKNOWN,
661658
mne.io.constants.FIFF.FIFFV_COORD_...).
662659
%(verbose)s
663660
"""
664-
write_dig(fname, pts, coord_frame)
661+
from ..digitization._utils import write_dig as ff
662+
ff(fname, pts, coord_frame)
665663

666664

667665
def write_dig(fname, pts, coord_frame=None):
@@ -679,214 +677,8 @@ def write_dig(fname, pts, coord_frame=None):
679677
here. Can be None (default) if the points could have varying
680678
coordinate frames.
681679
"""
682-
if coord_frame is not None:
683-
coord_frame = _to_const(coord_frame)
684-
pts_frames = {pt.get('coord_frame', coord_frame) for pt in pts}
685-
bad_frames = pts_frames - {coord_frame}
686-
if len(bad_frames) > 0:
687-
raise ValueError(
688-
'Points have coord_frame entries that are incompatible with '
689-
'coord_frame=%i: %s.' % (coord_frame, str(tuple(bad_frames))))
690-
691-
with start_file(fname) as fid:
692-
write_dig_points(fid, pts, block=True, coord_frame=coord_frame)
693-
end_file(fid)
694-
695-
696-
def _read_dig_fif(fid, meas_info):
697-
"""Read digitizer data from a FIFF file."""
698-
isotrak = dir_tree_find(meas_info, FIFF.FIFFB_ISOTRAK)
699-
dig = None
700-
if len(isotrak) == 0:
701-
logger.info('Isotrak not found')
702-
elif len(isotrak) > 1:
703-
warn('Multiple Isotrak found')
704-
else:
705-
isotrak = isotrak[0]
706-
dig = []
707-
for k in range(isotrak['nent']):
708-
kind = isotrak['directory'][k].kind
709-
pos = isotrak['directory'][k].pos
710-
if kind == FIFF.FIFF_DIG_POINT:
711-
tag = read_tag(fid, pos)
712-
dig.append(tag.data)
713-
dig[-1]['coord_frame'] = FIFF.FIFFV_COORD_HEAD
714-
return _format_dig_points(dig)
715-
716-
717-
def _read_dig_points(fname, comments='%', unit='auto'):
718-
"""Read digitizer data from a text file.
719-
720-
If fname ends in .hsp or .esp, the function assumes digitizer files in [m],
721-
otherwise it assumes space-delimited text files in [mm].
722-
723-
Parameters
724-
----------
725-
fname : str
726-
The filepath of space delimited file with points, or a .mat file
727-
(Polhemus FastTrak format).
728-
comments : str
729-
The character used to indicate the start of a comment;
730-
Default: '%'.
731-
unit : 'auto' | 'm' | 'cm' | 'mm'
732-
Unit of the digitizer files (hsp and elp). If not 'm', coordinates will
733-
be rescaled to 'm'. Default is 'auto', which assumes 'm' for *.hsp and
734-
*.elp files and 'mm' for *.txt files, corresponding to the known
735-
Polhemus export formats.
736-
737-
Returns
738-
-------
739-
dig_points : np.ndarray, shape (n_points, 3)
740-
Array of dig points in [m].
741-
"""
742-
_check_option('unit', unit, ['auto', 'm', 'mm', 'cm'])
743-
744-
_, ext = op.splitext(fname)
745-
if ext == '.elp' or ext == '.hsp':
746-
with open(fname) as fid:
747-
file_str = fid.read()
748-
value_pattern = r"\-?\d+\.?\d*e?\-?\d*"
749-
coord_pattern = r"({0})\s+({0})\s+({0})\s*$".format(value_pattern)
750-
if ext == '.hsp':
751-
coord_pattern = '^' + coord_pattern
752-
points_str = [m.groups() for m in re.finditer(coord_pattern, file_str,
753-
re.MULTILINE)]
754-
dig_points = np.array(points_str, dtype=float)
755-
elif ext == '.mat': # like FastScan II
756-
from scipy.io import loadmat
757-
dig_points = loadmat(fname)['Points'].T
758-
else:
759-
dig_points = np.loadtxt(fname, comments=comments, ndmin=2)
760-
if unit == 'auto':
761-
unit = 'mm'
762-
if dig_points.shape[1] > 3:
763-
warn('Found %d columns instead of 3, using first 3 for XYZ '
764-
'coordinates' % (dig_points.shape[1],))
765-
dig_points = dig_points[:, :3]
766-
767-
if dig_points.shape[-1] != 3:
768-
err = 'Data must be (n, 3) instead of %s' % (dig_points.shape,)
769-
raise ValueError(err)
770-
771-
if unit == 'mm':
772-
dig_points /= 1000.
773-
elif unit == 'cm':
774-
dig_points /= 100.
775-
776-
return dig_points
777-
778-
779-
def _write_dig_points(fname, dig_points):
780-
"""Write points to text file.
781-
782-
Parameters
783-
----------
784-
fname : str
785-
Path to the file to write. The kind of file to write is determined
786-
based on the extension: '.txt' for tab separated text file.
787-
dig_points : numpy.ndarray, shape (n_points, 3)
788-
Points.
789-
"""
790-
_, ext = op.splitext(fname)
791-
dig_points = np.asarray(dig_points)
792-
if (dig_points.ndim != 2) or (dig_points.shape[1] != 3):
793-
err = ("Points must be of shape (n_points, 3), "
794-
"not %s" % (dig_points.shape,))
795-
raise ValueError(err)
796-
797-
if ext == '.txt':
798-
with open(fname, 'wb') as fid:
799-
version = __version__
800-
now = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")
801-
fid.write(b'%% Ascii 3D points file created by mne-python version'
802-
b' %s at %s\n' % (version.encode(), now.encode()))
803-
fid.write(b'%% %d 3D points, x y z per line\n' % len(dig_points))
804-
np.savetxt(fid, dig_points, delimiter='\t', newline='\n')
805-
else:
806-
msg = "Unrecognized extension: %r. Need '.txt'." % ext
807-
raise ValueError(msg)
808-
809-
810-
# XXX: all points are supposed to be in FIFFV_COORD_HEAD
811-
def _make_dig_points(nasion=None, lpa=None, rpa=None, hpi=None,
812-
extra_points=None, dig_ch_pos=None):
813-
"""Construct digitizer info for the info.
814-
815-
Parameters
816-
----------
817-
nasion : array-like | numpy.ndarray, shape (3,) | None
818-
Point designated as the nasion point.
819-
lpa : array-like | numpy.ndarray, shape (3,) | None
820-
Point designated as the left auricular point.
821-
rpa : array-like | numpy.ndarray, shape (3,) | None
822-
Point designated as the right auricular point.
823-
hpi : array-like | numpy.ndarray, shape (n_points, 3) | None
824-
Points designated as head position indicator points.
825-
extra_points : array-like | numpy.ndarray, shape (n_points, 3)
826-
Points designed as the headshape points.
827-
dig_ch_pos : dict
828-
Dict of EEG channel positions.
829-
830-
Returns
831-
-------
832-
dig : Digitization
833-
A container of DigPoints to be added to the info['dig'].
834-
"""
835-
dig = []
836-
if lpa is not None:
837-
lpa = np.asarray(lpa)
838-
if lpa.shape != (3,):
839-
raise ValueError('LPA should have the shape (3,) instead of %s'
840-
% (lpa.shape,))
841-
dig.append({'r': lpa, 'ident': FIFF.FIFFV_POINT_LPA,
842-
'kind': FIFF.FIFFV_POINT_CARDINAL,
843-
'coord_frame': FIFF.FIFFV_COORD_HEAD})
844-
if nasion is not None:
845-
nasion = np.asarray(nasion)
846-
if nasion.shape != (3,):
847-
raise ValueError('Nasion should have the shape (3,) instead of %s'
848-
% (nasion.shape,))
849-
dig.append({'r': nasion, 'ident': FIFF.FIFFV_POINT_NASION,
850-
'kind': FIFF.FIFFV_POINT_CARDINAL,
851-
'coord_frame': FIFF.FIFFV_COORD_HEAD})
852-
if rpa is not None:
853-
rpa = np.asarray(rpa)
854-
if rpa.shape != (3,):
855-
raise ValueError('RPA should have the shape (3,) instead of %s'
856-
% (rpa.shape,))
857-
dig.append({'r': rpa, 'ident': FIFF.FIFFV_POINT_RPA,
858-
'kind': FIFF.FIFFV_POINT_CARDINAL,
859-
'coord_frame': FIFF.FIFFV_COORD_HEAD})
860-
if hpi is not None:
861-
hpi = np.asarray(hpi)
862-
if hpi.ndim != 2 or hpi.shape[1] != 3:
863-
raise ValueError('HPI should have the shape (n_points, 3) instead '
864-
'of %s' % (hpi.shape,))
865-
for idx, point in enumerate(hpi):
866-
dig.append({'r': point, 'ident': idx + 1,
867-
'kind': FIFF.FIFFV_POINT_HPI,
868-
'coord_frame': FIFF.FIFFV_COORD_HEAD})
869-
if extra_points is not None:
870-
extra_points = np.asarray(extra_points)
871-
if extra_points.shape[1] != 3:
872-
raise ValueError('Points should have the shape (n_points, 3) '
873-
'instead of %s' % (extra_points.shape,))
874-
for idx, point in enumerate(extra_points):
875-
dig.append({'r': point, 'ident': idx + 1,
876-
'kind': FIFF.FIFFV_POINT_EXTRA,
877-
'coord_frame': FIFF.FIFFV_COORD_HEAD})
878-
if dig_ch_pos is not None:
879-
keys = sorted(dig_ch_pos.keys())
880-
try: # use the last 3 as int if possible (e.g., EEG001->1)
881-
idents = [int(key[-3:]) for key in keys]
882-
except ValueError: # and if any conversion fails, simply use arange
883-
idents = np.arange(1, len(keys) + 1)
884-
for key, ident in zip(keys, idents):
885-
dig.append({'r': dig_ch_pos[key], 'ident': ident,
886-
'kind': FIFF.FIFFV_POINT_EEG,
887-
'coord_frame': FIFF.FIFFV_COORD_HEAD})
888-
889-
return Digitization(_format_dig_points(dig))
680+
from ..digitization._utils import write_dig as ff
681+
return ff(fname, pts, coord_frame=None)
890682

891683

892684
@verbose

mne/io/tests/test_meas_info.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
anonymize_info)
2222
from mne.io.constants import FIFF
2323
from mne.io.write import DATE_NONE
24-
from mne.io.meas_info import (Info, create_info, _write_dig_points,
25-
_read_dig_points, _make_dig_points, _merge_info,
24+
from mne.io.meas_info import (Info, create_info, _merge_info,
2625
_force_update_info, RAW_INFO_FIELDS,
2726
_bad_chans_comp, _get_valid_units)
27+
from mne.digitization._utils import (_write_dig_points, _read_dig_points,
28+
_make_dig_points,)
2829
from mne.io import read_raw_ctf
2930
from mne.utils import _TempDir, run_tests_if_main, catch_logging
3031
from mne.channels.montage import read_montage, read_dig_montage

0 commit comments

Comments
 (0)