-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[MRG+1] CTF support for ds bad channels and bad segments #5255
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
|
I would go with 2 and see if it actually breaks any test. Make the bad segments really short and make only one channel bad? |
|
It seems as if mne-python also doesn't read in time of the first data sample from ctf data. From Lines 629 to 633 in ab4571a
it seems like adjusting this time is not possible is that correct? |
Codecov Report
@@ Coverage Diff @@
## master #5255 +/- ##
==========================================
+ Coverage 88.22% 88.25% +0.03%
==========================================
Files 358 358
Lines 66228 66284 +56
Branches 11254 11268 +14
==========================================
+ Hits 58429 58502 +73
+ Misses 4981 4959 -22
- Partials 2818 2823 +5 |
| # Add measurement id | ||
| if info['meas_id'] is not None: | ||
| write_id(fid, FIFF.FIFF_PARENT_BLOCK_ID, info['meas_id']) | ||
|
|
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 check needed or wanted?
Lines 224 to 226 in ab4571a
| def write_id(fid, kind, id_=None): | |
| """Write fiff id.""" | |
| id_ = _generate_meas_id() if id_ is None else id_ |
will put in the default (DATE_NONE)
I guess the question is do you always want a meas_id in a the fiff structure?
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 FIF file itself will need one, but I don't know if meas_info needs one. Can you try writing a file with an info without meas_id in it and see if the C tools can read it?
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 don't have the C tools running or any experience with them.
For what its worth without this line (ie the info['meas_id'] == None case) it would revert to the backend of write_info method so if those played nice with the C code I imagine this would be fine as well
In those cases (ie the info['meas_id'] == None) read_info in mne-python returned an info['meas_id'] with the DATE_NONE usecs in it.
Also the file gets the default (None/DATE_NONE) id.
mne/io/tests/test_raw.py
Outdated
| assert_array_equal(raw.info['meas_id']['machid'], | ||
| raw3.info['meas_id']['machid']) | ||
| else: | ||
| logger.warn('Reader does not set meas_id') |
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.
Do we want this to raise an error? it would catch IO readers that don't set meas_id.
Currently it is only raising errors when the reader doesn't set meas_id and when the tests that expect the warning messages to be a specific thing.
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.
We probably don't need to warn. I don't think we are guaranteed that all formats will have it.
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.
Ok I can pull it. What is info['meas_id'] used for... anything?
mne/io/ctf/ctf.py
Outdated
|
|
||
| # Add bad segments as Annotations (correct for start time) | ||
| s_time = -res4['pre_trig_pts'] / float(info['sfreq']) | ||
| self.annotations = _read_bad_segments(directory, s_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.
Ideally this s_time would be the start of the 'raw.times' array. Is that possible with the current fif structures?
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.
raw.times always starts at 0. but there is raw.first_samp which is an offset, is that what you mean?
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.
raw.first_samp at least from what I saw doesn't change raw.times[0] but does skip the first raw.first_samp samples of the data array. Is that the correct understanding?
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 what it does in the context of CTF. But for Neuromag data it is the offset between when the acquisition started and the recording began. In MNE we use it when cropping files, too.
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 problem with setting raw.first_samp is that it skips those samples as stored on disk, so while it makes sense of the timing issues needs to say set to 0 to read in all of the data.
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.
first_samp should not impact the reading of the first samples on disk. It's basically an increment in events and allows to know when samples where recorded wrt the original absolute 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.
That doesn't match what I am seeing.
for instance running this test code
import os.path as op
from mne.io import read_raw_ctf
from mne.datasets import testing
ctf_dir = op.join(testing.data_path(download=True), 'CTF')
ctf_fname = op.join(ctf_dir, 'testdata_ctf_short.ds')
raw = read_raw_ctf(ctf_fname, preload=True)
print ('first_samp - %d' % raw.first_samp)
print ('_data.shape', raw._data.shape)
print ('_data[3,0]', raw._data[3, 0])
print ('_data[3,5]', raw._data[3, 5])
print ('len(raw.times) - %d' % len(raw.times))
print ('raw.times.min() - %f' % raw.times.min())
print ('raw.times.max() - %f' % raw.times.max())
on the current master(not this branch) returns
first_samp - 0
('_data.shape', (356, 4801))
('_data[3,0]', 16442.588333333333)
('_data[3,5]', 16442.592499999999)
len(raw.times) - 4801
raw.times.min() - 0.000000
raw.times.max() - 4.000000
if I change
Line 146 in da1d329
| first_samps = [0] * len(last_samps) |
to
first_samps = [5] * len(last_samps)
returns
first_samp - 5
('_data.shape', (356, 4796))
('_data[3,0]', 16442.592499999999)
('_data[3,5]', 16442.596666666665)
len(raw.times) - 4796
raw.times.min() - 0.000000
raw.times.max() - 3.995833
so it certainly seems like setting first_samp skips the opening of the data array.
|
@larsoner ok for you? can someone replicate the travis failure? |
|
|
larsoner
left a comment
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.
LGTM aside from the seemingly unresolved first_samp issue.
| assert_equal(raw.info['meas_date'], raw_read.info['meas_date']) | ||
|
|
||
| for key in ['secs', 'usecs', 'version']: | ||
| assert_equal(raw.info['meas_id'][key], raw_read.info['meas_id'][key]) |
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 you can now do the simpler assert raw.info['meas_id'][key] == raw_read.info['meas_id'][key]. The codebase is slowly migrating toward this pytest way of doing things (except for comparisons that require numpy.testing). Feel free to change it here or not, I'm happy either way
|
first_samp should tell you when raw[:, 0] was recorded. It's modified by
the crop method for example.
so I think it's consistent to say that raw[:, 0] which corresponds to
raw.times[0] (which is always 0)
was actually recorded at: orig_time + first_samp / sfreq
does it make sense. Sorry if I miss something but I looked quickly.
|
|
All the My concern is the differences in Similarly first data sample ( |
|
This is where first_samp is used to skip the opening of the data on disk. Lines 506 to 520 in da1d329
readers then implement I assume that fif file/IO sorts this all out for you when you use crop? |
|
> I assume that fif file/IO sorts this all out for you when you use crop?
yes.
|
|
Do we want to add add keywords to I would vote for adding keywords that default to the old behavior (ignoring bad channels and segments) and maybe plan to change the default at some later release. |
|
I see it as more of a bugfix / something we should have been doing all along. Do you think it's likely that people had bad channels and/or segments marked during acq that they wouldn't want marked during offline analysis? |
|
I agree that this is something that should have been done the whole time so should become the default behavior at some point. I am perhaps being overly conservative after the comp channels stuff :). I am fine either way. I due think its possible that there are people who didn't know there were bad channels/segments marked in the data they were using and now their pipelines will behave slightly differently. |
|
I also see as BUG FIX that we should clearly document in the next release
email
|
|
@bloyl can you resurrect this? |
|
+1 for merging on my end I'll be away the next two weeks with limited email so feel free to make any changes you feel are needed. |
|
@bloyl have you tested this with some of your own files and found it to work okay? I'll probably test it locally just by using the |
|
I have. it seemed to be working fine. the only issue has to do with the
start time, but I don't see away around that.
…On Mon, Jul 9, 2018 at 9:46 PM Eric Larson ***@***.***> wrote:
@bloyl <https://github.com/bloyl> have you tested this with some of your
own files and found it to work okay?
I'll probably test it locally just by using the testing dataset and
visually inspecting the Annotations.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#5255 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AFU7najTQ36KdxPqvheZ0ROTmBtTIZW-ks5uFAdugaJpZM4UVlgo>
.
|
larsoner
left a comment
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.
LGTM +1 for merge
| start_block(fid, FIFF.FIFFB_MEAS) | ||
| write_id(fid, FIFF.FIFF_BLOCK_ID) | ||
| if info['meas_id'] is not None: | ||
| write_id(fid, FIFF.FIFF_PARENT_BLOCK_ID, info['meas_id']) |
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 this?
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.
@agramfort I know @bloyl is out for a bit so I'm working on this now.
Maybe we should just revert this bit for now?
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.
Reverted
|
@bloyl can you rebase to fix CIs? |
|
Green |
Current CTF IO doesn't read in bad channels or segments from *.ds/BadChannels and *.ds/bad.segments files.
This PR should address that.
I stuck the new methods in
info.pywithout a strong reason so if anyone thinks they make more sense somewhere else I'm happy to move them,How should I test this?
I could make a new version of
MNE-testing-data/CTF/testdata_ctf_short.dswith a bad segment and a bad channel marked.I could alter an exists ds folder in
MNE-testing-data/CTF/to have a bad segment and channel.Downside to option 1 is that it'll add ~10M to
MNE-testing-data. Downside to option 2 is that it would potentially break/alter existing tests.