-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
ENH: Add digitization class #6369
Conversation
This pull request introduces 1 alert when merging 835f0e0 into b9b2c68 - view on LGTM.com new alerts:
Comment posted by LGTM.com |
Codecov Report
@@ Coverage Diff @@
## master #6369 +/- ##
==========================================
+ Coverage 89.26% 89.27% +<.01%
==========================================
Files 410 411 +1
Lines 74435 74469 +34
Branches 12312 12316 +4
==========================================
+ Hits 66446 66482 +36
+ Misses 5135 5131 -4
- Partials 2854 2856 +2 |
This pull request introduces 1 alert when merging 7f37ecb into 5093d00 - view on LGTM.com new alerts:
Comment posted by LGTM.com |
mne/utils/_bunch.py
Outdated
self._items = list() | ||
elif all([isinstance(_, kls) for _ in elements]): | ||
if elements is None: | ||
self._items = list() |
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.
move this on the previous condition.
if elements is None or (isinstance(elements, list) and not elements):
mne/utils/_bunch.py
Outdated
self._items = deepcopy(list(elements)) | ||
else: | ||
# XXX: _msg should not be Digitization related | ||
_msg = 'Digitization expected a iterable of DigPoint objects.' |
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.
this should be addressed. (the tests should be modified aswell)
mne/io/meas_info.py
Outdated
@@ -156,6 +158,7 @@ def _unique_channel_names(ch_names): | |||
|
|||
|
|||
# XXX Eventually this should be de-duplicated with the MNE-MATLAB stuff... | |||
# XXX: Digitization, Docstrings need a pass changing lists for Digitization |
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.
Is this still true?
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.
The one I added? yes. I did not do the pass. True the pass is not needed there but on the refactorized.
mne/utils/_bunch.py
Outdated
|
||
class NamedFloat(_Named, float): | ||
"""Float with a name in __repr__.""" | ||
|
||
pass | ||
|
||
class MNEObjectsList(MutableSequence): |
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.
One problem I expect with this subclassing MutableSequence
instead of list
is that mne.externals.h5io.write_hdf5(...)
will not work on it. IIRC currently you can write_hdf5
on info
objects and it will work because all info
entries and Python built-in types. After this PR it will not. Can you check? If this is the case we should fix it somehow.
I would consider just subclassing list
like we do for SourceSpaces, and if at some point we want to not subclass list for these sorts of things, we can change Digitization
and SourceSpaces
at the same time.
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 have the same feeling as @larsoner here. Subclassing list is not a great pattern but it's simple. We just want to have a repr. The argument to make sure that it contains only instance of DigPoint is fair but do we really expect to have the problem with users hacking the info['dig'] manually? I don't expect anyone to do this and think that it will be fine...
my 2c
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 can make MNEObjectsList
derive from list()
I can leave with it.
I am not expecting "users" to mess up the list, but I do like to have some safety nets when writing digitizations, montages, etc.. (or force developers of new readers to use these safeties) I can always get read of this class and do that in Digitization, or keep it as a private thing. But we have lots of lists of things and we never ensure those elements are always the same. (if I'm not mistaken, this object does not prevent insertions of other types. I thought YAGNI, and that it was easy to add if needed)
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.
can we avoid the MNEObjectsList and have Digitization inherit from list? it would remove a lot of code in this PR
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.
It's a trade off between safety net and barrier to write new code. The more you nest classes, the less accessible it becomes to new contributors. I tend to lean more on the side of assuming good intent -- i.e., if you hack info['dig'] you are on your own.
This pull request introduces 1 alert when merging 8b17361 into f4ff170 - view on LGTM.com new alerts:
Comment posted by LGTM.com |
mne/digitization/base.py
Outdated
@@ -73,3 +74,16 @@ def __eq__(self, other): # noqa: D105 | |||
return False | |||
else: | |||
return np.allclose(self['r'], other['r']) | |||
|
|||
|
|||
class Digitization(MNEObjectsList): |
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.
New public class has been added but it's not documented in API reference.
Do we miss entry to the glossary? cc: @drammock |
mne/utils/numerics.py
Outdated
@@ -663,13 +663,15 @@ def object_size(x): | |||
x : object | |||
Object to approximate the size of. | |||
Can be anything comprised of nested versions of: | |||
{dict, list, tuple, ndarray, str, bytes, float, int, None}. | |||
{dict, list, tuple, ndarray, str, bytes, float, int, None, | |||
Digitization}. |
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.
maybe the changes in this file are not needed as Digitization is just a list?
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.
great catch!
This should be green. Feel free to merge. |
mne/digitization/_utils.py
Outdated
@@ -261,7 +261,7 @@ def _make_dig_points(nasion=None, lpa=None, rpa=None, hpi=None, | |||
'kind': FIFF.FIFFV_POINT_EEG, | |||
'coord_frame': FIFF.FIFFV_COORD_HEAD}) | |||
|
|||
return _format_dig_points(dig) | |||
return Digitization(_format_dig_points(dig)) |
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.
It looks like things would be a bit simpler if _format_dig_points
returned a list cast to Digitization
already. Then there wouldn't need to be a bunch of Digitization(_format_dig_points(...))
calls
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.
agreed.
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.
Agreed, that was on my list already. But I can do it here. no prob.
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 have liked better to do it the other way around. Prefer to import a constructor and have a call that does something = MyConstructor()
than importing a private function and call something = _my_obscure_func(foo)
.
But since I'll be doing subsequent PRs in these things, I'll change it back.
@massich as we discussed we could review the visualization module. I think having a |
@GuillaumeFavelier great! we should open an issue and cross reference it here. |
This PR:
info['dig']
to beDigitization
orNone
On the top, here is a summary of which readers go through
_test_raw_reader
, if so with wastype(info['dig'])
:None
,Digitization
, or both. And for those readers expected to not haveDigitization
do they havemontage
. The goal of this table is to keep in mind the current status + plan following PRs.