Esempio n. 1
0
def load_power_spectra_from_files(*file_numbers, low_freq = None, high_freq = None, step = 1, filter = False):
    '''Returns a list,
    where each element is a tuple corresponding to a picture block,
    where first element is a tuple,
    where first element is a 2D np.array
    with first index corresponding to channel number
    and second index corresponding frequency
    and second element is a np.array
    where i-th element is the i-th frequency, in Hz
    and second element is a tuple
    of patient's arousal and valence evaluation
    (or may be other way around, it's just the way they are ordered in file).

    Visually:
    [ (   ( [[ch1pow1,ch1pow2,...],[ch2pow1,ch2pow2...],...], [freq1, freq2, ...] ), (arousal, valence)   ),
      (   ( [[ch1pow1,ch1pow2,...],[ch2pow1,ch2pow2...],...], [freq1, freq2, ...] ), (arousal, valence)   ),
      ...                                                                                                    ]
                                                                                ]
    Parameters:
        - file_numbers - indices of available EEG files (from 0 to 10).
            There are loaded all blocks for each number in the order their indices are passed,
            i.e. load_data_from_files(3,1,2,3) will first return data for all blocks
            from file of index 3, then index 1, 2 and 3 again (duplicated).
        - low_freq - low frequency used for power spectra calcuation, in Hz
        - high_freq - high frequency used for power spectra calcuation, in Hz
        - step - the frequency step in returned power spectrum
        - filter - if True, the data will be explicitly filtered before power spectra calculation
            between the given frequencies
    
    This function uses mne function to get power spectra directly from whole EEG while defining frequencies.
    Notice that low_freq and high_freq are keyword-only parameters.'''

    available_eeg_paths_snapshot = available_eeg_paths()
    eegs_to_load = [available_eeg_paths_snapshot[i] for i in file_numbers]
    markers_to_load = [single_eeg_to_load + '.mrk' for single_eeg_to_load in eegs_to_load]
    evals_to_load = [_eval_path_from_eeg_path(single_eeg_to_load)
                     for single_eeg_to_load in eegs_to_load]
    loaded_data = []
    for eeg_path, marker_path, eval_path in zip(eegs_to_load, markers_to_load, evals_to_load):
        block_ranges = _load_block_ranges_from_marker(marker_path)  # list of tuples
        eval_list = _load_evals(eval_path)
        raw_eeg = mne.io.read_raw_edf(eeg_path, preload = True)
        raw_eeg.pick_channels(raw_eeg.info["ch_names"][:-8])
        if filter and not (low_freq is None and high_freq is None):
            raw_eeg.filter(low_freq, high_freq)
        low_freq = low_freq if low_freq is not None else 0
        high_freq = high_freq if high_freq is not None else float("inf")
        for (eeg_start, eeg_end), single_eval in zip(block_ranges, eval_list):
            sample_freq = raw_eeg.info["sfreq"]
            block_frequencies = psd.psd_welch(raw_eeg, low_freq, high_freq, raw_eeg.times[eeg_start], raw_eeg.times[eeg_end], n_fft = round(sample_freq / step))
            picture_block_data = (block_frequencies, single_eval)
            loaded_data.append(picture_block_data)
            # raw_eeg[channel's, sample's][tuple_elem(0=samples,1=times)]
            block_eeg = np.array(raw_eeg[0:-1, eeg_start:eeg_end + 1][0])
            block_data = (block_eeg, single_eval)
            loaded_data.append(block_data)
    return loaded_data
Esempio n. 2
0
 def power_spectrum(self, low_freq = None, high_freq = None, step = 1):
     '''Returns a tuple,
     where first element is a 2D np.array
     with first index corresponding to channel number
     and second index corresponding frequency
     and second element is a np.array
     where i-th element is the i-th frequency, in Hz.
     
     The frequencies will be from low_freq to high_freq, inclusive, with step step.'''
     if low_freq is None:
         low_freq = self._low_freq if self._low_freq is not None else 0
     if high_freq is None:
         high_freq = self._high_freq if self._high_freq is not None else float("inf")
     sample_freq = self.mne_eeg.info["sfreq"]
     return psd.psd_welch(self.mne_eeg, low_freq, high_freq, n_fft = round(sample_freq / step))
Esempio n. 3
0
def remove_linenoise(raw,
                     noise_freq,
                     width=2,
                     shuffle_time=True,
                     decim=100,
                     n_component=1,
                     plot=False,
                     copy=True,
                     picks=None,
                     harmonics=True):
    import matplotlib.pyplot as plt
    from mne import pick_types
    from mne.preprocessing import ICA
    from mne.time_frequency.psd import psd_welch

    # Setup line frequency
    if isinstance(noise_freq, str):
        # automatic harmonics
        if noise_freq == 'us':
            noise_freq = 60
        else:
            noise_freq = 50
    elif not isinstance(noise_freq, (float, int)):
        raise NotImplementedError('Multiple bands')

    def plot_psd(psd, freqs, ax, title):
        for psd_ in psd:
            ax.plot(freqs, np.log10(psd_))
        ax.set_xlabel('Frequencies')
        ax.set_title(title)

    if copy:
        raw = raw.copy()

    if picks is None:
        picks = pick_types(raw.info, eeg=True, meg=True, seeg=True)

    if plot:
        fig, axes = plt.subplots(1, 3, sharex=True)
        psd, freqs = psd_welch(raw, picks=picks)
        plot_psd(psd, freqs, axes[0], 'Raw Sensors')

    # Fit ICA on filtered data
    raw_ = raw.copy()
    if harmonics:
        # set up harmonics
        n_harm = raw_.info['sfreq'] // (2. * noise_freq) + 1
        harmonics = noise_freq * np.arange(1, n_harm)
        # Band pass filtering outside lowest harmonics and nquist
        raw_.filter(noise_freq - width, harmonics[-1] + width)
        # Band stop filter in between harmonics
        raw_.notch_filter(freqs=harmonics[:-1] + noise_freq // 2,
                          notch_widths=noise_freq - 2 * width)
    else:
        raw_.filter(noise_freq - width, noise_freq + width)

    # Shuffle time axis to avoid decimation aliasing
    if shuffle_time:
        time = np.arange(raw_.n_times)
        np.random.shuffle(time)
        raw_._data[:, time] = raw_._data
    ica = ICA(verbose=False)
    ica.fit(raw_, decim=decim, picks=picks)

    # Compute PSD of components
    raw_._data[picks, :] = np.dot(ica.mixing_matrix_, raw._data[picks, :])
    psd, freqs = psd_welch(raw_, picks=picks)
    if plot:
        plot_psd(psd, freqs, axes[1], 'Components')

    # Find noise component and remove
    freq = np.where(freqs >= noise_freq)[0][0]
    sel = np.argsort(psd[:, freq])[-n_component:].tolist()
    raw_ = ica.apply(raw, exclude=sel, copy=True)

    if plot:
        psd, freqs = psd_welch(raw_, picks=picks)
        plot_psd(psd, freqs, axes[2], 'Clean sensors')

    return raw_
Esempio n. 4
0
def remove_linenoise(raw, noise_freq, width=2, shuffle_time=True, decim=100,
                     n_component=1, plot=False, copy=True, picks=None,
                     harmonics=True):
    import matplotlib.pyplot as plt
    from mne import pick_types
    from mne.preprocessing import ICA
    from mne.time_frequency.psd import psd_welch

    # Setup line frequency
    if isinstance(noise_freq, str):
        # automatic harmonics
        if noise_freq == 'us':
            noise_freq = 60
        else:
            noise_freq = 50
    elif not isinstance(noise_freq, (float, int)):
        raise NotImplementedError('Multiple bands')

    def plot_psd(psd, freqs, ax, title):
        for psd_ in psd:
            ax.plot(freqs, np.log10(psd_))
        ax.set_xlabel('Frequencies')
        ax.set_title(title)

    if copy:
        raw = raw.copy()

    if picks is None:
        picks = pick_types(raw.info, eeg=True, meg=True, seeg=True)

    if plot:
        fig, axes = plt.subplots(1, 3, sharex=True)
        psd, freqs = psd_welch(raw, picks=picks)
        plot_psd(psd, freqs, axes[0], 'Raw Sensors')

    # Fit ICA on filtered data
    raw_ = raw.copy()
    if harmonics:
        # set up harmonics
        n_harm = raw_.info['sfreq'] // (2. * noise_freq) + 1
        harmonics = noise_freq * np.arange(1, n_harm)
        # Band pass filtering outside lowest harmonics and nquist
        raw_.filter(noise_freq - width, harmonics[-1] + width)
        # Band stop filter in between harmonics
        raw_.notch_filter(freqs=harmonics[:-1]+noise_freq//2,
                          notch_widths=noise_freq - 2*width)
    else:
        raw_.filter(noise_freq-width, noise_freq+width)

    # Shuffle time axis to avoid decimation aliasing
    if shuffle_time:
        time = np.arange(raw_.n_times)
        np.random.shuffle(time)
        raw_._data[:, time] = raw_._data
    ica = ICA(verbose=False)
    ica.fit(raw_, decim=decim, picks=picks)

    # Compute PSD of components
    raw_._data[picks, :] = np.dot(ica.mixing_matrix_, raw._data[picks, :])
    psd, freqs = psd_welch(raw_, picks=picks)
    if plot:
        plot_psd(psd, freqs, axes[1], 'Components')

    # Find noise component and remove
    freq = np.where(freqs >= noise_freq)[0][0]
    sel = np.argsort(psd[:, freq])[-n_component:].tolist()
    raw_ = ica.apply(raw, exclude=sel, copy=True)

    if plot:
        psd, freqs = psd_welch(raw_, picks=picks)
        plot_psd(psd, freqs, axes[2], 'Clean sensors')

    return raw_
 def calcPSD(self, raw, fmin, fmax, picks=None):
     return psd_welch(raw, fmin, fmax, picks=picks)