Extracting EEG segments from an MNE Raw objects such that the time frames are preserved

I have an MNE raw EEG object from which I would like to extract segments given by start time and end time points that are in a csv file that looks like this:


Sleep Stage     start    end
SLEEP-REM       4770.0   5280.0
SLEEP-REM       5310.0   5760.0
SLEEP-REM       10620.0  12270.0
SLEEP-REM       16440.0  17010.0
SLEEP-REM       17040.0  17670.0
SLEEP-REM       21390.0  21630.0

I just want the REM segments such that the times are preserved exactly as they are. I tried the following:

rem_raw = raw.copy().crop(tmin=rem_df.iloc[0,1], tmax=rem_df.iloc[0,2])     #first rem epoch
for i in range(1,len(rem_df)):      
    t_start = rem_df.iloc[i,1]       #iterating over start
    t_end = rem_df.iloc[i,2]           #iterating over end
    rem_raw.append(raw.copy().crop(tmin=t_start, tmax=t_end))

This does extract the REM stages for me, but the problem in appending this way is that it completely restarts the timepoints from t = 0 and has a continuous data structure, while I want a discontinuous structure.

Is there a way to store all of this in discontinuous epochs?

  • MNE version: Version 1.2.1
  • operating system: macOS

cropping a raw will always reset the times to start at 0. However, the offset from the original raw’s start time will be preserved in the attribute raw.first_time, so the info is still recoverable as long as you don’t concatenate the segments into one Raw object.

import os
import mne

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(sample_data_folder, 'MEG', 'sample',
raw = mne.io.read_raw_fif(sample_data_raw_file, verbose=False, preload=True)

raws = list()
for tmin, tmax in rem_df[['start', 'end']].itertuples(index=False, name=None):
    this_raw = raw.copy().crop(tmin, tmax)
    assert tmin == this_raw.first_time - raw.first_time

This does give me a list of raw objects, but isn’t there a way to preserve the original time points? This code preserves epochs, but not their start and end time points. Plotting raws[1] for example, still plots from time t=0.

As I said above:

This is not something we will change; a lot of module code implicitly assumes that raw times always start at zero.

Is plotting your ultimate goal here? Can you say more about exactly what kind of plot you want / what you want to accomplish? What other advice we offer depends on what you want to do.


Plotting isn’t the only goal. I wanted to have a way to revert back to the original time points. For example, if I find an anomaly on the third segment/epoch, I want to be able to specify at what time point it occurs in the original dataset.

You can do that by adding the value raws[2].first_time - raw.first_time to the apparent time of the anomaly.