-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[MRG+1] kit2fiff support for *.elp and *.hsp files #3320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
+1 for |
Current coverage is 86.67%@@ master #3320 diff @@
==========================================
Files 337 337
Lines 58126 58176 +50
Methods 0 0
Messages 0 0
Branches 8862 8868 +6
==========================================
+ Hits 50364 50424 +60
+ Misses 5081 5072 -9
+ Partials 2681 2680 -1
|
mne/io/meas_info.py
Outdated
| Array of dig points in [m]. | ||
| """ | ||
| dig_points = np.loadtxt(fname, comments=comments, ndmin=2) | ||
| if unit not in('auto', 'm', 'mm', 'cm'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space after in
|
is there any API change in this PR? |
| Unit of the digitizer files (hsp and elp). If not 'm', coordinates will | ||
| be rescaled to 'm'. Default is 'auto', which assumes 'm' for *.hsp and | ||
| *.elp files and 'mm' for *.txt files, corresponding to the known | ||
| Polhemus export formats. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @agramfort ! This here would be the API change (default to unit="auto" instead of unit="mm"). It does not change the behavior for previously possible argument combination because "auto" amounts to "mm" for *.txt files and arrays.
Currently (as well as before this PR) hsp and elp provided as arrays also get rescaled, I wonder if this could be confusing... if you agree I could add a check that raises an error or at least a warning if the head has a strange size (<10 mm or >1 m)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, no code using public API will break.
6fac539 to
2da0f75
Compare
mne/channels/montage.py
Outdated
| else: | ||
| raise TypeError('HPI file with extension *%s is not ' | ||
| 'supported. Only *.txt, *.sqd and *.mrk are ' | ||
| 'supported.' % ext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would the proper exception here be IOError?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would use ValueError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, should I change it or leave it for the sake of not changing API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt some catches specific TypeError. I would use ValueError
2da0f75 to
96a296f
Compare
|
KIT users any objections? |
96a296f to
b914951
Compare
|
Rebased to add whats_new |
|
no objection to merge but I'd really like to have one of our KIT users to also test .... |
|
no objection, @teonbrooks? |
|
(ping me in two weeks if it's not merged, I'll be back in the lab) |
|
sorry for the delay, i'm a bit backlogged on things. if it's not a rush, I will get to it soonish. if not, someone else can review in my stead. |
|
No rush, I know you're traveling |
|
Definitely stuff for the kit people. Make sure also here that you few people who use this code are happy. |
mne/gui/help/kit2fiff.json
Outdated
| @@ -1,7 +1,10 @@ | |||
| { | |||
| "hsp_file": "*.hsp or *.txt file containing digitized head shape points", | |||
| "fid_file": "*.elp or *.txt file containing 8 digitized fiducial points (\"electrode laser points\")", | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we be calling this fid_file? only the first three points are typically referred to as fiducials. wouldn't elp_file be a better name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's just how it's called in the traits gui already... :) technically aren't all 8 points fiducial points?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
according to wikipedia, yes :) https://en.wikipedia.org/wiki/Fiducial_marker#Medical_imaging
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However looking at that description again, what does ELP really stand for? "Electrode Location Point"?
|
other than those concerns, LGTM |
e3fb301 to
a3f8e3c
Compare
| .. versionadded:: 0.9.0 | ||
| """ | ||
| if not isinstance(unit, string_types) or unit not in('m', 'mm', 'cm'): | ||
| raise ValueError('unit must be "m", "mm", or "cm"') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would keep the sanity check. If I understand correctly, with this solution, data will just not be scaled if someone passes something erroneus (like "CM").
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for catching that! See 76ab987
76ab987 to
37eabdb
Compare
|
ping @teonbrooks @kingjr are there any concerns left here? |
|
Could you make a snippet so that I can adapt and test it onto my data? On 11 July 2016 at 16:23, Christian Brodbeck notifications@github.com
|
|
@kingjr the GUI will be useful to verify that coordinates are read correctly, and you can use the testing data import mne
import os
root = os.path.dirname(mne.io.kit.__file__)
data_dir = root + '/tests/data/'
hsp = data_dir + 'test.hsp'
elp = data_dir + 'test.elp'
mrk = data_dir + 'test_mrk.sqd'
sqd = data_dir + 'test.sqd'
raw = mne.io.read_raw_kit(sqd, mrk, elp, hsp)
mne.channels.read_dig_montage(hsp, mrk, elp, ['nasion', 'lpa', 'rpa'] + [''] * 5) |
|
that's it for me. +1 |
|
@christianbrodbeck you need to rebaase |
37eabdb to
72eb10a
Compare
|
Rebased and fixed the exception |
|
@kingjr do you have time to take one last look? |
|
I didn't manage to run the snippet because I don't have the kit sample data (how do I download that?) But I think if @teonbrooks is happy is probably good. |
|
@kingjr this is the testing data in the snippet, it should be part of mne after this PR |
mne/io/kit/tests/test_coreg.py
Outdated
| pts_2 = read_mrk(fname) | ||
| assert_array_equal(pts_2, pts, "pickle mrk") | ||
| with open(fname, 'wb') as fid: | ||
| pickle.dump({}, fid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
explicit dict()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is dict() better than {}? Just curious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Matlab converts? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure where the convention comes from. I think it may because it's indeed more explicit to those who don't speak python, but I'm not sure.
|
LGTM |
|
Addressed the remaining issues. I don't know what's wrong with CI, it's indicating it can't find some SUBJECTS_DIR, which does not seem related to the changes in the last commit. |
|
|
||
| def test_hsp_elp(): | ||
| """Test KIT usage of *.elp and *.hsp files against *.txt files | ||
| """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI our converged convention is now to put these on the same line like """Test ... """
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also in #3463
|
I agree the CI is unrelated, shouldn't happen on |
Replacing #1001, adding support for files exported by the head shape digitizer used at UMD (and in the past at NYU NY).
For our KIT purposes we know that ELP/HSP are in [m] while TXT files are in [mm]. So I figured we could make things simpler by modifying
_read_dig_points(https://github.com/mne-tools/mne-python/compare/master...christianbrodbeck:elp-hsp?expand=1#diff-74542bee8ed1be44ba6e68f0458010d8L358) such that it always return coordinates in [m](i.e. multiply coordinates from *.txt files with 0.001).The
mne.channels.read_dig_montagefunction also uses_read_dig_points, and inmne.channels.read_dig_montage(unlike the kit2fiff importers) the user specifies the unit the files are in, and the default is "mm". This leads to an ambiguous case where the users leavesunit="mm"but specifies *.hsp and *.elp files which we know (?) are in [m]. What should be the default behavior here?unitfor *.hsp and *.elp, assuming they are always in m?unit=Noneand use mm for text and m for hsp/elp as long as unit is None?We could also add a check that raises an error for unrealistic head diameters (>1m or <1cm) that way we should always catch erraneous units.