Currently, mne.Epochs and mne.time_frequency.EpochsTFR (and the related mne.time_frequency.AverageTFR) behave a bit inconsistently. Specifically:
EpochsTFR should have some attributes/methods that are present in Epochs, e.g. time_as_index.len() for Epochs, but this does not work for EpochsTFR. It would be nice to make len also work, but even better it would be useful to have this stored in an attribute (e.g. n_epochs).Epochs.crop returns a copy, whereas EpochsTFR (and also AverageTFR) operates inplaceEpochsTFT.crop says it returns an instance of AverageTFR in its docstringepochs.get_data() returns the data, whereas you have to do epochs_tfr.data for an EpochsTFR object.There might be more, but this is all I found so far by just working with these objects (I haven't explicitly searched for inconsistencies yet).
Do you agree that these objects should be more consistent? Or are there specific reasons why they behave differently?
yes more consistency is better
and yes crop should operate inplace but for epochs it may be tough...
OK, I'll make a PR. I'd add an inplace parameter to crop. Then we could even have different default values if there are good reasons. Why do you think operating inplace may be tough for epochs? Personally, I'd set the default to inplace=False for both Epochs and EpochsTFR.
see
https://mne-tools.github.io/dev/tutorials/philosophy.html#mne-gives-you-objects-with-methods
we removed all inplace or copy=True | False params to say "all methods
operate inplace"
OK, then I guess crop should indeed operate inplace even for epochs. Or why did you think it might be tough?
yes exactly but I don't know how easy it would be for non-preloaded epochs
I've never cropped non-preloaded epochs, but I'll see what I can come up with. I've added another point to the list in the initial comment.
Adding to that list: EpochsTFR seems to not store/maintain the metadata field that is present in the Epochs structure; this means that Epoch indexing based on the metadata table (a feature I love for the Epochs structure) doesn't work for the EpochsTFR.
Currently I'm working around this by making sure there is always an epochs object loaded alongside it, which has the corresponding indices in the EpochsTFR structure stored in a separate column. After selecting a subset of Epochs, this column can help me select the corresponding subset from EpochsTFR -- this all works but seems hopelessly inefficient
@wkruijne can you be more specific? What exactly do you use for indexing that is only available in Epochs?
I'm referring to indexing as described here:
https://martinos.org/mne/stable/auto_tutorials/plot_metadata_epochs.html
In my case, it could be something silly as:
epochs_unilateral = epochs["practice == 'no' & lateral=='unilateral'"]
E: in order to select only the epochs that have 'unilateral cues' and are not part of the practice phase.
For the EpochsTFR objects I need the specific (trial) index numbers to make this work -- and in particular make sure that these trial numbers are still aligned after, say, dropping epochs by annotation.
yes that would be nice to have. We could do this with a MetaDataMixin
class to factorize the logic of pick epochs that match a certain query
I just noticed that this already came up some time ago, so linking this to #3556 for reference.
Would be super cool if you could tackle #3556 @cbrnr
I will, only ATM I don't have much time, but I'll get to it.
For the EpochsTFR objects I need the specific (trial) index numbers to make this work -- and in particular make sure that these trial numbers are still aligned after, say, dropping epochs by annotation.
I don't see any means for indexing in EpochsTFR currently. Other than indexing the data directly, EpochsTFR.data, and creating a new EpochsTFR instance with the selected trials. Is that what you mean @wkruijne ? If yes, it would be great to also include this more basic functionality similar to Epochs where you can index directly (e.g.):
first_ten_epochs = epochs[:10]
I'm happy to help as needed!
My understanding is that @wkruijne would like to be able to do something like this:
TFR_fast = TFR_all['RT < 0.5'].average()
eventually, EpochsTFR.__getitem__ should support everything Epochs.__getitem__ does.
yes it is as simple as this. We just need a volunteer to do this :)
I can try my hand at this.
Just to clarify:
I don't see any means for indexing in EpochsTFR currently. Other than indexing the data directly,(...) Is that what you mean @wkruijne ?
Yes, I currently make a new object from a data subset. -- but indexing the same data segments from an Epoch- and EpochsTFR objects then becomes cumbersome because they can not be indexed in the same way.
My understanding is that @wkruijne would like to be able to do something like this:
Yes. That too.
eventually,
EpochsTFR.__getitem__should support everythingEpochs.__getitem__does.
That's what it boils down to, I guess.
Thanks everyone!
Closed due to #5762
Most helpful comment
eventually,
EpochsTFR.__getitem__should support everythingEpochs.__getitem__does.