How to use equalize_event_counts() combined with metadata instead of event_ids

  • MNE-Python version: 0.23.dev
  • operating system: linux

Hey! guys,

I’m wondering whether the function equalize_event_counts (event_ids , method='mintime') can be used combined with metadata instead of event_ids.
In my situation, I have metadata like this:


I hope that the numbers of epochs of each condition can be equal, is there a way to achieve this based on my metadata?

Thanks a lot!
Best

Hello @YuZhou, this is an interesting and very valid question that recently came up in discussions with @virvw and @sophie as well. The short answer is, we currently support doing this, but it’s on our todo list. We’ll hopefully have something ready within the next two weeks, but I cannot make any promises here. I’ll open an issue on GitHub with this feature request.

Edit: The issue can be found here:

1 Like

Hi! Richard,
Thanks a lot for your reply :blush: Looking forward to the implementation of the new feature. You guys are really really cool to develop such a handy and excellent tool :+1: :+1: :+1: :+1: :+1:
By the way, if this new feature is added, will it be updated to version 0.23.dev0 or other versions?

1 Like

We’ll need to see what will need to be changed to get this to work. Typically, we’ll add new features for new releases only (in this case, this would probably be the upcoming 0.23.0); although sometimes we also backport small and important enhancements to the current “stable” tree. It really depends on how drastic the changes are, and I cannot tell you that with certainty now for this feature. Although my gut feeling is it will only land in 0.23 and not be backported to 0.22, but who knows.

And yes, once this is implemented, it will be merged into the current development tree, i.e., 0.23.dev0.

2 Likes

Great! :grin:Actually, that’s exactly what I’m hoping, because the version I’m using is 0.23.dev0. So if this feature is added, what I need to do is to type this in my terminal in the mne environment, right?

$ pip install --upgrade --no-deps https://github.com/mne-tools/mne-python/archive/main.zip

Yes that’s one way to update to the latest development version.

1 Like

Hi @richard ,

i see this issue is supposed to be solved, but i have the same problem. i’m using mne 1.2.3., macOS-13.5.2-x86_64-i386-64bit and Python 3.9.15.

For me the problem is that SOMEtimes epochs.equalize_event_counts( [condition1, condition2) ] works, and sometimes it doesn’t. It does this in the same project, so the same version of MNE and everything else. When it doesn’t, the error is "KeyError: "adj/dist not found in the epoch object's event_id." (adj/dist is the string in the variable condition1 and corresponds to the event metadata). However, when it gives this error, and just one line below in the notebook i ask it to find epochs[condition1] it finds it ok. Any advice on how i should address this because i have many many event codes associated with condition1 (adj/dist) and it would be annoying to have to use the codes instead of just the annotation keywords…

Thanks (:
bissera

Hello @bissera, unfortunately it seems that this feature still hasn’t been implemented:

Until this is resolved, I’m afraid you’ll have to work around it somehow…

Best wishes,
Richard

Ah sorry, i saw it was marked as completed at some point, my bad. But how come it works sometimes then ?

Possibly because the conditions you’re referring to are sometimes also listed in epochs.event_id?

Hello everyone,

I am bit confused about the use case of equalize_event_counts on metadata.
Why not use equalize_epoch_counts() on epoch objects, which are based on metadata:

In my current project I investigate differences between two conditions that I create based on metadata, before I equalize the epochs in both conditions:


        if cond == "probability":
            epochs_a = epochs[((epochs.metadata.cue == 0.75)
                              & (epochs.metadata.prevresp == 0)
                              & (epochs.metadata.previsyes == 1))]
            epochs_b = epochs[((epochs.metadata.cue == 0.25)
                              & (epochs.metadata.prevresp == 0)
                              & (epochs.metadata.previsyes == 1))]
            cond_a_name = "high_fa"
            cond_b_name = "low_fa"

            if mirror:
                cond_a_name = f'{cond_a_name}_mirror'
                cond_b_name = f'{cond_b_name}_mirror'

        elif cond == "prev_resp":
            epochs_a = epochs[((epochs.metadata.prevresp == 1) &
                               (epochs.metadata.previsyes == 1) &
                               (epochs.metadata.cue == 0.75))]
            epochs_b = epochs[((epochs.metadata.prevresp == 0) &
                               (epochs.metadata.previsyes == 1) &
                                (epochs.metadata.cue == 0.75))]
            cond_a_name = "prevyesresp_highprob_stim"
            cond_b_name = "prevnoresp_highprob_stim"

            if mirror:
                cond_a_name = f'{cond_a_name}_mirror'
                cond_b_name = f'{cond_b_name}_mirror'

        else:
            raise ValueError("input should be 'probability' or 'prev_resp'")

        # make sure we have an equal amount of trials in both conditions
        mne.epochs.equalize_epoch_counts([epochs_a, epochs_b])

Maybe I miss something here?

@CarinaFo The function doesn’t take metadata into consideration (yet), but works based on epochs.event_id.

Best wishes,
Richard

There is nothing related to epochs.event_id in the source code of equalize_epoch_counts(). I worked on this function during the SPRINT last week, so I am quite confident :slight_smile:

My bad, I was talking about equalize_event_counts(), not equalize_epoch_counts() :smiley: