-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[MRG] Add events/annotations tutorial #5608
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
b2dc85f to
180620d
Compare
Codecov Report
@@ Coverage Diff @@
## master #5608 +/- ##
==========================================
+ Coverage 88.55% 88.57% +0.01%
==========================================
Files 369 369
Lines 69182 69194 +12
Branches 11653 11654 +1
==========================================
+ Hits 61266 61286 +20
+ Misses 5060 5056 -4
+ Partials 2856 2852 -4 |
|
@massich do we need this for 0.17? If so it's likely to be one of the last blockers for release |
48a7308 to
80c6966
Compare
|
From the whish list in #5201 it mainly addresses point 4 which is the urgent part to get in 0.17. (So I'll edit the PR description) |
|
There's still one broken link. |
|
I don't understand why this link does not work and it does not appear in the build as broken |
|
its the same as this is linking to. But here renders properly. I don't get it. |
| @@ -0,0 +1,134 @@ | |||
| """ | |||
| .. _tut_events_and_annotation_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.
remove this label, we do not need it (it's in other examples for historical reasons and those should be removed, too)
we can use the auto-generated sphx_glr_... labels instead
| Events and annotations are quite similar. This tutorial highlights their | ||
| differences and similitudes and tries to shade some light to which one is | ||
| preferred to use in different situations when using MNE. | ||
| Here follows both terms definition from the glossary. |
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 be good to add a RST link to the glossary
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 but I did not find how. I don't think is referenceable yet.
| events | ||
| Events correspond to specific time points in raw data; e.g., triggers, | ||
| experimental condition events, etc. MNE represents events with integers | ||
| that are stored in numpy arrays of shape (n_events, 3). Such arrays are |
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 am always forget what the second column of the events array is. Maybe it's worth repeating here what the three columns represent?
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 this you need an example where the second column is more than array of 0s. And is not yet covered in this tutorial.
| Events correspond to specific time points in raw data; e.g., triggers, | ||
| experimental condition events, etc. MNE represents events with integers | ||
| that are stored in numpy arrays of shape (n_events, 3). Such arrays are | ||
| classically obtained from a trigger channel, also referred to as stim |
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.
stim is really an abbreviation. Since it's a tutorial, I'd suggest expanding to the full 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.
My only goal here was just to replicate whatever is in glossary. Once glossary is linkable I would remove it.
| classically obtained from a trigger channel, also referred to as stim | ||
| channel. | ||
|
|
||
| annotations |
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.
Link to documentation of annotations class?
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.
b18b962 to
a9c0e66
Compare
|
I think I've addressed everybody's concerns. What I did not manage is to link to the annotations attributes. (ie: @larsoner yes, they are inconsistent. I did not check if the inconsistency was released already. But I was certainly planning to correct it after the release due to #5699. And maybe find a better name for Please, give a read to the tutorial. Thx a lot. |
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.
Otherwise LGTM
tutorials/plot_object_annotations.py
Outdated
|
|
||
| Both events and :class:`Annotations <mne.Annotations>` be seen as triplets | ||
| where the first element answers to **when** something happens and the last | ||
| element refers to **what** is 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.
what it is
tutorials/plot_object_annotations.py
Outdated
| the description is an integer value. | ||
| In contrast, :class:`Annotations <mne.Annotations>` represents the | ||
| ``onset`` in seconds (relative to the reference ``orig_time``), | ||
| and the ``description`` is an arbitrary string. |
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.
Remove leading space
tutorials/plot_object_annotations.py
Outdated
| # Create an annotation object with orig_time | ||
| orig_time = '2002-12-03 19:01:31.676071' | ||
| my_datetime = datetime.strptime(orig_time, '%Y-%m-%d %H:%M:%S.%f') | ||
| posix_timestamp = (my_datetime - datetime(1970, 1, 1)).total_seconds() |
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 is not used in the annotations object
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.
No I used only for printing. There's a subtiliy. the orig_time has to be .6760709 otherwise they wont match.
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.
well okay but you don't use this orig_time either ...
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.
print(posix_timestamp - annot_orig.orig_time)1.1920928955078125e-07I am using the same number. (except the rounding error)
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.
1038942091.676071 is the POSIX timestamp of 2002-12-03 19:01:31.676071
it only differs in the .6760709
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.
okay maybe then it's a matter of renaming your variables. Because I see this:
orig_time = '2002-12-03 19:01:31.676071'and I'm confused why in the class instantiation you do: orig_time=1038942091.6760709.
also how much does the 1e-7 matter? couldn't we live with a slightly offset annotation with 1 sample?
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.
@jasmainak I agree it's probably too much to ask to our user to understand this gymnastic of dates.
I am going to push now a way to pass directly '2002-12-03 19:01:31.676071' to the Annotations constructor.
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.
tutorials/plot_object_annotations.py
Outdated
|
|
||
| annot = mne.Annotations(onset=[10], duration=[0.5], | ||
| description=['foobar'], | ||
| orig_time=1038942091.6760709) |
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.
still to be fixed ...
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 see this timestamp as a problem. At least now it is stated that it has been 'chosen' and that is not completely arbitrary. But shows that orig_time is under the hood this kind of ugly floats.
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.
Sorry to insist here.
But if a user wanted to use the Annotations class, how do you propose that they would set orig_time? I don't think anyone could dream up this number. If the idea to expose this parameter is that allows people to adjust the orig_time if it's not aligned. You could perhaps make it annot.orig_time - 0.2 to shift orig time ...
jasmainak
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.
Except those last two comments LGTM. Thanks @massich !
|
Onsets no longer match: We need to be able to parse |
|
we should round at the microsecond
|
|
I pushed a commit that at least makes things pass on both systems. Had to use |
|
Pushed a better version that did not necessitate using |
|
It should be able to go in once green. |
|
@jasmainak feel free to merge when you are happy |
|
Looks really nice. Thanks @massich and @agramfort for the teamwork ! |
|
great !
|
| annotated_blink_raw = raw.copy() | ||
| eog_events = mne.preprocessing.find_eog_events(raw) | ||
| n_blinks = len(eog_events) | ||
| # Center to cover the whole blink with full duration of 0.5s: |
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 may be a bit misleading - the events are centered and we are actually de-cenetering them by pushing them back in time to mark onset, not event center.
|
please send a quick PR.
|
|
@agramfort sure thing, I have some other small suggestions. :) |
|
go for it !
|

From the whish list in #5201 it mainly addresses point 4.