epochs realignment: shifting time by variable length on each epoch.
See original GitHub issueDescribe the problem
I have a dataset where subjects listen to a series of 4-5 tones on each trial. However, the Inter Onset Interval between tones is different from trial to trial. I would like to create a function that allows me to realign epochs so that the 0 in epoch.times
is now centered on the 2nd, third, final, etc tone. Typically this is done by altering the event array directly. However, because of the series of tones, I still want my baseline to always be before the first tone where there is silence.
So I want to be able to:
- define large epochs that cover all tones in each trial
- Apply a baseline, timelocked to pre first tone, in an epoch by epoch manner
- Realign epochs to a specific tone in the trial. Critically, this shift would be by a different amount for each epoch so
epochs.shift_time
wouldn’t work.
Describe your solution
I have found a solution to do this outside of mne and would like to implement it in a TimeMixin so that it can be used for both Epochs, EpochsTFR and wherever else there are multiple trials with time stored, (Source Estimates?).
It’s a bit ugly and hard to follow, which is exactly why I think we should implement it so that it’s well tested and users can avoid the potential errors when they try to do it outside of mne. Here is a very basic example which shows the concept of the method.
import numpy as np
t = np.round(np.linspace(-.5, 1., 16), 1)
sfreq = 1. / (t[1] - t[0])
n_epochs = 3
# faux data, 3 epochs x 16 timepoints
data = t * np.ones(n_epochs)[:, None]
# How many samples to shift for each epoch in realignment
sampshift = np.array([2, 4, 6])
# realigned epochs must have smaller window than original epoch
new_tmin, new_tmax = -.2, .3
# indices to extract the correct realigned samples
minsamp = np.round((new_tmin - t[0]) * sfreq).astype(int)
maxsamp = np.round((new_tmax - new_tmin) * sfreq).astype(int) + minsamp
idx = sampshift[:, None] + np.arange(minsamp, maxsamp + 1)
# needs some checks here to make sure you don't exceed epoch size
shift_data = data[np.arange(n_epochs)[:, None], idx]
I would also like to move some methods like .shift_time,
maybe .crop
into the TimeMixin so that they are not implemented in multiple places. This could be a separate PR.
Describe possible alternatives
Another alternative for my specific problem is to allow for different baseline windows for each epoch but this doesn’t seem to me to be a good practice generally and I’m not sure how much we want to encourage people to draw baselines from different timepoints in a typical use case.
Issue Analytics
- State:
- Created 5 years ago
- Comments:13 (13 by maintainers)
Top GitHub Comments
We have an example somewhere plots/reorders things by RT. That could be adapted to re-epoch based on RT?
This seems like the sort of manipulation that is specific enough to justify using custom NumPy operations and EpochsArray rather than adding a function to MNE. There are potentially lots of custom baseline, re-epoching, sub-epoching, custom rejection, etc. use cases users can have, and rather than to to support them in MNE it’s more sustainable to make sure it’s clear how to leverage NumPy in combination with MNE.