def filter(raw: mne.io.BaseRaw, subject: str, session: Optional[str],
           run: Optional[str], l_freq: Optional[float],
           h_freq: Optional[float],
           l_trans_bandwidth: Optional[Union[float, Literal['auto']]],
           h_trans_bandwidth: Optional[Union[float, Literal['auto']]]) -> None:
    """Filter data channels (MEG and EEG)."""

    data_type = 'empty-room' if subject == 'emptyroom' else 'experimental'

    if l_freq is not None and h_freq is None:
        msg = (f'High-pass filtering {data_type} data; lower bound: '
               f'{l_freq} Hz')
    elif l_freq is None and h_freq is not None:
        msg = (f'Low-pass filtering {data_type} data; upper bound: '
               f'{h_freq} Hz')
    elif l_freq is not None and h_freq is not None:
        msg = (f'Band-pass filtering {data_type} data; range: '
               f'{l_freq} – {h_freq} Hz')
    else:
        msg = (f'Not applying frequency filtering to {data_type} data.')

    logger.info(**gen_log_kwargs(
        message=msg, subject=subject, session=session, run=run))

    if l_freq is None and h_freq is None:
        return

    raw.filter(l_freq=l_freq,
               h_freq=h_freq,
               l_trans_bandwidth=l_trans_bandwidth,
               h_trans_bandwidth=h_trans_bandwidth,
               filter_length='auto',
               phase='zero',
               fir_window='hamming',
               fir_design='firwin')
def resample(raw: mne.io.BaseRaw, subject: str, session: Optional[str],
             run: Optional[str], sfreq: Optional[float]) -> None:
    if not sfreq:
        return

    data_type = 'empty-room' if subject == 'emptyroom' else 'experimental'
    msg = f'Resampling {data_type} data to {sfreq:.1f} Hz'
    logger.info(**gen_log_kwargs(
        message=msg,
        subject=subject,
        session=session,
        run=run,
    ))
    raw.resample(sfreq, npad='auto')
Example #3
0
def make_ecg_epochs(*,
                    cfg,
                    raw: mne.io.BaseRaw,
                    subject: str,
                    session: str,
                    run: Optional[str] = None) -> Optional[mne.BaseEpochs]:
    # ECG either needs an ecg channel, or avg of the mags (i.e. MEG data)
    if ('ecg' in raw.get_channel_types() or 'meg' in cfg.ch_types
            or 'mag' in cfg.ch_types):
        msg = 'Creating ECG epochs …'
        logger.info(**gen_log_kwargs(
            message=msg, subject=subject, session=session, run=run))

        ecg_epochs = create_ecg_epochs(raw,
                                       baseline=(None, -0.2),
                                       tmin=-0.5,
                                       tmax=0.5)

        if len(ecg_epochs) == 0:
            msg = ('No ECG events could be found. Not running ECG artifact '
                   'detection.')
            logger.info(**gen_log_kwargs(
                message=msg, subject=subject, session=session, run=run))
            ecg_epochs = None
    else:
        msg = ('No ECG or magnetometer channels are present. Cannot '
               'automate artifact detection for ECG')
        logger.info(**gen_log_kwargs(
            message=msg, subject=subject, session=session, run=run))
        ecg_epochs = None

    return ecg_epochs
Example #4
0
def filter_for_ica(*,
                   cfg,
                   raw: mne.io.BaseRaw,
                   subject: str,
                   session: str,
                   run: Optional[str] = None) -> None:
    """Apply a high-pass filter if needed."""
    if cfg.ica_l_freq is None:
        msg = (f'Not applying high-pass filter (data is already filtered, '
               f'cutoff: {raw.info["highpass"]} Hz).')
        logger.info(**gen_log_kwargs(
            message=msg, subject=subject, session=session, run=run))
    else:
        msg = f'Applying high-pass filter with {cfg.ica_l_freq} Hz cutoff …'
        logger.info(**gen_log_kwargs(
            message=msg, subject=subject, session=session, run=run))
        raw.filter(l_freq=cfg.ica_l_freq, h_freq=None)
Example #5
0
def _channel_text_scrub(raw: mne.io.BaseRaw):
    """
    Clean and formats the channel text inside a MNE-Raw data structure.

    Parameters
    ----------
    raw : MNE-raw data structure
    """

    def _reformatchanlabel(label):  # noqa
        """Process a single channel label.

        To make sure it is:

        - upper case
        - removed unnecessary strings (POL, eeg, -ref)
        - removed empty spaces
        """

        # hard coded replacement rules
        # label = str(label).replace("POL ", "").upper()
        label = str(label).replace("POL", "").upper()
        label = label.replace("EEG", "").replace("-REF", "")  # .replace("!","1")

        # replace "Grid" with 'G' label
        label = label.replace("GRID", "G")
        # for BIDS format, you cannot have blank channel name
        if label == "":
            label = "N/A"
        return label

    # apply channel scrubbing
    raw = raw.rename_channels(lambda x: x.upper())

    # encapsulated into a try statement in case there are blank channel names
    # after scrubbing these characters
    try:
        raw = raw.rename_channels(
            lambda x: x.strip(".")
        )  # remove dots from channel names
        raw = raw.rename_channels(
            lambda x: x.strip("-")
        )  # remove dashes from channel names
    except ValueError as e:
        logger.error(f"Ran into an issue when debugging: {raw.info}")
        logger.exception(e)

    raw = raw.rename_channels(lambda x: x.replace(" ", ""))
    raw = raw.rename_channels(
        lambda x: x.replace("’", "'")
    )  # remove dashes from channel names
    raw = raw.rename_channels(
        lambda x: x.replace("`", "'")
    )  # remove dashes from channel names
    raw = raw.rename_channels(lambda x: _reformatchanlabel(x))

    return raw
Example #6
0
    def __init__(self, fpath=None, raw: mne.io.BaseRaw = None, type: str = "fif"):
        # if raw != None and fpath == None:
        #     raise RuntimeError("Pass in a file path to save data!")
        #
        # if fpath != None and raw == None:
        #     raise RuntimeError("Pass in a MNE Raw object to save!")

        if fpath != None and raw != None:
            if not os.path.exists(os.path.dirname(fpath)):
                fdir = os.path.dirname(fpath)
                raise RuntimeError(
                    "Filepath you passed to save data does not exist. Please "
                    f"first create the corresponding directory: {fdir}"
                )
            if type == "fif":
                self.saveas_fif(fpath, raw.get_data(return_times=False), raw.info)
Example #7
0
    def channel_text_scrub(cls, raw: mne.io.BaseRaw):
        """
        Cleans and formats the channel text inside a MNE-Raw data structure.

        TODO: ACCOUNT FOR - BEING IN BIPOLAR MONTAGE CHANNEL LABELS.

        Parameters
        ----------
        raw : MNE-raw data structure

        Returns
        -------

        """
        def _reformatchanlabel(label):
            """
            Helper function to process a single channel label to make sure it is:

            - upper case
            - removed unnecessary strings (POL, eeg, -ref)
            - removed empty spaces

            :param label: (str) a contact label that may have extra chars, or be improperly cased
            :return: label (str) the reformatted string that is uppercase and w/o spaces
            """
            # hard coded replacement rules
            # label = str(label).replace("POL ", "").upper()
            label = str(label).replace("POL", "").upper()
            label = label.replace("EEG", "").replace("-REF", "")

            # replace "Grid" with 'G' label
            label = label.replace("GRID", "G")
            # for BIDS format, you cannot have blank channel name
            if label == "":
                label = "N/A"
            return label

        # apply channel scrubbing
        raw.rename_channels(lambda x: x.upper())
        raw.rename_channels(
            lambda x: x.strip("."))  # remove dots from channel names
        raw.rename_channels(
            lambda x: x.strip("-"))  # remove dashes from channel names
        raw.rename_channels(lambda x: x.replace(" ", ""))
        raw.rename_channels(
            lambda x: x.replace("’", "'"))  # remove dashes from channel names
        raw.rename_channels(
            lambda x: x.replace("`", "'"))  # remove dashes from channel names
        raw.rename_channels(lambda x: _reformatchanlabel(x))

        return raw