def test_fooof_checks(): """Test various checks, errors and edge cases in FOOOF.""" xs, ys = gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2]) tfm = FOOOF(verbose=False) # Check dimension error with raises(ValueError): tfm.fit(xs, np.reshape(ys, [1, len(ys)])) # Check shape mismatch error with raises(ValueError): tfm.fit(xs[:-1], ys) # Check wrong data type error with raises(ValueError): tfm.fit(list(xs), list(ys)) # Check trim_spectrum range tfm.fit(xs, ys, [3, 40]) # Check freq of 0 issue xs, ys = gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2]) tfm.fit(xs, ys) assert tfm.freqs[0] != 0 # Check fit, and string report model error (no data / model fit) tfm = FOOOF(verbose=False) with raises(ValueError): tfm.fit()
def test_fooof_fit_failure(): """Test FOOOF fit failures.""" ## Induce a runtime error, and check it runs through tfm = FOOOF(verbose=False) tfm._maxfev = 5 tfm.fit(*gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2, 20, 0.3, 4])) # Check after failing out of fit, all results are reset for result in OBJ_DESC['results']: assert np.all(np.isnan(getattr(tfm, result))) ## Monkey patch to check errors in general # This mimics the main fit-failure, without requiring bad data / waiting for it to fail. tfm = FOOOF(verbose=False) def raise_runtime_error(*args, **kwargs): raise FitError('Test-MonkeyPatch') tfm._fit_peaks = raise_runtime_error # Run a FOOOF fit - this should raise an error, but continue in try/except tfm.fit(*gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2, 20, 0.3, 4])) # Check after failing out of fit, all results are reset for result in OBJ_DESC['results']: assert np.all(np.isnan(getattr(tfm, result)))
def test_fooof_checks(): """Test various checks, errors and edge cases in FOOOF. This tests all the input checking done in `_prepare_data`. """ xs, ys = gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2]) tfm = FOOOF(verbose=False) ## Check checks & errors done in `_prepare_data` # Check wrong data type error with raises(DataError): tfm.fit(list(xs), list(ys)) # Check dimension error with raises(DataError): tfm.fit(xs, np.reshape(ys, [1, len(ys)])) # Check shape mismatch error with raises(InconsistentDataError): tfm.fit(xs[:-1], ys) # Check complex inputs error with raises(DataError): tfm.fit(xs, ys.astype('complex')) # Check trim_spectrum range tfm.fit(xs, ys, [3, 40]) # Check freq of 0 issue xs, ys = gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2]) tfm.fit(xs, ys) assert tfm.freqs[0] != 0 # Check error if there is a post-logging inf or nan with raises(DataError): # Double log (1) -> -inf tfm.fit(np.array([1, 2, 3]), np.log10(np.array([1, 2, 3]))) with raises(DataError): # Log (-1) -> NaN tfm.fit(np.array([1, 2, 3]), np.array([-1, 2, 3])) ## Check errors & errors done in `fit` # Check fit, and string report model error (no data / model fit) tfm = FOOOF(verbose=False) with raises(NoDataError): tfm.fit()
def test_fooof_report(skip_if_no_mpl): """Check that running the top level model method runs.""" tfm = FOOOF(verbose=False) tfm.report(*gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2, 20, 0.3, 4])) assert tfm
def test_fooof_debug(): """Test FOOOF in debug mode, including with fit failures.""" tfm = FOOOF(verbose=False) tfm._maxfev = 5 tfm.set_debug_mode(True) assert tfm._debug is True with raises(FitError): tfm.fit(*gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2, 20, 0.3, 4]))
def test_fooof_fit_knee(): """Test FOOOF fit, with a knee.""" ap_params = [50, 2, 1] gaussian_params = [10, 0.5, 2, 20, 0.3, 4] xs, ys = gen_power_spectrum([3, 50], ap_params, gaussian_params) tfm = FOOOF(aperiodic_mode='knee', verbose=False) tfm.fit(xs, ys) # Note: currently, this test has no accuracy checking at all assert True
def test_fooof_fit_nk_noise(): """Test FOOOF fit on noisy data, to make sure nothing breaks.""" ap_params = [50, 2] gauss_params = [10, 0.5, 2, 20, 0.3, 4] nlv = 1.0 xs, ys = gen_power_spectrum([3, 50], ap_params, gauss_params, nlv) tfm = FOOOF(max_n_peaks=8, verbose=False) tfm.fit(xs, ys) # No accuracy checking here - just checking that it ran assert tfm.has_model
def test_fooof_fit_knee(): """Test FOOOF fit, with a knee.""" ap_params = [50, 10, 1] gauss_params = [10, 0.3, 2, 20, 0.1, 4, 60, 0.3, 1] nlv = 0.0025 xs, ys = gen_power_spectrum([1, 150], ap_params, gauss_params, nlv) tfm = FOOOF(aperiodic_mode='knee', verbose=False) tfm.fit(xs, ys) # Check model results - aperiodic parameters assert np.allclose(ap_params, tfm.aperiodic_params_, [1, 2, 0.2]) # Check model results - gaussian parameters for ii, gauss in enumerate(group_three(gauss_params)): assert np.allclose(gauss, tfm.gaussian_params_[ii], [2.0, 0.5, 1.0])
def test_fooof_fit_nk(): """Test FOOOF fit, no knee.""" ap_params = [50, 2] gauss_params = [10, 0.5, 2, 20, 0.3, 4] nlv = 0.0025 xs, ys = gen_power_spectrum([3, 50], ap_params, gauss_params, nlv) tfm = FOOOF(verbose=False) tfm.fit(xs, ys) # Check model results - aperiodic parameters assert np.allclose(ap_params, tfm.aperiodic_params_, [0.5, 0.1]) # Check model results - gaussian parameters for ii, gauss in enumerate(group_three(gauss_params)): assert np.allclose(gauss, tfm.gaussian_params_[ii], [2.0, 0.5, 1.0])
def test_fooof_fit_failure(): """Test that fit handles a failure.""" # Use a new FOOOF, that is monkey-patched to raise an error # This mimicks the main fit-failure, without requiring bad data / waiting for it to fail. tfm = FOOOF(verbose=False) def raise_runtime_error(*args, **kwargs): raise RuntimeError('Test-MonkeyPatch') tfm._fit_peaks = raise_runtime_error # Run a FOOOF fit - this should raise an error, but continue in try/except tfm.fit(*gen_power_spectrum([3, 50], [50, 2], [10, 0.5, 2, 20, 0.3, 4])) # Check after failing out of fit, all results are reset for result in get_description()['results']: cur_res = getattr(tfm, result) assert cur_res is None or np.all(np.isnan(cur_res))