-
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: Preserve annotations in epochs #8376
Comments
I actually don't think we need this. Annotations store data in seconds not samples -- so they have no notion of (or need for) a
... make EpochsTFR (and the functions that create them) respect the annotations properly. |
That would be useful! I would first start with |
Makes sense. We might even be able to do this in a backward-compatible way by adding a As a concrete example, if you have events at sample numbers equivalent to raw t=0 and t=1 and one Raw annotation from 0.25-1.25 sec, if you epoch with |
Oh, yes, good idea.
Yes, I think they should be split like this, that would keep the representation simple. |
Since we have channel-specific annotation support now, I've re-titled this as the missing component, namely what @mmagnuski mentioned:
We need to preserve annotations in the Epochs (and EpochsTFR, etc.) objects next. |
What's the status of having epoch-id in events/annotations? |
Somebody motivated to work on it needs to propose what attribute should be added to Epochs, how it should be saved (maybe reuse |
I suppose there might be some complexities with Is there anything internally more difficult? What is |
Notes from today's discord OH: discuss next week at dev meeting. Prolly best to only handle Epochs, not EpochsTFR, and replicate annotations for all epochs it falls under and downstream allow users to select which epochs they want to consider, possibly in get_data, or something else? |
I'll add a bit more detail from today's discussion (so I don't forget about it by next week):
|
Okay I'll take a stab at this based on discord dev meeting: Annotations for Epochs will be literally the same Annotations as Raw (these are "events" that occur over continuous time). Note the diff vs Epochs.events, which just denote how the "epoching/windowing" occurred over the original raw continuous time. And also metadata, which is data associated with each epoch, not necessarily with some time associated with it The PR should:
cc: @hoechenberger @drammock @larsoner @rob-luke who were on the call |
I think we'll want some time to fully test + implement this (including viz) so I think this shouldn't go into 0.24 but rather 0.25/1.0 |
if Annotations have the same meaning as for Raw yes we need to link back to
a raw object. This would
not work with EpochsArray. But if we have a meas_date and events in Epochs
then indeed we could
make it fly although events are relative to the sfreq of the original raw
which may be different from sfreq
in Epochs. We need to be careful here
… |
I think we can make it work with EpochsArray. If we make sure that the |
with EpochsArray the events onsets are just place older and the meas_date
is absent.
So I don't see how annotations would make sense unless you mark them with
the GUI
and it becomes more meaningful. So maybe....
What also worries me is the use change of sfreq eg if you resample the
epochs
you lose the provenance of sfreq don't you think?
… |
I think whatever user-facing API you are envisioning for adding annotations to individual epochs (one of these being the GUI example) can/will be the same regardless of whether our "storage backend" for the annotations keeps track of them in the annotations in terms of continuous time, or in terms of epoch-by-epoch annotations separate from the original times. The user won't "feel" our use of a continuous time backend for EpochsArray, but they definitely can for Raw->Epochs->Raw
We should probably adjust the If you're not convinced by these arguments @agramfort I say we hold off for another couple weeks and hash it out at the next developer meeting. I think iterating there will be faster, and we don't need to do this for 0.24 so waiting a couple weeks isn't a bad idea anyway. |
+1 to discuss this during our next dev meeting
… |
by the dev meeting you mean the office hours announced on MNE discourse or something else? I'd be interested to join. :)
I think it would still be very helpful to have epoch annotations even if they would not link back to the raw object. Or if the "linking" was conditional on not changing the sampling rate etc. If I undrestand correctly, the use case for such "linking" would be to be able to move the annotations created in Epochs back to the Raw object. Something similar to My usecase for epoch annotations for example is mimicing some of the functionality I used in fieldtrip - marking artifacts on epochs (semi-automatically for example) and using these for "partial rejection". More concretely when one is interested in both pre and post-stimulus activity it is convenient to mark artifacts as parts of epochs and then when analysing the pre-stimulus activity - first Also, if I undrestand last post by @adam2392 the idea is to keep the same Annotations object to work in Raw and Epochs? Maybe I misunderstood but in majority of cases I would want to programmatically add annotations to epochs via BTW @adam2392 I think I had a function that maps bad annotations onto tfr (as NaNs) taking into accont the n_cycles of each TFR "pixel". Let me know if you still need it, I may do some digging :) |
on discord, but separate from the office hours. I didn't find you in a search of the discord users, ping me there and I'll fill you in. |
Describe the new feature or enhancement
Is there a way to map annotations from the raw dataset onto the AverageTFR object? Since the tfr is occurring over windows, then the time scale of the annotations from the original time scale are inherently different.
E.g. if I have an event at sample 10000, with sfreq=1000, then it occurs at 10 seconds into the raw dataset. If i have an averageTFR that was computed with a moving window of say 1 second step size, then the new sample point of the event would be 10.
Describe your proposed implementation
Ideally this would consist of two things that I could see being useful:
A public function
map_annotations_to_sfreq
that allows mappingAnnotations
to different time-scales based on a passed say...sfreq
value. So based on the above example, if I wanted to mapAnnotations
that are based onsfreq=1000
Hz, to some tfr object withsfreq=1
Hz, then I would somehow pass that information tomap_annotations_to_sfreq
that returns me a newAnnotations
object that hasonset
andduration
in the new time-scale.Use the public function above to make
AverageTFR
, orEpochsTFR
, etc. to keep theirAnnotations
when the time-scale changes.I strongly would prefer having 1 because besides mne-python objects, I create other derivatives of the raw data that inherently have a "sliding" window component to them, and hence change the time-scale in the same way as a sliding FFT would.
Additional comments
@larsoner's comment on gitter for reference:
The text was updated successfully, but these errors were encountered: