ECG and EOG

UML diagrams presenting the flow of the analysis for each module are available here: https://github.com/ANCPLabOldenburg/MEG-QC-code/tree/main/diagrams

class meg_qc.calculation.metrics.ECG_EOG_meg_qc.Avg_artif(name: str, artif_data: list, peak_loc=None, peak_magnitude=None, wave_shape: bool | None = None, artif_over_threshold: bool | None = None, main_peak_loc: int | None = None, main_peak_magnitude: float | None = None, artif_data_smoothed: list | None = None, peak_loc_smoothed=None, peak_magnitude_smoothed=None, wave_shape_smoothed: bool | None = None, artif_over_threshold_smoothed: bool | None = None, main_peak_loc_smoothed: int | None = None, main_peak_magnitude_smoothed: float | None = None, corr_coef: float | None = None, p_value: float | None = None, lobe: str | None = None, color: str | None = None)[source]

Instance of this class:

  • contains average ECG/EOG epoch for a particular channel,

  • calculates its main peak (location and magnitude), possibe on both smoothed and non smoothed data.

  • evaluates if this epoch is concidered as artifact or not based on the main peak amplitude.

name

name of the channel

Type:

str

artif_data

list of floats, average ecg epoch for a particular channel

Type:

list

peak_loc

locations of peaks inside the artifact epoch

Type:

int

peak_magnitude

magnitudes of peaks inside the artifact epoch

Type:

float

wave_shape

True if the average epoch has typical wave shape, False otherwise. R wave shape - for ECG or just a wave shape for EOG.

Type:

bool

artif_over_threshold

True if the main peak is concidered as artifact, False otherwise. True if artifact sas magnitude over the threshold

Type:

bool

main_peak_loc

location of the main peak inside the artifact epoch

Type:

int

main_peak_magnitude

magnitude of the main peak inside the artifact epoch

Type:

float

artif_data_smoothed

list of floats, average ecg epoch for a particular channel, smoothed usig Gaussian filter

Type:

list

peak_loc_smoothed

locations of peaks inside the artifact epoch calculated on smoothed data

Type:

int

peak_magnitude_smoothed

magnitudes of peaks inside the artifact epoch calculated on smoothed data

Type:

float

wave_shape_smoothed

True if the average epoch has typical wave shape, False otherwise. R wave shape - for ECG or just a wave shape for EOG. Calculated on smoothed data

Type:

bool

artif_over_threshold_smoothed

True if the main peak is concidered as artifact, False otherwise. True if artifact sas magnitude over the threshold. Calculated on smoothed data

Type:

bool

main_peak_loc_smoothed

location of the main peak inside the artifact epoch. Calculated on smoothed data

Type:

int

main_peak_magnitude_smoothed

magnitude of the main peak inside the artifact epoch. Calculated on smoothed data

Type:

float

corr_coef

correlation coefficient between the ECG/EOG channels data and average data of this mag/grad channel

Type:

float

p_value

p-value of the correlation coefficient between the ECG/EOG channels data and average data of this mag/grad channel

Type:

float

lobe

which lobe his channel belongs to

Type:

str

color

color code for this channel according to the lobe it belongs to

Type:

str

__init__(self, name: str, artif_data: list, peak_loc=None, peak_magnitude=None, wave_shape: bool = None, artif_over_threshold: bool = None, main_peak_loc: int = None, main_peak_magnitude: float = None)[source]

Constructor

__repr__(self)[source]

Returns a string representation of the object

detect_artif_above_threshold(artif_threshold_lvl: float, t: ndarray, timelimit_min: float, timelimit_max: float)[source]

Detect if the highest peak of the artifact epoch is above a given threshold. Time window is centered around the t0 of the ecg/eog event and limited by timelimit_min and timelimit_max.

Parameters:
  • artif_threshold_lvl (float) – threshold level

  • t (list) – time vector

  • timelimit_min (float) – minimum time limit for the peak

  • timelimit_max (float) – maximum time limit for the peak

Returns:

self.artif_over_threshold – True if the highest peak is above the threshold, False otherwise

Return type:

bool

detect_artif_above_threshold_smoothed(artif_threshold_lvl: float, t: ndarray, timelimit_min: float, timelimit_max: float)[source]

Detect if the highest peak of the artifact epoch is above a given threshold for SMOOTHED data. Time window is centered around the t0 of the ecg/eog event and limited by timelimit_min and timelimit_max.

Parameters:
  • artif_threshold_lvl (float) – threshold level

  • t (list) – time vector

  • timelimit_min (float) – minimum time limit for the peak

  • timelimit_max (float) – maximum time limit for the peak

Returns:

self.artif_over_threshold – True if the highest peak is above the threshold, False otherwise

Return type:

bool

flip_artif()[source]

Flip the artifact epoch upside down on original (non smoothed) data. This is only done if the need to flip was detected in flip_channels() function.

Returns:

Avg_artif object with flipped artifact epoch in self.artif_data and self.peak_magnitude

Return type:

self

flip_artif_smoothed()[source]

Flip the SMOOTHED artifact epoch upside down. This is only done if the need to flip was detected in flip_channels() function.

Returns:

Avg_artif object with flipped smoothed artifact epoch in self.artif_data_smoothed and self.peak_magnitude_smoothed

Return type:

self

get_highest_peak(t: ndarray, timelimit_min: float, timelimit_max: float)[source]

Find the highest peak of the artifact epoch inside the give time window. Time window is centered around the t0 of the ecg/eog event and limited by timelimit_min and timelimit_max.

Parameters:
  • t (list) – time vector

  • timelimit_min (float) – minimum time limit for the peak

  • timelimit_max (float) – maximum time limit for the peak

Returns:

  • main_peak_loc (int) – location of the main peak

  • main_peak_magnitude (float) – magnitude of the main peak

get_highest_peak_smoothed(t: ndarray, timelimit_min: float, timelimit_max: float)[source]

Find the highest peak of the artifact epoch inside the give time window on SMOOTHED data. Time window is centered around the t0 of the ecg/eog event and limited by timelimit_min and timelimit_max.

Parameters:
  • t (list) – time vector

  • timelimit_min (float) – minimum time limit for the peak

  • timelimit_max (float) – maximum time limit for the peak

Returns:

  • main_peak_magnitude_smoothed (float) – magnitude of the main peak on smoothed data

  • main_peak_loc_smoothed (int) – location of the main peak on smoothed data

get_peaks_wave(max_n_peaks_allowed: int, thresh_lvl_peakfinder: float)[source]

Find peaks in the average artifact epoch and decide if the epoch has wave shape: few peaks (different number allowed for ECG and EOG) - wave shape, many or no peaks - not. On non smoothed data!

Parameters:
  • max_n_peaks_allowed (int) – maximum number of peaks allowed in the average artifact epoch

  • thresh_lvl_peakfinder (float) – threshold for peakfinder function.

get_peaks_wave_smoothed(gaussian_sigma: int, max_n_peaks_allowed: int, thresh_lvl_peakfinder: float)[source]

Find peaks in the average artifact epoch and decide if the epoch has wave shape: few peaks (different number allowed for ECG and EOG) - wave shape, many or no peaks - not. On smoothed data! If it was not smoothed yet - it will be smoothed inside this function

Parameters:
  • gaussian_sigma (int) – sigma for gaussian smoothing

  • max_n_peaks_allowed (int) – maximum number of peaks allowed in the average artifact epoch

  • thresh_lvl_peakfinder (float) – threshold for peakfinder function.

plot_epoch_and_peak(t: ndarray, fig_tit: str, ch_type: str, fig: Figure | None = None, plot_original: bool = True, plot_smoothed: bool = True)[source]

Plot the average artifact epoch and the peak inside it. Allowes to plot both originl and smoothed data or only 1 of them in same figure.

Parameters:
  • t (list) – time vector as numpy array. It can be created as: t = np.round(np.arange(tmin, tmax+1/sfreq, 1/sfreq), 3) #yes, you need to round

  • fig_tit (str) – title of the figure not including ch type.

  • ch_type (str) – type of the channel (‘mag, ‘grad’). Used only as title of the figure

  • fig (plotly.graph_objects.Figure) – (Empty) plotly figure to be filled. If set to None - figure will be created inside this function. Giving figure is useful if you want to plot more traces on top of the figure you already have using this function. But! If you plot into the same figure on the loop - create the figure first. And then input same figure into this function on every iteration. If you ll input None, figure will be overwritten on every itertion.

  • plot_original (bool) – if True - plot originl artifact data (non smoothed)

  • plot_smoothed (bool) – if True - plot smoothed artifact data

Returns:

fig – figure with the epoch and the peak

Return type:

plotly.graph_objects.Figure

smooth_artif(gauss_sigma: int)[source]

Smooth the artifact epoch using gaussian filter. This is done do detect the wave shape in presence of noise. Usually EOG are more noisy than ECG which prevents from detecting a wave shape with same settings on these 2 types of artifacts.

Parameters:

gauss_sigma (int) – sigma of the gaussian filter

Returns:

Avg_artif object with smoothed artifact epoch in self.artif_data_smoothed

Return type:

self

meg_qc.calculation.metrics.ECG_EOG_meg_qc.ECG_meg_qc(ecg_params: dict, ecg_params_internal: dict, raw: Raw, channels: list, chs_by_lobe_orig: dict, m_or_g_chosen: list, verbose_plots: bool)[source]

Main ECG function. Calculates average ECG artifact and finds affected channels.

Parameters:
  • ecg_params (dict) – Dictionary with ECG parameters originating from config file.

  • ecg_params_internal (dict) – Dictionary with ECG parameters originating from config file preset, not to be changed by user.

  • raw (mne.io.Raw) – Raw data.

  • channels (dict) – Dictionary with listds of channels for each channel type (mag and grad).

  • chs_by_lobe (dict) – Dictionary with lists of channels by lobe.

  • m_or_g_chosen (list) – List of channel types chosen for the analysis.

  • verbose_plots (bool) – True for showing plot in notebook.

Returns:

  • ecg_derivs (list) – List of all derivatives (plotly figures) as QC_derivative instances

  • simple_metric_ECG (dict) – Dictionary with simple metrics for ECG artifacts to be exported into json file.

  • ecg_str_for_report (str) – String with information about ECG channel used in the final report.

meg_qc.calculation.metrics.ECG_EOG_meg_qc.EOG_meg_qc(eog_params: dict, eog_params_internal: dict, raw: Raw, channels: dict, chs_by_lobe_orig: dict, m_or_g_chosen: list, verbose_plots: bool)[source]

Main EOG function. Calculates average EOG artifact and finds affected channels.

Parameters:
  • eog_params (dict) – Dictionary with EOG parameters originating from the config file.

  • eog_params_internal (dict) – Dictionary with EOG parameters originating from the config file - preset for internal use, not to be changed by the user.

  • raw (mne.io.Raw) – Raw MEG data.

  • channels (dict) – Dictionary with listds of channels for each channel type (mag and grad).

  • chs_by_lobe (dict) – Dictionary with lists of channels separated by lobe.

  • m_or_g_chosen (list) – List of channel types chosen for the analysis.

  • verbose_plots (bool) – True for showing plot in notebook.

Returns:

  • eog_derivs (list) – List of all derivatives (plotly figures) as QC_derivative instances

  • simple_metric_EOG (dict) – Dictionary with simple metrics for ECG artifacts to be exported into json file.

  • eog_str_for_report (str) – String with information about EOG channel used in the final report.

meg_qc.calculation.metrics.ECG_EOG_meg_qc.align_mean_rwave(mean_rwave: ndarray, artif_per_ch: list, tmin: float, tmax: float)[source]

Aligns the mean ECG wave with the ECG artifacts found on meg channels. 1) The average highest point of 10 most prominent meg channels is used as refernce. The ECG artifact is shifted multiple times, 2) each time the correlation of ECG channel with meg channel artofacts is calculated, then the aligment versiob which shows highes correlation is chosen as final. Part 1) is done inside this function, part 2) is done inside the main ECG_meg_qc function, but they are both the part of one algorithm.

Parameters:
  • mean_rwave (np.array) – The mean ECG wave (resulting from recorded or recosntructed ECG signal).

  • artif_per_ch (list) – List of Avg_artif objects, each of which contains the ECG artifact from one MEG channel.

  • tmin (float) – The start time of the ECG artifact, set in config

  • tmax (float) – The end time of the ECG artifact, set in config

Returns:

mean_rwave_shifted_variations – List of arrays. Every array is a variation of he mean ECG wave shifted to align with the ECG artifacts found on meg channels.

Return type:

list

meg_qc.calculation.metrics.ECG_EOG_meg_qc.assign_lobe_to_artifacts(artif_per_ch, chs_by_lobe)[source]

Loop over all channels in artif_per_ch and assign lobe and lobe color to each channel for plotting purposes.

Parameters:
  • artif_per_ch (list) – List of channels with Avg_artif objects.

  • chs_by_lobe (dict) – Dictionary of channels grouped by lobe with color codes.

Returns:

artif_per_ch – List of channels with Avg_artif objects, now with assigned lobe and color for plotting.

Return type:

list

meg_qc.calculation.metrics.ECG_EOG_meg_qc.calculate_artifacts_on_channels(artif_epochs: Epochs, channels: list, chs_by_lobe: dict, thresh_lvl_peakfinder: float, tmin: float, tmax: float, params_internal: dict, gaussian_sigma: int)[source]

Find channels that are affected by ECG or EOG events. The function calculates average ECG epoch for each channel and then finds the peak of the wave on each channel.

Parameters:
  • artif_epochs (mne.Epochs) – ECG epochs.

  • channels (list) – List of channels to use.

  • chs_by_lobe (dict) – dictionary with channel objects sorted by lobe

  • thresh_lvl_peakfinder (float) – Threshold level for peakfinder.

  • tmin (float) – Start time.

  • tmax (float) – End time.

  • params_internal (dict) – Dictionary with internal parameters.

  • gaussian_sigma (int, optional) – Sigma for gaussian filter. The default is 6. Usually for EOG need higher (6-7), t s more noisy, for ECG - lower (4-5).

Returns:

all_artifs_nonflipped – List of channels with Avg_artif objects, data in these is not flipped yet.

Return type:

list

meg_qc.calculation.metrics.ECG_EOG_meg_qc.check_3_conditions(ch_data: list, fs: int, ecg_or_eog: str, n_breaks_bursts_allowed_per_10min: int, allowed_range_of_peaks_stds: float, height_multiplier: float)[source]

Check if the ECG/EOG channel is not corrupted using 3 conditions: - peaks have similar amplitude - no breaks longer than normal max distance between peaks of hear beats - no bursts: too short intervals between peaks

Parameters:
  • ch_data (list or np.ndarray) – Data of the channel to check

  • fs (int) – Sampling frequency of the data

  • ecg_or_eog (str) – ‘ECG’ or ‘EOG’

  • n_breaks_bursts_allowed_per_10min (int, optional) – Number of breaks allowed per 10 minutes of recording, by default 3. Can also set to 0, but then it can falsely detect a break/burst if the peak detection was not perfect.

  • allowed_range_of_peaks_stds (float, optional) – Allowed range of standard deviations of peak amplitudes, by default 0.05. Works for ECG channel, but not good for EOG channel.

  • height_multiplier (float) – Will define how high the peaks on the ECG channel should be to be counted as peaks. Higher value - higher the peak need to be, hense less peaks will be found.

Returns:

  • ecg_eval (dict) – Dictionary with 3 booleans, indicating if the channel is good or bad according to 3 conditions: - similar_ampl: True if peaks have similar amplitudes, False otherwise - no_breaks: True if there are no breaks longer than normal max distance between peaks of hear beats, False otherwise - no_bursts: True if there are no bursts: too short intervals between peaks, False otherwise

  • fig (plotly.graph_objects.Figure) – Plot of the channel data and detected peaks

meg_qc.calculation.metrics.ECG_EOG_meg_qc.check_mean_wave(raw: Raw, use_method: str, ecg_data: ndarray, ecg_or_eog: str, event_indexes: ndarray, tmin: float, tmax: float, sfreq: int, params_internal: dict, thresh_lvl_peakfinder: float, verbose_plots: bool)[source]

Calculate mean R wave based on either real ECG channel data or on reconstructed data (depends on the method used) and check if it has an R wave shape. Plot Rwave with peaks.

Parameters:
  • raw (mne.io.Raw) – Raw data.

  • use_method (str) – String with the method chosen for the analysis.

  • ecg_data (np.ndarray) – ECG channel data. If it s empty, it will be reconstructed here

  • event_indexes – Indexes of the ECG events.

  • tmin (float) – Epoch start time before event (negative value)

  • tmax (float) – Epoch end time after event (positive value)

  • sfreq (float) – Sampling frequency

  • params_internal (dict) – Dictionary with internal parameters originating from settings_internal.

  • thresh_lvl_peakfinder (float) – Threshold level for peakfinder function.

Returns:

  • mean_rwave_obj.wave_shape (bool) – True if the mean R wave shape is good, False if not.

  • ecg_str_checked (str) – String with info about the ECG channel quality (after checking)

  • mean_rwave (np.array) – Mean R wave (1 dimentional).

meg_qc.calculation.metrics.ECG_EOG_meg_qc.detect_channels_above_norm(norm_lvl: float, list_mean_artif_epochs: list, mean_magnitude_peak: float, t: ndarray, t0_actual: float, window_size_for_mean_threshold_method: float, mean_magnitude_peak_smoothed: float | None = None, t0_actual_smoothed: float | None = None)[source]

Find the channels which got average artifact amplitude higher than the average over all channels*norm_lvl.

Parameters:
  • norm_lvl (float) – The norm level is the scaling factor for the threshold. The mean artifact amplitude over all channels is multiplied by the norm_lvl to get the threshold.

  • list_mean_artif_epochs (list) – List of MeanArtifactEpoch objects, each hold the information about mean artifact for one channel.

  • mean_magnitude_peak (float) – The magnitude the mean artifact amplitude over all channels.

  • t (np.ndarray) – Time vector.

  • t0_actual (float) – The time of the ecg/eog event.

  • window_size_for_mean_threshold_method (float) – this value will be taken before and after the t0_actual. It defines the time window in which the peak of artifact on the channel has to present to be counted as artifact peak and compared t the threshold. Unit: seconds

  • mean_magnitude_peak_smoothed (float, optional) – The magnitude the mean artifact amplitude over all channels for SMOOTHED data. The default is None.

  • t0_actual_smoothed (float, optional) – The time of the ecg/eog event for SMOOTHED data. The default is None.

Returns:

  • affected_orig (list) – List of channels which got average artifact amplitude higher than the average over all channels*norm_lvl.

  • not_affected_orig (list) – List of channels which got average artifact amplitude lower than the average over all channels*norm_lvl.

  • artif_threshold_lvl (float) – The threshold level for the artifact amplitude.

  • affected_smoothed (list) – List of channels which got average artifact amplitude higher than the average over all channels*norm_lvl for SMOOTHED data.

  • not_affected_smoothed (list) – List of channels which got average artifact amplitude lower than the average over all channels*norm_lvl for SMOOTHED data.

  • artif_threshold_lvl_smoothed (float) – The threshold level for the artifact amplitude for SMOOTHED data.

meg_qc.calculation.metrics.ECG_EOG_meg_qc.detect_noisy_ecg(raw: Raw, ecg_ch: str, ecg_or_eog: str, n_breaks_bursts_allowed_per_10min: int, allowed_range_of_peaks_stds: float, height_multiplier: float)[source]

Detects noisy ecg or eog channels.

The channel is noisy when:

  1. The distance between the peaks of ECG/EOG signal is too large (events are not frequent enoigh for a human) or too small (events are too frequent for a human).

  2. There are too many breaks in the data (indicating lack of heartbeats or blinks for a too long period) -corrupted channel or dustructed recording

  3. Peaks are of significantly different amplitudes (indicating that the channel is noisy).

Parameters:
  • raw (mne.io.Raw) – Raw data.

  • ecg_ch (str) – ECG channel names to be checked.

  • ecg_or_eog (str) – ‘ECG’ or ‘EOG’

  • n_breaks_bursts_allowed_per_10min (int) – Number of breaks allowed per 10 minutes of recording. The default is 3.

  • allowed_range_of_peaks_stds (float) –

    Allowed range of peaks standard deviations. The default is 0.05.

    • The channel data will be scaled from 0 to 1, so the setting is universal for all data sets.

    • The peaks will be detected on the scaled data

    • The average std of all peaks has to be within this allowed range, If it is higher - the channel has too high deviation in peaks height and is counted as noisy

  • height_multiplier (float) – Defines how high the peaks on the ECG channel should be to be counted as peaks. Higher value - higher the peak need to be, hense less peaks will be found.

Returns:

  • bad_ecg_eog (dict) – Dictionary with channel names as keys and ‘good’ or ‘bad’ as values.

  • all_ch_data[0] (list) – data of the ECG channel recorded.

  • ecg_eval (tuple) – Tuple of 3 booleans, indicating if the channel is good or bad according to 3 conditions: - similar_ampl: True if peaks have similar amplitudes, False otherwise - no_breaks: True if there are no breaks longer than normal max distance between peaks of hear beats, False otherwise - no_bursts: True if there are no bursts: too short intervals between peaks, False otherwise

meg_qc.calculation.metrics.ECG_EOG_meg_qc.estimate_t0(artif_per_ch_nonflipped: list, t: ndarray, params_internal: dict)[source]

Estimate t0 for the artifact. MNE has it s own estimation of t0, but it is often not accurate. t0 will be the point of the maximal amplitude of the artifact. Steps:

  1. find maxima on all channels (absolute values) in time frame around -0.02<t[peak_loc]<0.012

    (here R wave is typically detected by mne - for ecg, for eog it is -0.1<t[peak_loc]<0.2)

  2. take 5 channels with most prominent peak

  3. find estimated average t0 for all 5 channels, set it as new t0.

Parameters:
  • ecg_or_eog (str) – The type of the artifact: ‘ECG’ or ‘EOG’.

  • avg_ecg_epoch_data_nonflipped (np.ndarray) – The data of the channels.

  • t (np.ndarray) – The time vector.

  • params_internal (dict) – Dictionary with internal parameters.

Returns:

  • t0_estimated_ind (int) – The index of the estimated t0.

  • t0_estimated (float) – The estimated t0.

  • t0_estimated_ind_start (int) – The start index of the time window for the estimated t0.

  • t0_estimated_ind_end (int) – The end index of the time window for the estimated t0.

meg_qc.calculation.metrics.ECG_EOG_meg_qc.find_affected_by_correlation(mean_rwave: ndarray, artif_per_ch: list)[source]

” Calculate correlation coefficient and p-value between mean R wave and each channel in artif_per_ch. Higher correlation coefficient means that the channel is more likely to be affected by ECG artifact.

Here we assume that both vectors have sme length! these are defined by tmin and tmax which are set in config and propageted in this script. Keep in mind if changing anything with tmin and tmax

Parameters:
  • mean_rwave (np.ndarray) – Mean R wave (1 dimentional).

  • artif_per_ch (list) – List of channels with Avg_artif objects.

Returns:

artif_per_ch – List of channels with Avg_artif objects, now with assigned correlation coefficient and p-value.

Return type:

list

meg_qc.calculation.metrics.ECG_EOG_meg_qc.find_affected_over_mean(artif_per_ch: list, ecg_or_eog: str, params_internal: dict, thresh_lvl_peakfinder: float, plotflag: bool, verbose_plots: bool, m_or_g: str, chs_by_lobe: dict, norm_lvl: float, flip_data: bool, gaussian_sigma: float, artif_time_vector: ndarray)[source]

1. Calculate average ECG epoch on the epochs from all channels. Check if average has a wave shape. If no wave shape - no need to check for affected channels further. If it has - check further

2. Set a threshold which defines a high amplitude of ECG event. (All above this threshold counted as potential ECG peak.) Threshold is the magnitude of the peak of the average ECG/EOG epoch multiplued by norm_lvl. norl_lvl is chosen by user in config file

3. Find all peaks above this threshold. Finding approach:

  • again, set t0 actual as the time point of the peak of an average artifact (over all channels)

  • again, set a window around t0_actual. this new window is defined by how long the wave of the artifact normally is.

    The window is centered around t0 and for ECG it will be -0.-02 to 0.02s, for EOG it will be -0.1 to 0.1s.

  • find one main peak of the epoch for each channel which would be inside this window and closest to t0.

  • if this peaks magnitude is over the threshold - this channels is considered to be affected by ECG or EOG. Otherwise - not affected.

    (The epoch has to have a wave shape).

  1. Affected and non affected channels will be plotted and outputted as lists for adding tothe json on the next step.

Parameters:
  • artif_per_ch (list) – list of Avg_artif objects

  • ecg_or_eog (str) – ‘ECG’ or ‘EOG’

  • params_internal (dict) – dictionary with parameters from setings_internal file

  • thresh_lvl_peakfinder (float) – threshold for peakfinder. Defines the magnitude of the peak of the average ECG/EOG epoch multiplued by norm_lvl.

  • plotflag (bool) – if True - plots will be made

  • verbose_plots (bool) – if True - plots will be shown in notebook

  • m_or_g (str) – ‘mag’ or ‘grad’

  • chs_by_lobe (dict) – dictionary with channels grouped by lobes

  • norm_lvl (float) – defines the threshold for peakfinder. Threshold = mean overall artifact poch magnitude * norm_lvl

  • flip_data (bool) – ifo for plotting. If data was flipped - only upper threshold will be shown on the plot, if not - both upper and lower

  • gaussian_sigma (float) – sigma for gaussian smoothing

  • artif_time_vector (np.ndarray) – time vector for the artifact epoch

Returns:

  • affected_channels (list) – list of affected channels

  • affected_derivs (list) – list of QC_derivative objects with figures for affected and not affected channels (smoothed and not soothed versions)

  • bad_avg_str (str) – string about the average artifact: if it was not considered to be a wave shape

  • avg_overall_obj (Avg_artif) – Avg_artif object with the average artifact

meg_qc.calculation.metrics.ECG_EOG_meg_qc.find_epoch_peaks(ch_data: ndarray, thresh_lvl_peakfinder: float)[source]

Find the peaks in the epoch data using the peakfinder algorithm.

Parameters:
  • ch_data (np.ndarray) – The data of the channel.

  • thresh_lvl_peakfinder (float) – The threshold for the peakfinder algorithm.

Returns:

  • peak_locs_pos (np.ndarray) – The locations of the positive peaks.

  • peak_locs_neg (np.ndarray) – The locations of the negative peaks.

  • peak_magnitudes_pos (np.ndarray) – The magnitudes of the positive peaks.

  • peak_magnitudes_neg (np.ndarray) – The magnitudes of the negative peaks.

Calculate mean R wave on the data of either original ECG channel or reconstructed ECG channel. In some cases (for reconstructed) there are no events, so mean Rwave cant be estimated. This usually does not happen for real ECG channel. Because real ECG channel passes the check even earlier in the code. (see check_3_conditions())

Parameters:
  • ch_data (np.ndarray) – Data of the channel (real or reconstructed).

  • event_indexes (array) – Array of event indexes (R wave peaks).

  • tmin (float) – Start time of ECG epoch (negative value).

  • tmax (float) – End time of ECG epoch (positive value).

  • sfreq (int) – Sampling frequency.

Returns:

mean_rwave – Mean R wave (1 dimentional).

Return type:

np.ndarray

meg_qc.calculation.metrics.ECG_EOG_meg_qc.find_t0_channels(artif_per_ch: list, tmin: float, tmax: float)[source]

Run peak detection on all channels and find the 10 channels with the highest peaks. Then find the t0 for each of these channels and take the mean of these t0s as the final t0. It is also possible that t0 of these 10 channels dont concentrate around the same point, but around 1 points. For this reason theer is a check on how far the time points are from each other. If over 0.01, then they probabably concentrate around 2 points and then just the 1 highes magnitude (not the mean) as taken as the final t0.

Parameters:
  • artif_per_ch (list) – List of Avg_artif objects, one for each channel.

  • tmin (float) – Start time of epoch.

  • tmax (float) – End time of epoch.

Returns:

t0_channels – The final t0 (index, not the seconds!) that will be used for all channels as a refernce point. To this point the Average ECG will be aligned.

Return type:

int

meg_qc.calculation.metrics.ECG_EOG_meg_qc.find_t0_highest(ch_data: ndarray)[source]

Find the t0 as the largest in absolute amplitude peak of the ECG artifact on ONE channel. This function is looped over all channels to find the t0 for all channels.

Parameters:

ch_data (np.ndarray or list) – the data for average ECG artifact on meg channel.

Returns:

t0 – t0 for the channel (index, not the seconds!).

Return type:

int

meg_qc.calculation.metrics.ECG_EOG_meg_qc.find_t0_mean(ch_data: ndarray)[source]

Find all t0 options for the mean ECG wave.

Parameters:

ch_data (np.ndarray or list) – averaged ECG channel data.

Returns:

potential_t0 – List with all potential t0 options for the mean ECG wave. Will be used to get all possible option for shifting the ECG wave to align it with the MEG channels.

Return type:

list

meg_qc.calculation.metrics.ECG_EOG_meg_qc.flip_channels(artif_per_ch_nonflipped: list, tmin: float, tmax: float, sfreq: int, params_internal: dict)[source]

Flip the channels if the peak of the artifact is negative and located close to the estimated t0.

Flip approach:

  • define a window around the ecg/eog event deteceted by mne. This is not the real t0, but an approximation.

    The size of the window defines by how large on average the error of mne is when mne algorythm estimates even time. So for example if mne is off by 0.05s on average, then the window should be -0.05 to 0.05s.

  • take 5 channels with the largest peak in this window - assume these peaks are the actual artifact.

  • find the average of these 5 peaks - this is the new estimated_t0 (but still not the real t0)

  • create a new window around this new t0 - in this time window all the artifact wave shapes should be located on all channels.

  • flip the channels, if they have a peak inside of this new window, but the peak is negative and it is the closest peak to estimated t0.

    if the peak is positive - do not flip.

  • collect all final flipped+unflipped eppochs of these channels

Parameters:
  • avg_artif_nonflipped (list) – List of Avg_artif objects with not flipped data.

  • tmin (float) – time in sec before the peak of the artifact (negative number).

  • tmax (float) – time in sec after the peak of the artifact (positive number).

  • sfreq (int) – Sampling frequency.

  • params_internal (dict) – Dictionary with internal parameters.

Returns:

  • artifacts_flipped (list) – The list of the ecg epochs.

  • artif_time_vector (np.ndarray) – The time vector for the ecg epoch (for plotting further).

meg_qc.calculation.metrics.ECG_EOG_meg_qc.get_ECG_data_choose_method(raw: Raw, ecg_params: dict)[source]

Choose the method of finding affected channels based on the presense and quality of ECG channel.

Options: - Channel present and good: correlation with ECG channel - Channel present and bad or missing:correlation with reconstructed channel - Use mean ECG artifact as threshold (currrently not used)

Parameters:
  • ecg_params (dict) – Dictionary with ECG parameters originating from config file.

  • raw (mne.io.Raw) – Raw data.

  • verbose_plots (bool) – If True, plots are displayed in notebook.

Returns:

  • use_method (str) – String with the method chosen for the analysis.

  • ecg_str (str) – String with info about the ECG channel presense.

  • noisy_ch_derivs (list) – List of QC_derivative objects with plot of the ECG channel

  • ecg_data – ECG channel data.

  • event_indexes – Indexes of the ECG events.

meg_qc.calculation.metrics.ECG_EOG_meg_qc.get_EOG_data(raw: Raw)[source]

Find if the EOG channel is present anfd get its data.

Parameters:

raw (mne.io.Raw) – Raw data.

Returns:

  • eog_str (str) – String with info about the EOG channel presense.

  • eog_data – EOG channel data.

  • event_indexes – Indexes of the ECG events.

  • eog_ch_name (str) – Name of the EOG channel.

meg_qc.calculation.metrics.ECG_EOG_meg_qc.make_dict_global_ECG_EOG(channels_ranked: list, use_method: str)[source]

Make a dictionary for the global part of simple metrics for ECG/EOG artifacts. For ECG/EOG no local metrics are calculated, so global is the only one.

Parameters:
  • channels_ranked (list) – List of all affected channels

  • use_method (str) – Method used for detection of ECG/EOG artifacts: correlation, correlation_reconstructed or mean_threshold. Depending in this the dictionary will have difefrent structure and descriptions.

Returns:

metric_global_content – Dictionary with simple metrics for ECG/EOG artifacts.

Return type:

dict

meg_qc.calculation.metrics.ECG_EOG_meg_qc.make_simple_metric_ECG_EOG(channels_ranked: dict, m_or_g_chosen: list, ecg_or_eog: str, avg_artif_str: dict, use_method: str)[source]

Make simple metric for ECG/EOG artifacts as a dictionary, which will further be converted into json file.

Parameters:
  • channels_ranked (dict) – Dictionary with lists of channels.

  • m_or_g_chosen (list) – List of channel types chosen for the analysis.

  • ecg_or_eog (str) – String ‘ecg’ or ‘eog’ depending on the artifact type.

  • avg_artif_str (dict) – Dict with strings with info about the ECG/EOG channel and average artifact.

  • use_method (str) – Method used for detection of ECG/EOG artifacts: correlation, correlation_reconstructed or mean_threshold. Depending in this the dictionary will have difefrent structure and descriptions.

Returns:

simple_metric – Dictionary with simple metrics for ECG/EOG artifacts.

Return type:

dict

meg_qc.calculation.metrics.ECG_EOG_meg_qc.plot_affected_channels(artif_affected_channels: list, artifact_lvl: float, t: ndarray, ch_type: str, fig_tit: str, chs_by_lobe: dict, flip_data: bool = 'flip', smoothed: bool = False, verbose_plots: bool = True)[source]

Plot the mean artifact amplitude for all affected (not affected) channels in 1 plot together with the artifact_lvl.

Parameters:
  • artif_affected_channels (list) – List of ECG/EOG artifact affected channels.

  • artifact_lvl (float) – The threshold for the artifact amplitude: average over all channels*norm_lvl.

  • t (np.ndarray) – Time vector.

  • ch_type (str) – Either ‘mag’ or ‘grad’.

  • fig_tit (str) – The title of the figure.

  • chs_by_lobe (dict) – dictionary with channel objects sorted by lobe

  • flip_data (bool) – If True, the absolute value of the data will be used for the calculation of the mean artifact amplitude. Default to ‘flip’. ‘flip’ means that the data will be flipped if the peak of the artifact is negative. This is donr to get the same sign of the artifact for all channels, then to get the mean artifact amplitude over all channels and the threshold for the artifact amplitude onbase of this mean And also for the reasons of visualization: the artifact amplitude is always positive.

  • smoothed (bool) – Plot smoothed data (true) or nonrmal (false)

  • verbose_plots (bool) – True for showing plot in notebook.

Returns:

fig – The plotly figure with the mean artifact amplitude for all affected (not affected) channels in 1 plot together with the artifact_lvl.

Return type:

plotly.graph_objects.Figure

meg_qc.calculation.metrics.ECG_EOG_meg_qc.plot_artif_per_ch_correlated_lobes(artif_per_ch: list, tmin: float, tmax: float, m_or_g: str, ecg_or_eog: str, chs_by_lobe: dict, flip_data: bool, verbose_plots: bool)[source]

Plot average artifact for each channel, colored by lobe, channels are split into 3 separate plots, based on their correlation with mean_rwave: equal number of channels in each group.

Parameters:
  • artif_per_ch (list) – List of objects of class Avg_artif

  • tmin (float) – Start time of the epoch (negative value)

  • tmax (float) – End time of the epoch

  • m_or_g (str) – Type of the channel: mag or grad

  • ecg_or_eog (str) – Type of the artifact: ECG or EOG

  • chs_by_lobe (dict) – Dictionary with channels split by lobe

  • flip_data (bool) – Use True or False, doesnt matter here. It is only passed into the plotting function and influences the threshold presentation. But since treshold is not used in correlation method, this is not used.

  • verbose_plots (bool) – If True, plots are shown in the notebook.

Returns:

  • artif_per_ch (list) – List of objects of class Avg_artif

  • affected_derivs (list) – List of objects of class QC_derivative (plots)

meg_qc.calculation.metrics.ECG_EOG_meg_qc.plot_correlation(artif_per_ch, ecg_or_eog, m_or_g, verbose_plots=False)[source]

Plot correlation coefficient and p-value between mean R wave and each channel in artif_per_ch.

Parameters:
  • artif_per_ch (list) – List of channels with Avg_artif objects.

  • ecg_or_eog (str) – Either ‘ECG’ or ‘EOG’.

  • m_or_g (str) – Either ‘mag’ or ‘grad’.

  • verbose_plots (bool) – If True, plot will be displayed in a notebook.

Returns:

corr_derivs – List with 1 QC_derivative instance: Figure with correlation coefficient and p-value between mean R wave and each channel in artif_per_ch.

Return type:

list

meg_qc.calculation.metrics.ECG_EOG_meg_qc.plot_ecg_eog_mne(ecg_epochs: Epochs, m_or_g: str, tmin: float, tmax: float)[source]

Plot ECG/EOG artifact with topomap and average over epochs (MNE plots based on matplotlib)

Parameters:
  • ecg_epochs (mne.Epochs) – ECG/EOG epochs.

  • m_or_g (str) – String ‘mag’ or ‘grad’ depending on the channel type.

  • tmin (float) – Start time of the epoch.

  • tmax (float) – End time of the epoch.

Returns:

ecg_derivs – List of QC_derivative objects with plots.

Return type:

list

meg_qc.calculation.metrics.ECG_EOG_meg_qc.plot_mean_rwave_shifted(mean_rwave_shifted: ndarray, mean_rwave: ndarray, ecg_or_eog: str, tmin: float, tmax: float, verbose_plots: bool)[source]

Only for demonstartion while running the pipeline. Dpesnt go into final report.

Plots the mean ECG wave and the mean ECG wave shifted to align with the ECG artifacts found on meg channels. Probably will not be included into the report. Just for algorythm demosntration. The already shifted mean ECG wave is plotted in the report.

Parameters:
  • mean_rwave_shifted (np.ndarray) – The mean ECG wave shifted to align with the ECG artifacts found on meg channels.

  • mean_rwave (np.ndarray) – The mean ECG wave, not shifted, original.

  • ecg_or_eog (str) – ‘ECG’ or ‘EOG’

  • tmin (float) – The start time of the epoch.

  • tmax (float) – The end time of the epoch.

  • verbose_plots (bool) – If True, the plot will be shown in the notebook.

Returns:

fig_derivs – list with one QC_derivative object, which contains the plot. (in case want to input intot he report)

Return type:

list

meg_qc.calculation.metrics.ECG_EOG_meg_qc.shift_mean_wave(mean_rwave: ndarray, t0_channels: int, t0_mean: int)[source]

Shifts the mean ECG wave to align with the ECG artifacts found on meg channels. np.roll is used to shift. meaning: foer example wjen shifte to the right: the end of array will be attached in the beginning to the leaft. Usually ok, but it may cause issues if the array was originally very short or very strongly shifted, then it may split the wave shape in half and the shifted wave will look completely unusable. Therefore, dont limit tmin and tmax too tight in config file (default is good). Or come up with other way insted of np.roll.

Parameters:
  • mean_rwave (np.ndarray) – The mean ECG wave, not shifted yet.

  • t0_channels (int) – The location of the peak of ECG artifact on the MEG channels. (This is not seconds! This is index).

  • t0_mean (int) – The location of the peak of the mean ECG wave on the ECG channel. (This is not seconds! This is index).

Returns:

mean_rwave_shifted – The mean ECG wave shifted to align with the ECG artifacts found on meg channels.

Return type:

np.ndarray

meg_qc.calculation.metrics.ECG_EOG_meg_qc.split_correlated_artifacts_into_3_groups(artif_per_ch)[source]

Collect artif_per_ch into 3 lists - for plotting: - a third of all channels that are the most correlated with mean_rwave - a third of all channels that are the least correlated with mean_rwave - a third of all channels that are in the middle of the correlation with mean_rwave

Parameters:

artif_per_ch (list) – List of objects of class Avg_artif

Returns:

  • artif_per_ch (list) – List of objects of class Avg_artif, ranked by correlation coefficient

  • most_correlated (list) – List of objects of class Avg_artif that are the most correlated with mean_rwave

  • least_correlated (list) – List of objects of class Avg_artif that are the least correlated with mean_rwave

  • middle_correlated (list) – List of objects of class Avg_artif that are in the middle of the correlation with mean_rwave

  • corr_val_of_last_least_correlated (float) – Correlation value of the last channel in the list of the least correlated channels

  • corr_val_of_last_middle_correlated (float) – Correlation value of the last channel in the list of the middle correlated channels

  • corr_val_of_last_most_correlated (float) – Correlation value of the last channel in the list of the most correlated channels