Spaces:
Running
Running
| # Authors: The MNE-Python contributors. | |
| # License: BSD-3-Clause | |
| # Copyright the MNE-Python contributors. | |
| import copy as cp | |
| import numpy as np | |
| from .._fiff.pick import pick_types | |
| from .._fiff.reference import make_eeg_average_ref_proj | |
| from ..epochs import Epochs | |
| from ..proj import compute_proj_epochs, compute_proj_evoked | |
| from ..utils import _validate_type, logger, verbose, warn | |
| from .ecg import find_ecg_events | |
| from .eog import find_eog_events | |
| def _safe_del_key(dict_, key): | |
| """Aux function. | |
| Use this function when preparing rejection parameters | |
| instead of directly deleting keys. | |
| """ | |
| if key in dict_: | |
| del dict_[key] | |
| def _compute_exg_proj( | |
| mode, | |
| raw, | |
| raw_event, | |
| tmin, | |
| tmax, | |
| n_grad, | |
| n_mag, | |
| n_eeg, | |
| l_freq, | |
| h_freq, | |
| average, | |
| filter_length, | |
| n_jobs, | |
| ch_name, | |
| reject, | |
| flat, | |
| bads, | |
| avg_ref, | |
| no_proj, | |
| event_id, | |
| exg_l_freq, | |
| exg_h_freq, | |
| tstart, | |
| qrs_threshold, | |
| filter_method, | |
| iir_params, | |
| return_drop_log, | |
| copy, | |
| meg, | |
| verbose, | |
| ): | |
| """Compute SSP/PCA projections for ECG or EOG artifacts.""" | |
| raw = raw.copy() if copy else raw | |
| del copy | |
| raw.load_data() # we will filter it later | |
| if no_proj: | |
| projs = [] | |
| else: | |
| projs = cp.deepcopy(raw.info["projs"]) | |
| logger.info(f"Including {len(projs)} SSP projectors from raw file") | |
| if avg_ref: | |
| eeg_proj = make_eeg_average_ref_proj(raw.info) | |
| projs.append(eeg_proj) | |
| if raw_event is None: | |
| raw_event = raw | |
| assert mode in ("ECG", "EOG") # internal function | |
| logger.info(f"Running {mode} SSP computation") | |
| if mode == "ECG": | |
| events, _, _ = find_ecg_events( | |
| raw_event, | |
| ch_name=ch_name, | |
| event_id=event_id, | |
| l_freq=exg_l_freq, | |
| h_freq=exg_h_freq, | |
| tstart=tstart, | |
| qrs_threshold=qrs_threshold, | |
| filter_length=filter_length, | |
| ) | |
| else: # mode == 'EOG': | |
| events = find_eog_events( | |
| raw_event, | |
| event_id=event_id, | |
| l_freq=exg_l_freq, | |
| h_freq=exg_h_freq, | |
| filter_length=filter_length, | |
| ch_name=ch_name, | |
| tstart=tstart, | |
| ) | |
| # Check to make sure we actually got at least one usable event | |
| if events.shape[0] < 1: | |
| warn(f"No {mode} events found") | |
| return ([], events) + (([],) if return_drop_log else ()) | |
| logger.info("Computing projector") | |
| my_info = cp.deepcopy(raw.info) | |
| my_info["bads"] += bads | |
| # Handler rejection parameters | |
| _validate_type(reject, (None, dict), "reject") | |
| _validate_type(flat, (None, dict), "flat") | |
| if reject is not None: # make sure they didn't pass None | |
| reject = reject.copy() # must make a copy or we modify default! | |
| if ( | |
| len( | |
| pick_types( | |
| my_info, | |
| meg="grad", | |
| eeg=False, | |
| eog=False, | |
| ref_meg=False, | |
| exclude="bads", | |
| ) | |
| ) | |
| == 0 | |
| ): | |
| _safe_del_key(reject, "grad") | |
| if ( | |
| len( | |
| pick_types( | |
| my_info, | |
| meg="mag", | |
| eeg=False, | |
| eog=False, | |
| ref_meg=False, | |
| exclude="bads", | |
| ) | |
| ) | |
| == 0 | |
| ): | |
| _safe_del_key(reject, "mag") | |
| if ( | |
| len( | |
| pick_types( | |
| my_info, | |
| meg=False, | |
| eeg=True, | |
| eog=False, | |
| ref_meg=False, | |
| exclude="bads", | |
| ) | |
| ) | |
| == 0 | |
| ): | |
| _safe_del_key(reject, "eeg") | |
| if ( | |
| len( | |
| pick_types( | |
| my_info, | |
| meg=False, | |
| eeg=False, | |
| eog=True, | |
| ref_meg=False, | |
| exclude="bads", | |
| ) | |
| ) | |
| == 0 | |
| ): | |
| _safe_del_key(reject, "eog") | |
| if flat is not None: # make sure they didn't pass None | |
| flat = flat.copy() | |
| if ( | |
| len( | |
| pick_types( | |
| my_info, | |
| meg="grad", | |
| eeg=False, | |
| eog=False, | |
| ref_meg=False, | |
| exclude="bads", | |
| ) | |
| ) | |
| == 0 | |
| ): | |
| _safe_del_key(flat, "grad") | |
| if ( | |
| len( | |
| pick_types( | |
| my_info, | |
| meg="mag", | |
| eeg=False, | |
| eog=False, | |
| ref_meg=False, | |
| exclude="bads", | |
| ) | |
| ) | |
| == 0 | |
| ): | |
| _safe_del_key(flat, "mag") | |
| if ( | |
| len( | |
| pick_types( | |
| my_info, | |
| meg=False, | |
| eeg=True, | |
| eog=False, | |
| ref_meg=False, | |
| exclude="bads", | |
| ) | |
| ) | |
| == 0 | |
| ): | |
| _safe_del_key(flat, "eeg") | |
| if ( | |
| len( | |
| pick_types( | |
| my_info, | |
| meg=False, | |
| eeg=False, | |
| eog=True, | |
| ref_meg=False, | |
| exclude="bads", | |
| ) | |
| ) | |
| == 0 | |
| ): | |
| _safe_del_key(flat, "eog") | |
| # exclude bad channels from projection | |
| # keep reference channels if compensation channels are present | |
| ref_meg = len(my_info["comps"]) > 0 | |
| picks = pick_types( | |
| my_info, meg=True, eeg=True, eog=True, ecg=True, ref_meg=ref_meg, exclude="bads" | |
| ) | |
| raw.filter( | |
| l_freq, | |
| h_freq, | |
| picks=picks, | |
| filter_length=filter_length, | |
| n_jobs=n_jobs, | |
| method=filter_method, | |
| iir_params=iir_params, | |
| l_trans_bandwidth=0.5, | |
| h_trans_bandwidth=0.5, | |
| phase="zero-double", | |
| fir_design="firwin2", | |
| ) | |
| epochs = Epochs( | |
| raw, | |
| events, | |
| None, | |
| tmin, | |
| tmax, | |
| baseline=None, | |
| preload=True, | |
| picks=picks, | |
| reject=reject, | |
| flat=flat, | |
| proj=True, | |
| ) | |
| drop_log = epochs.drop_log | |
| if epochs.events.shape[0] < 1: | |
| warn("No good epochs found") | |
| return ([], events) + ((drop_log,) if return_drop_log else ()) | |
| if average: | |
| evoked = epochs.average() | |
| ev_projs = compute_proj_evoked( | |
| evoked, n_grad=n_grad, n_mag=n_mag, n_eeg=n_eeg, meg=meg | |
| ) | |
| else: | |
| ev_projs = compute_proj_epochs( | |
| epochs, n_grad=n_grad, n_mag=n_mag, n_eeg=n_eeg, n_jobs=n_jobs, meg=meg | |
| ) | |
| for p in ev_projs: | |
| p["desc"] = mode + "-" + p["desc"] | |
| projs.extend(ev_projs) | |
| logger.info("Done.") | |
| return (projs, events) + ((drop_log,) if return_drop_log else ()) | |
| def compute_proj_ecg( | |
| raw, | |
| raw_event=None, | |
| tmin=-0.2, | |
| tmax=0.4, | |
| n_grad=2, | |
| n_mag=2, | |
| n_eeg=2, | |
| l_freq=1.0, | |
| h_freq=35.0, | |
| average=True, | |
| filter_length="10s", | |
| n_jobs=None, | |
| ch_name=None, | |
| reject=dict(grad=2000e-13, mag=3000e-15, eeg=50e-6, eog=250e-6), # noqa: B006 | |
| flat=None, | |
| bads=(), | |
| avg_ref=False, | |
| no_proj=False, | |
| event_id=999, | |
| ecg_l_freq=5, | |
| ecg_h_freq=35, | |
| tstart=0.0, | |
| qrs_threshold="auto", | |
| filter_method="fir", | |
| iir_params=None, | |
| copy=True, | |
| return_drop_log=False, | |
| meg="separate", | |
| verbose=None, | |
| ): | |
| """Compute SSP (signal-space projection) vectors for ECG artifacts. | |
| %(compute_proj_ecg)s | |
| .. note:: Raw data will be loaded if it hasn't been preloaded already. | |
| Parameters | |
| ---------- | |
| raw : mne.io.Raw | |
| Raw input file. | |
| raw_event : mne.io.Raw or None | |
| Raw file to use for event detection (if None, raw is used). | |
| tmin : float | |
| Time before event in seconds. | |
| tmax : float | |
| Time after event in seconds. | |
| n_grad : int | |
| Number of SSP vectors for gradiometers. | |
| n_mag : int | |
| Number of SSP vectors for magnetometers. | |
| n_eeg : int | |
| Number of SSP vectors for EEG. | |
| l_freq : float | None | |
| Filter low cut-off frequency for the data channels in Hz. | |
| h_freq : float | None | |
| Filter high cut-off frequency for the data channels in Hz. | |
| average : bool | |
| Compute SSP after averaging. Default is True. | |
| filter_length : str | int | None | |
| Number of taps to use for filtering. | |
| %(n_jobs)s | |
| ch_name : str | None | |
| Channel to use for ECG detection (Required if no ECG found). | |
| reject : dict | None | |
| Epoch rejection configuration (see Epochs). | |
| flat : dict | None | |
| Epoch flat configuration (see Epochs). | |
| bads : list | |
| List with (additional) bad channels. | |
| avg_ref : bool | |
| Add EEG average reference proj. | |
| no_proj : bool | |
| Exclude the SSP projectors currently in the fiff file. | |
| event_id : int | |
| ID to use for events. | |
| ecg_l_freq : float | |
| Low pass frequency applied to the ECG channel for event detection. | |
| ecg_h_freq : float | |
| High pass frequency applied to the ECG channel for event detection. | |
| tstart : float | |
| Start artifact detection after tstart seconds. | |
| qrs_threshold : float | str | |
| Between 0 and 1. qrs detection threshold. Can also be "auto" to | |
| automatically choose the threshold that generates a reasonable | |
| number of heartbeats (40-160 beats / min). | |
| filter_method : str | |
| Method for filtering ('iir' or 'fir'). | |
| iir_params : dict | None | |
| Dictionary of parameters to use for IIR filtering. | |
| See mne.filter.construct_iir_filter for details. If iir_params | |
| is None and method="iir", 4th order Butterworth will be used. | |
| copy : bool | |
| If False, filtering raw data is done in place. Defaults to True. | |
| return_drop_log : bool | |
| If True, return the drop log. | |
| .. versionadded:: 0.15 | |
| meg : str | |
| Can be ``'separate'`` (default) or ``'combined'`` to compute projectors | |
| for magnetometers and gradiometers separately or jointly. | |
| If ``'combined'``, ``n_mag == n_grad`` is required and the number of | |
| projectors computed for MEG will be ``n_mag``. | |
| .. versionadded:: 0.18 | |
| %(verbose)s | |
| Returns | |
| ------- | |
| %(projs)s | |
| ecg_events : ndarray | |
| Detected ECG events. | |
| drop_log : list | |
| The drop log, if requested. | |
| See Also | |
| -------- | |
| find_ecg_events | |
| create_ecg_epochs | |
| Notes | |
| ----- | |
| Filtering is applied to the ECG channel while finding events using | |
| ``ecg_l_freq`` and ``ecg_h_freq``, and then to the ``raw`` instance | |
| using ``l_freq`` and ``h_freq`` before creation of the epochs used to | |
| create the projectors. | |
| """ | |
| return _compute_exg_proj( | |
| "ECG", | |
| raw, | |
| raw_event, | |
| tmin, | |
| tmax, | |
| n_grad, | |
| n_mag, | |
| n_eeg, | |
| l_freq, | |
| h_freq, | |
| average, | |
| filter_length, | |
| n_jobs, | |
| ch_name, | |
| reject, | |
| flat, | |
| bads, | |
| avg_ref, | |
| no_proj, | |
| event_id, | |
| ecg_l_freq, | |
| ecg_h_freq, | |
| tstart, | |
| qrs_threshold, | |
| filter_method, | |
| iir_params, | |
| return_drop_log, | |
| copy, | |
| meg, | |
| verbose, | |
| ) | |
| def compute_proj_eog( | |
| raw, | |
| raw_event=None, | |
| tmin=-0.2, | |
| tmax=0.2, | |
| n_grad=2, | |
| n_mag=2, | |
| n_eeg=2, | |
| l_freq=1.0, | |
| h_freq=35.0, | |
| average=True, | |
| filter_length="10s", | |
| n_jobs=None, | |
| reject=dict(grad=2000e-13, mag=3000e-15, eeg=500e-6, eog=np.inf), # noqa: B006 | |
| flat=None, | |
| bads=(), | |
| avg_ref=False, | |
| no_proj=False, | |
| event_id=998, | |
| eog_l_freq=1, | |
| eog_h_freq=10, | |
| tstart=0.0, | |
| filter_method="fir", | |
| iir_params=None, | |
| ch_name=None, | |
| copy=True, | |
| return_drop_log=False, | |
| meg="separate", | |
| verbose=None, | |
| ): | |
| """Compute SSP (signal-space projection) vectors for EOG artifacts. | |
| %(compute_proj_eog)s | |
| .. note:: Raw data must be preloaded. | |
| Parameters | |
| ---------- | |
| raw : mne.io.Raw | |
| Raw input file. | |
| raw_event : mne.io.Raw or None | |
| Raw file to use for event detection (if None, raw is used). | |
| tmin : float | |
| Time before event in seconds. | |
| tmax : float | |
| Time after event in seconds. | |
| n_grad : int | |
| Number of SSP vectors for gradiometers. | |
| n_mag : int | |
| Number of SSP vectors for magnetometers. | |
| n_eeg : int | |
| Number of SSP vectors for EEG. | |
| l_freq : float | None | |
| Filter low cut-off frequency for the data channels in Hz. | |
| h_freq : float | None | |
| Filter high cut-off frequency for the data channels in Hz. | |
| average : bool | |
| Compute SSP after averaging. Default is True. | |
| filter_length : str | int | None | |
| Number of taps to use for filtering. | |
| %(n_jobs)s | |
| reject : dict | None | |
| Epoch rejection configuration (see Epochs). | |
| flat : dict | None | |
| Epoch flat configuration (see Epochs). | |
| bads : list | |
| List with (additional) bad channels. | |
| avg_ref : bool | |
| Add EEG average reference proj. | |
| no_proj : bool | |
| Exclude the SSP projectors currently in the fiff file. | |
| event_id : int | |
| ID to use for events. | |
| eog_l_freq : float | |
| Low pass frequency applied to the E0G channel for event detection. | |
| eog_h_freq : float | |
| High pass frequency applied to the EOG channel for event detection. | |
| tstart : float | |
| Start artifact detection after tstart seconds. | |
| filter_method : str | |
| Method for filtering ('iir' or 'fir'). | |
| iir_params : dict | None | |
| Dictionary of parameters to use for IIR filtering. | |
| See mne.filter.construct_iir_filter for details. If iir_params | |
| is None and method="iir", 4th order Butterworth will be used. | |
| ch_name : str | None | |
| If not None, specify EOG channel name. | |
| copy : bool | |
| If False, filtering raw data is done in place. Defaults to True. | |
| return_drop_log : bool | |
| If True, return the drop log. | |
| .. versionadded:: 0.15 | |
| meg : str | |
| Can be 'separate' (default) or 'combined' to compute projectors | |
| for magnetometers and gradiometers separately or jointly. | |
| If 'combined', ``n_mag == n_grad`` is required and the number of | |
| projectors computed for MEG will be ``n_mag``. | |
| .. versionadded:: 0.18 | |
| %(verbose)s | |
| Returns | |
| ------- | |
| %(projs)s | |
| eog_events: ndarray | |
| Detected EOG events. | |
| drop_log : list | |
| The drop log, if requested. | |
| See Also | |
| -------- | |
| find_eog_events | |
| create_eog_epochs | |
| Notes | |
| ----- | |
| Filtering is applied to the EOG channel while finding events using | |
| ``eog_l_freq`` and ``eog_h_freq``, and then to the ``raw`` instance | |
| using ``l_freq`` and ``h_freq`` before creation of the epochs used to | |
| create the projectors. | |
| """ | |
| return _compute_exg_proj( | |
| "EOG", | |
| raw, | |
| raw_event, | |
| tmin, | |
| tmax, | |
| n_grad, | |
| n_mag, | |
| n_eeg, | |
| l_freq, | |
| h_freq, | |
| average, | |
| filter_length, | |
| n_jobs, | |
| ch_name, | |
| reject, | |
| flat, | |
| bads, | |
| avg_ref, | |
| no_proj, | |
| event_id, | |
| eog_l_freq, | |
| eog_h_freq, | |
| tstart, | |
| "auto", | |
| filter_method, | |
| iir_params, | |
| return_drop_log, | |
| copy, | |
| meg, | |
| verbose, | |
| ) | |