def fooofmodel(): import sys import numpy as np from scipy.io import loadmat, savemat from fooof import FOOOFGroup import matplotlib.pyplot as plt data = loadmat('ModelPowSpctraForFOOOF.mat') # Unpack data from dictionary, and squeeze numpy arrays freqs = np.squeeze(data['fx']).astype('float') psds = np.squeeze(data['avgpwr']).astype('float') # ^Note: this also explicitly enforces type as float (type casts to float64, instead of float32) # This is not strictly necessary for fitting, but is for saving out as json from FOOOF, if you want to do that # Transpose power spectra, to have the expected orientation for FOOOF #psds = psds.T fg = FOOOFGroup(peak_threshold=7, peak_width_limits=[3, 14]) #, aperiodic_mode='knee' #fg.report(freqs, psds, [1, 290]) #fg.fit(freqs,psds,[0.2,290]) fg.fit(freqs, psds, [1, 290]) fg.plot() fg.save_report('modelfits') slp = fg.get_params('aperiodic_params', 'exponent') off = fg.get_params('aperiodic_params', 'offset') r = fg.get_params('r_squared') savemat('slp.mat', {'slp': slp}) savemat('off.mat', {'off': off}) savemat('r.mat', {'r': r}) return
def create_report(subject, params): """ Collect parameters from the dialog and creates an FOOOFReport item """ report_name = params['name'] spectrum_name = params['spectrum_name'] peak_width_low = params['peak_width_low'] peak_width_high = params['peak_width_high'] peak_threshold = params['peak_threshold'] max_n_peaks = params['max_n_peaks'] aperiodic_mode = params['aperiodic_mode'] minfreq = params['minfreq'] maxfreq = params['maxfreq'] spectrum = subject.spectrum.get(spectrum_name) peak_width_limits = [peak_width_low, peak_width_high] peak_threshold = peak_threshold max_n_peaks = max_n_peaks aperiodic_mode = aperiodic_mode freq_range = [minfreq, maxfreq] # As meggie spectrum items can contain data for multiple conditions, # reports are also created for all those conditions, and dict is used. report_content = {} for key, data in spectrum.content.items(): fg = FOOOFGroup(peak_width_limits=peak_width_limits, peak_threshold=peak_threshold, max_n_peaks=max_n_peaks, aperiodic_mode=aperiodic_mode, verbose=False) fg.fit(spectrum.freqs, data, freq_range) logging.getLogger('ui_logger').info('FOOOF results for ' + subject.name + ', ' + 'condition: ' + key) # Log the textual report logging.getLogger('ui_logger').info( gen_results_fg_str(fg, concise=True)) report_content[key] = fg params['conditions'] = list(spectrum.content.keys()) params['ch_names'] = spectrum.ch_names fooof_directory = subject.fooof_report_directory # Create a container item that meggie understands, # and which holds the report data report = FOOOFReport(report_name, fooof_directory, params, report_content) # save report data to fs report.save_content() # and add the report item to subject subject.add(report, 'fooof_report')
def fooof_channel_rejection(eeg, psds, freqs, f_low, f_high, participant, session_name): from scipy.stats import bayes_mvs n_bads = 0 fooof_group = FOOOFGroup(max_n_peaks=6, min_peak_amplitude=0.1, peak_width_limits=[1, 12], background_mode='knee') fooof_group.fit(freqs, psds, freq_range=[f_low, f_high / 2], n_jobs=-1) fooof_group_fig = fooof_group.plot(save_fig=True, file_name='FOOOF_group_' + participant + '_' + session_name, file_path=data_dir + '/results/') bg_slope = fooof_group.get_all_data('background_params', col='slope') mean_cntr, var_cntr, std_cntr = bayes_mvs(bg_slope, alpha=0.9) lower_slope = mean_cntr[1][0] - std_cntr[1][1] upper_slope = mean_cntr[1][1] + std_cntr[1][1] print('upper and lower slope range (mean, std)', lower_slope, upper_slope, np.mean(bg_slope), np.std(bg_slope)) for channel_idx, slope in enumerate(bg_slope): if slope < lower_slope or slope > upper_slope: eeg.info['bads'].append(eeg.ch_names[channel_idx]) n_bads += 1 eeg.interpolate_bads(reset_bads=True) return eeg, n_bads
def indiv_fooofcode(): import sys import numpy as np from scipy.io import loadmat, savemat from fooof import FOOOFGroup import matplotlib.pyplot as plt patientcount = 16 alloffset = [] allr2 = [] allexps = [] allcfs = [] for k in range(1,patientcount+1): matfile = 'indiv_' + str(k) + '.mat' data = loadmat(matfile) # Unpack data from dictionary, and squeeze numpy arrays freqs = np.squeeze(data['indiv_frq']).astype('float') psds = np.squeeze(data['indiv_pow']).astype('float') # ^Note: this also explicitly enforces type as float (type casts to float64, instead of float32) # This is not strictly necessary for fitting, but is for saving out as json from FOOOF, if you want to do that fg = FOOOFGroup(peak_threshold=7,peak_width_limits=[3, 14])#, aperiodic_mode='knee' #fg.report(freqs, psds, [30, 300]) #fg.fit(freqs,psds,[float(sys.argv[1]),float(sys.argv[2])]) fg.fit(freqs,psds,[float(sys.argv[1]),float(sys.argv[2])]) fg.plot() reportname = str(k) + '_indiv result' fg.save_report(reportname) #print(fg.group_results) r2 = fg.get_params('r_squared') allr2.append(r2) exps = fg.get_params('aperiodic_params', 'exponent') allexps.append(exps) centerfrq = fg.get_params('peak_params','CF') allcfs.append(centerfrq) offset = fg.get_params('aperiodic_params','offset') alloffset.append(offset) #knee = fg.get_params('aperiodic_params','knee') #savemat('knee_allpeeps.mat', {'knee' : knee}) #NOW OUTSIDE OF BIG FORLOOP! #concat everythin. savemat('all_offset.mat',{'all_offset' : alloffset}) savemat('all_r2.mat', {'all_r2' : allr2}) savemat('all_exps.mat', {'all_exps' : allexps}) savemat('all_cfs.mat',{'all_cfs' : allcfs}) #these are cell arrays! I didn't even mean for them to be but heck yea useful
def get_tfg(): """Get a FOOOFGroup object, with some fit power spectra, for testing.""" n_spectra = 2 xs, ys = gen_group_power_spectra(n_spectra, *default_group_params()) tfg = FOOOFGroup() tfg.fit(xs, ys) return tfg
def fooofy(components, spectra, freq_range): """ A FOOOF Function, gets exponent parameters """ fg = FOOOFGroup(max_n_peaks=0, aperiodic_mode='fixed', verbose = False) #initialize FOOOF object #print(spectra.shape, components.shape) #Use this line if things go weird fg.fit(components, spectra, freq_range) # THIS IS WHERE YOU SAY WHICH FREQ RANGE TO FIT m_array = fg.get_params('aperiodic_params', 'exponent') r2_array = fg.get_params('r_squared') #correlation between components (freqs or PCs) and spectra (powers or eigvals) #fg.r_squared_ return m_array, r2_array
def test_fg_fit_par(): """Test FOOOFGroup fit, running in parallel.""" n_spectra = 2 xs, ys = gen_group_power_spectra(n_spectra, *default_group_params()) tfg = FOOOFGroup() tfg.fit(xs, ys, n_jobs=2) out = tfg.get_results() assert out assert len(out) == n_spectra assert isinstance(out[0], FOOOFResult) assert np.all(out[1].background_params)
def foof2mat_customfreq(): import sys import hdf5storage import sklearn from scipy import io import scipy import numpy as np from fooof import FOOOF import neurodsp import matplotlib.pyplot as plt import pacpy import h5py import matplotlib from matplotlib import lines import math from neurodsp import spectral # FOOOF imports: get FOOOF & FOOOFGroup objects from fooof import FOOOFGroup slpa = [] ra = [] dat = hdf5storage.loadmat(str(sys.argv[1])) frq_ax = np.linspace(0, 1000, 10001) #dat["fx"][0] pwr_spectra = dat['avgpwr'] #dat["powall"] for fl in range(30, 100, 2): for ul in range(50, 300, 2): if fl < ul: # pwr_spectra=x['x'] # Initialize a FOOOFGroup object - it accepts all the same settings as FOOOF fg = FOOOFGroup(max_n_peaks=6, peak_threshold=4) frange = (fl, ul) # Fit a group of power spectra with the .fit() method# Fit a # The key difference (compared to FOOOF) is that it takes a 2D array of spectra # This matrix should have the shape of [n_spectra, n_freqs] fg.fit(frq_ax, pwr_spectra, frange) slp = fg.get_all_data('background_params', 'slope') r = fg.get_all_data('r_squared') slpa = np.concatenate((slpa, slp)) ra = np.concatenate((ra, r)) scipy.io.savemat('slpa.mat', {'slpa': slpa}) scipy.io.savemat('ra.mat', {'ra': ra}) return
def foof2mat_model(): import sys from scipy.io import loadmat, savemat import sklearn from scipy import io import scipy import numpy as np from fooof import FOOOF import neurodsp import matplotlib.pyplot as plt import pacpy import h5py import matplotlib from matplotlib import lines import math from neurodsp import spectral # FOOOF imports: get FOOOF & FOOOFGroup objects from fooof import FOOOFGroup dat = hdf5storage.loadmat(str(sys.argv[1])) frq_ax = np.linspace(0, 500, 5001) #dat["fx"][0] pwr_spectra = dat['avgpwr'] #dat["powall"] #pwr_spectra=x['x'] # Initialize a FOOOFGroup object - it accepts all the same settings as FOOOF fg = FOOOFGroup(peak_threshold=7, peak_width_limits=[3, 14]) #, aperiodic_mode='knee' frange = (1, 290) # Fit a group of power spectra with the .fit() method# Fit a # The key difference (compared to FOOOF) is that it takes a 2D array of spectra # This matrix should have the shape of [n_spectra, n_freqs] fg.fit(frq_ax, pwr_spectra, frange) slp = fg.get_params('aperiodic_params', 'exponent') off = fg.get_params('aperiodic_params', 'offset') r = fg.get_params('r_squared') savemat('slp.mat', {'slp': slp}) savemat('off.mat', {'off': off}) savemat('r.mat', {'r': r}) return
def fit_fooof(epochs): # Estimate the PSD in the pre-stimulus window spectrum, freqs = psd_welch(epochs, tmin=-.5, tmax=0, fmin=2, fmax=30, n_fft=126, average='median', n_per_seg=100, n_overlap=50) spectrum = np.mean(spectrum, axis=0) # Run FOOF fm = FOOOFGroup(peak_width_limits=(4.0, 12.0), aperiodic_mode='fixed', peak_threshold=1) # Set the frequency range to fit the model freq_range = [2, 30] # Fit the FOOOF model fm.fit(freqs, spectrum, freq_range) return fm.copy()
def fooofy(components, spectra, x_range, group=True): """ fit FOOOF model on given spectrum and return params components: frequencies or PC dimensions spectra: PSDs or variance explained x_range: range for x axis of spectrum to fit group: whether to use FOOOFGroup or not """ if group: fg = FOOOFGroup(max_n_peaks=0, aperiodic_mode='fixed', verbose=False) #initialize FOOOF object else: fg = FOOOF(max_n_peaks=0, aperiodic_mode='fixed', verbose=False) #initialize FOOOF object #print(spectra.shape, components.shape) #Use this line if things go weird fg.fit(components, spectra, x_range) exponents = fg.get_params('aperiodic_params', 'exponent') errors = fg.get_params('error') # MAE offsets = fg.get_params('aperiodic_params', 'offset') return exponents, errors, offsets
def fooof_perps(): import sys import numpy as np from scipy.io import loadmat, savemat from fooof import FOOOFGroup import matplotlib.pyplot as plt data = loadmat('perps_proper.mat') # Unpack data from dictionary, and squeeze numpy arrays freqs = np.squeeze(data['fx_regular']).astype('float') psds = np.squeeze(data['powa_regular']).astype('float') # ^Note: this also explicitly enforces type as float (type casts to float64, instead of float32) # This is not strictly necessary for fitting, but is for saving out as json from FOOOF, if you want to do that # Transpose power spectra, to have the expected orientation for FOOOF #psds = psds.T fg = FOOOFGroup(peak_threshold=4,peak_width_limits=[3, 14])#, aperiodic_mode='knee' #fg.report(freqs, psds, [1, 290]) #fg.fit(freqs,psds,[0.2,290]) fg.fit(freqs,psds,[float(sys.argv[1]),float(sys.argv[2])]) fg.plot() fg.save_report('perps') #print(fg.group_results) r2 = fg.get_params('r_squared') savemat('p_r2.mat', {'p_r2' : r2}) exps = fg.get_params('aperiodic_params', 'exponent') centerfrq = fg.get_params('peak_params','CF') peakheight = fg.get_params('peak_params','PW') savemat('p_exps.mat', {'p_exps' : exps}) savemat('p_cfs.mat', {'p_cfs' : centerfrq}) savemat('p_peakheight.mat',{'p_peakheight' : peakheight}) offset = fg.get_params('aperiodic_params','offset') savemat('p_offs.mat', {'p_offs' : offset})
def compute_intsc(ts, numtps, srate, freq_range=(2, 50)): """ Compute intrinsic neural timescale """ # figure out tr in seconds tr = 1 / srate # grab electrode names colnames2use = ts.columns colnames2use = colnames2use.to_list() # normalize (divide all elements of the timeseries by the first value in the timeseries) ts = np.array(ts) for col_index, ts2use in enumerate(ts.T): ts[:, col_index] = np.divide(ts2use, ts2use[0]) # compute spectrum via FFT f_axis = np.fft.fftfreq(numtps, tr)[:int(np.floor(numtps / 2))] psds = (np.abs(sp.fft(ts, axis=0))**2)[:len(f_axis)] # fit FOOOF & get knee parameter & convert to timescale fooof = FOOOFGroup(aperiodic_mode='knee', max_n_peaks=0, verbose=False) fooof.fit(freqs=f_axis, power_spectra=psds.T, freq_range=freq_range) fit_knee = fooof.get_params('aperiodic_params', 'knee') fit_exp = fooof.get_params('aperiodic_params', 'exponent') knee_freq, taus = convert_knee_val(fit_knee, fit_exp) # convert timescale into ms taus = taus * 1000 # convert taus into a data frame taus_df = pd.DataFrame(taus.tolist(), index=colnames2use, columns=["intsc"]) taus_df = taus_df.T return (taus_df)
def main(): # Get project database objects, and list of available subjects db = SLFDB() subjs = db.check_subjs() done = db.get_fooof_subjs() for cur_subj in subjs: # Skip specified subjects if cur_subj in SKIP_SUBJS: print('\n\n\nSKIPPING SUBJECT: ', str(cur_subj), '\n\n\n') continue # Skip subject if PSD already calculated if cur_subj in done: print('\n\n\nSUBJECT ALREADY RUN: ', str(cur_subj), '\n\n\n') continue # Print status print('\n\n\nRUNNING SUBJECT: ', str(cur_subj), '\n\n\n') # Get subject data files try: dat_f, ev_f, _ = db.get_subj_files(cur_subj) if dat_f is None: print('\n\n\nSKIPPING DUE TO FILE ISSUE: ', str(cur_subj), '\n\n\n') continue except: print('\tFAILED TO GET SUBJ FILES') continue # Get the resting data file - file 001 temp = [ef.split('_')[1] for ef in ev_f] temp = [fn[-3:] for fn in temp] f_ind = None for i, tt in enumerate(temp): if tt == '001': f_ind = i if f_ind is None: print('\tFAILED TO FIND 001 BLOCK') continue # Get file file path for data file & associated event file dat_f_name = db.gen_dat_path(cur_subj, dat_f[f_ind]) eve_f_name = db.gen_dat_path(cur_subj, ev_f[f_ind]) # Set the sampling rate s_freq = 500 # Load data file dat = np.loadtxt(dat_f_name, delimiter=',') # Read in list of channel names that are kept in reduced 111 montage with open('../data/chans111.csv', 'r') as csv_file: reader = csv.reader(csv_file) ch_labels = list(reader)[0] # Read montage, reduced to 111 channel selection montage = mne.channels.read_montage('GSN-HydroCel-129', ch_names=ch_labels) # Create the info structure needed by MNE info = mne.create_info(ch_labels, s_freq, 'eeg', montage) # Create the MNE Raw data object raw = mne.io.RawArray(dat, info) # Create a stim channel stim_info = mne.create_info(['stim'], s_freq, 'stim') stim_raw = mne.io.RawArray(np.zeros(shape=[1, len(raw._times)]), stim_info) # Add stim channel to data object raw.add_channels([stim_raw], force_update_info=True) # Load events from file # Initialize headers and variable to store event info headers = ['type', 'value', 'latency', 'duration', 'urevent'] evs = np.empty(shape=[0, 3]) # Load events from csv file with open(eve_f_name, 'r') as csv_file: reader = csv.reader(csv_file) for row in reader: # Skip the empty rows if row == []: continue # Skip the header row, since there is one for every event... if row[0] == 'type': continue # Collect actual event data rows evs = np.vstack((evs, np.array([int(row[2]), 0, int(row[0])]))) # Add events to data object raw.add_events(evs, stim_channel='stim') # Check events dat_evs = mne.find_events(raw) # Find flat channels and set them as bad flat_chans = np.mean(raw._data[:111, :], axis=1) == 0 raw.info['bads'] = list(np.array(raw.ch_names[:111])[flat_chans]) print('Bad channels: ', raw.info['bads']) # Interpolate bad channels raw.interpolate_bads() # Set average reference raw.set_eeg_reference() raw.apply_proj() # Get good eeg channel indices eeg_chans = mne.pick_types(raw.info, meg=False, eeg=True) # Epoch resting eeg data events eo_epochs = mne.Epochs(raw, events=dat_evs, event_id={'EO': 20}, tmin=2, tmax=18, baseline=None, picks=eeg_chans, preload=True) ec_epochs = mne.Epochs(raw, events=dat_evs, event_id={'EC': 30}, tmin=5, tmax=35, baseline=None, picks=eeg_chans, preload=True) # Calculate PSDs - EO Data eo_psds, eo_freqs = mne.time_frequency.psd_welch(eo_epochs, fmin=2., fmax=40., n_fft=1000, n_overlap=250, verbose=False) # Average PSDs for each channel across each rest block eo_avg_psds = np.mean(eo_psds, axis=0) # Calculate PSDs - EC Data ec_psds, ec_freqs = mne.time_frequency.psd_welch(ec_epochs, fmin=2., fmax=40., n_fft=1000, n_overlap=250, verbose=False) # Average PSDs for each channel across each rest block ec_avg_psds = np.mean(ec_psds, axis=0) # Save out PSDs np.savez(os.path.join(db.psd_path, str(cur_subj) + '_ec_avg_psds.npz'), ec_freqs, ec_avg_psds, np.array(ec_epochs.ch_names)) np.savez(os.path.join(db.psd_path, str(cur_subj) + '_eo_avg_psds.npz'), eo_freqs, eo_avg_psds, np.array(eo_epochs.ch_names)) np.savez(os.path.join(db.psd_path, str(cur_subj) + '_ec_psds.npz'), ec_freqs, ec_psds, np.array(ec_epochs.ch_names)) np.savez(os.path.join(db.psd_path, str(cur_subj) + '_eo_psds.npz'), eo_freqs, eo_psds, np.array(eo_epochs.ch_names)) # Print status print('\n\n\nPSD DATA SAVED FOR SUBJ: ', str(cur_subj), '\n\n\n') print('\n\n\nFOOOFING DATA FOR SUBJ: ', str(cur_subj), '\n\n\n') # Fit FOOOF to PSDs averaged across rest epochs fg = FOOOFGroup(peak_width_limits=[1, 8], max_n_peaks=6) fg.fit(eo_freqs, eo_avg_psds, F_RANGE) sls_eo_avg = fg.get_all_data('background_params', 'slope') fg.fit(ec_freqs, ec_avg_psds, F_RANGE) sls_ec_avg = fg.get_all_data('background_params', 'slope') # Fit FOOOF to PSDs from each epoch eo_fgs = [] for ep_psds in eo_psds: fg.fit(eo_freqs, ep_psds, F_RANGE) eo_fgs.append(fg.copy()) sls_eo = [ fg.get_all_data('background_params', 'slope') for fg in eo_fgs ] ec_fgs = [] for ep_psds in ec_psds: fg.fit(ec_freqs, ep_psds, F_RANGE) ec_fgs.append(fg.copy()) sls_ec = [ fg.get_all_data('background_params', 'slope') for fg in ec_fgs ] # Collect data together subj_dat = { 'ID': cur_subj, 'sls_eo_avg': sls_eo_avg, 'sls_ec_avg': sls_ec_avg, 'sls_eo': sls_eo, 'sls_ec': sls_ec } # Save out slope data f_name = str(cur_subj) + '_fooof.p' save_pickle(subj_dat, f_name, db.fooof_path) # Print status print('\n\n\nFOOOF DATA SAVED AND FINISHED WITH SUBJ: ', str(cur_subj), '\n\n\n')
# Fit Power Spectrum Models # ~~~~~~~~~~~~~~~~~~~~~~~~~ # # Now that we have our simulated data, we can fit our power spectrum models, using FOOOFGroup. # ################################################################################################### # Initialize a FOOOFGroup object for each group fg1 = FOOOFGroup(verbose=False) fg2 = FOOOFGroup(verbose=False) ################################################################################################### # Parameterize neural power spectra fg1.fit(freqs, powers1) fg2.fit(freqs, powers2) ################################################################################################### # Plotting Parameters & Components # -------------------------------- # # In the following, we will explore two visualization options: # # - plotting parameter values # - plotting component reconstructions # # Each of these approaches can be done for either aperiodic or periodic parameters. # # All of the plots that we will use in this example can be used to visualize either # one or multiple groups of data. As we will see, you can pass in a single group of
# accessed in the same way as the FOOOF object. # # Internally, it runs the exact same fitting procedure, per spectrum, as the FOOOF object. # ################################################################################################### # Initialize a FOOOFGroup object - it accepts all the same settings as FOOOF fg = FOOOFGroup(peak_width_limits=[1, 8], min_peak_height=0.05, max_n_peaks=6) ################################################################################################### # Fit a group of power spectra with the .fit() method # The key difference (compared to FOOOF) is that it takes a 2D array of spectra # This matrix should have the shape of [n_spectra, n_freqs] fg.fit(freqs, spectra) ################################################################################################### # Print out results fg.print_results() ################################################################################################### # Plot a summary of the results across the group # Note: given the simulations, we expect exponents at {1.5, 2.0. 2.5} and peaks around {10, 20} fg.plot() ################################################################################################### # # Just as with the FOOOF object, you can call the convenience method `report` to run
print("Error: File not found!") continue print('Processing S%d B%d M%d ...' % (isubj, iblock, m)) freqs = np.squeeze(dat['fxx']) aper = np.empty([2, dat['pxx'].shape[1]]) only_gauss = np.zeros([dat['pxx'].shape[0], dat['pxx'].shape[1]]) full_gauss = np.zeros([dat['pxx'].shape[0], dat['pxx'].shape[1]]) fm = FOOOFGroup(peak_width_limits=[1, 8], min_peak_height=0.05, max_n_peaks=6) fm._maxfev = 30000 freq_range = [3, 40] fm.fit(freqs, np.transpose(dat['pxx']), freq_range) tmp = fm.get_results() for isens in range(0, dat['pxx'].shape[1]): aper[:, isens] = tmp[isens].aperiodic_params F = fm.freqs for isens in range(0, dat['pxx'].shape[1]): for i in range(0, len(tmp[isens].gaussian_params)): c = tmp[isens].gaussian_params[i][0] w = tmp[isens].gaussian_params[i][2] a = tmp[isens].gaussian_params[i][1] only_gauss[:, isens] = only_gauss[:, isens] + a * np.exp( (-(F - c)**2) / (2 * pow(w, 2))) b = tmp[isens].aperiodic_params[0]
# Generate some synthetic power spectra and fit a FOOOFGroup to use freqs, spectra, _ = gen_group_power_spectra( n_spectra=10, freq_range=[3, 40], aperiodic_params=param_sampler([[20, 2], [35, 1.5]]), gauss_params=param_sampler([[], [10, 0.5, 2]])) ################################################################################################### # Fit FOOOF models across the group of synthesized power spectra fg = FOOOFGroup(peak_width_limits=[1, 8], min_peak_height=0.05, max_n_peaks=6, verbose=False) fg.fit(freqs, spectra) ################################################################################################### # Get all alpha oscillations from a FOOOFGroup object alphas = get_band_peak_group(fg.get_all_data('peak_params'), alpha_band, len(fg)) ################################################################################################### # Check out some of the alpha data print(alphas[0:5, :]) ################################################################################################### # # Note that the design of :func:`get_band_peak_group` is such that it will retain
third_half = np.mean( dat['pxx'][:, :, sorted.size - int(np.floor(sorted.size / 3)) + 1:], axis=2) fm = FOOOFGroup(peak_width_limits=[1, 8], min_peak_height=0.05, max_n_peaks=6) fm._maxfev = 30000 freq_range = [3, 40] freqs = np.squeeze(dat['fxx']) aperiodic = np.zeros([2, np.shape(dat['pxx'])[1], 2]) fm.fit(freqs, np.transpose(first_half), freq_range) fm.save( '/home/tpfeffer/pp/proc/src/pp_hh_task_fooof_result_lo_s%d_b%d_v%d' % (isubj, iblock, v), save_results=True, save_settings=False, save_data=True) fm.fit(freqs, np.transpose(second_half), freq_range) fm.save( '/home/tpfeffer/pp/proc/src/pp_hh_task_fooof_result_me_s%d_b%d_v%d' % (isubj, iblock, v), save_results=True, save_settings=False, save_data=True)
################################################################################################### # Simulate some example power spectra to use for the example freqs, powers = gen_group_power_spectra(25, [1, 50], [1, 1], [10, 0.25, 3], nlvs=0.1, freq_res=0.25) ################################################################################################### # Initialize a FOOOFGroup object, with some desired settings fg = FOOOFGroup(min_peak_height=0.1, max_n_peaks=6) ################################################################################################### # Fit power spectra fg.fit(freqs, powers) ################################################################################################### # # If there are failed fits, these are stored as null models. # # Let's check if there were any null models, from model failures, in the models # that we have fit so far. To do so, the :class:`~fooof.FOOOFGroup` object has some # attributes that provide information on any null model fits. # # These attributes are: # # - ``n_null_`` : the number of model results that are null # - ``null_inds_`` : the indices of any null model results #
def main(argv): # defining paths basepath = '/Users/rdgao/Documents/data/MNI_rest/' datafile = basepath + 'WakefulnessMatlabFile.mat' result_basepath = '/Users/rdgao/Documents/code/research/field-echos/results/MNI_rest/' # load data data_dict = io.loadmat(datafile, squeeze_me=True) fs = data_dict['SamplingFrequency'] data = data_dict['Data'] if 'do_psds' in argv: print('Computing PSDs...') # 1 second window nperseg, noverlap = int(fs), int(fs / 2) f_axis, psd_mean, psd_med = compute_psds_whole(data, fs, nperseg, noverlap) saveout_path = utils.makedir(result_basepath, 'psd/1sec/', timestamp=False) np.savez(saveout_path + 'psds.npz', psd_mean=psd_mean, psd_med=psd_med, f_axis=f_axis, nperseg=nperseg, noverlap=noverlap) # 5 second window nperseg, noverlap = int(fs * 5), int(fs * 4) f_axis, psd_mean, psd_med = compute_psds_whole(data, fs, nperseg, noverlap) saveout_path = utils.makedir(result_basepath, '/psd/5sec/', timestamp=False) np.savez(saveout_path + 'psds.npz', psd_mean=psd_mean, psd_med=psd_med, f_axis=f_axis, nperseg=nperseg, noverlap=noverlap) if 'do_fooof' in argv: print('FOOOFing...') fooof_settings = [['knee', 2, (1, 55)], ['fixed', 2, (1, 55)], ['fixed', 1, (1, 10)], ['fixed', 1, (30, 55)]] for psd_win in ['1sec/', '5sec/']: psd_folder = result_basepath + '/psd/' + psd_win psd_data = np.load(psd_folder + 'psds.npz') for f_s in fooof_settings: # fit to mean and median psd for psd_mode in ['psd_mean', 'psd_med']: fg = FOOOFGroup(aperiodic_mode=f_s[0], max_n_peaks=f_s[1]) fg.fit(psd_data['f_axis'], psd_data[psd_mode].T, freq_range=f_s[2]) fooof_savepath = utils.makedir(psd_folder, '/fooof/' + psd_mode + '/', timestamp=False) fg.save('fg_%s_%ipks_%i-%iHz' % (f_s[0], f_s[1], f_s[2][0], f_s[2][1]), fooof_savepath, save_results=True, save_settings=True) print('Done.')
# accessed in the same way as the :class:`~fooof.FOOOF` object. # # Internally, it runs the exact same fitting procedure, per spectrum, as the FOOOF object. # ################################################################################################### # Initialize a FOOOFGroup object, which accepts all the same settings as FOOOF fg = FOOOFGroup(peak_width_limits=[1, 8], min_peak_height=0.05, max_n_peaks=6) ################################################################################################### # Fit a group of power spectra with the .fit() method # The key difference (compared to FOOOF) is that it takes a 2D array of spectra # This matrix should have the shape of [n_spectra, n_freqs] fg.fit(freqs, spectra, [3, 30]) ################################################################################################### # Print out results fg.print_results() ################################################################################################### # Plot a summary of the results across the group fg.plot() ################################################################################################### # # Just as with the FOOOF object, you can call the convenience method # :meth:`fooof.FOOOFGroup.report` to run the fitting, and then print the results and plots.
axis=-1, fs=200, window='hann', average='mean', nperseg=200, nfft=400, return_onesided=True) theta_params_clean = np.zeros(shape=[64, len(eps), 3]) - 1 for elec_n in np.arange(n_elec): if np.logical_not(elec_n % 10): print('\telec : %s' % eps.info['ch_names'][elec_n]) fg = FOOOFGroup(verbose=False, max_n_peaks=4, peak_width_limits=[.5, 2]) fg.fit(freqs_welch, amp_welch[:, elec_n, :], [2, 20], n_jobs=-1) theta_params =\ np.array([fg_res_n.peak_params[(fg_res_n.peak_params[:,0]>3.9)\ & (fg_res_n.peak_params[:,0]<8)] for fg_res_n in fg.get_results()]) for trial_n in np.arange(len(theta_params)): if len(theta_params[trial_n]) == 1: theta_params_clean[ elec_n, trial_n, :] = theta_params[trial_n].squeeze() elif len(theta_params[trial_n]) > 1: max_amp_ind = np.argmax(theta_params[trial_n][:, 1]).squeeze() theta_params_clean[elec_n, trial_n, :] = theta_params[trial_n][ max_amp_ind, :].squeeze() np.savez(obs_eegpath +\ 'obs_%i_fooof_params_theta.npz' % obs_i,
dat = scipy.io.loadmat( '/home/tpfeffer/pp/proc/src/pp_sens_gla_fooof_s%s_b1_v%d.mat' % (isubj + 1, v)) fm = FOOOFGroup(peak_width_limits=[1, 8], min_peak_height=0.05, max_n_peaks=6) freq_range = [3, 40] freqs = np.squeeze(dat['fxx']) slp = np.zeros([np.shape(dat['pxx'])[1], np.shape(dat['pxx'])[2]]) for iseg in range(0, np.shape(dat['pxx'])[2]): print('Processing segment %d' % iseg) power_spectrum = np.squeeze(dat['pxx'][:, :, iseg]) spectrum = np.transpose(power_spectrum) fm.fit(freqs, spectrum, freq_range) tmp = fm.get_results() for isens in range(0, np.shape(dat['pxx'])[1]): slp[isens][iseg] = tmp[isens][0][1] r = np.zeros([np.shape(dat['pxx'])[1], 1]) for iseg in range(0, np.shape(dat['pxx'])[1]): r[iseg] = np.corrcoef(slp[iseg, :], dat['pup'], rowvar=True)[0][1] scipy.io.savemat( '/home/tpfeffer/pp/proc/src/pp_sens_gla_fooof_exp_s%d.mat' % (isubj + 1), {'r': r})
def main(): ################################################# ## SETUP ## Get list of subject files subj_files = listdir(DAT_PATH) subj_files = [file for file in subj_files if EXT.lower() in file.lower()] ## Set up FOOOF Objects # Initialize FOOOF settings & objects objects fooof_settings = FOOOFSettings(peak_width_limits=PEAK_WIDTH_LIMITS, max_n_peaks=MAX_N_PEAKS, min_peak_amplitude=MIN_PEAK_AMP, peak_threshold=PEAK_THRESHOLD, aperiodic_mode=APERIODIC_MODE) fm = FOOOF(*fooof_settings, verbose=False) fg = FOOOFGroup(*fooof_settings, verbose=False) # Save out a settings file fg.save('0-FOOOF_Settings', pjoin(RES_PATH, 'FOOOF'), save_settings=True) # Set up the dictionary to store all the FOOOF results fg_dict = dict() for load_label in LOAD_LABELS: fg_dict[load_label] = dict() for side_label in SIDE_LABELS: fg_dict[load_label][side_label] = dict() for seg_label in SEG_LABELS: fg_dict[load_label][side_label][seg_label] = [] ## Initialize group level data stores n_subjs, n_conds, n_times = len(subj_files), 3, N_TIMES group_fooofed_alpha_freqs = np.zeros(shape=[n_subjs]) dropped_components = np.ones(shape=[n_subjs, 50]) * 999 dropped_trials = np.ones(shape=[n_subjs, 1500]) * 999 canonical_group_avg_dat = np.zeros(shape=[n_subjs, n_conds, n_times]) fooofed_group_avg_dat = np.zeros(shape=[n_subjs, n_conds, n_times]) # Set channel types ch_types = {'LHor' : 'eog', 'RHor' : 'eog', 'IVer' : 'eog', 'SVer' : 'eog', 'LMas' : 'misc', 'RMas' : 'misc', 'Nose' : 'misc', 'EXG8' : 'misc'} ################################################# ## RUN ACROSS ALL SUBJECTS # Run analysis across each subject for s_ind, subj_file in enumerate(subj_files): # Get subject label and print status subj_label = subj_file.split('.')[0] print('\nCURRENTLY RUNNING SUBJECT: ', subj_label, '\n') ################################################# ## LOAD / ORGANIZE / SET-UP DATA # Load subject of data, apply apply fixes for channels, etc eeg_dat = mne.io.read_raw_edf(pjoin(DAT_PATH, subj_file), preload=True, verbose=False) # Fix channel name labels eeg_dat.info['ch_names'] = [chl[2:] for chl in \ eeg_dat.ch_names[:-1]] + [eeg_dat.ch_names[-1]] for ind, chi in enumerate(eeg_dat.info['chs']): eeg_dat.info['chs'][ind]['ch_name'] = eeg_dat.info['ch_names'][ind] # Update channel types eeg_dat.set_channel_types(ch_types) # Set reference - average reference eeg_dat = eeg_dat.set_eeg_reference(ref_channels='average', projection=False, verbose=False) # Set channel montage chs = mne.channels.read_montage('standard_1020', eeg_dat.ch_names) eeg_dat.set_montage(chs) # Get event information & check all used event codes evs = mne.find_events(eeg_dat, shortest_event=1, verbose=False) # Pull out sampling rate srate = eeg_dat.info['sfreq'] ################################################# ## Pre-Processing: ICA # High-pass filter data for running ICA eeg_dat.filter(l_freq=1., h_freq=None, fir_design='firwin') if RUN_ICA: print("\nICA: CALCULATING SOLUTION\n") # ICA settings method = 'fastica' n_components = 0.99 random_state = 47 reject = {'eeg': 20e-4} # Initialize ICA object ica = ICA(n_components=n_components, method=method, random_state=random_state) # Fit ICA ica.fit(eeg_dat, reject=reject) # Save out ICA solution ica.save(pjoin(RES_PATH, 'ICA', subj_label + '-ica.fif')) # Otherwise: load previously saved ICA to apply else: print("\nICA: USING PRECOMPUTED\n") ica = read_ica(pjoin(RES_PATH, 'ICA', subj_label + '-ica.fif')) # Find components to drop, based on correlation with EOG channels drop_inds = [] for chi in EOG_CHS: inds, _ = ica.find_bads_eog(eeg_dat, ch_name=chi, threshold=2.5, l_freq=1, h_freq=10, verbose=False) drop_inds.extend(inds) drop_inds = list(set(drop_inds)) # Set which components to drop, and collect record of this ica.exclude = drop_inds dropped_components[s_ind, 0:len(drop_inds)] = drop_inds # Apply ICA to data eeg_dat = ica.apply(eeg_dat) ################################################# ## SORT OUT EVENT CODES # Extract a list of all the event labels all_trials = [it for it2 in EV_DICT.values() for it in it2] # Create list of new event codes to be used to label correct trials (300s) all_trials_new = [it + 100 for it in all_trials] # This is an annoying way to collapse across the doubled event markers from above all_trials_new = [it - 1 if not ind%2 == 0 else it for ind, it in enumerate(all_trials_new)] # Get labelled dictionary of new event names ev_dict2 = {k:v for k, v in zip(EV_DICT.keys(), set(all_trials_new))} # Initialize variables to store new event definitions evs2 = np.empty(shape=[0, 3], dtype='int64') lags = np.array([]) # Loop through, creating new events for all correct trials t_min, t_max = -0.4, 3.0 for ref_id, targ_id, new_id in zip(all_trials, CORR_CODES * 6, all_trials_new): t_evs, t_lags = mne.event.define_target_events(evs, ref_id, targ_id, srate, t_min, t_max, new_id) if len(t_evs) > 0: evs2 = np.vstack([evs2, t_evs]) lags = np.concatenate([lags, t_lags]) ################################################# ## FOOOF # Set channel of interest ch_ind = eeg_dat.ch_names.index(CHL) # Calculate PSDs over ~ first 2 minutes of data, for specified channel fmin, fmax = 1, 50 tmin, tmax = 5, 125 psds, freqs = mne.time_frequency.psd_welch(eeg_dat, fmin=fmin, fmax=fmax, tmin=tmin, tmax=tmax, n_fft=int(2*srate), n_overlap=int(srate), n_per_seg=int(2*srate), verbose=False) # Fit FOOOF across all channels fg.fit(freqs, psds, FREQ_RANGE, n_jobs=-1) # Save out FOOOF results fg.save(subj_label + '_fooof', pjoin(RES_PATH, 'FOOOF'), save_results=True) # Extract individualized CF from specified channel, add to group collection fm = fg.get_fooof(ch_ind, False) fooof_freq, _, _ = get_band_peak(fm.peak_params_, [7, 14]) group_fooofed_alpha_freqs[s_ind] = fooof_freq # If not FOOOF alpha extracted, reset to 10 if np.isnan(fooof_freq): fooof_freq = 10 ################################################# ## ALPHA FILTERING # CANONICAL: Filter data to canonical alpha band: 8-12 Hz alpha_dat = eeg_dat.copy() alpha_dat.filter(8, 12, fir_design='firwin', verbose=False) alpha_dat.apply_hilbert(envelope=True, verbose=False) # FOOOF: Filter data to FOOOF derived alpha band fooof_dat = eeg_dat.copy() fooof_dat.filter(fooof_freq-2, fooof_freq+2, fir_design='firwin') fooof_dat.apply_hilbert(envelope=True) ################################################# ## EPOCH TRIALS # Set epoch timings tmin, tmax = -0.85, 1.1 # Epoch trials - raw data for trial rejection epochs = mne.Epochs(eeg_dat, evs2, ev_dict2, tmin=tmin, tmax=tmax, baseline=None, preload=True, verbose=False) # Epoch trials - filtered version epochs_alpha = mne.Epochs(alpha_dat, evs2, ev_dict2, tmin=tmin, tmax=tmax, baseline=(-0.5, -0.35), preload=True, verbose=False) epochs_fooof = mne.Epochs(fooof_dat, evs2, ev_dict2, tmin=tmin, tmax=tmax, baseline=(-0.5, -0.35), preload=True, verbose=False) ################################################# ## PRE-PROCESSING: AUTO-REJECT if RUN_AUTOREJECT: print('\nAUTOREJECT: CALCULATING SOLUTION\n') # Initialize and run autoreject across epochs ar = AutoReject(n_jobs=4, verbose=False) ar.fit(epochs) # Save out AR solution ar.save(pjoin(RES_PATH, 'AR', subj_label + '-ar.hdf5'), overwrite=True) # Otherwise: load & apply previously saved AR solution else: print('\nAUTOREJECT: USING PRECOMPUTED\n') ar = read_auto_reject(pjoin(RES_PATH, 'AR', subj_label + '-ar.hdf5')) ar.verbose = 'tqdm' # Apply autoreject to the original epochs object it was learnt on epochs, rej_log = ar.transform(epochs, return_log=True) # Apply autoreject to the copies of the data - apply interpolation, then drop same epochs _apply_interp(rej_log, epochs_alpha, ar.threshes_, ar.picks_, ar.verbose) epochs_alpha.drop(rej_log.bad_epochs) _apply_interp(rej_log, epochs_fooof, ar.threshes_, ar.picks_, ar.verbose) epochs_fooof.drop(rej_log.bad_epochs) # Collect which epochs were dropped dropped_trials[s_ind, 0:sum(rej_log.bad_epochs)] = np.where(rej_log.bad_epochs)[0] ################################################# ## SET UP CHANNEL CLUSTERS # Set channel clusters - take channels contralateral to stimulus presentation # Note: channels will be used to extract data contralateral to stimulus presentation le_chs = ['P3', 'P5', 'P7', 'P9', 'O1', 'PO3', 'PO7'] # Left Side Channels le_inds = [epochs.ch_names.index(chn) for chn in le_chs] ri_chs = ['P4', 'P6', 'P8', 'P10', 'O2', 'PO4', 'PO8'] # Right Side Channels ri_inds = [epochs.ch_names.index(chn) for chn in ri_chs] ################################################# ## TRIAL-RELATED ANALYSIS: CANONICAL vs. FOOOF ## Pull out channels of interest for each load level # Channels extracted are those contralateral to stimulus presentation # Canonical Data lo1_a = np.concatenate([epochs_alpha['LeLo1']._data[:, ri_inds, :], epochs_alpha['RiLo1']._data[:, le_inds, :]], 0) lo2_a = np.concatenate([epochs_alpha['LeLo2']._data[:, ri_inds, :], epochs_alpha['RiLo2']._data[:, le_inds, :]], 0) lo3_a = np.concatenate([epochs_alpha['LeLo3']._data[:, ri_inds, :], epochs_alpha['RiLo3']._data[:, le_inds, :]], 0) # FOOOFed data lo1_f = np.concatenate([epochs_fooof['LeLo1']._data[:, ri_inds, :], epochs_fooof['RiLo1']._data[:, le_inds, :]], 0) lo2_f = np.concatenate([epochs_fooof['LeLo2']._data[:, ri_inds, :], epochs_fooof['RiLo2']._data[:, le_inds, :]], 0) lo3_f = np.concatenate([epochs_fooof['LeLo3']._data[:, ri_inds, :], epochs_fooof['RiLo3']._data[:, le_inds, :]], 0) ## Calculate average across trials and channels - add to group data collection # Canonical data canonical_group_avg_dat[s_ind, 0, :] = np.mean(lo1_a, 1).mean(0) canonical_group_avg_dat[s_ind, 1, :] = np.mean(lo2_a, 1).mean(0) canonical_group_avg_dat[s_ind, 2, :] = np.mean(lo3_a, 1).mean(0) # FOOOFed data fooofed_group_avg_dat[s_ind, 0, :] = np.mean(lo1_f, 1).mean(0) fooofed_group_avg_dat[s_ind, 1, :] = np.mean(lo2_f, 1).mean(0) fooofed_group_avg_dat[s_ind, 2, :] = np.mean(lo3_f, 1).mean(0) ################################################# ## FOOOFING TRIAL AVERAGED DATA # Loop loop loads & trials segments for seg_label, seg_time in zip(SEG_LABELS, SEG_TIMES): tmin, tmax = seg_time[0], seg_time[1] # Calculate PSDs across trials, fit FOOOF models to averages for le_label, ri_label, load_label in zip(['LeLo1', 'LeLo2', 'LeLo3'], ['RiLo1', 'RiLo2', 'RiLo3'], LOAD_LABELS): ## Calculate trial wise PSDs for left & right side trials trial_freqs, le_trial_psds = periodogram( epochs[le_label]._data[:, :, _time_mask(epochs.times, tmin, tmax, srate)], srate, window='hann', nfft=4*srate) trial_freqs, ri_trial_psds = periodogram( epochs[ri_label]._data[:, :, _time_mask(epochs.times, tmin, tmax, srate)], srate, window='hann', nfft=4*srate) ## FIT ALL CHANNELS VERSION if FIT_ALL_CHANNELS: ## Average spectra across trials within a given load & side le_avg_psd_contra = avg_func(le_trial_psds[:, ri_inds, :], 0) le_avg_psd_ipsi = avg_func(le_trial_psds[:, le_inds, :], 0) ri_avg_psd_contra = avg_func(ri_trial_psds[:, le_inds, :], 0) ri_avg_psd_ipsi = avg_func(ri_trial_psds[:, ri_inds, :], 0) ## Combine spectra across left & right trials for given load ch_psd_contra = np.vstack([le_avg_psd_contra, ri_avg_psd_contra]) ch_psd_ipsi = np.vstack([le_avg_psd_ipsi, ri_avg_psd_ipsi]) ## Fit FOOOFGroup to all channels, average & and collect results fg.fit(trial_freqs, ch_psd_contra, FREQ_RANGE) fm = avg_fg(fg) fg_dict[load_label]['Contra'][seg_label].append(fm.copy()) fg.fit(trial_freqs, ch_psd_ipsi, FREQ_RANGE) fm = avg_fg(fg) fg_dict[load_label]['Ipsi'][seg_label].append(fm.copy()) ## COLLAPSE ACROSS CHANNELS VERSION else: ## Average spectra across trials and channels within a given load & side le_avg_psd_contra = avg_func(avg_func(le_trial_psds[:, ri_inds, :], 0), 0) le_avg_psd_ipsi = avg_func(avg_func(le_trial_psds[:, le_inds, :], 0), 0) ri_avg_psd_contra = avg_func(avg_func(ri_trial_psds[:, le_inds, :], 0), 0) ri_avg_psd_ipsi = avg_func(avg_func(ri_trial_psds[:, ri_inds, :], 0), 0) ## Collapse spectra across left & right trials for given load avg_psd_contra = avg_func(np.vstack([le_avg_psd_contra, ri_avg_psd_contra]), 0) avg_psd_ipsi = avg_func(np.vstack([le_avg_psd_ipsi, ri_avg_psd_ipsi]), 0) ## Fit FOOOF, and collect results fm.fit(trial_freqs, avg_psd_contra, FREQ_RANGE) fg_dict[load_label]['Contra'][seg_label].append(fm.copy()) fm.fit(trial_freqs, avg_psd_ipsi, FREQ_RANGE) fg_dict[load_label]['Ipsi'][seg_label].append(fm.copy()) ################################################# ## SAVE OUT RESULTS # Save out group data np.save(pjoin(RES_PATH, 'Group', 'alpha_freqs_group'), group_fooofed_alpha_freqs) np.save(pjoin(RES_PATH, 'Group', 'canonical_group'), canonical_group_avg_dat) np.save(pjoin(RES_PATH, 'Group', 'fooofed_group'), fooofed_group_avg_dat) np.save(pjoin(RES_PATH, 'Group', 'dropped_trials'), dropped_trials) np.save(pjoin(RES_PATH, 'Group', 'dropped_components'), dropped_components) # Save out second round of FOOOFing for load_label in LOAD_LABELS: for side_label in SIDE_LABELS: for seg_label in SEG_LABELS: fg = combine_fooofs(fg_dict[load_label][side_label][seg_label]) fg.save('Group_' + load_label + '_' + side_label + '_' + seg_label, pjoin(RES_PATH, 'FOOOF'), save_results=True)
def main(): # Initialize fg # TODO: add any settings we want to ue fg = FOOOFGroup(peak_width_limits=[1, 6], min_peak_amplitude=0.075, max_n_peaks=6, peak_threshold=1, verbose=False) # Save out a settings file fg.save(file_name=GROUP + '_fooof_group_settings', file_path=SAVE_PATH, save_settings=True) # START LOOP for sub in SUBJ_DAT_NUM: print('Current Subject' + str(sub)) # load subject data subj_dat_fname = str(sub) + "_resampled.set" full_path = os.path.join(BASE_PATH, subj_dat_fname) path_check = Path(full_path) if path_check.is_file(): eeg_dat = mne.io.read_raw_eeglab(full_path, event_id_func=None, preload=True) evs = mne.io.eeglab.read_events_eeglab(full_path, EV_DICT) new_evs = np.empty(shape=(0, 3)) for ev_label in BLOCK_EVS: ev_code = EV_DICT[ev_label] temp = evs[evs[:, 2] == ev_code] new_evs = np.vstack([new_evs, temp]) eeg_dat.add_events(new_evs) # set EEG average reference eeg_dat.set_eeg_reference() ## PRE-PROCESSING: ICA if RUN_ICA: # ICA settings method = 'fastica' n_components = 0.99 random_state = 47 reject = {'eeg': 20e-4} # Initialize ICA object ica = ICA(n_components=n_components, method=method, random_state=random_state) # High-pass filter data for running ICA eeg_dat.filter(l_freq=1., h_freq=None, fir_design='firwin') # Fit ICA ica.fit(eeg_dat, reject=reject) # Find components to drop, based on correlation with EOG channels drop_inds = [] for chi in EOG_CHS: inds, scores = ica.find_bads_eog(eeg_dat, ch_name=chi, threshold=2.5, l_freq=1, h_freq=10, verbose=False) drop_inds.extend(inds) drop_inds = list(set(drop_inds)) # Set which components to drop, and collect record of this ica.exclude = drop_inds #dropped_components[s_ind, 0:len(drop_inds)] = drop_inds # Save out ICA solution ica.save(pjoin(ICA_PATH, str(sub) + '-ica.fif')) # Apply ICA to data eeg_dat = ica.apply(eeg_dat) ## EPOCH BLOCKS events = mne.find_events(eeg_dat) #epochs = mne.Epochs(eeg_dat, events=events, tmin=5, tmax=125, baseline=None, preload=True) rest_epochs = mne.Epochs(eeg_dat, events=events, event_id=REST_EVENT_ID, tmin=5, tmax=125, baseline=None, preload=True) trial_epochs = mne.Epochs(eeg_dat, events=events, event_id=TRIAL_EVENT_ID, tmin=5, tmax=125, baseline=None, preload=True) ## PRE-PROCESSING: AUTO-REJECT if RUN_AUTOREJECT: # Initialize and run autoreject across epochs ar = AutoReject(n_jobs=4, verbose=False) epochs, rej_log = ar.fit_transform(epochs, True) # Drop same trials from filtered data rest_epochs.drop(rej_log.bad_epochs) trial_epochs.drop(rej_log.bad_epochs) # Collect list of dropped trials dropped_trials[s_ind, 0:sum(rej_log.bad_epochs)] = np.where( rej_log.bad_epochs)[0] # Set montage chs = mne.channels.read_montage('standard_1020', rest_epochs.ch_names[:-1]) rest_epochs.set_montage(chs) trial_epochs.set_montage(chs) # Calculate PSDs rest_psds, rest_freqs = mne.time_frequency.psd_welch(rest_epochs, fmin=1., fmax=50., n_fft=2000, n_overlap=250, n_per_seg=500) trial_psds, trial_freqs = mne.time_frequency.psd_welch( trial_epochs, fmin=1., fmax=50., n_fft=2000, n_overlap=250, n_per_seg=500) # Setting frequency range freq_range = [3, 30] ## FOOOF the Data # Rest Data for ind, entry in enumerate(rest_psds): rest_fooof_psds = rest_psds[ind, :, :] fg.fit(rest_freqs, rest_fooof_psds, freq_range) fg.save(file_name=str(sub) + 'fooof_group_results' + str(ind), file_path=REST_SAVE_PATH, save_results=True) # Trial Data for ind, entry in enumerate(trial_psds): trial_fooof_psds = trial_psds[ind, :, :] fg.fit(trial_freqs, trial_fooof_psds, freq_range) fg.save(file_name=str(sub) + 'fooof_group_results' + str(ind), file_path=TRIAL_SAVE_PATH, save_results=True) print('Subject Saved') else: print('Current Subject' + str(sub) + ' does not exist') print(path_check) print('Pre-processing Complete')
################################################################################################### # Initialize a FOOOFGroup object, with desired settings fg = FOOOFGroup(peak_width_limits=[1, 6], min_peak_height=0.15, peak_threshold=2., max_n_peaks=6, verbose=False) # Define the frequency range to fit freq_range = [1, 30] ################################################################################################### # Fit the power spectrum model across all channels fg.fit(freqs, spectra, freq_range) ################################################################################################### # Check the overall results of the group fits fg.plot() ################################################################################################### # Plotting Topographies # --------------------- # # Now that we have our power spectrum models calculated across all channels, # let's start by plotting topographies of some of the resulting model parameters. # # To do so, we can leverage the fact that both MNE and FOOOF objects preserve data order. # So, when we calculated power spectra, our output spectra kept the channel order
def main(argv): # define data and result paths basepath = '/Users/rdgao/Documents/data/NeuroTycho/' result_basepath = '/Users/rdgao/Documents/code/research/field-echos/results/NeuroTycho/rest_anes/' datasets = [ 'Propofol/20120730PF_Anesthesia+and+Sleep_Chibi_Toru+Yanagawa_mat_ECoG128', 'Propofol/20120731PF_Anesthesia+and+Sleep_George_Toru+Yanagawa_mat_ECoG128', 'Propofol/20120802PF_Anesthesia+and+Sleep_Chibi_Toru+Yanagawa_mat_ECoG128', 'Propofol/20120803PF_Anesthesia+and+Sleep_George_Toru+Yanagawa_mat_ECoG128', 'Ketamine/20120719KT_Anesthesia+and+Sleep_Chibi_Toru+Yanagawa_mat_ECoG128', 'Ketamine/20120724KT_Anesthesia+and+Sleep_George_Toru+Yanagawa_mat_ECoG128', 'Ketamine/20120810KT_Anesthesia+and+Sleep_George_Toru+Yanagawa_mat_ECoG128', 'Ketamine/20120813KT_Anesthesia+and+Sleep_Chibi_Toru+Yanagawa_mat_ECoG128' ] sess_append = '/Session%d/' session_indices = [(1, 0, 1), (1, 2, 3), (2, 0, 1), (2, 1, 2)] session_labels = ['EyesOpen', 'EyesClosed', 'Delivery', 'Anesthesia'] if 'do_psds' in argv: for ds in datasets: print('------\n', ds) for i in range(len(session_indices)): session = session_indices[i] outfile = str(i) + '_' + (session_labels[i] + '_' + ds).replace('/', '_').replace( '+', '_') print(outfile) # grab ECoG data indices = access_nt.get_cond(data_path + ds + sess_append, session[0], session[1], session[2]) data = access_nt.get_ECoG(data_path + ds + sess_append, session[0], range(1, 129), indices) fs = 1000. # compute PSDs psd_path = result_basepath + outfile + '/psd/' # 1Hz resolution psd saveout_path = utils.makedir(psd_path, '/1sec/', timestamp=False) nperseg, noverlap, f_lim, spg_outlier_pct = int(fs), int( fs / 2), 200., 5 f_axis, psd_mean = ndsp.spectral.compute_spectrum( data, fs, method='mean', nperseg=nperseg, noverlap=noverlap, f_lim=f_lim, spg_outlier_pct=spg_outlier_pct) f_axis, psd_med = ndsp.spectral.compute_spectrum( data, fs, method='median', nperseg=nperseg, noverlap=noverlap, f_lim=f_lim, spg_outlier_pct=spg_outlier_pct) save_dict = dict((name, eval(name)) for name in [ 'f_axis', 'psd_mean', 'psd_med', 'nperseg', 'noverlap', 'fs', 'spg_outlier_pct' ]) np.savez(file=saveout_path + 'psd.npz', **save_dict) # 0.2Hz resolution psd saveout_path = utils.makedir(psd_path, '/5sec/', timestamp=False) nperseg, noverlap, f_lim, spg_outlier_pct = int(fs * 5), int( fs * 4), 200., 5 f_axis, psd_mean = ndsp.spectral.compute_spectrum( data, fs, method='mean', nperseg=nperseg, noverlap=noverlap, f_lim=f_lim, spg_outlier_pct=spg_outlier_pct) f_axis, psd_med = ndsp.spectral.compute_spectrum( data, fs, method='median', nperseg=nperseg, noverlap=noverlap, f_lim=f_lim, spg_outlier_pct=spg_outlier_pct) save_dict = dict((name, eval(name)) for name in [ 'f_axis', 'psd_mean', 'psd_med', 'nperseg', 'noverlap', 'fs', 'spg_outlier_pct' ]) np.savez(file=saveout_path + 'psd.npz', **save_dict) if 'do_fooof' in argv: fooof_settings = [['knee', 3, (1, 70)], ['fixed', 3, (1, 70)], ['fixed', 1, (1, 10)], ['fixed', 1, (30, 70)]] session_resultpath = [ result_basepath + f + '/' for f in os.listdir(result_basepath) if os.path.isdir(result_basepath + f) ] print('FOOOFing...') for s in session_resultpath: for psd_win in ['1sec/', '5sec/']: psd_folder = s + '/psd/' + psd_win psd_data = np.load(psd_folder + 'psd.npz') for f_s in fooof_settings: # fit to mean and median psd for psd_mode in ['psd_mean', 'psd_med']: fg = FOOOFGroup(aperiodic_mode=f_s[0], max_n_peaks=f_s[1]) fg.fit(psd_data['f_axis'], psd_data[psd_mode], freq_range=f_s[2]) fooof_savepath = utils.makedir(psd_folder, '/fooof/' + psd_mode + '/', timestamp=False) fg.save('fg_%s_%ipks_%i-%iHz' % (f_s[0], f_s[1], f_s[2][0], f_s[2][1]), fooof_savepath, save_results=True, save_settings=True) print('Done.')
allexps = [] alloffset = [] if not (j > (i + 2)): pass else: for k in range(1, patientcount + 1): freqs = freq_nparray[k - 1] psds = psds_nparray[k - 1] # ^Note: this also explicitly enforces type as float (type casts to float64, instead of float32) # This is not strictly necessary for fitting, but is for saving out as json from FOOOF, if you want to do that fg = FOOOFGroup(peak_threshold=15, peak_width_limits=[3.0, 14.0 ]) #, aperiodic_mode='knee' #fg.report(freqs, psds, [1, 290]) #fg.fit(freqs,psds,[0.2,290]) fg.fit(freqs, psds, [i, j]) #this was all i could think of... ;_; #fg.plot() #reportname = str(k) + '_indiv result' #fg.save_report(reportname) #print(fg.group_results) exps = fg.get_params('aperiodic_params', 'exponent') allexps.append(exps) offset = fg.get_params('aperiodic_params', 'offset') alloffset.append(offset) #ok, so for each range, we have 16 sets ofx exponents and 16 sets of y offsets. exp_r2 = 0 off_r2 = 0
def main(): ## Individual Model Plot # Download examples data files needed for this example freqs = load_fooof_data('freqs.npy', folder='data') spectrum = load_fooof_data('spectrum.npy', folder='data') # Initialize and fit an example power spectrum model fm = FOOOF(peak_width_limits=[1, 6], max_n_peaks=6, min_peak_height=0.2, verbose=False) fm.fit(freqs, spectrum, [3, 40]) # Save out the report fm.save_report('FOOOF_report.png', 'img') ## Group Plot # Download examples data files needed for this example freqs = load_fooof_data('group_freqs.npy', folder='data') spectra = load_fooof_data('group_powers.npy', folder='data') # Initialize and fit a group of example power spectrum models fg = FOOOFGroup(peak_width_limits=[1, 6], max_n_peaks=6, min_peak_height=0.2, verbose=False) fg.fit(freqs, spectra, [3, 30]) # Save out the report fg.save_report('FOOOFGroup_report.png', 'img') ## Make the icon plot # Simulate an example power spectrum fs, ps = gen_power_spectrum([4, 35], [0, 1], [[10, 0.3, 1], [22, 0.15, 1.25]], nlv=0.01) def custom_style(ax, log_freqs, log_powers): """Custom styler-function for the icon plot.""" # Set the top and right side frame & ticks off ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # Set linewidth of remaining spines ax.spines['left'].set_linewidth(10) ax.spines['bottom'].set_linewidth(10) ax.set_xticks([], []) ax.set_yticks([], []) # Create and save out the plot plot_spectrum(fs, ps, log_freqs=False, log_powers=True, lw=12, alpha=0.8, color='grey', plot_style=custom_style, ax=check_ax(None, [6, 6])) plt.tight_layout() plt.savefig('img/spectrum.png') ## Clean Up # Remove the data folder shutil.rmtree('data')