My goal is to read in EDFs using mne.io.read_raw_edf and then concatenate them.
Under certain conditions, I need to pad an individual EDF with zeros, so in the end I have a list of some RawEDFs, and some RawArrays (my zero-padded EDFs, which are created in the following way)
Is there a way to concatenate these two types with mne.concatenate_raws, without failing this check in append? Or basically, is there a way to cast RawArrays to RawEDFs?
def edf_pad(raw_edf, amount):
curr_data = raw_edf.get_data() # Last time point in seconds
sfreq = raw_edf.info['sfreq']
old = raw_edf.duration
pad_samples = int(amount.seconds * sfreq)
pad_data = np.zeros((len(raw_edf.ch_names), pad_samples))
new_data = np.hstack((curr_data, pad_data))
# Create new info object
new_info = raw_edf.info.copy()
res = mne.io.RawArray(new_data, new_info)
print(f"Attempted to pad {amount}: From {old} to {res.duration}.")
return res
The error is ValueError: raw[2] type must match. Based on my image, we see that raw[2] corresponds to the RawArray, which appears to fail this check due to type incompatibility.
I did some quick sanity checks between the RawArray and the RawEDF, and they have the same number of channels and sampling frequency.
Any help would be appreciated! Would be happy to send any other info.
Hi Teunis, thanks for the help. That package looks very handy, but I think the issue is my specific use case requires some EDF’s to be zero-padded to a certain duration prior to concatenation.
The only way I’ve found to do this is the hacky way making a new RawArray, which is why I am running into this issue concatenating RawArrays with RawEDFs. If there exists a way to convert a RawArray to RawEDF, then I believe this problem would be solved. I’ve unfortunately yet to find a method for this, however.
EDFtk will zero-pad a file if the next file to be concatenated has a starttime later than the endtime.
The only thing you need to do is to check (and maybe modify) the startime of the files to be concatenated.
I don’t think it’s necessary to require the objects to have the exact same type. At the end of the day, continuous data should be treated as a Raw object, regardless of how it was created. The various types (RawEDF, RawArray, …) should ideally be subclasses of Raw, but I think such a hierarchy has not been implemented (unless BaseRaw could be used). Can you open an issue in our GitHub repository to discuss if the current behavior can be changed?
Since this whole issue is the result of me wanting to manipulate a RawEDF by zero-padding, I was also thinking about raising a feature request Issue about adding a native “padding” method to the Raw class, since my method involving converting EDFs to RawArrays seems a bit ugly?
My particular use case is I have to concatenate many 5 minute files that aren’t necessarily continuous (eg. maybe equipment cuts out last 3 seconds). In this case, I want to first pad that file to the desired amount prior to concatenation.
Thoughts? Sorry I’ve never contributed to MNE before so just asking!
I’m not sure that’s a common enough use case that warrants adding a dedicated method, because you can use np.pad() to achieve this (but your approach is also perfectly fine and not ugly). But you are right that you have to create a RawArray.