def wavelet_coeffs(data, srate, freqs, nco=2): """ Wavelet transform with complex morlet wavelet (i.e., a sinusiodial with a gaussian window). Useful to analyse signals in the oscillatory domain. Currently requires the mne toolbox to compute the convolution of the signal with the wavelet (this may change in the future). INPUT data should be (epochs,samples,channels) OR single-channel vector ... OUTPUT coeffs complex-valued wavelet coefficients Ws the wavelets """ # Generate the scaled wavelets for each frequency Ws = list() for k, f in enumerate(freqs): sigma_tf = nco / (2 * np.pi * f) #f: frequency in Hz t = np.arange(0, 5 * sigma_tf, 1 / srate) t = np.r_[-t[::-1], t[1:]] osc = np.exp(2. * 1j * np.pi * f * t) gauss = np.exp(-t**2 / (2. * sigma_tf**2)) W_tf = osc * gauss W_tf /= sqrt(.5) * linalg.norm(W_tf.ravel()) Ws.append(W_tf) # Do the actual transform (e.g., convolve the signal with the wavelets) # Caveat: This is currently only the single-job version of cwt !!! isVector = False if data.ndim == 1: data = np.array([data, data]) isVector = True if data.ndim == 3: channels = data.shape[2] coeffs = list() for c in range(channels): dummy = tfr.cwt(data[:, :, c], Ws) coeffs.append(dummy) else: coeffs = tfr.cwt(data, Ws) if isVector: coeffs = np.squeeze(coeffs[0, :, :]) print("Removed dummy dimension from coeffs!") return coeffs, Ws
def cwt(self, wave: np.ndarray, freqs: Union[List[float], range, np.ndarray], use_fft: bool = True, mode: str = 'same', decim: float = 1) -> np.ndarray: from mne.time_frequency import tfr ''' Run cwt of mne-python. Because of use of IFFT before FFT to the same wave, this ugly method is disgusting. Parameters ---------- freqs: float | Frequencies. Before use this, please run plot. Returns ------- Result of cwt. Complex np.ndarray. ''' return tfr.cwt(wave, list(self.make_wavelets(range(1, 100))), use_fft=use_fft, mode=mode, decim=decim).mean(axis=0)
def envelope_coherence(se_data, seed_l, seed_r, fmin, fmax): ''' se_data == used adaptive linear spatial filtering (beamforming) to estimate the spectral amplitude and phase of neuronal signals at the source level Example: seed_l = Index of Left somatosensory cortex source estimate data seed_r = Index of Right somatosensory cortex source estimate data ''' se_data = se_data.data[[seed_l,seed_r]].copy() # logarithm of the squared amplitude envelopes (power envelopes) data_squared = np.abs(se_data) * np.abs(se_data) data_mag = np.log(data_squared) log_range = np.arange(-1.5,1.1,0.1) covar_freqs = [math.pow(10,val) for val in log_range] ''' We chose a spectral bandwidth of (σf = f * 3.15) and spaced the center frequencies log- arithmically according to the exponentiation of the base 10 with exponents ranging from −1.5 in steps of 0.1 We derived spectral estimates in successive half-overlapping temporal windows that cov- ered ±3 σ t . From these complex numbers, we derived the coherency between power envelopes and took the real part of coherency as the frequency-specific measure of correlation ''' covar_freq_list = [] sfreq = 1000 for freq in covar_freqs: sigma = 3.15 * freq wvlt = morlet(sfreq, [freq], sigma=sigma, n_cycles=7) spectral_estimate = cwt(data_mag, wvlt) spectral_estimate = spectral_estimate[:,0,:] spectral_estimate_squared = np.abs(spectral_estimate) * np.abs(spectral_estimate) power_envelope = np.log(spectral_estimate_squared) power_envelope = power_envelope[np.newaxis,:,:] coherency, freqs, times, n_epochs, n_tapers = spectral_connectivity( power_envelope, fmin=freq, fmax=freq+0.5, method='cohy',faverage=True, sfreq=sfreq, n_jobs=4) coherence_corr = np.real(coherency) coherence_corr = coherence_corr[1,:,:][0] covar_freq_list.append(coherence_corr) coherence_correlation = np.vstack(covar_freq_list) ''' coherence_correlation.shape = (26,21) 26 is the co-variation frequency (x-axis) [0.032 - 10] log_range = np.arange(-1.5,1.1,0.1) covar_freqs = [math.pow(10,val) for val in log_range] 21 is the carrier freqeuncy (y-axis) [4 - 128] log_range = np.arange(2,7.25,0.25) carrier_freqs = [math.pow(2,val) for val in log_range] ''' return coherence_correlation
def test_time_frequency(): """Test time-frequency transform (PSD and ITC).""" # Set parameters event_id = 1 tmin = -0.2 tmax = 0.498 # Allows exhaustive decimation testing # Setup for reading the raw data raw = read_raw_fif(raw_fname) events = read_events(event_fname) include = [] exclude = raw.info['bads'] + ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = pick_types(raw.info, meg='grad', eeg=False, stim=False, include=include, exclude=exclude) picks = picks[:2] epochs = Epochs(raw, events, event_id, tmin, tmax, picks=picks) data = epochs.get_data() times = epochs.times nave = len(data) epochs_nopicks = Epochs(raw, events, event_id, tmin, tmax) freqs = np.arange(6, 20, 5) # define frequencies of interest n_cycles = freqs / 4. # Test first with a single epoch power, itc = tfr_morlet(epochs[0], freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True) # Now compute evoked evoked = epochs.average() power_evoked = tfr_morlet(evoked, freqs, n_cycles, use_fft=True, return_itc=False) pytest.raises(ValueError, tfr_morlet, evoked, freqs, 1., return_itc=True) power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True) power_, itc_ = tfr_morlet(epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, decim=slice(0, 2)) # Test picks argument and average parameter pytest.raises(ValueError, tfr_morlet, epochs, freqs=freqs, n_cycles=n_cycles, return_itc=True, average=False) power_picks, itc_picks = \ tfr_morlet(epochs_nopicks, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, picks=picks, average=True) epochs_power_picks = \ tfr_morlet(epochs_nopicks, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=False, picks=picks, average=False) power_picks_avg = epochs_power_picks.average() # the actual data arrays here are equivalent, too... assert_array_almost_equal(power.data, power_picks.data) assert_array_almost_equal(power.data, power_picks_avg.data) assert_array_almost_equal(itc.data, itc_picks.data) assert_array_almost_equal(power.data, power_evoked.data) # complex output pytest.raises(ValueError, tfr_morlet, epochs, freqs, n_cycles, return_itc=False, average=True, output="complex") pytest.raises(ValueError, tfr_morlet, epochs, freqs, n_cycles, output="complex", average=False, return_itc=True) epochs_power_complex = tfr_morlet(epochs, freqs, n_cycles, output="complex", average=False, return_itc=False) epochs_power_2 = abs(epochs_power_complex) epochs_power_3 = epochs_power_2.copy() epochs_power_3.data[:] = np.inf # test that it's actually copied assert_array_almost_equal(epochs_power_2.data, epochs_power_picks.data) power_2 = epochs_power_2.average() assert_array_almost_equal(power_2.data, power.data) print(itc) # test repr print(itc.ch_names) # test property itc += power # test add itc -= power # test sub power = power.apply_baseline(baseline=(-0.1, 0), mode='logratio') assert 'meg' in power assert 'grad' in power assert 'mag' not in power assert 'eeg' not in power assert power.nave == nave assert itc.nave == nave assert (power.data.shape == (len(picks), len(freqs), len(times))) assert (power.data.shape == itc.data.shape) assert (power_.data.shape == (len(picks), len(freqs), 2)) assert (power_.data.shape == itc_.data.shape) assert (np.sum(itc.data >= 1) == 0) assert (np.sum(itc.data <= 0) == 0) # grand average itc2 = itc.copy() itc2.info['bads'] = [itc2.ch_names[0]] # test channel drop gave = grand_average([itc2, itc]) assert gave.data.shape == (itc2.data.shape[0] - 1, itc2.data.shape[1], itc2.data.shape[2]) assert itc2.ch_names[1:] == gave.ch_names assert gave.nave == 2 itc2.drop_channels(itc2.info["bads"]) assert_array_almost_equal(gave.data, itc2.data) itc2.data = np.ones(itc2.data.shape) itc.data = np.zeros(itc.data.shape) itc2.nave = 2 itc.nave = 1 itc.drop_channels([itc.ch_names[0]]) combined_itc = combine_tfr([itc2, itc]) assert_array_almost_equal(combined_itc.data, np.ones(combined_itc.data.shape) * 2 / 3) # more tests power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=2, use_fft=False, return_itc=True) assert (power.data.shape == (len(picks), len(freqs), len(times))) assert (power.data.shape == itc.data.shape) assert (np.sum(itc.data >= 1) == 0) assert (np.sum(itc.data <= 0) == 0) tfr = tfr_morlet(epochs[0], freqs, use_fft=True, n_cycles=2, average=False, return_itc=False) tfr_data = tfr.data[0] assert (tfr_data.shape == (len(picks), len(freqs), len(times))) tfr2 = tfr_morlet(epochs[0], freqs, use_fft=True, n_cycles=2, decim=slice(0, 2), average=False, return_itc=False).data[0] assert (tfr2.shape == (len(picks), len(freqs), 2)) single_power = tfr_morlet(epochs, freqs, 2, average=False, return_itc=False).data single_power2 = tfr_morlet(epochs, freqs, 2, decim=slice(0, 2), average=False, return_itc=False).data single_power3 = tfr_morlet(epochs, freqs, 2, decim=slice(1, 3), average=False, return_itc=False).data single_power4 = tfr_morlet(epochs, freqs, 2, decim=slice(2, 4), average=False, return_itc=False).data assert_array_almost_equal(np.mean(single_power, axis=0), power.data) assert_array_almost_equal(np.mean(single_power2, axis=0), power.data[:, :, :2]) assert_array_almost_equal(np.mean(single_power3, axis=0), power.data[:, :, 1:3]) assert_array_almost_equal(np.mean(single_power4, axis=0), power.data[:, :, 2:4]) power_pick = power.pick_channels(power.ch_names[:10:2]) assert_equal(len(power_pick.ch_names), len(power.ch_names[:10:2])) assert_equal(power_pick.data.shape[0], len(power.ch_names[:10:2])) power_drop = power.drop_channels(power.ch_names[1:10:2]) assert_equal(power_drop.ch_names, power_pick.ch_names) assert_equal(power_pick.data.shape[0], len(power_drop.ch_names)) power_pick, power_drop = mne.equalize_channels([power_pick, power_drop]) assert_equal(power_pick.ch_names, power_drop.ch_names) assert_equal(power_pick.data.shape, power_drop.data.shape) # Test decimation: # 2: multiple of len(times) even # 3: multiple odd # 8: not multiple, even # 9: not multiple, odd for decim in [2, 3, 8, 9]: for use_fft in [True, False]: power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=2, use_fft=use_fft, return_itc=True, decim=decim) assert_equal(power.data.shape[2], np.ceil(float(len(times)) / decim)) freqs = list(range(50, 55)) decim = 2 _, n_chan, n_time = data.shape tfr = tfr_morlet(epochs[0], freqs, 2., decim=decim, average=False, return_itc=False).data[0] assert_equal(tfr.shape, (n_chan, len(freqs), n_time // decim)) # Test cwt modes Ws = morlet(512, [10, 20], n_cycles=2) pytest.raises(ValueError, cwt, data[0, :, :], Ws, mode='foo') for use_fft in [True, False]: for mode in ['same', 'valid', 'full']: cwt(data[0], Ws, use_fft=use_fft, mode=mode) # Test invalid frequency arguments with pytest.raises(ValueError, match=" 'freqs' must be greater than 0"): tfr_morlet(epochs, freqs=np.arange(0, 3), n_cycles=7) with pytest.raises(ValueError, match=" 'freqs' must be greater than 0"): tfr_morlet(epochs, freqs=np.arange(-4, -1), n_cycles=7) # Test decim parameter checks pytest.raises(TypeError, tfr_morlet, epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, decim='decim') # When convolving in time, wavelets must not be longer than the data pytest.raises(ValueError, cwt, data[0, :, :Ws[0].size - 1], Ws, use_fft=False) with pytest.warns(UserWarning, match='one of the wavelets is longer'): cwt(data[0, :, :Ws[0].size - 1], Ws, use_fft=True) # Check for off-by-one errors when using wavelets with an even number of # samples psd = cwt(data[0], [Ws[0][:-1]], use_fft=False, mode='full') assert_equal(psd.shape, (2, 1, 420))
def test_time_frequency(): """Test time-frequency transform (PSD and ITC).""" # Set parameters event_id = 1 tmin = -0.2 tmax = 0.498 # Allows exhaustive decimation testing # Setup for reading the raw data raw = read_raw_fif(raw_fname) events = read_events(event_fname) include = [] exclude = raw.info['bads'] + ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = pick_types(raw.info, meg='grad', eeg=False, stim=False, include=include, exclude=exclude) picks = picks[:2] epochs = Epochs(raw, events, event_id, tmin, tmax, picks=picks) data = epochs.get_data() times = epochs.times nave = len(data) epochs_nopicks = Epochs(raw, events, event_id, tmin, tmax) freqs = np.arange(6, 20, 5) # define frequencies of interest n_cycles = freqs / 4. # Test first with a single epoch power, itc = tfr_morlet(epochs[0], freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True) # Now compute evoked evoked = epochs.average() power_evoked = tfr_morlet(evoked, freqs, n_cycles, use_fft=True, return_itc=False) pytest.raises(ValueError, tfr_morlet, evoked, freqs, 1., return_itc=True) power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True) power_, itc_ = tfr_morlet(epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, decim=slice(0, 2)) # Test picks argument and average parameter pytest.raises(ValueError, tfr_morlet, epochs, freqs=freqs, n_cycles=n_cycles, return_itc=True, average=False) power_picks, itc_picks = \ tfr_morlet(epochs_nopicks, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, picks=picks, average=True) epochs_power_picks = \ tfr_morlet(epochs_nopicks, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=False, picks=picks, average=False) power_picks_avg = epochs_power_picks.average() # the actual data arrays here are equivalent, too... assert_array_almost_equal(power.data, power_picks.data) assert_array_almost_equal(power.data, power_picks_avg.data) assert_array_almost_equal(itc.data, itc_picks.data) assert_array_almost_equal(power.data, power_evoked.data) # complex output pytest.raises(ValueError, tfr_morlet, epochs, freqs, n_cycles, return_itc=False, average=True, output="complex") pytest.raises(ValueError, tfr_morlet, epochs, freqs, n_cycles, output="complex", average=False, return_itc=True) epochs_power_complex = tfr_morlet(epochs, freqs, n_cycles, output="complex", average=False, return_itc=False) epochs_power_2 = abs(epochs_power_complex) epochs_power_3 = epochs_power_2.copy() epochs_power_3.data[:] = np.inf # test that it's actually copied assert_array_almost_equal(epochs_power_2.data, epochs_power_picks.data) power_2 = epochs_power_2.average() assert_array_almost_equal(power_2.data, power.data) print(itc) # test repr print(itc.ch_names) # test property itc += power # test add itc -= power # test sub power = power.apply_baseline(baseline=(-0.1, 0), mode='logratio') assert 'meg' in power assert 'grad' in power assert 'mag' not in power assert 'eeg' not in power assert_equal(power.nave, nave) assert_equal(itc.nave, nave) assert (power.data.shape == (len(picks), len(freqs), len(times))) assert (power.data.shape == itc.data.shape) assert (power_.data.shape == (len(picks), len(freqs), 2)) assert (power_.data.shape == itc_.data.shape) assert (np.sum(itc.data >= 1) == 0) assert (np.sum(itc.data <= 0) == 0) # grand average itc2 = itc.copy() itc2.info['bads'] = [itc2.ch_names[0]] # test channel drop gave = grand_average([itc2, itc]) assert_equal(gave.data.shape, (itc2.data.shape[0] - 1, itc2.data.shape[1], itc2.data.shape[2])) assert_equal(itc2.ch_names[1:], gave.ch_names) assert_equal(gave.nave, 2) itc2.drop_channels(itc2.info["bads"]) assert_array_almost_equal(gave.data, itc2.data) itc2.data = np.ones(itc2.data.shape) itc.data = np.zeros(itc.data.shape) itc2.nave = 2 itc.nave = 1 itc.drop_channels([itc.ch_names[0]]) combined_itc = combine_tfr([itc2, itc]) assert_array_almost_equal(combined_itc.data, np.ones(combined_itc.data.shape) * 2 / 3) # more tests power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=2, use_fft=False, return_itc=True) assert (power.data.shape == (len(picks), len(freqs), len(times))) assert (power.data.shape == itc.data.shape) assert (np.sum(itc.data >= 1) == 0) assert (np.sum(itc.data <= 0) == 0) tfr = tfr_morlet(epochs[0], freqs, use_fft=True, n_cycles=2, average=False, return_itc=False).data[0] assert (tfr.shape == (len(picks), len(freqs), len(times))) tfr2 = tfr_morlet(epochs[0], freqs, use_fft=True, n_cycles=2, decim=slice(0, 2), average=False, return_itc=False).data[0] assert (tfr2.shape == (len(picks), len(freqs), 2)) single_power = tfr_morlet(epochs, freqs, 2, average=False, return_itc=False).data single_power2 = tfr_morlet(epochs, freqs, 2, decim=slice(0, 2), average=False, return_itc=False).data single_power3 = tfr_morlet(epochs, freqs, 2, decim=slice(1, 3), average=False, return_itc=False).data single_power4 = tfr_morlet(epochs, freqs, 2, decim=slice(2, 4), average=False, return_itc=False).data assert_array_almost_equal(np.mean(single_power, axis=0), power.data) assert_array_almost_equal(np.mean(single_power2, axis=0), power.data[:, :, :2]) assert_array_almost_equal(np.mean(single_power3, axis=0), power.data[:, :, 1:3]) assert_array_almost_equal(np.mean(single_power4, axis=0), power.data[:, :, 2:4]) power_pick = power.pick_channels(power.ch_names[:10:2]) assert_equal(len(power_pick.ch_names), len(power.ch_names[:10:2])) assert_equal(power_pick.data.shape[0], len(power.ch_names[:10:2])) power_drop = power.drop_channels(power.ch_names[1:10:2]) assert_equal(power_drop.ch_names, power_pick.ch_names) assert_equal(power_pick.data.shape[0], len(power_drop.ch_names)) mne.equalize_channels([power_pick, power_drop]) assert_equal(power_pick.ch_names, power_drop.ch_names) assert_equal(power_pick.data.shape, power_drop.data.shape) # Test decimation: # 2: multiple of len(times) even # 3: multiple odd # 8: not multiple, even # 9: not multiple, odd for decim in [2, 3, 8, 9]: for use_fft in [True, False]: power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=2, use_fft=use_fft, return_itc=True, decim=decim) assert_equal(power.data.shape[2], np.ceil(float(len(times)) / decim)) freqs = list(range(50, 55)) decim = 2 _, n_chan, n_time = data.shape tfr = tfr_morlet(epochs[0], freqs, 2., decim=decim, average=False, return_itc=False).data[0] assert_equal(tfr.shape, (n_chan, len(freqs), n_time // decim)) # Test cwt modes Ws = morlet(512, [10, 20], n_cycles=2) pytest.raises(ValueError, cwt, data[0, :, :], Ws, mode='foo') for use_fft in [True, False]: for mode in ['same', 'valid', 'full']: cwt(data[0], Ws, use_fft=use_fft, mode=mode) # Test decim parameter checks pytest.raises(TypeError, tfr_morlet, epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, decim='decim') # When convolving in time, wavelets must not be longer than the data pytest.raises(ValueError, cwt, data[0, :, :Ws[0].size - 1], Ws, use_fft=False) with pytest.warns(UserWarning, match='one of the wavelets is longer'): cwt(data[0, :, :Ws[0].size - 1], Ws, use_fft=True) # Check for off-by-one errors when using wavelets with an even number of # samples psd = cwt(data[0], [Ws[0][:-1]], use_fft=False, mode='full') assert_equal(psd.shape, (2, 1, 420))
def test_time_frequency(): """Test the to-be-deprecated time-frequency transform (PSD and ITC).""" # Set parameters event_id = 1 tmin = -0.2 tmax = 0.498 # Allows exhaustive decimation testing # Setup for reading the raw data raw = read_raw_fif(raw_fname) events = read_events(event_fname) include = [] exclude = raw.info['bads'] + ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = pick_types(raw.info, meg='grad', eeg=False, stim=False, include=include, exclude=exclude) picks = picks[:2] epochs = Epochs(raw, events, event_id, tmin, tmax, picks=picks) data = epochs.get_data() times = epochs.times nave = len(data) epochs_nopicks = Epochs(raw, events, event_id, tmin, tmax) freqs = np.arange(6, 20, 5) # define frequencies of interest n_cycles = freqs / 4. # Test first with a single epoch power, itc = tfr_morlet(epochs[0], freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True) # Now compute evoked evoked = epochs.average() power_evoked = tfr_morlet(evoked, freqs, n_cycles, use_fft=True, return_itc=False) assert_raises(ValueError, tfr_morlet, evoked, freqs, 1., return_itc=True) power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True) power_, itc_ = tfr_morlet(epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, decim=slice(0, 2)) # Test picks argument and average parameter assert_raises(ValueError, tfr_morlet, epochs, freqs=freqs, n_cycles=n_cycles, return_itc=True, average=False) power_picks, itc_picks = \ tfr_morlet(epochs_nopicks, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, picks=picks, average=True) epochs_power_picks = \ tfr_morlet(epochs_nopicks, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=False, picks=picks, average=False) power_picks_avg = epochs_power_picks.average() # the actual data arrays here are equivalent, too... assert_array_almost_equal(power.data, power_picks.data) assert_array_almost_equal(power.data, power_picks_avg.data) assert_array_almost_equal(itc.data, itc_picks.data) assert_array_almost_equal(power.data, power_evoked.data) print(itc) # test repr print(itc.ch_names) # test property itc += power # test add itc -= power # test sub power = power.apply_baseline(baseline=(-0.1, 0), mode='logratio') assert_true('meg' in power) assert_true('grad' in power) assert_false('mag' in power) assert_false('eeg' in power) assert_equal(power.nave, nave) assert_equal(itc.nave, nave) assert_true(power.data.shape == (len(picks), len(freqs), len(times))) assert_true(power.data.shape == itc.data.shape) assert_true(power_.data.shape == (len(picks), len(freqs), 2)) assert_true(power_.data.shape == itc_.data.shape) assert_true(np.sum(itc.data >= 1) == 0) assert_true(np.sum(itc.data <= 0) == 0) # grand average itc2 = itc.copy() itc2.info['bads'] = [itc2.ch_names[0]] # test channel drop gave = grand_average([itc2, itc]) assert_equal( gave.data.shape, (itc2.data.shape[0] - 1, itc2.data.shape[1], itc2.data.shape[2])) assert_equal(itc2.ch_names[1:], gave.ch_names) assert_equal(gave.nave, 2) itc2.drop_channels(itc2.info["bads"]) assert_array_almost_equal(gave.data, itc2.data) itc2.data = np.ones(itc2.data.shape) itc.data = np.zeros(itc.data.shape) itc2.nave = 2 itc.nave = 1 itc.drop_channels([itc.ch_names[0]]) combined_itc = combine_tfr([itc2, itc]) assert_array_almost_equal(combined_itc.data, np.ones(combined_itc.data.shape) * 2 / 3) # more tests power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=2, use_fft=False, return_itc=True) assert_true(power.data.shape == (len(picks), len(freqs), len(times))) assert_true(power.data.shape == itc.data.shape) assert_true(np.sum(itc.data >= 1) == 0) assert_true(np.sum(itc.data <= 0) == 0) tfr = tfr_morlet(epochs[0], freqs, use_fft=True, n_cycles=2, average=False, return_itc=False).data[0] assert_true(tfr.shape == (len(picks), len(freqs), len(times))) tfr2 = tfr_morlet(epochs[0], freqs, use_fft=True, n_cycles=2, decim=slice(0, 2), average=False, return_itc=False).data[0] assert_true(tfr2.shape == (len(picks), len(freqs), 2)) single_power = tfr_morlet(epochs, freqs, 2, average=False, return_itc=False).data single_power2 = tfr_morlet(epochs, freqs, 2, decim=slice(0, 2), average=False, return_itc=False).data single_power3 = tfr_morlet(epochs, freqs, 2, decim=slice(1, 3), average=False, return_itc=False).data single_power4 = tfr_morlet(epochs, freqs, 2, decim=slice(2, 4), average=False, return_itc=False).data assert_array_almost_equal(np.mean(single_power, axis=0), power.data) assert_array_almost_equal(np.mean(single_power2, axis=0), power.data[:, :, :2]) assert_array_almost_equal(np.mean(single_power3, axis=0), power.data[:, :, 1:3]) assert_array_almost_equal(np.mean(single_power4, axis=0), power.data[:, :, 2:4]) power_pick = power.pick_channels(power.ch_names[:10:2]) assert_equal(len(power_pick.ch_names), len(power.ch_names[:10:2])) assert_equal(power_pick.data.shape[0], len(power.ch_names[:10:2])) power_drop = power.drop_channels(power.ch_names[1:10:2]) assert_equal(power_drop.ch_names, power_pick.ch_names) assert_equal(power_pick.data.shape[0], len(power_drop.ch_names)) mne.equalize_channels([power_pick, power_drop]) assert_equal(power_pick.ch_names, power_drop.ch_names) assert_equal(power_pick.data.shape, power_drop.data.shape) # Test decimation: # 2: multiple of len(times) even # 3: multiple odd # 8: not multiple, even # 9: not multiple, odd for decim in [2, 3, 8, 9]: for use_fft in [True, False]: power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=2, use_fft=use_fft, return_itc=True, decim=decim) assert_equal(power.data.shape[2], np.ceil(float(len(times)) / decim)) freqs = list(range(50, 55)) decim = 2 _, n_chan, n_time = data.shape tfr = tfr_morlet(epochs[0], freqs, 2., decim=decim, average=False, return_itc=False).data[0] assert_equal(tfr.shape, (n_chan, len(freqs), n_time // decim)) # Test cwt modes Ws = morlet(512, [10, 20], n_cycles=2) assert_raises(ValueError, cwt, data[0, :, :], Ws, mode='foo') for use_fft in [True, False]: for mode in ['same', 'valid', 'full']: # XXX JRK: full wavelet decomposition needs to be implemented if (not use_fft) and mode == 'full': assert_raises(ValueError, cwt, data[0, :, :], Ws, use_fft=use_fft, mode=mode) continue cwt(data[0, :, :], Ws, use_fft=use_fft, mode=mode) # Test decim parameter checks assert_raises(TypeError, tfr_morlet, epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, decim='decim')
def test_time_frequency(): """Test time frequency transform (PSD and phase lock) """ # Set parameters event_id = 1 tmin = -0.2 tmax = 0.5 # Setup for reading the raw data raw = io.Raw(raw_fname) events = read_events(event_fname) include = [] exclude = raw.info['bads'] + ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = pick_types(raw.info, meg='grad', eeg=False, stim=False, include=include, exclude=exclude) picks = picks[:2] epochs = Epochs(raw, events, event_id, tmin, tmax, picks=picks, baseline=(None, 0)) data = epochs.get_data() times = epochs.times nave = len(data) epochs_nopicks = Epochs(raw, events, event_id, tmin, tmax, baseline=(None, 0)) freqs = np.arange(6, 20, 5) # define frequencies of interest n_cycles = freqs / 4. # Test first with a single epoch power, itc = tfr_morlet(epochs[0], freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True) # Now compute evoked evoked = epochs.average() power_evoked = tfr_morlet(evoked, freqs, n_cycles, use_fft=True, return_itc=False) assert_raises(ValueError, tfr_morlet, evoked, freqs, 1., return_itc=True) power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True) # Test picks argument power_picks, itc_picks = tfr_morlet(epochs_nopicks, freqs=freqs, n_cycles=n_cycles, use_fft=True, return_itc=True, picks=picks) # the actual data arrays here are equivalent, too... assert_array_almost_equal(power.data, power_picks.data) assert_array_almost_equal(itc.data, itc_picks.data) assert_array_almost_equal(power.data, power_evoked.data) print(itc) # test repr print(itc.ch_names) # test property itc += power # test add itc -= power # test add power.apply_baseline(baseline=(-0.1, 0), mode='logratio') assert_true('meg' in power) assert_true('grad' in power) assert_false('mag' in power) assert_false('eeg' in power) assert_equal(power.nave, nave) assert_equal(itc.nave, nave) assert_true(power.data.shape == (len(picks), len(freqs), len(times))) assert_true(power.data.shape == itc.data.shape) assert_true(np.sum(itc.data >= 1) == 0) assert_true(np.sum(itc.data <= 0) == 0) # grand average itc2 = itc.copy() itc2.info['bads'] = [itc2.ch_names[0]] # test channel drop gave = grand_average([itc2, itc]) assert_equal(gave.data.shape, (itc2.data.shape[0] - 1, itc2.data.shape[1], itc2.data.shape[2])) assert_equal(itc2.ch_names[1:], gave.ch_names) assert_equal(gave.nave, 2) itc2.drop_channels(itc2.info["bads"]) assert_array_almost_equal(gave.data, itc2.data) itc2.data = np.ones(itc2.data.shape) itc.data = np.zeros(itc.data.shape) itc2.nave = 2 itc.nave = 1 itc.drop_channels([itc.ch_names[0]]) combined_itc = combine_tfr([itc2, itc]) assert_array_almost_equal(combined_itc.data, np.ones(combined_itc.data.shape) * 2 / 3) # more tests power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=2, use_fft=False, return_itc=True) assert_true(power.data.shape == (len(picks), len(freqs), len(times))) assert_true(power.data.shape == itc.data.shape) assert_true(np.sum(itc.data >= 1) == 0) assert_true(np.sum(itc.data <= 0) == 0) Fs = raw.info['sfreq'] # sampling in Hz tfr = cwt_morlet(data[0], Fs, freqs, use_fft=True, n_cycles=2) assert_true(tfr.shape == (len(picks), len(freqs), len(times))) single_power = single_trial_power(data, Fs, freqs, use_fft=False, n_cycles=2) assert_array_almost_equal(np.mean(single_power), power.data) power_pick = power.pick_channels(power.ch_names[:10:2]) assert_equal(len(power_pick.ch_names), len(power.ch_names[:10:2])) assert_equal(power_pick.data.shape[0], len(power.ch_names[:10:2])) power_drop = power.drop_channels(power.ch_names[1:10:2]) assert_equal(power_drop.ch_names, power_pick.ch_names) assert_equal(power_pick.data.shape[0], len(power_drop.ch_names)) mne.equalize_channels([power_pick, power_drop]) assert_equal(power_pick.ch_names, power_drop.ch_names) assert_equal(power_pick.data.shape, power_drop.data.shape) # Test decimation for decim in [2, 3]: for use_fft in [True, False]: power, itc = tfr_morlet(epochs, freqs=freqs, n_cycles=2, use_fft=use_fft, return_itc=True, decim=decim) assert_equal(power.data.shape[2], np.ceil(float(len(times)) / decim)) # Test cwt modes Ws = morlet(512, [10, 20], n_cycles=2) assert_raises(ValueError, cwt, data[0, :, :], Ws, mode='foo') for use_fft in [True, False]: for mode in ['same', 'valid', 'full']: # XXX JRK: full wavelet decomposition needs to be implemented if (not use_fft) and mode == 'full': assert_raises(ValueError, cwt, data[0, :, :], Ws, use_fft=use_fft, mode=mode) continue cwt(data[0, :, :], Ws, use_fft=use_fft, mode=mode)
def single_trial_tfr(data, sfreq, frequencies, use_fft=True, n_cycles=7, decim=1, n_jobs=1, zero_mean=False, verbose=None): """Compute time-frequency decomposition single epochs. Parameters ---------- data : array of shape [n_epochs, n_channels, n_times] The epochs sfreq : float Sampling rate frequencies : array-like The frequencies use_fft : bool Use the FFT for convolutions or not. n_cycles : float | array of float Number of cycles in the Morlet wavelet. Fixed number or one per frequency. decim : int | slice To reduce memory usage, decimation factor after time-frequency decomposition. If `int`, returns tfr[..., ::decim]. If `slice` returns tfr[..., decim]. Note that decimation may create aliasing artifacts. Defaults to 1. n_jobs : int The number of epochs to process at the same time zero_mean : bool Make sure the wavelets are zero mean. verbose : bool, str, int, or None If not None, override default verbose level (see mne.verbose). Returns ------- tfr : 4D array, shape (n_epochs, n_chan, n_freq, n_time) Time frequency estimate (complex). """ decim = _check_decim(decim) mode = 'same' n_frequencies = len(frequencies) n_epochs, n_channels, n_times = data[:, :, decim].shape # Precompute wavelets for given frequency range to save time Ws = morlet(sfreq, frequencies, n_cycles=n_cycles, zero_mean=zero_mean) parallel, my_cwt, _ = parallel_func(cwt, n_jobs) logger.info("Computing time-frequency deomposition on single epochs...") out = np.empty((n_epochs, n_channels, n_frequencies, n_times), dtype=np.complex128) # Package arguments for `cwt` here to minimize omissions where only one of # the two calls below is updated with new function arguments. cwt_kw = dict(Ws=Ws, use_fft=use_fft, mode=mode, decim=decim) if n_jobs == 1: for k, e in enumerate(data): out[k] = cwt(e, **cwt_kw) else: # Precompute tf decompositions in parallel tfrs = parallel(my_cwt(e, **cwt_kw) for e in data) for k, tfr in enumerate(tfrs): out[k] = tfr return out