Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the ability to mark certain Epochs as noisy and unusable from Autoreject #61

Open
adam2392 opened this issue Dec 16, 2021 · 0 comments · May be fixed by #62
Open

Adding the ability to mark certain Epochs as noisy and unusable from Autoreject #61

adam2392 opened this issue Dec 16, 2021 · 0 comments · May be fixed by #62

Comments

@adam2392
Copy link
Member

Problem

Autoreject is a MNE-Python compatible package for running automated artifact detection in MEG/EEG/iEEG data. However, the RejectLog requires the Epochs to be loaded in again, and also operates over some arbitrary Epoching.

Epoch*Connectivity classes store Connectivity data that is computed over Epochs with a possibly different Epoching procedure.

Solution

This function can be used to map Autoreject windows -> other Epoch windows.

def map_epoch_annotations_to_epoch(dest_epoch, src_epoch):
    """Map Annotations that occur in one Epoch to another Epoch.

    Two different Epochs might occur at different time points.
    This function will map Annotations that occur in one Epoch
    setting to another Epoch taking into account their onset
    samples and window lengths.

    Parameters
    ----------
    dest_epoch : instance of Epochs | events array
        The reference Epochs that you want to match to.
    src_epoch : instance of Epochs | events array
        The source Epochs that contain Epochs you want to
        see if it overlaps at any point with ``dest_epoch``.

    Returns
    -------
    all_cases : np.ndarray of shape (n_src_epochs, n_dest_epochs)
        This is an array indicating the overlap of any source epoch
        relative to the destination epoch. An overlap is indicated
        by a ``True``, whereas if a source Epoch does not overlap
        with a destination Epoch, then the element will be ``False``.

    Notes
    -----
    This is a useful utility function to enable mapping Autoreject
    ``RejectLog`` that occurs over a set of defined Epochs to
    another Epoched data structure, such as a ``Epoch*`` connectivity
    class, which computes connectivity over Epochs.
    """
    if isinstance(dest_epoch, BaseEpochs):
        dest_events = dest_epoch.events
        dest_times = dest_epoch.times
        dest_sfreq = dest_epoch._raw_sfreq
    else:
        dest_events = dest_epoch
    if isinstance(src_epoch, BaseEpochs):
        src_events = src_epoch.events
        src_times = src_epoch.times
        src_sfreq = src_epoch._raw_sfreq
    else:
        src_events = src_epoch

    # get the sample points of the source Epochs we want
    # to map over to the destination sample points
    src_onset_sample = src_events[:, 0]
    src_epoch_tzeros = src_onset_sample / src_sfreq
    dest_onset_sample = dest_events[:, 0]
    dest_epoch_tzeros = dest_onset_sample / dest_sfreq

    # get start and stop points of every single source Epoch
    src_epoch_starts, src_epoch_stops = np.atleast_2d(
        src_epoch_tzeros) + np.atleast_2d(src_times[[0, -1]]).T

    # get start and stop points of every single destination Epoch
    dest_epoch_starts, dest_epoch_stops = np.atleast_2d(
        dest_epoch_tzeros) + np.atleast_2d(dest_times[[0, -1]]).T

    # get destination Epochs that start within the source Epoch
    src_straddles_dest_start = np.logical_and(
        np.atleast_2d(dest_epoch_starts) >= np.atleast_2d(src_epoch_starts).T,
        np.atleast_2d(dest_epoch_starts) < np.atleast_2d(src_epoch_stops).T)

    # get epochs that end within the annotations
    src_straddles_dest_end = np.logical_and(
        np.atleast_2d(dest_epoch_stops) > np.atleast_2d(src_epoch_starts).T,
        np.atleast_2d(dest_epoch_stops) <= np.atleast_2d(src_epoch_stops).T)

    # get epochs that are fully contained within annotations
    src_fully_within_dest = np.logical_and(
        np.atleast_2d(dest_epoch_starts) <= np.atleast_2d(src_epoch_starts).T,
        np.atleast_2d(dest_epoch_stops) >= np.atleast_2d(src_epoch_stops).T)

    # combine all cases to get array of shape (n_src_epochs, n_dest_epochs).
    # Nonzero entries indicate overlap between the corresponding
    # annotation (row index) and epoch (column index).
    all_cases = (src_straddles_dest_start +
                 src_straddles_dest_end +
                 src_fully_within_dest)

    return all_cases

Reference: autoreject/autoreject#240

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant