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(verbose=False) tfg.fit(xs, ys) return tfg
# Create some new settings for simulating a group of power spectra n_spectra = 2 freq_range = [3, 40] nlv = 0.02 # Aperiodic params: define values for each spectrum, with length equal to n_spectra aperiodic_params = [[0.5, 1], [1, 1.5]] # Periodic parameters: define a single definition, to be applied to all spectra periodic_params = [10, 0.4, 1] ################################################################################################### # Simulate a group of power spectra freqs, powers = gen_group_power_spectra(n_spectra, freq_range, aperiodic_params, periodic_params, nlv) ################################################################################################### # Plot the power spectra that were just generated plot_spectra(freqs, powers, log_freqs=True, log_powers=True) ################################################################################################### # Tracking Simulation Parameters # ------------------------------ # # When you start simulating multiple power spectra across different parameters, # you may want to keep track of these parameters, so that you can compare any measure # taken on these power spectra to ground truth values. # # When simulating power spectra, you also have the option of returning SimParams objects
# each successive entry is used to generate each successive power spectrum, or # a function or generator that can be called to return parameters for each spectrum. # ################################################################################################### # Create some new settings for simulating a group of power spectra n_spectra = 2 freq_range = [3, 40] ap_params = [[0.5, 1], [1, 1.5]] gauss_params = [10, 0.4, 1] nlv = 0.02 ################################################################################################### # Simulate a group of power spectra fs, ps, sim_params = gen_group_power_spectra(n_spectra, freq_range, ap_params, gauss_params, nlv) ################################################################################################### # Plot the power spectra that were just generated plot_spectra(fs, ps, log_freqs=True, log_powers=True) ################################################################################################### # # Note that when you simulate a group of power spectra, FOOOF returns SimParam objects that # keep track of the simulations. This, and other utilties to manage parameters and provide # parameter definitions for simulating groups of power spectra are covered in the # `Simulated Parameters` example. #
################################################################################################### # Settings & parameters for the simulations freq_range = [3, 30] ap_params = [1, 1] # Simulate a single 10 Hz centered alpha freqs_al10, powers_al10 = gen_power_spectrum(freq_range, ap_params, [10, 0.25, 1], nlv=0) # Simulate spectra stepping across alpha center frequency cf_steps = Stepper(8, 12.5, 0.5) freqs_al, powers_al = gen_group_power_spectra(len(cf_steps), freq_range, ap_params, param_iter([cf_steps, 0.25, 1])) ################################################################################################### # Create the plot, plotting onto the same axes object fig, ax = plt.subplots(figsize=[12, 8]) plot_spectra_shading(freqs_al, powers_al, [8, 12], log_powers=True, alpha=0.6, ax=ax) plot_spectra(freqs_al10, powers_al10, log_powers=True, color='black',
# `examples <https://fooof-tools.github.io/fooof/auto_examples/index.html>`_ section. # ################################################################################################### # Simulation settings for a group of power spectra n_spectra = 10 sim_freq_range = [3, 50] nlv = 0.010 # Set the parameter options for aperiodic component and peaks ap_opts = param_sampler([[20, 2], [50, 2.5], [35, 1.5]]) gauss_opts = param_sampler([[], [10, 0.5, 2], [10, 0.5, 2, 20, 0.3, 4]]) # Simulate a group of power spectra freqs, power_spectra = gen_group_power_spectra(n_spectra, sim_freq_range, ap_opts, gauss_opts, nlv) ################################################################################################### # Initialize a FOOOFGroup object fg = FOOOFGroup(peak_width_limits=[1, 6]) ################################################################################################### # Fit power spectrum models and report on the group fg.report(freqs, power_spectra) ################################################################################################### # # In the :class:`~fooof.FOOOFGroup` report we can get a sense of the overall performance # by looking at the information about the goodness of fit metrics, and also things like
# Define the frequency range for our simulations freq_range = [1, 50] # Define aperiodic parameters for each group, with some variation g1_aps = param_jitter([1, 1.25], [0.5, 0.2]) g2_aps = param_jitter([1, 1.00], [0.5, 0.2]) # Define periodic parameters for each group, with some variation g1_peaks = param_jitter([11, 1, 0.5], [0.5, 0.2, 0.2]) g2_peaks = param_jitter([9, 1, 0.5], [0.25, 0.1, 0.3]) ################################################################################################### # Simulate some test data, as two groups of power spectra freqs, powers1 = gen_group_power_spectra(n_subjs, freq_range, g1_aps, g1_peaks) freqs, powers2 = gen_group_power_spectra(n_subjs, freq_range, g2_aps, g2_peaks) ################################################################################################### # 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)
from fooof.sim.params import param_sampler ################################################################################################### # Settings for creating simulated data n_spectra = 10 freq_range = [3, 40] ap_opts = param_sampler([[0, 1.0], [0, 1.5], [0, 2]]) gauss_opts = param_sampler([[], [10, 1, 1], [10, 1, 1, 20, 2, 1]]) ################################################################################################### # Generate some simulated power spectra, and organize into a 3D matrix spectra = [] for ind in range(3): fs, ps, _ = gen_group_power_spectra(n_spectra, freq_range, ap_opts, gauss_opts) spectra.append(ps) spectra = np.array(spectra) ################################################################################################### # Check the shape of the spectra # This kind of 3D organization can be thought to represent [n_conditions, n_channels, n_freqs] print(spectra.shape) ################################################################################################### # fit_fooof_group_3d # ------------------ # # The :func:`fit_fooof_group_3d` is a function that takes in a FOOOFGroup object, # which has been initialized with the desired settings, as well as a frequency
n_conditions = 3 n_channels = 10 n_freqs = len(gen_freqs(freq_range, freq_res)) # Define parameters for the simulated power spectra ap_opts = param_sampler([[0, 1.0], [0, 1.5], [0, 2]]) pe_opts = param_sampler([[], [10, 0.25, 1], [10, 0.25, 1, 20, 0.15, 1]]) ################################################################################################### # Generate some simulated power spectra, and organize into a 3D array spectra = [] for ind in range(n_conditions): freqs, powers = gen_group_power_spectra(n_channels, freq_range, ap_opts, pe_opts, freq_res=freq_res) spectra.append(powers) # Convert collected spectra into a numpy array spectra = np.array(spectra) ################################################################################################### # Check the shape of the spectra # Note that this should reflect [n_conditions, n_channels, n_freqs] print('Shape of the spectra object: \t\t\t{}, {}, {}'.format(*spectra.shape)) print('Number of conditions, channels & frequencies: \t{}, {}, {}'.format(\ n_conditions, n_channels, n_freqs))
################################################################################################### # Simulate and Fit Group Data # ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # We will also simulate and fit some additional example data. # ################################################################################################### # Set random seed, for consistency generating simulated data set_random_seed(21) # Generate some simulated power spectra freqs, spectra = gen_group_power_spectra( n_spectra=10, freq_range=[3, 40], aperiodic_params=param_sampler([[20, 2], [35, 1.5]]), periodic_params=param_sampler([[], [10, 0.5, 2]])) ################################################################################################### # Initialize a FOOOFGroup object with some settings fg = FOOOFGroup(peak_width_limits=[1, 8], min_peak_height=0.05, max_n_peaks=6, verbose=False) # Fit power spectrum models across the group of simulated power spectra fg.fit(freqs, spectra) ###################################################################################################
gauss_opts = param_sampler([[], [10, 0.5, 2], [10, 0.5, 2, 20, 0.3, 4]]) ################################################################################################### # # We can now feed these settings into :func:`gen_group_power_spectra`, # that will generate a group of power spectra for us. # # Note that this function also returns a list of the parameters # used to generate each power spectrum. # ################################################################################################### # Simulate the group of simulated spectra # Note that this function also returns a list of the parameters for each func freqs, spectra, sim_params = gen_group_power_spectra(n_spectra, f_range, ap_opts, gauss_opts) ################################################################################################### # FOOOFGroup # ---------- # # The FOOOFGroup object is very similar to the FOOOF object (programmatically, it inherits # from the FOOOF object), and can be used in the same way. # # The main difference is that instead of running across a single power spectrum, it # operates across 2D matrices containing multiple power spectra. # # Note that by 'group' we mean merely to refer to a group of power-spectra, # not necessarily to a group in terms of multiple subjects or similar. # Most likely, a FOOOFGroup will be run across a collection of spectra from across # channels, and/or across trials, within or across subjects.
# Check reconstructed parameters from simulated definition print('Ground Truth \t\t FOOOF Reconstructions') for sy, fi in zip(np.array(group_three(gauss_params)), fm.gaussian_params_): print('{:5.2f} {:5.2f} {:5.2f} \t {:5.2f} {:5.2f} {:5.2f}'.format( *sy, *fi)) ################################################################################################### # Checking Fits Across a Group # ---------------------------- # Set the parameters options for aperiodic signal and Gaussian peaks ap_opts = param_sampler([[20, 2], [50, 2.5], [35, 1.5]]) gauss_opts = param_sampler([[], [10, 0.5, 2], [10, 0.5, 2, 20, 0.3, 4]]) # Simulate a group of power spectra freqs, power_spectra, sim_params = gen_group_power_spectra( 10, [3, 50], ap_opts, gauss_opts) ################################################################################################### # Initialize a FOOOFGroup fg = FOOOFGroup(peak_width_limits=[1, 6]) ################################################################################################### # Fit FOOOF and report on the group fg.report(freqs, power_spectra) ################################################################################################### # Find the index of the worst FOOOF fit from the group worst_fit_ind = np.argmax(fg.get_params('error'))
# - ``nlv`` # ################################################################################################### # Set up settings for simulating a group of power spectra n_spectra = 2 freq_range = [3, 40] ap_params = [[0.5, 1], [1, 1.5]] pe_params = [[10, 0.4, 1], [10, 0.2, 1, 22, 0.1, 3]] nlv = 0.02 ################################################################################################### # Simulate a group of power spectra freqs, powers, sim_params = gen_group_power_spectra(n_spectra, freq_range, ap_params, pe_params, nlv, return_params=True) ################################################################################################### # Print out the SimParams objects that track the parameters used to create power spectra for sim_param in sim_params: print(sim_param) ################################################################################################### # You can also use a SimParams object to regenerate a particular power spectrum cur_params = sim_params[0] freqs, powers = gen_power_spectrum(freq_range, *cur_params) ################################################################################################### # Managing Parameters
# - `nlv` # ################################################################################################### # Set up settings for simulating a group of power spectra n_spectra = 2 freq_range = [3, 40] ap_params = [[0.5, 1], [1, 1.5]] gauss_params = [[10, 0.4, 1], [10, 0.2, 1, 22, 0.1, 3]] nlv = 0.02 ################################################################################################### # Simulate a group of power spectra fs, ps, sim_params = gen_group_power_spectra(n_spectra, freq_range, ap_params, gauss_params, nlv) ################################################################################################### # Print out the SimParams objects that track the parameters used to create power spectra for sim_param in sim_params: print(sim_param) ################################################################################################### # You can also use a SimParams object to regenerate a particular power spectrum cur_params = sim_params[0] fs, ps = gen_power_spectrum(freq_range, *cur_params) ################################################################################################### # Managing Parameters
Use the plots available with FOOOF. """ ################################################################################################### # Import FOOOF plotting functions from fooof.plts.spectra import plot_spectrum, plot_spectra from fooof.plts.spectra import plot_spectrum_shading, plot_spectra_shading ################################################################################################### # Create a couple simulated power spectra to explore plotting with # Here we create two spectra, with different aperiodic components # but each with the same oscillations (a theta, alpha & beta) from fooof.sim.gen import gen_group_power_spectra fs, ps, _ = gen_group_power_spectra(2, [3, 40], [[0.75, 1.5], [0.25, 1]], [6, 0.2, 1, 10, 0.3, 1, 25, 0.15, 3]) ps1, ps2 = ps ################################################################################################### # The FOOOF plotting module has plots for plotting single or multiple # power spectra, options for plotting in linear or log space, and # plots for shading frequency regions of interest. # # Plotting in FOOOF uses matplotlib. Plotting functions can also take in any # matplotlib keyword arguments, that will be passed into the plot call. ################################################################################################### # Create a spectrum plot with a single power spectrum plot_spectrum(fs, ps2, log_powers=True)
# Model fit failures are rare, and they typically only happen on spectra that are # particular noisy, and/or are some kind of outlier for which the fitting procedure # fails to find a good model solution. # # In general, model fit failures should lead to a clean exit, meaning that # a failed model fit does not lead to a code error. The failed fit will be encoded in # the results as a null model, and the code can continue onwards. # # In this example, we will look through what it looks like when model fits fail. # ################################################################################################### # 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.
print('FOOOF model fit error: \t\t {:1.3f}'.format(fm.error_)) ################################################################################################### # Checking the Error Across Groups of Model Fits # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Next, lets move on to calculating frequency-by-frequency error across groups of fits, # again using some simulated data. # # To analyze error from a FOOOFGroup object, use :func:`~.compute_pointwise_error_fg`. # ################################################################################################### # Simulate a group of power spectra freqs, powers = gen_group_power_spectra(10, [3, 50], [1, 1], [10, 0.3, 1], nlvs=0.1) ################################################################################################### # Initialize a FOOOFGroup object to fit fg = FOOOFGroup(min_peak_height=0.25, verbose=False) ################################################################################################### # Parameterize our group of power spectra fg.fit(freqs, powers) ################################################################################################### # # Just as before, we can plot and/or return the error. #