def test_stft(): """Test stft and istft tight frame property.""" sfreq = 1000. # Hz f = 7. # Hz for T in [127, 128]: # try with even and odd numbers # Test with low frequency signal t = np.arange(T).astype(np.float64) x = np.sin(2 * np.pi * f * t / sfreq) x = np.array([x, x + 1.]) wsize = 128 tstep = 4 X = stft(x, wsize, tstep) xp = istft(X, tstep, Tx=T) freqs = stftfreq(wsize, sfreq=1000) max_freq = freqs[np.argmax(np.sum(np.abs(X[0])**2, axis=1))] assert X.shape[1] == len(freqs) assert np.all(freqs >= 0.) assert np.abs(max_freq - f) < 1. assert_array_almost_equal(x, xp, decimal=6) # norm conservation thanks to tight frame property assert_almost_equal(np.sqrt(stft_norm2(X)), [linalg.norm(xx) for xx in x], decimal=6) # Test with random signal x = np.random.randn(2, T) wsize = 16 tstep = 8 X = stft(x, wsize, tstep) xp = istft(X, tstep, Tx=T) freqs = stftfreq(wsize, sfreq=1000) max_freq = freqs[np.argmax(np.sum(np.abs(X[0])**2, axis=1))] assert X.shape[1] == len(freqs) assert np.all(freqs >= 0.) assert_array_almost_equal(x, xp, decimal=6) # norm conservation thanks to tight frame property assert_almost_equal(np.sqrt(stft_norm2(X)), [linalg.norm(xx) for xx in x], decimal=6) # Try with empty array x = np.zeros((0, T)) X = stft(x, wsize, tstep) xp = istft(X, tstep, T) assert xp.shape == x.shape
def get_logpsd(ica, rawdata): """Given MNE ICA object already fit to data, and MNE RawArray, return numpy array of the log power spectral density of the data in the RawArray.""" sources = ica.get_sources(rawdata).to_data_frame().values nsamples = 512 # number of samples in FT window FTtstep = int(nsamples/2) fourtrans = stft(sources.T, nsamples, tstep = FTtstep, verbose=False) return np.log(np.abs(fourtrans)**2), FTtstep
def mne_stft(grid,ws,delta,sigs=None,fs=None,events=None): #Performs a stft transform across the events???????????? if events is None: events = grid.event_matrix() if fs is None: fs = grid.fs() if sigs is None: sigs = grid.wd() ws*=fs delta*=fs maxtimediff = (events['pulse.off']-events['pulse.on']).max() maxtimepoints = round(maxtimediff*fs/delta) - np.floor(ws/delta) powMap = np.zeros([len(events),len(grid.wc()),ws]) data = np.zeros([len(events),len(grid.wc()),maxtimepoints]) for j,(on,off) in enumerate(events.values): for k,chan in enumerate(grid.wc()): d=grid.splice(sigs[chan], times=[on,off]) data[j,k,:len(d)] = mtf.stft(x=d,wsize=ws,tstep=delta) return powMap.mean(axis=2)
def mne_stft_regression(evoked_list, inverse_operator, X, labels = None, pick_ori=None, pick_normal=None, snr=1, wsize = 64, tstep = 4, Flag_reg_stats = False, method = "MNE"): ''' Get the MNE solution for a given snr(lambda value) Input: evoked_list, a list of evoked instances inverse_operator, the inverse operator for MNE X, [n_trials, p] array labels, ROI labels list, if None, use the whole brain snr, controls lambda wsize, window size of the stft transform tstep, time step of the stft transform method, "MNE", "dSPM", "sLORETA", Note that dSPM and sLORETA can not be used for prediction, and the coefficients are normalized too. Output: result_dict = dict(coef = coef, F = F, sel = sel,roi_data = roi_data) ['coef']: Regression coefficients, complex arrays [n_dipoles,n_coefs,n_steps,p] ['F'],F-statistics, complex arrays ['sel'], selction of the source points, columns of G ['roi_data'] the source data in the ROI ''' n_trials = len(evoked_list) sel = [] # The following line is wrong n_dipoles = inverse_operator['nsource'] # if label is specified, only do the regression on the labels # otherwise, select the data for the whole brain. if labels is not None: for i in range(len(labels)): _, sel_tmp = mne.source_space.label_src_vertno_sel(labels[i],inverse_operator['src']) sel = np.hstack([sel, sel_tmp]) sel = sel.astype(np.int) else: sel = np.arange(0,n_dipoles,1) sel.astype(np.int) # tested, the result is the same as running apply_inverse() roi_data = _apply_inverse_evoked_list(evoked_list, inverse_operator, lambda2= 1.0/snr**2, method=method, labels=labels, nave=1, pick_ori=pick_ori, verbose=None, pick_normal=None) n_dipoles, n_times = roi_data[0].shape n_trials = len(evoked_list) # stft transform, F means the coefficients F_roi_data = list() for i in range(n_trials): F_roi_data.append(stft(roi_data[:,:,i], wsize= wsize, tstep = tstep)) # put the stft transform into a matrix dim0,dim1,dim2 = F_roi_data[0].shape F_roi_data_3d = np.zeros([dim0,dim1,dim2,n_trials],dtype = np.complex) for i in range(n_trials): F_roi_data_3d[:,:,:,i] = F_roi_data[i] del(F_roi_data) # regression, return coefficients and F-values p = X.shape[1] coef = np.zeros([dim0,dim1,dim2,p], dtype = np.complex) F = np.zeros([dim0,dim1,dim2], dtype = np.complex) if Flag_reg_stats else None linreg_op = np.dot(la.inv(X.T.dot(X)),X.T) for i in range(dim0): for j in range(dim1): for k in range(dim2): tmpY = np.real(F_roi_data_3d[i,j,k,:]) tmp_coef = linreg_op.dot(tmpY) # debug #tmp_coef2 = np.linalg.lstsq(X,tmpY)[0] #print np.linalg.norm(tmp_coef-tmp_coef2) coef[i,j,k,:] += tmp_coef if Flag_reg_stats: tmpY_hat = np.dot(X,tmp_coef) tmp_res = tmpY_hat-tmpY SSE = np.dot(tmp_res,tmp_res) SST = np.sum((tmpY-np.mean(tmpY))**2) if SSE== 0: F[i,j,k] += 0 else: F[i,j,k] += (SST-SSE)/(p-1)/(SSE/(n_trials-p)) # imaginary tmpY = np.imag(F_roi_data_3d[i,j,k,:]) tmp_coef = linreg_op.dot(tmpY) coef[i,j,k,:] += tmp_coef*1j if Flag_reg_stats: tmpY_hat = np.dot(X,tmp_coef) tmp_res = tmpY_hat-tmpY SSE = np.dot(tmp_res,tmp_res) SST = np.sum((tmpY-np.mean(tmpY))**2) if SSE== 0: F[i,j,k] += 0 else: F[i,j,k] += (SST-SSE)/(p-1)/(SSE/(n_trials-p))*1j result_dict = dict(coef = coef, F = F, sel = sel,roi_data_3D = roi_data) return result_dict