Skip to content
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

Preventing losing/altering events when downsampling #1028

Open
skjerns opened this issue Nov 21, 2024 · 7 comments
Open

Preventing losing/altering events when downsampling #1028

skjerns opened this issue Nov 21, 2024 · 7 comments

Comments

@skjerns
Copy link

skjerns commented Nov 21, 2024

I have the following problem

Our trigger channel sometimes doesn't switch on all bits simultaneously, producing events in the STI101 channel (1000 Hz) like

0, 0, 0, 4, 5, 5, 5, 5, 5, 0, 0, 0

when I downsample these data using mne-bids-pipeline to 100 Hz, the resulting trigger channel values are downsampled to 0, 4, 0, such that the event is interpreted as a 4 instead of a 5.

Usually I would avoid this by extracting events beforehand with appropriate min_duration and shortest_event and resampling jointly (raw, events = raw.resample(100, events=events)). However, when using mne-bids-pipeline I don't have this option. The events are correctly inserted as annotations into the resampled pipeline data. However, converting back from annotations to events via mne.events_from_annotations(raw) will scramble the trigger code values, unless manually specified.

Is there any way to avoid this without relying on the _events.json sidecar (in which the correct event information is saved)?

@skjerns skjerns changed the title Preventing losing events when downsampling Preventing losing/altering events when downsampling Nov 21, 2024
@hoechenberger
Copy link
Member

hoechenberger commented Nov 21, 2024

Hi!

The events are correctly inserted as annotations into the resampled pipeline data. However, converting back from annotations to events via mne.events_from_annotations(raw) will scramble the trigger code values, unless manually specified.

I don't really understand what you're saying here, could you please provide an example? Doesn't need to be an MWE, just some illustration of what happens vs what you would expect. This will also help us triage whether this is a Pipeline or an MNE-Python problem. Are you trying to "eject" your data from the Pipeline? Or where does your issue occur? Thank you!

@skjerns
Copy link
Author

skjerns commented Nov 22, 2024

I don't really understand what you're saying here, could you please provide an example? Doesn't need to be an MWE, just some illustration of what happens vs what you would expect. This will also help us triage whether this is a Pipeline or an MNE-Python problem. Are you trying to "eject" your data from the Pipeline? Or where does your issue occur? Thank you!

Sure! I use various trigger codes that do not appear in order, e.g. a list of events extrated from mne.find_events would read 4, 99, 2, 4, 234. During the pipeline, these events (before resampling) are added as annotations to the raw object, with the use of the events.tsv (which got created by write_raw_bids(raw=raw, .., events=events,). Then later, if I want to convert from annotations back to events, the event codes would be simply enumerated in the order that they appeared, e.g. 1,2,3,1,4. However, as triggers are not in the same order for each participant, the resulting events code would be scrambled across participants. However, I'm also unable to access the regular events object after resampling, as some triggers get resampled in a wrong way. I could rely on the annotations as strings, but that makes things a bit more difficult and error prone, but would definitively be a workaround.

I am trying to use MNE to preprocess my data, without epoching. I.e. running ICA, downsampling, filtering etc, and then having the clean_raw.fif as input for all further processing :)

@hoechenberger
Copy link
Member

Ah okay, so you're basically running all pre-processing steps to get the "clean" raw data, and that's when you stop using the pipeline and want to proceed working with the data in your own manual code / pipeline, did I get this right? 🙂

@skjerns
Copy link
Author

skjerns commented Nov 22, 2024

Ah okay, so you're basically running all pre-processing steps to get the "clean" raw data, and that's when you stop using the pipeline and want to proceed working with the data in your own manual code / pipeline, did I get this right? 🙂

exactly! our final analysis is a bit more intricate than what mne-bids-pipeline offers

@hoechenberger
Copy link
Member

hoechenberger commented Nov 22, 2024

Thanks! Could you share what the annotations on that clean file look like?

@skjerns
Copy link
Author

skjerns commented Nov 25, 2024

sure! annotation.zip

I think this is intended behaviour in MNE, as far as I can tell, the original trigger values are not saved when running mne.annotations_from_events and when running the reverse mne.events_from_annotations, the resulting values are just enumerations?

@hoechenberger
Copy link
Member

You can pass the event_id to control which IDs will be used :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants