diff --git a/CHANGELOG.rst b/CHANGELOG.rst index de45c72..df53638 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,29 @@ Changelog ========= +Version 0.1.6 +============= +- Changes + - Feature ``total energy`` changed name to ``average power`` + - Features ``peak to peak``, ``absolute energy`` and ``entropy`` are now classified as statistical + +- Bugfixes + - Fixed a bug on numpy bool usage (`#133 `_) + - Fixed a bug on features' header names + +- Improvements + - Correlated features are now computed using absolute value + - Unit tests improvements + - Refactoring of some code sections and overall improved stability + + +Version 0.1.5 +============= +- Bugfixes + - Fixed a bug on scipy function median_absolute_deviation to median_abs_deviation (`#128 `_) + - Fixed on pandas function df.append to pd.concat (`#120 `_) + + Version 0.1.4 ============= - Bugfixes diff --git a/README.md b/README.md index 93f9c15..a120d19 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,12 @@ X = tsfel.time_series_features_extractor(cfg, df) #### Statistical domain | Features | Computational Cost | |----------------------------|:------------------:| +| Absolute energy | 1 | +| Average power | 1 | | ECDF | 1 | | ECDF Percentile | 1 | | ECDF Percentile Count | 1 | +| Entropy | 1 | | Histogram | 1 | | Interquartile range | 1 | | Kurtosis | 1 | @@ -72,11 +75,9 @@ X = tsfel.time_series_features_extractor(cfg, df) #### Temporal domain | Features | Computational Cost | |----------------------------|:------------------:| -| Absolute energy | 1 | | Area under the curve | 1 | | Autocorrelation | 1 | | Centroid | 1 | -| Entropy | 1 | | Mean absolute diff | 1 | | Mean diff | 1 | | Median absolute diff | 1 | @@ -87,7 +88,6 @@ X = tsfel.time_series_features_extractor(cfg, df) | Signal distance | 1 | | Slope | 1 | | Sum absolute diff | 1 | -| Total energy | 1 | | Zero crossing rate | 1 | | Neighbourhood peaks | 1 | diff --git a/notebooks/TSFEL_HAR_Example.ipynb b/notebooks/TSFEL_HAR_Example.ipynb index 585783e..8b5c403 100644 --- a/notebooks/TSFEL_HAR_Example.ipynb +++ b/notebooks/TSFEL_HAR_Example.ipynb @@ -184,11 +184,7 @@ "source": [ "# Feature Extraction\n", "\n", - "Through **Feature Extraction** methodologies, the data is translated into a feature vector containing information about the signal properties of each window. These properties can be classified according to their domain as Time, Frequency and Statistical features and allow to characterise the signal compactly, enhancing its characteristics. This features will be used as input to the machine learning classifier, thus, the chosen set of features can strongly influence the classification output.\n", - "\n", - "The features to extract are defined in the [google sheet](https://docs.google.com/spreadsheets/d/13u7L_5IX3XxFuq_SnbOZF1dXQfcBB0wR3PXhvevhPYA/edit?usp=sharing). Save a copy on your local drive and share it with featext@featext.iam.gserviceaccount.com.\n", - "\n", - "**Change your google sheet file name and the googleSheet_name variable to your name so both have the same name.**" + "Through **Feature Extraction** methodologies, the data is translated into a feature vector containing information about the signal properties of each window. These properties can be classified according to their domain as Time, Frequency and Statistical features and allow to characterise the signal compactly, enhancing its characteristics. This features will be used as input to the machine learning classifier, thus, the chosen set of features can strongly influence the classification output." ] }, { @@ -279,9 +275,10 @@ ], "source": [ "#@title Feature Extraction\n", - "googleSheet_name = \"Features_dev\"\n", - "# Extract excel info\n", - "cfg_file = tsfel.extract_sheet(googleSheet_name)\n", + "cfg_file = tsfel.get_features_by_domain() # All features \n", + "# cfg_file = tsfel.get_features_by_domain('statistical') # Only statistical features\n", + "# cfg_file = tsfel.get_features_by_domain('temporal') # Only temporal features\n", + "# cfg_file = tsfel.get_features_by_domain('spectral') # Only spectral features\n", "\n", "# Get features\n", "X_train = tsfel.time_series_features_extractor(cfg_file, x_train_sig, fs=fs)\n", @@ -461,7 +458,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.5" + "version": "3.6.9" } }, "nbformat": 4, diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt new file mode 100644 index 0000000..410dbbb --- /dev/null +++ b/requirements/requirements-dev.txt @@ -0,0 +1 @@ +pre-commit==2.17.0 \ No newline at end of file diff --git a/requirements/requirements-docs.txt b/requirements/requirements-docs.txt new file mode 100644 index 0000000..0ae564f --- /dev/null +++ b/requirements/requirements-docs.txt @@ -0,0 +1 @@ +Sphinx >= 1.8.5 \ No newline at end of file diff --git a/requirements/requirements-test.txt b/requirements/requirements-test.txt new file mode 100644 index 0000000..3a12ad6 --- /dev/null +++ b/requirements/requirements-test.txt @@ -0,0 +1,2 @@ +nose==1.3.7 +pytest==7.1.1 \ No newline at end of file diff --git a/requirements.txt b/requirements/requirements.txt similarity index 79% rename from requirements.txt rename to requirements/requirements.txt index 7a83ef1..188cebe 100644 --- a/requirements.txt +++ b/requirements/requirements.txt @@ -1,11 +1,5 @@ # Automatically generated by https://github.com/damnever/pigar. -# tsfel/docs/conf.py: 23 -Sphinx >= 1.8.5 - -# tsfel/utils/gSheetsFilters.py: 4 -gspread >= 3.1.0 - # tsfel/feature_extraction/calc_features.py: 15,16 # tsfel/utils/progress_bar.py: 1,2 ipython >= 7.4.0 @@ -13,13 +7,9 @@ ipython >= 7.4.0 # tsfel/feature_extraction/calc_features.py: 12 # tsfel/feature_extraction/features_utils.py: 2 # tsfel/utils/calculate_complexity.py: 3 -# tsfel/utils/gSheetsFilters.py: 5 # tsfel/utils/signal_processing.py: 1 numpy >= 1.18.5 -# tsfel/utils/gSheetsFilters.py: 6 -oauth2client >= 4.1.3 - # tsfel/feature_extraction/calc_features.py: 13 # tsfel/utils/signal_processing.py: 2 pandas >= 1.5.3 diff --git a/setup.py b/setup.py index 116c60e..39a7e73 100644 --- a/setup.py +++ b/setup.py @@ -1,30 +1,43 @@ import setuptools +from pathlib import Path +ROOT = Path(__file__).parent with open("README.md", "r") as fh: long_description = fh.read() -with open('requirements.txt', 'r') as f: - install_reqs = [ - s for s in [ - line.strip(' \n') for line in f - ] if not s.startswith('#') and s != '' - ] + +def find_requirements(filename): + with (ROOT / "requirements" / filename).open() as f: + return [ + s + for s in [line.strip(" \n") for line in f] + if not s.startswith("#") and s != "" + ] + + +install_reqs = find_requirements("requirements.txt") +docs_require = find_requirements("requirements-docs.txt") setuptools.setup( name="tsfel", - version="0.1.5", + version="0.1.6", author="Fraunhofer Portugal", description="Library for time series feature extraction", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/fraunhoferportugal/tsfel/", - package_data={'tsfel': ['feature_extraction/features.json', 'utils/client_secret.json']}, + package_data={ + "tsfel": ["feature_extraction/features.json"] + }, packages=setuptools.find_packages(), classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", ], - install_requires=install_reqs + install_requires=install_reqs, + extras_require={ + "docs": docs_require, + }, ) diff --git a/tests/test_calc_features.py b/tests/test_calc_features.py index 29e705a..74b4ea4 100644 --- a/tests/test_calc_features.py +++ b/tests/test_calc_features.py @@ -1,66 +1,98 @@ import os import json import glob -import tsfel +# import tsfel import pandas as pd from pathlib import Path - +from tsfel.feature_extraction.features_settings import get_features_by_domain, get_features_by_tag +from tsfel.feature_extraction.calc_features import time_series_features_extractor, dataset_features_extractor +from tsfel.utils.signal_processing import merge_time_series, signal_window_splitter +from tsfel.utils.add_personal_features import add_feature_json # Example of user preprocess sensor data def pre_process(sensor_data): - if 'Accelerometer' in sensor_data: - sensor_data['Accelerometer'].iloc[:, 1] = sensor_data['Accelerometer'].iloc[:, 1] * 0 + if "Accelerometer" in sensor_data: + sensor_data["Accelerometer"].iloc[:, 1] = sensor_data["Accelerometer"].iloc[:, 1] * 10 return sensor_data # DATASET DIR -main_directory = "tests" + os.sep + "tests_tools" + os.sep + "test_dataset" + os.sep +main_directory = os.path.join("tests", "tests_tools", "test_dataset", "") # JSON DIR -tsfel_path_json = tsfel.__path__[0] + os.sep + 'feature_extraction' + os.sep + 'features.json' -personal_path_json = 'tests' + os.sep + 'tests_tools' + os.sep + 'test_features.json' -personal_features_path = 'tests' + os.sep + "tests_tools" + os.sep + "test_personal_features.py" +# tsfel_path_json = tsfel.__path__[0] + os.sep + "feature_extraction" + os.sep + "features.json" +personal_path_json = os.path.join("tests", "tests_tools", "test_features.json") +personal_features_path = os.path.join("tests", "tests_tools", "test_personal_features.py") # DEFAULT PARAM for testing time_unit = 1e9 # seconds resample_rate = 30 # resample sampling frequency window_size = 100 # number of points overlap = 0 # varies between 0 and 1 -search_criteria = ['Accelerometer.txt', 'Gyroscope.txt'] -output_directory = str(Path.home()) + os.sep + 'Documents' + os.sep + 'tsfel_output' + os.sep +search_criteria = ["Accelerometer.txt", "Gyroscope.txt"] +output_directory = str(Path.home()) + os.sep + "Documents" + os.sep + "tsfel_output" + os.sep sensor_data = {} -key = 'Accelerometer' +key = "Accelerometer" folders = [f for f in glob.glob(main_directory + "**/", recursive=True)] -sensor_data[key] = pd.read_csv(folders[-1] + key + '.txt', header=None) +sensor_data[key] = pd.read_csv(folders[-1] + key + ".txt", header=None) -# add personal feature -# tsfel.add_feature_json(personal_features_path, personal_path_json) # Features Dictionary -settings0 = json.load(open(tsfel_path_json)) -settings1 = json.load(open(personal_path_json)) -settings2 = tsfel.get_features_by_domain('statistical') -settings3 = tsfel.get_features_by_domain('temporal') -settings4 = tsfel.get_features_by_domain('spectral') -settings5 = tsfel.get_features_by_domain() -# settings6 = tsfel.extract_sheet('Features') -# settings7 = tsfel.extract_sheet('Features_test', path_json=personal_path_json) -settings8 = tsfel.get_features_by_tag('inertial') -settings10 = tsfel.get_features_by_tag() +# settings0 = json.load(open(tsfel_path_json)) +settings2 = get_features_by_domain("statistical") +settings3 = get_features_by_domain("temporal") +settings4 = get_features_by_domain("spectral") +settings5 = get_features_by_domain() +settings8 = get_features_by_tag("inertial") +settings10 = get_features_by_tag() # Signal processing -data_new = tsfel.merge_time_series(sensor_data, resample_rate, time_unit) -windows = tsfel.signal_window_splitter(data_new, window_size, overlap) +data_new = merge_time_series(sensor_data, resample_rate, time_unit) +data_new = data_new[data_new.columns[:-1]] +windows = signal_window_splitter(data_new, window_size, overlap) +n_jobs = 1 # time_series_features_extractor -features0 = tsfel.time_series_features_extractor(settings4, windows, fs=resample_rate) -features1 = tsfel.time_series_features_extractor(settings2, data_new, fs=resample_rate, window_size=70, overlap=0.5) -features2 = tsfel.time_series_features_extractor(settings3, windows, fs=resample_rate) + +# multi windows and multi axis +# input: list +features0 = time_series_features_extractor(settings5, windows, fs=resample_rate, n_jobs=n_jobs) + +# multiple windows and single axis +# input: np.array +features1 = time_series_features_extractor(settings5, data_new.values[:, 0], fs=resample_rate, n_jobs=n_jobs, window_size=window_size, overlap=overlap) +# input: pd.series +features2 = time_series_features_extractor(settings5, data_new.iloc[:, 0], fs=resample_rate, n_jobs=n_jobs, window_size=window_size, overlap=overlap) + +# single window and multi axis +# input: pd.DataFrame +features3 = time_series_features_extractor(settings5, data_new, fs=resample_rate, n_jobs=n_jobs) +# input: np.array +features4 = time_series_features_extractor(settings4, data_new.values, fs=resample_rate, n_jobs=n_jobs) + +# single window and single axis +# input: pd.Series +features5 = time_series_features_extractor(settings2, data_new.iloc[:, 0], fs=resample_rate, n_jobs=n_jobs) +# input: np.array +features6 = time_series_features_extractor(settings4, data_new.values[:, 0], fs=resample_rate, n_jobs=n_jobs) + +# personal features +settings1 = json.load(open(personal_path_json)) +add_feature_json(personal_features_path, personal_path_json) +features7 = time_series_features_extractor(settings1, data_new.values[:, 0], fs=resample_rate, n_jobs=n_jobs, features_path=personal_features_path) + # Dataset features extractor -data = tsfel.dataset_features_extractor(main_directory, settings1, search_criteria=search_criteria, time_unit=time_unit, - resample_rate=resample_rate, window_size=window_size, overlap=overlap, - pre_process=pre_process, output_directory=output_directory, - features_path=personal_features_path) -print('-----------------------------------OK-----------------------------------') +data = dataset_features_extractor( + main_directory, + settings4, + search_criteria=search_criteria, + time_unit=time_unit, + resample_rate=resample_rate, + window_size=window_size, + overlap=overlap, + pre_process=pre_process, + output_directory=output_directory, +) +print("-----------------------------------OK-----------------------------------") \ No newline at end of file diff --git a/tests/test_features.py b/tests/test_features.py index 464fa30..3692251 100644 --- a/tests/test_features.py +++ b/tests/test_features.py @@ -1,5 +1,9 @@ +import unittest + +import numpy as np + from tsfel.feature_extraction.features import * -from numpy.testing import run_module_suite + # Unit testing for Linux OS # Implementing signals for testing features @@ -19,925 +23,880 @@ noiseWave = wave + np.random.normal(0, 0.1, 1000) offsetWave = wave + 2 - -# ############################################### STATISTICAL FEATURES ############################################### # -def test_hist(): - np.testing.assert_almost_equal(hist(const0, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(hist(const1, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(hist(constNeg, 10, 5), (0.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(hist(constF, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0)) - np.testing.assert_almost_equal(hist(lin, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2)) - np.testing.assert_almost_equal(hist(wave, 10, 5), (0.0, 0.0, 0.0, 0.0, 499, 496, 5, 0.0, 0.0, 0.0), decimal=5) - np.testing.assert_almost_equal(hist(offsetWave, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 499, 496, 5, 0.0), decimal=5) - np.testing.assert_almost_equal(hist(noiseWave, 10, 5), (0.0, 0.0, 0.0, 48, 446, 450, 56, 0.0, 0.0, 0.0), decimal=5) - - -def test_skewness(): - np.testing.assert_almost_equal(skewness(const0), 0.0) - np.testing.assert_almost_equal(skewness(const1), 0.0) - np.testing.assert_almost_equal(skewness(constNeg), 0.0) - np.testing.assert_almost_equal(skewness(constF), 0.0) - np.testing.assert_almost_equal(skewness(lin), 0) - np.testing.assert_almost_equal(skewness(lin0), -1.0167718723297815e-16, decimal=5) - np.testing.assert_almost_equal(skewness(wave), -2.009718347115232e-17, decimal=5) - np.testing.assert_almost_equal(skewness(offsetWave), 9.043732562018544e-16, decimal=5) - np.testing.assert_almost_equal(skewness(noiseWave), -0.0004854111290521465, decimal=5) - - -def test_kurtosis(): - np.testing.assert_almost_equal(kurtosis(const0), -3) - np.testing.assert_almost_equal(kurtosis(const1), -3) - np.testing.assert_almost_equal(kurtosis(constNeg), -3) - np.testing.assert_almost_equal(kurtosis(constF), -3.0) - np.testing.assert_almost_equal(kurtosis(lin), -1.206015037593985, decimal=2) - np.testing.assert_almost_equal(kurtosis(lin0), -1.2060150375939847, decimal=2) - np.testing.assert_almost_equal(kurtosis(wave), -1.501494077162359, decimal=2) - np.testing.assert_almost_equal(kurtosis(offsetWave), -1.5014940771623597, decimal=2) - np.testing.assert_almost_equal(kurtosis(noiseWave), -1.4606204906023366, decimal=2) - - -def test_mean(): - np.testing.assert_almost_equal(calc_mean(const0), 0.0) - np.testing.assert_almost_equal(calc_mean(const1), 1.0) - np.testing.assert_almost_equal(calc_mean(constNeg), -1.0) - np.testing.assert_almost_equal(calc_mean(constF), 2.5) - np.testing.assert_almost_equal(calc_mean(lin), 9.5) - np.testing.assert_almost_equal(calc_mean(lin0), -3.552713678800501e-16, decimal=5) - np.testing.assert_almost_equal(calc_mean(wave), 7.105427357601002e-18, decimal=5) - np.testing.assert_almost_equal(calc_mean(offsetWave), 2.0, decimal=5) - np.testing.assert_almost_equal(calc_mean(noiseWave), -0.0014556635615470554, decimal=5) - - -def test_median(): - np.testing.assert_almost_equal(calc_median(const0), 0.0) - np.testing.assert_almost_equal(calc_median(const1), 1.0) - np.testing.assert_almost_equal(calc_median(constNeg), -1.0) - np.testing.assert_almost_equal(calc_median(constF), 2.5) - np.testing.assert_almost_equal(calc_median(lin), 9.5) - np.testing.assert_almost_equal(calc_median(lin0), -3.552713678800501e-16, decimal=5) - np.testing.assert_almost_equal(calc_median(wave), 7.105427357601002e-18, decimal=5) - np.testing.assert_almost_equal(calc_median(offsetWave), 2.0, decimal=5) - np.testing.assert_almost_equal(calc_median(noiseWave), 0.013846093997438328, decimal=5) - - -def test_max(): - np.testing.assert_almost_equal(calc_max(const0), 0.0) - np.testing.assert_almost_equal(calc_max(const1), 1.0) - np.testing.assert_almost_equal(calc_max(constNeg), -1.0) - np.testing.assert_almost_equal(calc_max(constF), 2.5) - np.testing.assert_almost_equal(calc_max(lin), 19) - np.testing.assert_almost_equal(calc_max(lin0), 10.0, decimal=5) - np.testing.assert_almost_equal(calc_max(wave), 1.0, decimal=5) - np.testing.assert_almost_equal(calc_max(noiseWave), 1.221757617217142, decimal=5) - np.testing.assert_almost_equal(calc_max(offsetWave), 3.0, decimal=5) - - -def test_min(): - np.testing.assert_almost_equal(calc_min(const0), 0.0) - np.testing.assert_almost_equal(calc_min(const1), 1.0) - np.testing.assert_almost_equal(calc_min(constNeg), -1.0) - np.testing.assert_almost_equal(calc_min(constF), 2.5) - np.testing.assert_almost_equal(calc_min(lin), 0) - np.testing.assert_almost_equal(calc_min(lin0), -10.0, decimal=5) - np.testing.assert_almost_equal(calc_min(wave), -1.0, decimal=5) - np.testing.assert_almost_equal(calc_min(noiseWave), -1.2582533627830566, decimal=5) - np.testing.assert_almost_equal(calc_min(offsetWave), 1.0, decimal=5) - - -def test_variance(): - np.testing.assert_almost_equal(calc_var(const0), 0.0) - np.testing.assert_almost_equal(calc_var(const1), 0.0) - np.testing.assert_almost_equal(calc_var(constNeg), 0.0) - np.testing.assert_almost_equal(calc_var(constF), 0.0) - np.testing.assert_almost_equal(calc_var(lin), 33.25) - np.testing.assert_almost_equal(calc_var(lin0), 36.84210526315789, decimal=5) - np.testing.assert_almost_equal(calc_var(wave), 0.5, decimal=5) - np.testing.assert_almost_equal(calc_var(offsetWave), 0.5, decimal=5) - np.testing.assert_almost_equal(calc_var(noiseWave), 0.5081167177369529, decimal=5) - - -def test_std(): - np.testing.assert_almost_equal(calc_std(const0), 0.0) - np.testing.assert_almost_equal(calc_std(const1), 0.0) - np.testing.assert_almost_equal(calc_std(constNeg), 0.0) - np.testing.assert_almost_equal(calc_std(constF), 0.0) - np.testing.assert_almost_equal(calc_std(lin), 5.766281297335398) - np.testing.assert_almost_equal(calc_std(lin0), 6.069769786668839, decimal=5) - np.testing.assert_almost_equal(calc_std(wave), 0.7071067811865476, decimal=5) - np.testing.assert_almost_equal(calc_std(offsetWave), 0.7071067811865476, decimal=5) - np.testing.assert_almost_equal(calc_std(noiseWave), 0.7128230620125536, decimal=5) - - -def test_interq_range(): - np.testing.assert_almost_equal(interq_range(const0), 0.0) - np.testing.assert_almost_equal(interq_range(const1), 0.0) - np.testing.assert_almost_equal(interq_range(constNeg), 0.0) - np.testing.assert_almost_equal(interq_range(constF), 0.0) - np.testing.assert_almost_equal(interq_range(lin), 9.5) - np.testing.assert_almost_equal(interq_range(lin0), 10.0, decimal=5) - np.testing.assert_almost_equal(interq_range(wave), 1.414213562373095, decimal=5) - np.testing.assert_almost_equal(interq_range(offsetWave), 1.414213562373095, decimal=5) - np.testing.assert_almost_equal(interq_range(noiseWave), 1.4277110228590328, decimal=5) - - -def test_mean_abs_diff(): - np.testing.assert_almost_equal(mean_abs_diff(const0), 0.0) - np.testing.assert_almost_equal(mean_abs_diff(const1), 0.0) - np.testing.assert_almost_equal(mean_abs_diff(constNeg), 0.0) - np.testing.assert_almost_equal(mean_abs_diff(constF), 0.0) - np.testing.assert_almost_equal(mean_abs_diff(lin), 1.0) - np.testing.assert_almost_equal(mean_abs_diff(lin0), 1.0526315789473684, decimal=5) - np.testing.assert_almost_equal(mean_abs_diff(wave), 0.019988577818740614, decimal=5) - np.testing.assert_almost_equal(mean_abs_diff(noiseWave), 0.10700252903161511, decimal=5) - np.testing.assert_almost_equal(mean_abs_diff(offsetWave), 0.019988577818740614, decimal=5) - - -def test_mean_abs_deviation(): - np.testing.assert_almost_equal(mean_abs_deviation(const0), 0.0) - np.testing.assert_almost_equal(mean_abs_deviation(const1), 0.0) - np.testing.assert_almost_equal(mean_abs_deviation(constNeg), 0.0) - np.testing.assert_almost_equal(mean_abs_deviation(constF), 0.0) - np.testing.assert_almost_equal(mean_abs_deviation(lin), 5.0) - np.testing.assert_almost_equal(mean_abs_deviation(lin0), 5.263157894736842, decimal=5) - np.testing.assert_almost_equal(mean_abs_deviation(wave), 0.6365674116287157, decimal=5) - np.testing.assert_almost_equal(mean_abs_deviation(noiseWave), 0.6392749078483896, decimal=5) - np.testing.assert_almost_equal(mean_abs_deviation(offsetWave), 0.6365674116287157, decimal=5) - - -def test_calc_median_abs_deviation(): - np.testing.assert_almost_equal(median_abs_deviation(const0), 0.0) - np.testing.assert_almost_equal(median_abs_deviation(const1), 0.0) - np.testing.assert_almost_equal(median_abs_deviation(constNeg), 0.0) - np.testing.assert_almost_equal(median_abs_deviation(constF), 0.0) - np.testing.assert_almost_equal(median_abs_deviation(lin), 5.0) - np.testing.assert_almost_equal(median_abs_deviation(lin0), 5.2631578947368425, decimal=5) - np.testing.assert_almost_equal(median_abs_deviation(wave), 0.7071067811865475, decimal=5) - np.testing.assert_almost_equal(median_abs_deviation(offsetWave), 0.7071067811865475, decimal=5) - np.testing.assert_almost_equal(median_abs_deviation(noiseWave), 0.7068117164205888, decimal=5) - - -def test_rms(): - np.testing.assert_almost_equal(rms(const0), 0.0) - np.testing.assert_almost_equal(rms(const1), 1.0) - np.testing.assert_almost_equal(rms(constNeg), 1.0) - np.testing.assert_almost_equal(rms(constF), 2.5) - np.testing.assert_almost_equal(rms(lin), 11.113055385446435) - np.testing.assert_almost_equal(rms(lin0), 6.06976978666884, decimal=5) - np.testing.assert_almost_equal(rms(wave), 0.7071067811865476, decimal=5) - np.testing.assert_almost_equal(rms(offsetWave), 2.1213203435596424, decimal=5) - np.testing.assert_almost_equal(rms(noiseWave), 0.7128245483240299, decimal=5) - - -def test_ecdf(): - np.testing.assert_almost_equal(ecdf(const0), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) - np.testing.assert_almost_equal(ecdf(const1), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) - np.testing.assert_almost_equal(ecdf(constNeg), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) - np.testing.assert_almost_equal(ecdf(constF), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) - np.testing.assert_almost_equal(ecdf(lin), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) - np.testing.assert_almost_equal(ecdf(lin0), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) - np.testing.assert_almost_equal(ecdf(wave), (0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, - 0.01)) - np.testing.assert_almost_equal(ecdf(offsetWave), (0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, - 0.01)) - np.testing.assert_almost_equal(ecdf(noiseWave), (0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, - 0.01)) - - -def test_ecdf_percentile(): - np.testing.assert_almost_equal(ecdf_percentile(const0), (0, 0)) - np.testing.assert_almost_equal(ecdf_percentile(const1), (1, 1)) - np.testing.assert_almost_equal(ecdf_percentile(constNeg), (-1, -1)) - np.testing.assert_almost_equal(ecdf_percentile(constF), (2.5, 2.5)) - np.testing.assert_almost_equal(ecdf_percentile(lin), (3, 15)) - np.testing.assert_almost_equal(ecdf_percentile(lin0), (-6.8421053, 5.7894737)) - np.testing.assert_almost_equal(ecdf_percentile(wave), (-0.809017, 0.809017)) - np.testing.assert_almost_equal(ecdf_percentile(offsetWave), (1.1909830056250523, 2.809016994374947)) - np.testing.assert_almost_equal(ecdf_percentile(noiseWave), (-0.8095410722491809, 0.796916231269631)) - - -def test_ecdf_percentile_count(): - np.testing.assert_almost_equal(ecdf_percentile_count(const0), (0, 0)) - np.testing.assert_almost_equal(ecdf_percentile_count(const1), (1, 1)) - np.testing.assert_almost_equal(ecdf_percentile_count(constNeg), (-1, -1)) - np.testing.assert_almost_equal(ecdf_percentile_count(constF), (2.5, 2.5)) - np.testing.assert_almost_equal(ecdf_percentile_count(lin), (4, 16)) - np.testing.assert_almost_equal(ecdf_percentile_count(lin0), (4, 16)) - np.testing.assert_almost_equal(ecdf_percentile_count(wave), (200, 800)) - np.testing.assert_almost_equal(ecdf_percentile_count(offsetWave), (200, 800)) - np.testing.assert_almost_equal(ecdf_percentile_count(noiseWave), (200, 800)) - - -# ################################################ TEMPORAL FEATURES ################################################# # -def test_distance(): - np.testing.assert_almost_equal(distance(const0), 19.0) - np.testing.assert_almost_equal(distance(const1), 19.0) - np.testing.assert_almost_equal(distance(constNeg), 19.0) - np.testing.assert_almost_equal(distance(constF), 19.0) - np.testing.assert_almost_equal(distance(lin), 26.87005768508881) - np.testing.assert_almost_equal(distance(lin0), 27.586228448267438, decimal=5) - np.testing.assert_almost_equal(distance(wave), 999.2461809866238, decimal=5) - np.testing.assert_almost_equal(distance(offsetWave), 999.2461809866238, decimal=5) - np.testing.assert_almost_equal(distance(noiseWave), 1007.8711901383033, decimal=5) - - -def test_negative_turning(): - np.testing.assert_almost_equal(negative_turning(const0), 0.0) - np.testing.assert_almost_equal(negative_turning(const1), 0.0) - np.testing.assert_almost_equal(negative_turning(constNeg), 0.0) - np.testing.assert_almost_equal(negative_turning(constF), 0.0) - np.testing.assert_almost_equal(negative_turning(lin), 0.0) - np.testing.assert_almost_equal(negative_turning(lin0), 0.0, decimal=5) - np.testing.assert_almost_equal(negative_turning(wave), 5, decimal=5) - np.testing.assert_almost_equal(negative_turning(offsetWave), 5, decimal=5) - np.testing.assert_almost_equal(negative_turning(noiseWave), 323, decimal=5) - - -def test_positive_turning(): - np.testing.assert_almost_equal(positive_turning(const0), 0.0) - np.testing.assert_almost_equal(positive_turning(const1), 0.0) - np.testing.assert_almost_equal(positive_turning(constNeg), 0.0) - np.testing.assert_almost_equal(positive_turning(constF), 0.0) - np.testing.assert_almost_equal(positive_turning(lin), 0.0) - np.testing.assert_almost_equal(positive_turning(lin0), 0.0, decimal=5) - np.testing.assert_almost_equal(positive_turning(wave), 5, decimal=5) - np.testing.assert_almost_equal(positive_turning(offsetWave), 5, decimal=5) - np.testing.assert_almost_equal(positive_turning(noiseWave), 322, decimal=5) - - -def test_centroid(): - np.testing.assert_almost_equal(calc_centroid(const0, Fs), 0.0) - np.testing.assert_almost_equal(calc_centroid(const1, Fs), 0.009499999999999998) - np.testing.assert_almost_equal(calc_centroid(constNeg, Fs), 0.009499999999999998) - np.testing.assert_almost_equal(calc_centroid(constF, Fs), 0.0095) - np.testing.assert_almost_equal(calc_centroid(lin, Fs), 0.014615384615384615) - np.testing.assert_almost_equal(calc_centroid(lin0, Fs), 0.0095, decimal=5) - np.testing.assert_almost_equal(calc_centroid(wave, Fs), 0.5000000000000001, decimal=5) - np.testing.assert_almost_equal(calc_centroid(offsetWave, Fs), 0.47126367059427926, decimal=5) - np.testing.assert_almost_equal(calc_centroid(noiseWave, Fs), 0.4996034303128802, decimal=5) - - -def test_mean_diff(): - np.testing.assert_almost_equal(mean_diff(const0), 0.0) - np.testing.assert_almost_equal(mean_diff(const1), 0.0) - np.testing.assert_almost_equal(mean_diff(constNeg), 0.0) - np.testing.assert_almost_equal(mean_diff(constF), 0.0) - np.testing.assert_almost_equal(mean_diff(lin), 1.0) - np.testing.assert_almost_equal(mean_diff(lin0), 1.0526315789473684, decimal=5) - np.testing.assert_almost_equal(mean_diff(wave), -3.1442201279407477e-05, decimal=5) - np.testing.assert_almost_equal(mean_diff(offsetWave), -3.1442201279407036e-05, decimal=5) - np.testing.assert_almost_equal(mean_diff(noiseWave), -0.00010042477181949707, decimal=5) - - -def test_median_diff(): - np.testing.assert_almost_equal(median_diff(const0), 0.0) - np.testing.assert_almost_equal(median_diff(const1), 0.0) - np.testing.assert_almost_equal(median_diff(constNeg), 0.0) - np.testing.assert_almost_equal(median_diff(constF), 0.0) - np.testing.assert_almost_equal(median_diff(lin), 1.0) - np.testing.assert_almost_equal(median_diff(lin0), 1.0526315789473684, decimal=5) - np.testing.assert_almost_equal(median_diff(wave), -0.0004934396342684, decimal=5) - np.testing.assert_almost_equal(median_diff(offsetWave), -0.0004934396342681779, decimal=5) - np.testing.assert_almost_equal(median_diff(noiseWave), -0.004174819648320949, decimal=5) - - -def test_calc_mean_abs_diff(): - np.testing.assert_almost_equal(mean_abs_diff(const0), 0.0) - np.testing.assert_almost_equal(mean_abs_diff(const1), 0.0) - np.testing.assert_almost_equal(mean_abs_diff(constNeg), 0.0) - np.testing.assert_almost_equal(mean_abs_diff(constF), 0.0) - np.testing.assert_almost_equal(mean_abs_diff(lin), 1.0) - np.testing.assert_almost_equal(mean_abs_diff(lin0), 1.0526315789473684, decimal=5) - np.testing.assert_almost_equal(mean_abs_diff(wave), 0.019988577818740614, decimal=5) - np.testing.assert_almost_equal(mean_abs_diff(offsetWave), 0.019988577818740614, decimal=5) - np.testing.assert_almost_equal(mean_abs_diff(noiseWave), 0.10700252903161508, decimal=5) - - -def test_median_abs_diff(): - np.testing.assert_almost_equal(median_abs_diff(const0), 0.0) - np.testing.assert_almost_equal(median_abs_diff(const1), 0.0) - np.testing.assert_almost_equal(median_abs_diff(constNeg), 0.0) - np.testing.assert_almost_equal(median_abs_diff(constF), 0.0) - np.testing.assert_almost_equal(median_abs_diff(lin), 1.0) - np.testing.assert_almost_equal(median_abs_diff(lin0), 1.0526315789473681, decimal=5) - np.testing.assert_almost_equal(median_abs_diff(wave), 0.0218618462348652, decimal=5) - np.testing.assert_almost_equal(median_abs_diff(offsetWave), 0.021861846234865645, decimal=5) - np.testing.assert_almost_equal(median_abs_diff(noiseWave), 0.08958750592592835, decimal=5) - - -def test_sum_abs_diff(): - np.testing.assert_almost_equal(sum_abs_diff(const0), 0.0) - np.testing.assert_almost_equal(sum_abs_diff(const1), 0.0) - np.testing.assert_almost_equal(sum_abs_diff(constNeg), 0.0) - np.testing.assert_almost_equal(sum_abs_diff(constF), 0.0) - np.testing.assert_almost_equal(sum_abs_diff(lin), 19) - np.testing.assert_almost_equal(sum_abs_diff(lin0), 20.0, decimal=5) - np.testing.assert_almost_equal(sum_abs_diff(wave), 19.968589240921872, decimal=5) - np.testing.assert_almost_equal(sum_abs_diff(offsetWave), 19.968589240921872, decimal=5) - np.testing.assert_almost_equal(sum_abs_diff(noiseWave), 106.89552650258346, decimal=5) - - -def test_zerocross(): - np.testing.assert_almost_equal(zero_cross(const0), 0.0) - np.testing.assert_almost_equal(zero_cross(const1), 0.0) - np.testing.assert_almost_equal(zero_cross(constNeg), 0.0) - np.testing.assert_almost_equal(zero_cross(constF), 0.0) - np.testing.assert_almost_equal(zero_cross(lin), 1.0) - np.testing.assert_almost_equal(zero_cross(lin0), 1.0, decimal=5) - np.testing.assert_almost_equal(zero_cross(wave), 10, decimal=5) - np.testing.assert_almost_equal(zero_cross(offsetWave), 0.0, decimal=5) - np.testing.assert_almost_equal(zero_cross(noiseWave), 38, decimal=5) - - -def test_autocorr(): - np.testing.assert_almost_equal(autocorr(const0), 0.0) - np.testing.assert_almost_equal(autocorr(const1), 20.0) - np.testing.assert_almost_equal(autocorr(constNeg), 20.0) - np.testing.assert_almost_equal(autocorr(constF), 125.0) - np.testing.assert_almost_equal(autocorr(lin), 2470.0) - np.testing.assert_almost_equal(autocorr(lin0), 736.8421052631579, decimal=0) - np.testing.assert_almost_equal(autocorr(wave), 500.5, decimal=0) - np.testing.assert_almost_equal(autocorr(offsetWave), 4500.0, decimal=0) - np.testing.assert_almost_equal(autocorr(noiseWave), 508.6149018530489, decimal=0) - - -def test_auc(): - np.testing.assert_almost_equal(auc(const0, Fs), 0.0) - np.testing.assert_almost_equal(auc(const1, Fs), 0.019) - np.testing.assert_almost_equal(auc(constNeg, Fs), 0.019) - np.testing.assert_almost_equal(auc(constF, Fs), 0.0475) - np.testing.assert_almost_equal(auc(lin, Fs), 0.18050000000000002) - np.testing.assert_almost_equal(auc(lin0, Fs), 0.09473684210526315) - np.testing.assert_almost_equal(auc(wave, Fs), 0.6365517062491768) - np.testing.assert_almost_equal(auc(offsetWave, Fs), 1.998015705379539) - np.testing.assert_almost_equal(auc(noiseWave, Fs), 0.6375702578824347) - - -def test_abs_energy(): - np.testing.assert_almost_equal(abs_energy(const0), 0.0) - np.testing.assert_almost_equal(abs_energy(const1), 20.0) - np.testing.assert_almost_equal(abs_energy(constNeg), 20.0) - np.testing.assert_almost_equal(abs_energy(constF), 125.0) - np.testing.assert_almost_equal(abs_energy(lin), 2470) - np.testing.assert_almost_equal(abs_energy(lin0), 736.8421052631579) - np.testing.assert_almost_equal(abs_energy(wave), 500.0) - np.testing.assert_almost_equal(abs_energy(offsetWave), 4500.0) - np.testing.assert_almost_equal(abs_energy(noiseWave), 508.11883669335725) - - -def test_pk_pk_distance(): - np.testing.assert_almost_equal(pk_pk_distance(const0), 0.0) - np.testing.assert_almost_equal(pk_pk_distance(const1), 0.0) - np.testing.assert_almost_equal(pk_pk_distance(constNeg), 0.0) - np.testing.assert_almost_equal(pk_pk_distance(constF), 0.0) - np.testing.assert_almost_equal(pk_pk_distance(lin), 19) - np.testing.assert_almost_equal(pk_pk_distance(lin0), 20.0) - np.testing.assert_almost_equal(pk_pk_distance(wave), 2.0) - np.testing.assert_almost_equal(pk_pk_distance(offsetWave), 2.0) - np.testing.assert_almost_equal(pk_pk_distance(noiseWave), 2.4800109800001993) - - -def test_slope(): - np.testing.assert_almost_equal(slope(const0), 0.0) - np.testing.assert_almost_equal(slope(const1), -8.935559365603017e-18) - np.testing.assert_almost_equal(slope(constNeg), 8.935559365603017e-18) - np.testing.assert_almost_equal(slope(constF), 1.7871118731206033e-17) - np.testing.assert_almost_equal(slope(lin), 1.0) - np.testing.assert_almost_equal(slope(lin0), 1.0526315789473686) - np.testing.assert_almost_equal(slope(wave), -0.0003819408289180587) - np.testing.assert_almost_equal(slope(offsetWave), -0.00038194082891805853) - np.testing.assert_almost_equal(slope(noiseWave), -0.00040205425841671337) - - -def test_entropy(): - np.testing.assert_almost_equal(entropy(const0), 0.0) - np.testing.assert_almost_equal(entropy(const1), 0.0) - np.testing.assert_almost_equal(entropy(constNeg), 0.0) - np.testing.assert_almost_equal(entropy(constF), 0.0) - np.testing.assert_almost_equal(entropy(lin), 1.0) - np.testing.assert_almost_equal(entropy(lin0), 1.0) - np.testing.assert_almost_equal(entropy(wave), 0.9620267810255854) - np.testing.assert_almost_equal(entropy(offsetWave), 0.8890012261845581) - np.testing.assert_almost_equal(entropy(noiseWave), 1.0) - - -def test_neighbourhood_peaks(): - np.testing.assert_almost_equal(neighbourhood_peaks(const0), 0.0) - np.testing.assert_almost_equal(neighbourhood_peaks(const1), 0.0) - np.testing.assert_almost_equal(neighbourhood_peaks(constNeg), 0.0) - np.testing.assert_almost_equal(neighbourhood_peaks(constF), 0.0) - np.testing.assert_almost_equal(neighbourhood_peaks(lin), 0.0) - np.testing.assert_almost_equal(neighbourhood_peaks(lin0), 0.0) - np.testing.assert_almost_equal(neighbourhood_peaks(wave), 5.0) - np.testing.assert_almost_equal(neighbourhood_peaks(offsetWave), 5.0) - np.testing.assert_almost_equal(neighbourhood_peaks(noiseWave), 14.0) - - -# ################################################ SPECTRAL FEATURES ################################################# # -def test_max_fre(): - np.testing.assert_almost_equal(max_frequency(const0, Fs), 0.0) - np.testing.assert_almost_equal(max_frequency(const1, Fs), 0.0) - np.testing.assert_almost_equal(max_frequency(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(max_frequency(constF, Fs), 0.0) - np.testing.assert_almost_equal(max_frequency(lin, Fs), 444.44444444444446) - np.testing.assert_almost_equal(max_frequency(lin0, Fs), 500.0, decimal=5) - np.testing.assert_almost_equal(max_frequency(wave, Fs), 5.0100200400801596, decimal=5) - np.testing.assert_almost_equal(max_frequency(offsetWave, Fs), 5.0100200400801596, decimal=5) - np.testing.assert_almost_equal(max_frequency(noiseWave, Fs), 464.9298597194388, decimal=5) - np.testing.assert_almost_equal(max_frequency(x, Fs), 344.689378757515, decimal=1) - - -def test_med_fre(): - np.testing.assert_almost_equal(median_frequency(const0, Fs), 0.0) - np.testing.assert_almost_equal(median_frequency(const1, Fs), 0.0) - np.testing.assert_almost_equal(median_frequency(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(median_frequency(constF, Fs), 0.0) - np.testing.assert_almost_equal(median_frequency(lin, Fs), 55.55555555555556) - np.testing.assert_almost_equal(median_frequency(lin0, Fs), 166.66666666666669, decimal=5) - np.testing.assert_almost_equal(median_frequency(wave, Fs), 5.0100200400801596, decimal=5) - np.testing.assert_almost_equal(median_frequency(offsetWave, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(median_frequency(noiseWave, Fs), 146.29258517034066, decimal=5) - np.testing.assert_almost_equal(median_frequency(x, Fs), 4.008016032064128, decimal=1) - - -def test_fund_fre(): - np.testing.assert_almost_equal(fundamental_frequency(const0, 1), 0.0) - np.testing.assert_almost_equal(fundamental_frequency(const1, 1), 0.0) - np.testing.assert_almost_equal(fundamental_frequency(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(fundamental_frequency(constF, Fs), 0.0) - np.testing.assert_almost_equal(fundamental_frequency(lin, Fs), 55.55555555555556) - np.testing.assert_almost_equal(fundamental_frequency(lin0, Fs), 55.55555555555556, decimal=5) - np.testing.assert_almost_equal(fundamental_frequency(wave, Fs), 5.0100200400801596, decimal=1) - np.testing.assert_almost_equal(fundamental_frequency(offsetWave, Fs), 5.0100200400801596, decimal=1) - np.testing.assert_almost_equal(fundamental_frequency(noiseWave, Fs), 5.0100200400801596, decimal=1) - - -def test_power_spec(): - np.testing.assert_almost_equal(max_power_spectrum(const0, Fs), 0.0) - np.testing.assert_almost_equal(max_power_spectrum(const1, Fs), 0.0) - np.testing.assert_almost_equal(max_power_spectrum(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(max_power_spectrum(constF, Fs), 0.0) - np.testing.assert_almost_equal(max_power_spectrum(lin, Fs), 0.004621506382612649) - np.testing.assert_almost_equal(max_power_spectrum(lin0, Fs), 0.0046215063826126525, decimal=5) - np.testing.assert_almost_equal(max_power_spectrum(wave, Fs), 0.6666666666666667, decimal=5) - np.testing.assert_almost_equal(max_power_spectrum(offsetWave, Fs), 0.6666666666666667, decimal=5) - np.testing.assert_almost_equal(max_power_spectrum(noiseWave, Fs), 0.6570878541643916, decimal=5) - - -def test_total_energy(): - np.testing.assert_almost_equal(total_energy(const0, Fs), 0.0) - np.testing.assert_almost_equal(total_energy(const1, Fs), 1052.6315789473686) - np.testing.assert_almost_equal(total_energy(constNeg, Fs), 1052.6315789473686) - np.testing.assert_almost_equal(total_energy(constF, Fs), 6578.9473684210525) - np.testing.assert_almost_equal(total_energy(lin, Fs), 130000.0) - np.testing.assert_almost_equal(total_energy(lin0, Fs), 38781.16343490305, decimal=5) - np.testing.assert_almost_equal(total_energy(wave, Fs), 500.5005005005005, decimal=5) - np.testing.assert_almost_equal(total_energy(offsetWave, Fs), 4504.504504504504, decimal=5) - np.testing.assert_almost_equal(total_energy(noiseWave, Fs), 508.6274641575148, decimal=5) - - -def test_spectral_centroid(): - np.testing.assert_almost_equal(spectral_centroid(const0, Fs), 0.0) - np.testing.assert_almost_equal(spectral_centroid(const1, Fs), 2.7476856540265033e-14) - np.testing.assert_almost_equal(spectral_centroid(constNeg, Fs), 2.7476856540265033e-14) - np.testing.assert_almost_equal(spectral_centroid(constF, Fs), 2.4504208511457478e-14) - np.testing.assert_almost_equal(spectral_centroid(lin, Fs), 95.77382394996009) - np.testing.assert_almost_equal(spectral_centroid(lin0, Fs), 189.7228259594313, decimal=5) - np.testing.assert_almost_equal(spectral_centroid(wave, Fs), 5.010020040084022, decimal=5) - np.testing.assert_almost_equal(spectral_centroid(offsetWave, Fs), 1.0020040080169172, decimal=5) - np.testing.assert_almost_equal(spectral_centroid(noiseWave, Fs), 181.12036927310848, decimal=5) - - -def test_spectral_spread(): - np.testing.assert_almost_equal(spectral_spread(const0, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_spread(const1, Fs), 2.811883163207112e-06, decimal=5) - np.testing.assert_almost_equal(spectral_spread(constNeg, Fs), 2.811883163207112e-06, decimal=5) - np.testing.assert_almost_equal(spectral_spread(constF, Fs), 2.657703172211011e-06, decimal=5) - np.testing.assert_almost_equal(spectral_spread(lin, Fs), 137.9288076645223, decimal=5) - np.testing.assert_almost_equal(spectral_spread(lin0, Fs), 140.93247375966078, decimal=5) - np.testing.assert_almost_equal(spectral_spread(wave, Fs), 3.585399057660381e-05, decimal=5) - np.testing.assert_almost_equal(spectral_spread(offsetWave, Fs), 2.004008016105514, decimal=5) - np.testing.assert_almost_equal(spectral_spread(noiseWave, Fs), 165.6402040682083, decimal=5) - - -def test_spectral_skewness(): - np.testing.assert_almost_equal(spectral_skewness(const0, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_skewness(const1, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_skewness(constNeg, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_skewness(constF, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_skewness(lin, Fs), 1.5090650071326563, decimal=5) - np.testing.assert_almost_equal(spectral_skewness(lin0, Fs), 0.8140329168647044, decimal=5) - np.testing.assert_almost_equal(spectral_skewness(wave, Fs), 10643315.707158063, decimal=1) - np.testing.assert_almost_equal(spectral_skewness(offsetWave, Fs), 1.5000000137542306, decimal=1) - np.testing.assert_almost_equal(spectral_skewness(noiseWave, Fs), 0.4126776686583098, decimal=1) - - -def test_spectral_kurtosis(): - np.testing.assert_almost_equal(spectral_kurtosis(const0, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_kurtosis(const1, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_kurtosis(constNeg, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_kurtosis(constF, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_kurtosis(lin, Fs), 4.209140226148914, decimal=0) - np.testing.assert_almost_equal(spectral_kurtosis(lin0, Fs), 2.4060168768515413, decimal=5) - np.testing.assert_almost_equal(spectral_kurtosis(wave, Fs), 120959227206031.11, decimal=1) - np.testing.assert_almost_equal(spectral_kurtosis(offsetWave, Fs), 3.2500028252333513, decimal=5) - np.testing.assert_almost_equal(spectral_kurtosis(noiseWave, Fs), 1.7251592171239667, decimal=5) - - -def test_spectral_slope(): - np.testing.assert_almost_equal(spectral_slope(const0, Fs), 0.0) - np.testing.assert_almost_equal(spectral_slope(const1, Fs), -0.0009818181818181818) - np.testing.assert_almost_equal(spectral_slope(constNeg, Fs), -0.0009818181818181818) - np.testing.assert_almost_equal(spectral_slope(constF, Fs), -0.0009818181818181816) - np.testing.assert_almost_equal(spectral_slope(lin, Fs), -0.0006056882550328839) - np.testing.assert_almost_equal(spectral_slope(lin0, Fs), -0.00023672490168659717, decimal=1) - np.testing.assert_almost_equal(spectral_slope(wave, Fs), -2.3425149700598465e-05, decimal=5) - np.testing.assert_almost_equal(spectral_slope(offsetWave, Fs), -2.380838323353288e-05, decimal=5) - np.testing.assert_almost_equal(spectral_slope(noiseWave, Fs), -6.586047565550932e-06, decimal=5) - - -def test_spectral_decrease(): - np.testing.assert_almost_equal(spectral_decrease(const0, Fs), 0.0) - np.testing.assert_almost_equal(spectral_decrease(const1, Fs), 0.0) - np.testing.assert_almost_equal(spectral_decrease(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(spectral_decrease(constF, Fs), 0.0) - np.testing.assert_almost_equal(spectral_decrease(lin, Fs), -2.255518236004341) - np.testing.assert_almost_equal(spectral_decrease(lin0, Fs), 0.5195484076294969, decimal=5) - np.testing.assert_almost_equal(spectral_decrease(wave, Fs), 0.19999999999999687, decimal=5) - np.testing.assert_almost_equal(spectral_decrease(offsetWave, Fs), -26.963293719961584, decimal=5) - np.testing.assert_almost_equal(spectral_decrease(noiseWave, Fs), 0.06053938231990085, decimal=5) - - -def test_spectral_roll_on(): - np.testing.assert_almost_equal(spectral_roll_on(const0, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_on(const1, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_on(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_on(constF, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_on(lin, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_on(lin0, Fs), 55.55555555555556, decimal=5) - np.testing.assert_almost_equal(spectral_roll_on(wave, Fs), 5.0100200400801596, decimal=5) - np.testing.assert_almost_equal(spectral_roll_on(offsetWave, Fs), 0.0, decimal=5) - np.testing.assert_almost_equal(spectral_roll_on(noiseWave, Fs), 5.0100200400801596, decimal=5) - - -def test_spectral_roll_off(): - np.testing.assert_almost_equal(spectral_roll_off(const0, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_off(const1, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_off(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_off(constF, Fs), 0.0) - np.testing.assert_almost_equal(spectral_roll_off(lin, Fs), 444.44444444444446) - np.testing.assert_almost_equal(spectral_roll_off(lin0, Fs), 500.0, decimal=5) - np.testing.assert_almost_equal(spectral_roll_off(wave, Fs), 5.0100200400801596, decimal=5) - np.testing.assert_almost_equal(spectral_roll_off(offsetWave, Fs), 5.0100200400801596, decimal=5) - np.testing.assert_almost_equal(spectral_roll_off(noiseWave, Fs), 464.9298597194388, decimal=5) - - -def test_spectral_distance(): - np.testing.assert_almost_equal(spectral_distance(const0, Fs), 0.0) - np.testing.assert_almost_equal(spectral_distance(const1, Fs), -100) - np.testing.assert_almost_equal(spectral_distance(constNeg, Fs), -100) - np.testing.assert_almost_equal(spectral_distance(constF, Fs), -250) - np.testing.assert_almost_equal(spectral_distance(lin, Fs), -1256.997293357373) - np.testing.assert_almost_equal(spectral_distance(lin0, Fs), -323.15504563934024, decimal=5) - np.testing.assert_almost_equal(spectral_distance(wave, Fs), -122500.00000000022, decimal=5) - np.testing.assert_almost_equal(spectral_distance(offsetWave, Fs), -622500.0, decimal=5) - np.testing.assert_almost_equal(spectral_distance(noiseWave, Fs), -124832.72310672606, decimal=5) - - -def test_spect_variation(): - np.testing.assert_almost_equal(spectral_variation(const0, Fs), 1.0) - np.testing.assert_almost_equal(spectral_variation(const1, Fs), 1.0) - np.testing.assert_almost_equal(spectral_variation(constNeg, Fs), 1.0) - np.testing.assert_almost_equal(spectral_variation(constF, Fs), 1.0) - np.testing.assert_almost_equal(spectral_variation(lin, Fs), 0.04096548417849766) - np.testing.assert_almost_equal(spectral_variation(lin0, Fs), 0.39913530062615254, decimal=5) - np.testing.assert_almost_equal(spectral_variation(wave, Fs), 0.9999999999999997, decimal=5) - np.testing.assert_almost_equal(spectral_variation(offsetWave, Fs), 0.9999999999999999, decimal=5) - np.testing.assert_almost_equal(spectral_variation(noiseWave, Fs), 0.9775968083533805, decimal=5) - - -def test_spectral_positive_turning(): - np.testing.assert_almost_equal(spectral_positive_turning(const0, Fs), 0.0) - np.testing.assert_almost_equal(spectral_positive_turning(const1, Fs), 0.0) - np.testing.assert_almost_equal(spectral_positive_turning(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(spectral_positive_turning(constF, Fs), 0.0) - np.testing.assert_almost_equal(spectral_positive_turning(lin, Fs), 0.0) - np.testing.assert_almost_equal(spectral_positive_turning(lin0, Fs), 1.0, decimal=5) - np.testing.assert_almost_equal(spectral_positive_turning(wave, Fs), 155, decimal=0) - np.testing.assert_almost_equal(spectral_positive_turning(offsetWave, Fs), 158, decimal=1) - np.testing.assert_almost_equal(spectral_positive_turning(noiseWave, Fs), 172.0, decimal=1) - - -def test_human_range_energy(): - np.testing.assert_almost_equal(human_range_energy(const0, Fs), 0.0) - np.testing.assert_almost_equal(human_range_energy(const1, Fs), 0.0) - np.testing.assert_almost_equal(human_range_energy(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(human_range_energy(constF, Fs), 0.0) - np.testing.assert_almost_equal(human_range_energy(lin, Fs), 0.0) - np.testing.assert_almost_equal(human_range_energy(lin0, Fs), 0.0) - np.testing.assert_almost_equal(human_range_energy(wave, Fs), 2.838300923247935e-33) - np.testing.assert_almost_equal(human_range_energy(offsetWave, Fs), 1.6194431630448383e-33) - np.testing.assert_almost_equal(human_range_energy(noiseWave, Fs), 4.5026865350839304e-05) - - -def test_mfcc(): - np.testing.assert_almost_equal(mfcc(const0, Fs), (-1e-08, -2.5654632210061364e-08, -4.099058125255727e-08, - -5.56956514302075e-08, -6.947048992011573e-08, - -8.203468073398136e-08, - -9.313245317896842e-08, -1.0253788861142992e-07, - -1.1005951948899701e-07, - -1.1554422709759472e-07, -1.1888035860690259e-07, - -1.2000000000000002e-07)) - np.testing.assert_almost_equal(mfcc(const1, Fs), (0.14096637144714785, 0.4029720554090289, 0.2377457745400458, - 0.9307791929462678, -0.8138023913445843, -0.36127671623673, - 0.17779314470940918, 1.5842014538963525, -5.868875380858009, - -1.3484207382203723, -1.5899059472962034, 2.9774371742123975)) - np.testing.assert_almost_equal(mfcc(constNeg, Fs), (0.14096637144714785, 0.4029720554090289, 0.2377457745400458, - 0.9307791929462678, -0.8138023913445843, -0.36127671623673, - 0.17779314470940918, 1.5842014538963525, -5.868875380858009, - -1.3484207382203723, -1.5899059472962034, 2.9774371742123975)) - np.testing.assert_almost_equal(mfcc(constF, Fs), (0.1409663714471363, 0.40297205540906766, 0.23774577454002216, - 0.9307791929463864, -0.8138023913445535, -0.3612767162368284, - 0.17779314470931407, 1.584201453896316, -5.868875380858139, - -1.3484207382203004, -1.589905947296293, 2.977437174212552)) - np.testing.assert_almost_equal(mfcc(lin, Fs), (63.41077963677539, 42.33256774689686, 22.945623346731722, - -9.267967765468333, -30.918618746635172, -69.45624761250505, - -81.74881720705784, -112.32234611356338, -127.73335353282954, - -145.3505024599537, -152.08439229251312, -170.61228411241296)) - np.testing.assert_almost_equal(mfcc(lin0, Fs), (4.472854975902669, 9.303621966161266, 12.815317252229947, - 12.65260020301481, 9.763110307405048, 3.627814979708572, - 1.0051648150842092, -8.07514557618858, -24.79987026383853, - -36.55749714126207, -49.060094200797785, -61.45654150658956)) - np.testing.assert_almost_equal(mfcc(wave, Fs), (115.31298449242963, -23.978080415791883, 64.49711308839377, - -70.83883973188331, -17.4881594184545, -122.5191336465161, - -89.73379214517978, -164.5583844690884, -153.29482394321641, - -204.0607944643521, -189.9059214788022, -219.38937674972897)) - np.testing.assert_almost_equal(mfcc(offsetWave, Fs), (0.02803261518615674, 0.21714705316418328, 0.4010268706527706, - 1.0741653432632032, -0.26756380975236493, - -0.06446520044381611, 1.2229170142535633, 2.2173729990650166, - -5.161787305125577, -1.777027230578585, -2.2267834681371506, - 1.266610194040295)) - np.testing.assert_almost_equal(mfcc(noiseWave, Fs), (-59.93874366630627, -20.646010360067542, -5.9381521505819, - 13.868391975194648, 65.73380784148053, 67.65563377433688, - 35.223042940942214, 73.01746718829553, 137.50395589362876, - 111.61718917042731, 82.69709467796633, 110.67135918512074)) - - -def test_power_bandwidth(): - np.testing.assert_almost_equal(power_bandwidth(const0, Fs), 0.0) - np.testing.assert_almost_equal(power_bandwidth(const1, Fs), 0.0) - np.testing.assert_almost_equal(power_bandwidth(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(power_bandwidth(constF, Fs), 0.0) - np.testing.assert_almost_equal(power_bandwidth(lin, Fs), 0.0) - np.testing.assert_almost_equal(power_bandwidth(lin0, Fs), 0.0) - np.testing.assert_almost_equal(power_bandwidth(wave, Fs), 2.0) - np.testing.assert_almost_equal(power_bandwidth(offsetWave, Fs), 2.0) - np.testing.assert_almost_equal(power_bandwidth(noiseWave, Fs), 2.0) - - -def test_fft_mean_coeff(): - np.testing.assert_almost_equal(fft_mean_coeff(const0, Fs, nfreq=10), - (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(fft_mean_coeff(const1, Fs, nfreq=10), - (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(fft_mean_coeff(constNeg, Fs, nfreq=10), - (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(fft_mean_coeff(constF, Fs, nfreq=10), - (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(fft_mean_coeff(lin, Fs, nfreq=10), (0.00408221375370652, 0.29732082717207287, - 0.04400486791011177, 0.006686945426272411, - 0.00027732608206304087, 0.0003337183893114616, - 0.0008722727267959805, 0.0007221373313148659, - 0.00024061479410220662, 2.1097101108186473e-07)) - np.testing.assert_almost_equal(fft_mean_coeff(lin0, Fs, nfreq=10), (0.004523228535962903, 0.3294413597474491, - 0.04875885641009613, 0.007409357813044217, - 0.00030728651752137475, 0.0003697710684891545, - 0.0009665071765052403, 0.0008001521676618994, - 0.00026660919014094884, 2.337628931654879e-07)) - np.testing.assert_almost_equal(fft_mean_coeff(wave, Fs, nfreq=10), (2.0234880089914443e-06, 0.0001448004568848076, - 2.1047578415647817e-05, 3.2022732210152474e-06, - 1.52158292419209e-07, 1.7741879185514087e-07, - 4.2795757073284126e-07, 3.5003942541628605e-07, - 1.1626895252132188e-07, 1.6727906953620535e-10)) - np.testing.assert_almost_equal(fft_mean_coeff(offsetWave, Fs, nfreq=10), (2.0234880089914642e-06, - 0.00014480045688480763, - 2.104757841564781e-05, - 3.2022732210152483e-06, - 1.5215829241920897e-07, - 1.7741879185514156e-07, - 4.27957570732841e-07, - 3.500394254162859e-07, - 1.1626895252132173e-07, - 1.6727906953620255e-10)) - np.testing.assert_almost_equal(fft_mean_coeff(noiseWave, Fs, nfreq=10), (3.2947755935395495e-06, - 0.00014466702099241778, - 3.838265852158549e-05, - 1.6729032217627548e-05, - 1.6879950037320804e-05, - 1.571169205601392e-05, - 1.679718723715948e-05, - 1.810371503556574e-05, - 2.0106126483830693e-05, - 8.91285109135437e-06)) - - -def test_lpcc(): - np.testing.assert_almost_equal(lpcc(const0), (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - np.testing.assert_almost_equal(lpcc(const1), ((0.020164333842602966, 0.9865688990210231, 0.5256081668917854, - 0.36558947821279086, 0.2920451699576349, 0.25507545331173936, - 0.23917931511018226, 0.23917931511018226, 0.25507545331173936, - 0.2920451699576349, 0.36558947821279086, 0.5256081668917854, - 0.9865688990210231))) - np.testing.assert_almost_equal(lpcc(constNeg), (0.020164333842602966, 0.9865688990210231, 0.5256081668917854, - 0.36558947821279086, 0.2920451699576349, 0.25507545331173936, - 0.23917931511018226, 0.23917931511018226, 0.25507545331173936, - 0.2920451699576349, 0.36558947821279086, 0.5256081668917854, - 0.9865688990210231)) - np.testing.assert_almost_equal(lpcc(constF), (0.020164333842599635, 0.9865688990210177, 0.5256081668917822, - 0.365589478212793, 0.29204516995764224, 0.2550754533117383, - 0.2391793151101857, 0.2391793151101857, 0.2550754533117383, - 0.29204516995764224, 0.365589478212793, 0.5256081668917822, - 0.9865688990210177)) - np.testing.assert_almost_equal(lpcc(lin), (0.009787922299081098, 0.9403087900526141, 0.45515839811652303, - 0.2959902388191573, 0.2226794080995073, 0.18587538078947108, - 0.17006234165994988, 0.17006234165994988, 0.18587538078947108, - 0.2226794080995073, 0.2959902388191573, 0.45515839811652303, - 0.9403087900526141)) - np.testing.assert_almost_equal(lpcc(lin0), (0.14693248468111308, 0.7098379679548503, 0.27136979375401815, - 0.12066884688694682, 0.054365468824491156, 0.022184966988290034, - 0.00867554638640014, 0.00867554638640014, 0.022184966988290034, - 0.054365468824491156, 0.12066884688694682, 0.27136979375401815, - 0.7098379679548503)) - np.testing.assert_almost_equal(lpcc(wave), (0.27326478573784635, 2.2503511377184005, 1.3120406566259146, - 0.9508372630850437, 0.8377303045711273, 0.7195725472552679, - 0.715238952271539, 0.715238952271539, 0.7195725472552679, - 0.8377303045711273, 0.9508372630850437, 1.3120406566259146, - 2.2503511377184005)) - np.testing.assert_almost_equal(lpcc(offsetWave), (0.5435105244008235, 1.5815770053561224, 1.1189968861619681, - 0.9577304362743059, 0.8832739401503552, 0.8458651104475441, - 0.8295606293469393, 0.8295606293469393, 0.8458651104475441, - 0.8832739401503552, 0.9577304362743059, 1.1189968861619681, - 1.5815770053561224)) - np.testing.assert_almost_equal(lpcc(noiseWave), (0.332943861278751, 0.535742501182159, 0.6994290294792235, - 0.699314211544821, 0.6700910097813829, 0.67785538535114, - 0.7162476787322745, 0.7162476787322745, 0.67785538535114, - 0.6700910097813829, 0.699314211544821, 0.6994290294792235, - 0.535742501182159)) - - -def test_spectral_entropy(): - np.testing.assert_almost_equal(spectral_entropy(const0, Fs), 0.0) - np.testing.assert_almost_equal(spectral_entropy(const1, Fs), 0.0) - np.testing.assert_almost_equal(spectral_entropy(constNeg, Fs), 0.0) - np.testing.assert_almost_equal(spectral_entropy(constF, Fs), 0.0) - np.testing.assert_almost_equal(spectral_entropy(lin, Fs), 0.6006757398806453) - np.testing.assert_almost_equal(spectral_entropy(lin0, Fs), 0.57319032538303) - np.testing.assert_almost_equal(spectral_entropy(wave, Fs), 1.5228376718814352e-29) - np.testing.assert_almost_equal(spectral_entropy(offsetWave, Fs), 1.783049297437309e-29) - np.testing.assert_almost_equal(spectral_entropy(noiseWave, Fs), 0.030107186831275425) - - -def test_wavelet_entropy(): - np.testing.assert_almost_equal(wavelet_entropy(const0), 0.0) - np.testing.assert_almost_equal(wavelet_entropy(const1), 1.9188378548746368) - np.testing.assert_almost_equal(wavelet_entropy(constNeg), 1.9188378548746368) - np.testing.assert_almost_equal(wavelet_entropy(constF), 1.9188378548746368) - np.testing.assert_almost_equal(wavelet_entropy(lin), 1.9648440772467513) - np.testing.assert_almost_equal(wavelet_entropy(lin0), 2.0713919678725117) - np.testing.assert_almost_equal(wavelet_entropy(wave), 1.7277528462213683) - np.testing.assert_almost_equal(wavelet_entropy(offsetWave), 1.7965939302139549) - np.testing.assert_almost_equal(wavelet_entropy(noiseWave), 2.0467527462416153) - - -def test_wavelet_abs_mean(): - np.testing.assert_almost_equal(wavelet_abs_mean(const0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(wavelet_abs_mean(const1), - (0.081894185676901, 0.24260084511769256, 0.4653470776794248, - 0.8500400580778283, 1.3602249381214044, 1.8378460432593602, - 2.2080039502231164, 2.4676456085810874, 2.638131856418627)) - np.testing.assert_almost_equal(wavelet_abs_mean(constNeg), - (0.081894185676901, 0.24260084511769256, 0.4653470776794248, - 0.8500400580778283, 1.3602249381214044, 1.8378460432593602, - 2.2080039502231164, 2.4676456085810874, 2.638131856418627)) - np.testing.assert_almost_equal(wavelet_abs_mean(constF), - (0.20473546419225214, 0.6065021127942314, 1.1633676941985622, - 2.1251001451945712, 3.4005623453035114, 4.5946151081484015, - 5.5200098755577915, 6.169114021452717, 6.5953296410465665)) - np.testing.assert_almost_equal(wavelet_abs_mean(lin), (0.7370509925842613, 2.183416725919023, 4.1974435700809565, - 7.744819422931153, 12.504051331233388, 16.982183932901865, - 20.46332353598833, 22.91143100556329, 24.52363151471446)) - np.testing.assert_almost_equal(wavelet_abs_mean(lin0), - (0.0430987066803135, 0.12767505547269026, 0.23510912407745171, - 0.3479590829560181, 0.4400900851788993, 0.5024773453284851, - 0.5396989380329178, 0.5591602904810937, 0.5669696013289379)) - np.testing.assert_almost_equal(wavelet_abs_mean(wave), (5.138703105035948e-05, 0.00015178141653400073, - 0.00027925117450851024, 0.0004278724786267016, - 0.0005932191214607947, 0.0007717034331954587, - 0.0009601854175466062, 0.0011557903088208192, - 0.0013558175034366186)) - np.testing.assert_almost_equal(wavelet_abs_mean(offsetWave), (0.0032504208945027323, 0.009623752088931016, - 0.017761411181034453, 0.027372614777691914, - 0.03826512918833778, 0.050306487368868114, - 0.06339897203822373, 0.07746693331944604, - 0.09244971907566273)) - np.testing.assert_almost_equal(wavelet_abs_mean(noiseWave), (4.631139377647647e-05, 7.893225282164063e-05, - 0.00033257747958655794, 0.0005792253883615155, - 0.0007699898255271558, 0.0009106252575513913, - 0.0010387197644970154, 0.0011789334866018457, - 0.0013341945911985783)) - - -def test_wavelet_std(): - np.testing.assert_almost_equal(wavelet_std(const0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(wavelet_std(const1), (0.1767186264889806, 0.28069306259219023, 0.3235061868750311, - 0.3115893726751135, 0.31446140614407014, 0.3582016825631658, - 0.4133090941627322, 0.4598585090675407, 0.4935514064162697)) - np.testing.assert_almost_equal(wavelet_std(constNeg), (0.1767186264889806, 0.28069306259219023, 0.3235061868750311, - 0.3115893726751135, 0.31446140614407014, 0.3582016825631658, - 0.4133090941627322, 0.4598585090675407, 0.4935514064162697)) - np.testing.assert_almost_equal(wavelet_std(constF), (0.44179656622245145, 0.7017326564804757, 0.8087654671875778, - 0.7789734316877838, 0.7861535153601755, 0.8955042064079146, - 1.0332727354068305, 1.1496462726688517, 1.2338785160406742)) - np.testing.assert_almost_equal(wavelet_std(lin), (2.721791561180164, 5.325234998810811, 8.137581399111415, - 10.529795250703716, 11.836525442245224, 12.296195571788726, - 12.315744378517108, 12.135259348389042, 11.869294506387352)) - np.testing.assert_almost_equal(wavelet_std(lin0), (2.239406940011677, 4.7878443746478245, 7.797954379287043, - 10.418506686200207, 11.746946049852674, 12.045972295386465, - 11.828477896749822, 11.408150997410496, 10.932763618021895)) - np.testing.assert_almost_equal(wavelet_std(wave), (0.001939366875349316, 0.009733675496927717, 0.025635801097107388, - 0.05125305898778544, 0.08783649118731567, 0.13636963970273208, - 0.197613166916789, 0.2721306670702481, 0.360305525758368)) - np.testing.assert_almost_equal(wavelet_std(offsetWave), - (0.05459142980660159, 0.10410347082332229, 0.155831467554863, - 0.2101395066938644, 0.268489203478025, 0.33264452641566, - 0.4044076212671741, 0.4854392072251105, 0.5771385517659353)) - np.testing.assert_almost_equal(wavelet_std(noiseWave), - (0.08974931069698587, 0.09625674025798765, 0.10445386849293256, - 0.11395751571203461, 0.13232763520967267, 0.16659967802754122, - 0.2187573594673847, 0.2877270278501564, 0.3722670641715661)) - - -def test_wavelet_var(): - np.testing.assert_almost_equal(wavelet_var(const0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(wavelet_var(const1), (0.031229472948151833, 0.07878859538738324, 0.10465625294642253, - 0.09708793716407076, 0.09888597595410582, 0.128308445391083, - 0.17082440731761822, 0.21146984836182142, 0.24359299077547786)) - np.testing.assert_almost_equal(wavelet_var(constNeg), - (0.031229472948151833, 0.07878859538738324, 0.10465625294642253, - 0.09708793716407076, 0.09888597595410582, 0.128308445391083, - 0.17082440731761822, 0.21146984836182142, 0.24359299077547786)) - np.testing.assert_almost_equal(wavelet_var(constF), (0.19518420592594893, 0.49242872117114533, 0.654101580915141, - 0.6067996072754422, 0.6180373497131617, 0.8019277836942689, - 1.0676525457351138, 1.3216865522613839, 1.5224561923467361)) - np.testing.assert_almost_equal(wavelet_var(lin), (7.408149302511555, 28.35812779255958, 66.22023102716409, - 110.87658802174253, 140.10333454491848, 151.19642553967668, - 151.67755959697575, 147.26451945266362, 140.88015207935698)) - np.testing.assert_almost_equal(wavelet_var(lin0), (5.014943442972464, 22.923453755846815, 60.808092501441976, - 108.5452815703984, 137.99074149814933, 145.10544854121827, - 139.91288935389912, 130.1459091797181, 119.5253203275432)) - np.testing.assert_almost_equal(wavelet_var(wave), - (3.761143877202169e-06, 9.474443867949103e-05, 0.0006571942978904524, - 0.0026268760556054137, 0.007715249184099382, 0.018596678632652963, - 0.03905096373888271, 0.07405509996009821, 0.12982007189201397)) - np.testing.assert_almost_equal(wavelet_var(offsetWave), - (0.0029802242083291084, 0.010837532637462314, 0.02428344628030232, - 0.044158612273540676, 0.07208645238426431, 0.11065238095429873, - 0.16354552413897414, 0.2356512239113438, 0.33308890793448115)) - np.testing.assert_almost_equal(wavelet_var(noiseWave), - (0.008054938770584103, 0.0092653600450937, 0.01091061064313885, - 0.012986315387258616, 0.017510603040184203, 0.027755452718880403, - 0.04785478232114257, 0.08278684255548469, 0.1385827670669169)) - - -def test_wavelet_energy(): - np.testing.assert_almost_equal(wavelet_energy(const0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) - np.testing.assert_almost_equal(wavelet_energy(const1), (0.19477199643643478, 0.3710037269882903, 0.56674875884399, - 0.9053485723747671, 1.3961009484422982, 1.8724279756816202, - 2.2463539016634275, 2.510128422593423, 2.683902509896041)) - np.testing.assert_almost_equal(wavelet_energy(constNeg), (0.19477199643643478, 0.3710037269882903, 0.56674875884399, - 0.9053485723747671, 1.3961009484422982, - 1.8724279756816202, - 2.2463539016634275, 2.510128422593423, 2.683902509896041)) - np.testing.assert_almost_equal(wavelet_energy(constF), (0.48692999109108687, 0.9275093174707258, 1.4168718971099752, - 2.263371430936918, 3.4902523711057456, 4.6810699392040505, - 5.615884754158569, 6.275321056483556, 6.709756274740101)) - np.testing.assert_almost_equal(wavelet_energy(lin), (2.819821531264169, 5.7554701277638936, 9.156350995411767, - 13.071297407509103, 17.21785800380053, 20.966425462405052, - 23.883575313078858, 25.926785187819767, 27.244974853151422)) - np.testing.assert_almost_equal(wavelet_energy(lin0), (2.2398216316238173, 4.789546395603321, 7.8014978562880115, - 10.424315665491429, 11.75518697346929, 12.056447736534448, - 11.84078393931808, 11.421846147193937, 10.947455177180416)) - np.testing.assert_almost_equal(wavelet_energy(wave), - (0.0019400475520363772, 0.00973485882167256, 0.025637321995655413, - 0.051254844946242696, 0.08783849436907175, 0.13637182318514984, - 0.19761549963228792, 0.2721331214889804, 0.3603080766970352)) - np.testing.assert_almost_equal(wavelet_energy(offsetWave), - (0.054688110630378595, 0.10454735406375197, 0.15684040935755078, - 0.21191477606176637, 0.27120227229148447, 0.3364269959823273, - 0.4093469845918956, 0.49158147815928066, 0.584496243351187)) - np.testing.assert_almost_equal(wavelet_energy(noiseWave), - (0.08974932264551803, 0.09625677262091348, 0.10445439794914707, - 0.11395898775133596, 0.13232987540429264, 0.16660216672432593, - 0.2187598255162308, 0.2877294431226156, 0.37226945502166053)) - - -run_module_suite() +class TestFeatures(unittest.TestCase): + # ############################################### STATISTICAL FEATURES ############################################### # + def test_hist(self): + np.testing.assert_almost_equal(hist(const0, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(hist(const1, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(hist(constNeg, 10, 5), (0.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(hist(constF, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0)) + np.testing.assert_almost_equal(hist(lin, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2)) + np.testing.assert_almost_equal(hist(wave, 10, 5), (0.0, 0.0, 0.0, 0.0, 499, 496, 5, 0.0, 0.0, 0.0), decimal=5) + np.testing.assert_almost_equal(hist(offsetWave, 10, 5), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 499, 496, 5, 0.0), decimal=5) + np.testing.assert_almost_equal(hist(noiseWave, 10, 5), (0.0, 0.0, 0.0, 48, 446, 450, 56, 0.0, 0.0, 0.0), decimal=5) + + def test_skewness(self): + self.assertTrue(np.isnan(skewness(const0))) + self.assertTrue(np.isnan(skewness(const1))) + self.assertTrue(np.isnan(skewness(constNeg))) + self.assertTrue(np.isnan(skewness(constF))) + np.testing.assert_almost_equal(skewness(lin), 0) + np.testing.assert_almost_equal(skewness(lin0), -1.0167718723297815e-16, decimal=5) + np.testing.assert_almost_equal(skewness(wave), -2.009718347115232e-17, decimal=5) + np.testing.assert_almost_equal(skewness(offsetWave), 9.043732562018544e-16, decimal=5) + np.testing.assert_almost_equal(skewness(noiseWave), -0.0004854111290521465, decimal=5) + + def test_kurtosis(self): + self.assertTrue(np.isnan(kurtosis(const0))) + self.assertTrue(np.isnan(kurtosis(const1))) + self.assertTrue(np.isnan(kurtosis(constNeg))) + self.assertTrue(np.isnan(kurtosis(constF))) + np.testing.assert_almost_equal(kurtosis(lin), -1.206015037593985, decimal=2) + np.testing.assert_almost_equal(kurtosis(lin0), -1.2060150375939847, decimal=2) + np.testing.assert_almost_equal(kurtosis(wave), -1.501494077162359, decimal=2) + np.testing.assert_almost_equal(kurtosis(offsetWave), -1.5014940771623597, decimal=2) + np.testing.assert_almost_equal(kurtosis(noiseWave), -1.4606204906023366, decimal=2) + + def test_mean(self): + np.testing.assert_almost_equal(calc_mean(const0), 0.0) + np.testing.assert_almost_equal(calc_mean(const1), 1.0) + np.testing.assert_almost_equal(calc_mean(constNeg), -1.0) + np.testing.assert_almost_equal(calc_mean(constF), 2.5) + np.testing.assert_almost_equal(calc_mean(lin), 9.5) + np.testing.assert_almost_equal(calc_mean(lin0), -3.552713678800501e-16, decimal=5) + np.testing.assert_almost_equal(calc_mean(wave), 7.105427357601002e-18, decimal=5) + np.testing.assert_almost_equal(calc_mean(offsetWave), 2.0, decimal=5) + np.testing.assert_almost_equal(calc_mean(noiseWave), -0.0014556635615470554, decimal=5) + + def test_median(self): + np.testing.assert_almost_equal(calc_median(const0), 0.0) + np.testing.assert_almost_equal(calc_median(const1), 1.0) + np.testing.assert_almost_equal(calc_median(constNeg), -1.0) + np.testing.assert_almost_equal(calc_median(constF), 2.5) + np.testing.assert_almost_equal(calc_median(lin), 9.5) + np.testing.assert_almost_equal(calc_median(lin0), -3.552713678800501e-16, decimal=5) + np.testing.assert_almost_equal(calc_median(wave), 7.105427357601002e-18, decimal=5) + np.testing.assert_almost_equal(calc_median(offsetWave), 2.0, decimal=5) + np.testing.assert_almost_equal(calc_median(noiseWave), 0.013846093997438328, decimal=5) + + def test_max(self): + np.testing.assert_almost_equal(calc_max(const0), 0.0) + np.testing.assert_almost_equal(calc_max(const1), 1.0) + np.testing.assert_almost_equal(calc_max(constNeg), -1.0) + np.testing.assert_almost_equal(calc_max(constF), 2.5) + np.testing.assert_almost_equal(calc_max(lin), 19) + np.testing.assert_almost_equal(calc_max(lin0), 10.0, decimal=5) + np.testing.assert_almost_equal(calc_max(wave), 1.0, decimal=5) + np.testing.assert_almost_equal(calc_max(noiseWave), 1.221757617217142, decimal=5) + np.testing.assert_almost_equal(calc_max(offsetWave), 3.0, decimal=5) + + def test_min(self): + np.testing.assert_almost_equal(calc_min(const0), 0.0) + np.testing.assert_almost_equal(calc_min(const1), 1.0) + np.testing.assert_almost_equal(calc_min(constNeg), -1.0) + np.testing.assert_almost_equal(calc_min(constF), 2.5) + np.testing.assert_almost_equal(calc_min(lin), 0) + np.testing.assert_almost_equal(calc_min(lin0), -10.0, decimal=5) + np.testing.assert_almost_equal(calc_min(wave), -1.0, decimal=5) + np.testing.assert_almost_equal(calc_min(noiseWave), -1.2582533627830566, decimal=5) + np.testing.assert_almost_equal(calc_min(offsetWave), 1.0, decimal=5) + + def test_variance(self): + np.testing.assert_almost_equal(calc_var(const0), 0.0) + np.testing.assert_almost_equal(calc_var(const1), 0.0) + np.testing.assert_almost_equal(calc_var(constNeg), 0.0) + np.testing.assert_almost_equal(calc_var(constF), 0.0) + np.testing.assert_almost_equal(calc_var(lin), 33.25) + np.testing.assert_almost_equal(calc_var(lin0), 36.84210526315789, decimal=5) + np.testing.assert_almost_equal(calc_var(wave), 0.5, decimal=5) + np.testing.assert_almost_equal(calc_var(offsetWave), 0.5, decimal=5) + np.testing.assert_almost_equal(calc_var(noiseWave), 0.5081167177369529, decimal=5) + + def test_std(self): + np.testing.assert_almost_equal(calc_std(const0), 0.0) + np.testing.assert_almost_equal(calc_std(const1), 0.0) + np.testing.assert_almost_equal(calc_std(constNeg), 0.0) + np.testing.assert_almost_equal(calc_std(constF), 0.0) + np.testing.assert_almost_equal(calc_std(lin), 5.766281297335398) + np.testing.assert_almost_equal(calc_std(lin0), 6.069769786668839, decimal=5) + np.testing.assert_almost_equal(calc_std(wave), 0.7071067811865476, decimal=5) + np.testing.assert_almost_equal(calc_std(offsetWave), 0.7071067811865476, decimal=5) + np.testing.assert_almost_equal(calc_std(noiseWave), 0.7128230620125536, decimal=5) + + def test_interq_range(self): + np.testing.assert_almost_equal(interq_range(const0), 0.0) + np.testing.assert_almost_equal(interq_range(const1), 0.0) + np.testing.assert_almost_equal(interq_range(constNeg), 0.0) + np.testing.assert_almost_equal(interq_range(constF), 0.0) + np.testing.assert_almost_equal(interq_range(lin), 9.5) + np.testing.assert_almost_equal(interq_range(lin0), 10.0, decimal=5) + np.testing.assert_almost_equal(interq_range(wave), 1.414213562373095, decimal=5) + np.testing.assert_almost_equal(interq_range(offsetWave), 1.414213562373095, decimal=5) + np.testing.assert_almost_equal(interq_range(noiseWave), 1.4277110228590328, decimal=5) + + def test_mean_abs_diff(self): + np.testing.assert_almost_equal(mean_abs_diff(const0), 0.0) + np.testing.assert_almost_equal(mean_abs_diff(const1), 0.0) + np.testing.assert_almost_equal(mean_abs_diff(constNeg), 0.0) + np.testing.assert_almost_equal(mean_abs_diff(constF), 0.0) + np.testing.assert_almost_equal(mean_abs_diff(lin), 1.0) + np.testing.assert_almost_equal(mean_abs_diff(lin0), 1.0526315789473684, decimal=5) + np.testing.assert_almost_equal(mean_abs_diff(wave), 0.019988577818740614, decimal=5) + np.testing.assert_almost_equal(mean_abs_diff(noiseWave), 0.10700252903161511, decimal=5) + np.testing.assert_almost_equal(mean_abs_diff(offsetWave), 0.019988577818740614, decimal=5) + + def test_mean_abs_deviation(self): + np.testing.assert_almost_equal(mean_abs_deviation(const0), 0.0) + np.testing.assert_almost_equal(mean_abs_deviation(const1), 0.0) + np.testing.assert_almost_equal(mean_abs_deviation(constNeg), 0.0) + np.testing.assert_almost_equal(mean_abs_deviation(constF), 0.0) + np.testing.assert_almost_equal(mean_abs_deviation(lin), 5.0) + np.testing.assert_almost_equal(mean_abs_deviation(lin0), 5.263157894736842, decimal=5) + np.testing.assert_almost_equal(mean_abs_deviation(wave), 0.6365674116287157, decimal=5) + np.testing.assert_almost_equal(mean_abs_deviation(noiseWave), 0.6392749078483896, decimal=5) + np.testing.assert_almost_equal(mean_abs_deviation(offsetWave), 0.6365674116287157, decimal=5) + + def test_calc_median_abs_deviation(self): + np.testing.assert_almost_equal(median_abs_deviation(const0), 0.0) + np.testing.assert_almost_equal(median_abs_deviation(const1), 0.0) + np.testing.assert_almost_equal(median_abs_deviation(constNeg), 0.0) + np.testing.assert_almost_equal(median_abs_deviation(constF), 0.0) + np.testing.assert_almost_equal(median_abs_deviation(lin), 5.0) + np.testing.assert_almost_equal(median_abs_deviation(lin0), 5.2631578947368425, decimal=5) + np.testing.assert_almost_equal(median_abs_deviation(wave), 0.7071067811865475, decimal=5) + np.testing.assert_almost_equal(median_abs_deviation(offsetWave), 0.7071067811865475, decimal=5) + np.testing.assert_almost_equal(median_abs_deviation(noiseWave), 0.7068117164205888, decimal=5) + + def test_rms(self): + np.testing.assert_almost_equal(rms(const0), 0.0) + np.testing.assert_almost_equal(rms(const1), 1.0) + np.testing.assert_almost_equal(rms(constNeg), 1.0) + np.testing.assert_almost_equal(rms(constF), 2.5) + np.testing.assert_almost_equal(rms(lin), 11.113055385446435) + np.testing.assert_almost_equal(rms(lin0), 6.06976978666884, decimal=5) + np.testing.assert_almost_equal(rms(wave), 0.7071067811865476, decimal=5) + np.testing.assert_almost_equal(rms(offsetWave), 2.1213203435596424, decimal=5) + np.testing.assert_almost_equal(rms(noiseWave), 0.7128245483240299, decimal=5) + + def test_ecdf(self): + np.testing.assert_almost_equal(ecdf(const0), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) + np.testing.assert_almost_equal(ecdf(const1), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) + np.testing.assert_almost_equal(ecdf(constNeg), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) + np.testing.assert_almost_equal(ecdf(constF), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) + np.testing.assert_almost_equal(ecdf(lin), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) + np.testing.assert_almost_equal(ecdf(lin0), (0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5)) + np.testing.assert_almost_equal(ecdf(wave), (0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, + 0.01)) + np.testing.assert_almost_equal(ecdf(offsetWave), (0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, + 0.01)) + np.testing.assert_almost_equal(ecdf(noiseWave), (0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, + 0.01)) + + def test_ecdf_percentile(self): + np.testing.assert_almost_equal(ecdf_percentile(const0), (0, 0)) + np.testing.assert_almost_equal(ecdf_percentile(const1), (1, 1)) + np.testing.assert_almost_equal(ecdf_percentile(constNeg), (-1, -1)) + np.testing.assert_almost_equal(ecdf_percentile(constF), (2.5, 2.5)) + np.testing.assert_almost_equal(ecdf_percentile(lin), (3, 15)) + np.testing.assert_almost_equal(ecdf_percentile(lin0), (-6.8421053, 5.7894737), decimal=7) + np.testing.assert_almost_equal(ecdf_percentile(wave), (-0.809017, 0.809017)) + np.testing.assert_almost_equal(ecdf_percentile(offsetWave), (1.1909830056250523, 2.809016994374947)) + np.testing.assert_almost_equal(ecdf_percentile(noiseWave), (-0.8095410722491809, 0.796916231269631)) + + def test_ecdf_percentile_count(self): + np.testing.assert_almost_equal(ecdf_percentile_count(const0), (0, 0)) + np.testing.assert_almost_equal(ecdf_percentile_count(const1), (1, 1)) + np.testing.assert_almost_equal(ecdf_percentile_count(constNeg), (-1, -1)) + np.testing.assert_almost_equal(ecdf_percentile_count(constF), (2.5, 2.5)) + np.testing.assert_almost_equal(ecdf_percentile_count(lin), (4, 16)) + np.testing.assert_almost_equal(ecdf_percentile_count(lin0), (4, 16)) + np.testing.assert_almost_equal(ecdf_percentile_count(wave), (200, 800)) + np.testing.assert_almost_equal(ecdf_percentile_count(offsetWave), (200, 800)) + np.testing.assert_almost_equal(ecdf_percentile_count(noiseWave), (200, 800)) + + + # ################################################ TEMPORAL FEATURES ################################################# # + def test_distance(self): + np.testing.assert_almost_equal(distance(const0), 19.0) + np.testing.assert_almost_equal(distance(const1), 19.0) + np.testing.assert_almost_equal(distance(constNeg), 19.0) + np.testing.assert_almost_equal(distance(constF), 19.0) + np.testing.assert_almost_equal(distance(lin), 26.87005768508881) + np.testing.assert_almost_equal(distance(lin0), 27.586228448267438, decimal=5) + np.testing.assert_almost_equal(distance(wave), 999.2461809866238, decimal=5) + np.testing.assert_almost_equal(distance(offsetWave), 999.2461809866238, decimal=5) + np.testing.assert_almost_equal(distance(noiseWave), 1007.8711901383033, decimal=5) + + def test_negative_turning(self): + np.testing.assert_almost_equal(negative_turning(const0), 0.0) + np.testing.assert_almost_equal(negative_turning(const1), 0.0) + np.testing.assert_almost_equal(negative_turning(constNeg), 0.0) + np.testing.assert_almost_equal(negative_turning(constF), 0.0) + np.testing.assert_almost_equal(negative_turning(lin), 0.0) + np.testing.assert_almost_equal(negative_turning(lin0), 0.0, decimal=5) + np.testing.assert_almost_equal(negative_turning(wave), 5, decimal=5) + np.testing.assert_almost_equal(negative_turning(offsetWave), 5, decimal=5) + np.testing.assert_almost_equal(negative_turning(noiseWave), 323, decimal=5) + + def test_positive_turning(self): + np.testing.assert_almost_equal(positive_turning(const0), 0.0) + np.testing.assert_almost_equal(positive_turning(const1), 0.0) + np.testing.assert_almost_equal(positive_turning(constNeg), 0.0) + np.testing.assert_almost_equal(positive_turning(constF), 0.0) + np.testing.assert_almost_equal(positive_turning(lin), 0.0) + np.testing.assert_almost_equal(positive_turning(lin0), 0.0, decimal=5) + np.testing.assert_almost_equal(positive_turning(wave), 5, decimal=5) + np.testing.assert_almost_equal(positive_turning(offsetWave), 5, decimal=5) + np.testing.assert_almost_equal(positive_turning(noiseWave), 322, decimal=5) + + def test_centroid(self): + np.testing.assert_almost_equal(calc_centroid(const0, Fs), 0.0) + np.testing.assert_almost_equal(calc_centroid(const1, Fs), 0.009499999999999998) + np.testing.assert_almost_equal(calc_centroid(constNeg, Fs), 0.009499999999999998) + np.testing.assert_almost_equal(calc_centroid(constF, Fs), 0.0095) + np.testing.assert_almost_equal(calc_centroid(lin, Fs), 0.014615384615384615) + np.testing.assert_almost_equal(calc_centroid(lin0, Fs), 0.0095, decimal=5) + np.testing.assert_almost_equal(calc_centroid(wave, Fs), 0.5000000000000001, decimal=5) + np.testing.assert_almost_equal(calc_centroid(offsetWave, Fs), 0.47126367059427926, decimal=5) + np.testing.assert_almost_equal(calc_centroid(noiseWave, Fs), 0.4996034303128802, decimal=5) + + def test_mean_diff(self): + np.testing.assert_almost_equal(mean_diff(const0), 0.0) + np.testing.assert_almost_equal(mean_diff(const1), 0.0) + np.testing.assert_almost_equal(mean_diff(constNeg), 0.0) + np.testing.assert_almost_equal(mean_diff(constF), 0.0) + np.testing.assert_almost_equal(mean_diff(lin), 1.0) + np.testing.assert_almost_equal(mean_diff(lin0), 1.0526315789473684, decimal=5) + np.testing.assert_almost_equal(mean_diff(wave), -3.1442201279407477e-05, decimal=5) + np.testing.assert_almost_equal(mean_diff(offsetWave), -3.1442201279407036e-05, decimal=5) + np.testing.assert_almost_equal(mean_diff(noiseWave), -0.00010042477181949707, decimal=5) + + + def test_median_diff(self): + np.testing.assert_almost_equal(median_diff(const0), 0.0) + np.testing.assert_almost_equal(median_diff(const1), 0.0) + np.testing.assert_almost_equal(median_diff(constNeg), 0.0) + np.testing.assert_almost_equal(median_diff(constF), 0.0) + np.testing.assert_almost_equal(median_diff(lin), 1.0) + np.testing.assert_almost_equal(median_diff(lin0), 1.0526315789473684, decimal=5) + np.testing.assert_almost_equal(median_diff(wave), -0.0004934396342684, decimal=5) + np.testing.assert_almost_equal(median_diff(offsetWave), -0.0004934396342681779, decimal=5) + np.testing.assert_almost_equal(median_diff(noiseWave), -0.004174819648320949, decimal=5) + + + def test_calc_mean_abs_diff(self): + np.testing.assert_almost_equal(mean_abs_diff(const0), 0.0) + np.testing.assert_almost_equal(mean_abs_diff(const1), 0.0) + np.testing.assert_almost_equal(mean_abs_diff(constNeg), 0.0) + np.testing.assert_almost_equal(mean_abs_diff(constF), 0.0) + np.testing.assert_almost_equal(mean_abs_diff(lin), 1.0) + np.testing.assert_almost_equal(mean_abs_diff(lin0), 1.0526315789473684, decimal=5) + np.testing.assert_almost_equal(mean_abs_diff(wave), 0.019988577818740614, decimal=5) + np.testing.assert_almost_equal(mean_abs_diff(offsetWave), 0.019988577818740614, decimal=5) + np.testing.assert_almost_equal(mean_abs_diff(noiseWave), 0.10700252903161508, decimal=5) + + + def test_median_abs_diff(self): + np.testing.assert_almost_equal(median_abs_diff(const0), 0.0) + np.testing.assert_almost_equal(median_abs_diff(const1), 0.0) + np.testing.assert_almost_equal(median_abs_diff(constNeg), 0.0) + np.testing.assert_almost_equal(median_abs_diff(constF), 0.0) + np.testing.assert_almost_equal(median_abs_diff(lin), 1.0) + np.testing.assert_almost_equal(median_abs_diff(lin0), 1.0526315789473681, decimal=5) + np.testing.assert_almost_equal(median_abs_diff(wave), 0.0218618462348652, decimal=5) + np.testing.assert_almost_equal(median_abs_diff(offsetWave), 0.021861846234865645, decimal=5) + np.testing.assert_almost_equal(median_abs_diff(noiseWave), 0.08958750592592835, decimal=5) + + + def test_sum_abs_diff(self): + np.testing.assert_almost_equal(sum_abs_diff(const0), 0.0) + np.testing.assert_almost_equal(sum_abs_diff(const1), 0.0) + np.testing.assert_almost_equal(sum_abs_diff(constNeg), 0.0) + np.testing.assert_almost_equal(sum_abs_diff(constF), 0.0) + np.testing.assert_almost_equal(sum_abs_diff(lin), 19) + np.testing.assert_almost_equal(sum_abs_diff(lin0), 20.0, decimal=5) + np.testing.assert_almost_equal(sum_abs_diff(wave), 19.968589240921872, decimal=5) + np.testing.assert_almost_equal(sum_abs_diff(offsetWave), 19.968589240921872, decimal=5) + np.testing.assert_almost_equal(sum_abs_diff(noiseWave), 106.89552650258346, decimal=5) + + + def test_zerocross(self): + np.testing.assert_almost_equal(zero_cross(const0), 0.0) + np.testing.assert_almost_equal(zero_cross(const1), 0.0) + np.testing.assert_almost_equal(zero_cross(constNeg), 0.0) + np.testing.assert_almost_equal(zero_cross(constF), 0.0) + np.testing.assert_almost_equal(zero_cross(lin), 1.0) + np.testing.assert_almost_equal(zero_cross(lin0), 1.0, decimal=5) + np.testing.assert_almost_equal(zero_cross(wave), 10, decimal=5) + np.testing.assert_almost_equal(zero_cross(offsetWave), 0.0, decimal=5) + np.testing.assert_almost_equal(zero_cross(noiseWave), 38, decimal=5) + + + def test_autocorr(self): + np.testing.assert_almost_equal(autocorr(const0), 0.0) + np.testing.assert_almost_equal(autocorr(const1), 20.0) + np.testing.assert_almost_equal(autocorr(constNeg), 20.0) + np.testing.assert_almost_equal(autocorr(constF), 125.0) + np.testing.assert_almost_equal(autocorr(lin), 2470.0) + np.testing.assert_almost_equal(autocorr(lin0), 736.8421052631579, decimal=0) + np.testing.assert_almost_equal(autocorr(wave), 500.5, decimal=0) + np.testing.assert_almost_equal(autocorr(offsetWave), 4500.0, decimal=0) + np.testing.assert_almost_equal(autocorr(noiseWave), 508.6149018530489, decimal=0) + + + def test_auc(self): + np.testing.assert_almost_equal(auc(const0, Fs), 0.0) + np.testing.assert_almost_equal(auc(const1, Fs), 0.019) + np.testing.assert_almost_equal(auc(constNeg, Fs), 0.019) + np.testing.assert_almost_equal(auc(constF, Fs), 0.0475) + np.testing.assert_almost_equal(auc(lin, Fs), 0.18050000000000002) + np.testing.assert_almost_equal(auc(lin0, Fs), 0.09473684210526315) + np.testing.assert_almost_equal(auc(wave, Fs), 0.6365517062491768) + np.testing.assert_almost_equal(auc(offsetWave, Fs), 1.998015705379539) + np.testing.assert_almost_equal(auc(noiseWave, Fs), 0.6375702578824347) + + + def test_abs_energy(self): + np.testing.assert_almost_equal(abs_energy(const0), 0.0) + np.testing.assert_almost_equal(abs_energy(const1), 20.0) + np.testing.assert_almost_equal(abs_energy(constNeg), 20.0) + np.testing.assert_almost_equal(abs_energy(constF), 125.0) + np.testing.assert_almost_equal(abs_energy(lin), 2470) + np.testing.assert_almost_equal(abs_energy(lin0), 736.8421052631579) + np.testing.assert_almost_equal(abs_energy(wave), 500.0) + np.testing.assert_almost_equal(abs_energy(offsetWave), 4500.0) + np.testing.assert_almost_equal(abs_energy(noiseWave), 508.11883669335725) + + + def test_pk_pk_distance(self): + np.testing.assert_almost_equal(pk_pk_distance(const0), 0.0) + np.testing.assert_almost_equal(pk_pk_distance(const1), 0.0) + np.testing.assert_almost_equal(pk_pk_distance(constNeg), 0.0) + np.testing.assert_almost_equal(pk_pk_distance(constF), 0.0) + np.testing.assert_almost_equal(pk_pk_distance(lin), 19) + np.testing.assert_almost_equal(pk_pk_distance(lin0), 20.0) + np.testing.assert_almost_equal(pk_pk_distance(wave), 2.0) + np.testing.assert_almost_equal(pk_pk_distance(offsetWave), 2.0) + np.testing.assert_almost_equal(pk_pk_distance(noiseWave), 2.4800109800001993) + + + def test_slope(self): + np.testing.assert_almost_equal(slope(const0), 0.0) + np.testing.assert_almost_equal(slope(const1), -8.935559365603017e-18) + np.testing.assert_almost_equal(slope(constNeg), 8.935559365603017e-18) + np.testing.assert_almost_equal(slope(constF), 1.7871118731206033e-17) + np.testing.assert_almost_equal(slope(lin), 1.0) + np.testing.assert_almost_equal(slope(lin0), 1.0526315789473686) + np.testing.assert_almost_equal(slope(wave), -0.0003819408289180587) + np.testing.assert_almost_equal(slope(offsetWave), -0.00038194082891805853) + np.testing.assert_almost_equal(slope(noiseWave), -0.00040205425841671337) + + + def test_entropy(self): + np.testing.assert_almost_equal(entropy(const0), 0.0) + np.testing.assert_almost_equal(entropy(const1), 0.0) + np.testing.assert_almost_equal(entropy(constNeg), 0.0) + np.testing.assert_almost_equal(entropy(constF), 0.0) + np.testing.assert_almost_equal(entropy(lin), 1.0) + np.testing.assert_almost_equal(entropy(lin0), 1.0) + np.testing.assert_almost_equal(entropy(wave), 0.9620267810255854) + np.testing.assert_almost_equal(entropy(offsetWave), 0.8890012261845581) + np.testing.assert_almost_equal(entropy(noiseWave), 1.0) + + + def test_neighbourhood_peaks(self): + np.testing.assert_almost_equal(neighbourhood_peaks(const0), 0.0) + np.testing.assert_almost_equal(neighbourhood_peaks(const1), 0.0) + np.testing.assert_almost_equal(neighbourhood_peaks(constNeg), 0.0) + np.testing.assert_almost_equal(neighbourhood_peaks(constF), 0.0) + np.testing.assert_almost_equal(neighbourhood_peaks(lin), 0.0) + np.testing.assert_almost_equal(neighbourhood_peaks(lin0), 0.0) + np.testing.assert_almost_equal(neighbourhood_peaks(wave), 5.0) + np.testing.assert_almost_equal(neighbourhood_peaks(offsetWave), 5.0) + np.testing.assert_almost_equal(neighbourhood_peaks(noiseWave), 14.0) + + + # ################################################ SPECTRAL FEATURES ################################################# # + def test_max_fre(self): + np.testing.assert_almost_equal(max_frequency(const0, Fs), 0.0) + np.testing.assert_almost_equal(max_frequency(const1, Fs), 0.0) + np.testing.assert_almost_equal(max_frequency(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(max_frequency(constF, Fs), 0.0) + np.testing.assert_almost_equal(max_frequency(lin, Fs), 450.0) + np.testing.assert_almost_equal(max_frequency(lin0, Fs), 450.0, decimal=1) + np.testing.assert_almost_equal(max_frequency(wave, Fs), 5.0, decimal=1) + np.testing.assert_almost_equal(max_frequency(offsetWave, Fs), 5.0, decimal=1) + np.testing.assert_almost_equal(max_frequency(noiseWave, Fs), 465.0, decimal=1) + np.testing.assert_almost_equal(max_frequency(x, Fs), 345.0, decimal=1) + + def test_med_fre(self): + np.testing.assert_almost_equal(median_frequency(const0, Fs), 0.0) + np.testing.assert_almost_equal(median_frequency(const1, Fs), 0.0) + np.testing.assert_almost_equal(median_frequency(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(median_frequency(constF, Fs), 0.0) + np.testing.assert_almost_equal(median_frequency(lin, Fs), 50.0) + np.testing.assert_almost_equal(median_frequency(lin0, Fs), 150.0, decimal=1) + np.testing.assert_almost_equal(median_frequency(wave, Fs), 5.0, decimal=1) + np.testing.assert_almost_equal(median_frequency(offsetWave, Fs), 0.0, decimal=1) + np.testing.assert_almost_equal(median_frequency(noiseWave, Fs), 146.0, decimal=1) + np.testing.assert_almost_equal(median_frequency(x, Fs), 4.0, decimal=1) + + def test_fund_fre(self): + np.testing.assert_almost_equal(fundamental_frequency(const0, 1), 0.0) + np.testing.assert_almost_equal(fundamental_frequency(const1, 1), 0.0) + np.testing.assert_almost_equal(fundamental_frequency(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(fundamental_frequency(constF, Fs), 0.0) + np.testing.assert_almost_equal(fundamental_frequency(lin, Fs), 50.0) + np.testing.assert_almost_equal(fundamental_frequency(lin0, Fs), 50.0, decimal=1) + np.testing.assert_almost_equal(fundamental_frequency(wave, Fs), 5.0100200400801596, decimal=1) + np.testing.assert_almost_equal(fundamental_frequency(offsetWave, Fs), 5.0100200400801596, decimal=1) + np.testing.assert_almost_equal(fundamental_frequency(noiseWave, Fs), 5.0100200400801596, decimal=1) + + def test_power_spec(self): + np.testing.assert_almost_equal(max_power_spectrum(const0, Fs), 0.0) + np.testing.assert_almost_equal(max_power_spectrum(const1, Fs), 0.0) + np.testing.assert_almost_equal(max_power_spectrum(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(max_power_spectrum(constF, Fs), 0.0) + np.testing.assert_almost_equal(max_power_spectrum(lin, Fs), 0.004621506382612649) + np.testing.assert_almost_equal(max_power_spectrum(lin0, Fs), 0.0046215063826126525, decimal=5) + np.testing.assert_almost_equal(max_power_spectrum(wave, Fs), 0.6666666666666667, decimal=5) + np.testing.assert_almost_equal(max_power_spectrum(offsetWave, Fs), 0.6666666666666667, decimal=5) + np.testing.assert_almost_equal(max_power_spectrum(noiseWave, Fs), 0.6570878541643916, decimal=5) + + def test_average_power(self): + np.testing.assert_almost_equal(average_power(const0, Fs), 0.0) + np.testing.assert_almost_equal(average_power(const1, Fs), 1052.6315789473686) + np.testing.assert_almost_equal(average_power(constNeg, Fs), 1052.6315789473686) + np.testing.assert_almost_equal(average_power(constF, Fs), 6578.9473684210525) + np.testing.assert_almost_equal(average_power(lin, Fs), 130000.0) + np.testing.assert_almost_equal(average_power(lin0, Fs), 38781.16343490305, decimal=5) + np.testing.assert_almost_equal(average_power(wave, Fs), 500.5005005005005, decimal=5) + np.testing.assert_almost_equal(average_power(offsetWave, Fs), 4504.504504504504, decimal=5) + np.testing.assert_almost_equal(average_power(noiseWave, Fs), 508.6274641575148, decimal=5) + + def test_spectral_centroid(self): + np.testing.assert_almost_equal(spectral_centroid(const0, Fs), 0.0) + np.testing.assert_almost_equal(spectral_centroid(const1, Fs), 2.7476856540265033e-14) + np.testing.assert_almost_equal(spectral_centroid(constNeg, Fs), 2.7476856540265033e-14) + np.testing.assert_almost_equal(spectral_centroid(constF, Fs), 2.4504208511457478e-14) + np.testing.assert_almost_equal(spectral_centroid(lin, Fs), 96.7073273343592, decimal=5) + np.testing.assert_almost_equal(spectral_centroid(lin0, Fs), 186.91474845748346, decimal=5) + np.testing.assert_almost_equal(spectral_centroid(wave, Fs), 5.000000000003773, decimal=5) + np.testing.assert_almost_equal(spectral_centroid(offsetWave, Fs), 1.0000000000008324, decimal=5) + np.testing.assert_almost_equal(spectral_centroid(noiseWave, Fs), 181.0147784750644, decimal=5) + + def test_spectral_spread(self): + np.testing.assert_almost_equal(spectral_spread(const0, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_spread(const1, Fs), 2.811883163207112e-06, decimal=5) + np.testing.assert_almost_equal(spectral_spread(constNeg, Fs), 2.811883163207112e-06, decimal=5) + np.testing.assert_almost_equal(spectral_spread(constF, Fs), 2.657703172211011e-06, decimal=5) + np.testing.assert_almost_equal(spectral_spread(lin, Fs), 138.77058121011598, decimal=5) + np.testing.assert_almost_equal(spectral_spread(lin0, Fs), 142.68541769470383, decimal=5) + np.testing.assert_almost_equal(spectral_spread(wave, Fs), 3.585399057660381e-05, decimal=5) + np.testing.assert_almost_equal(spectral_spread(offsetWave, Fs), 2.0000000000692015, decimal=5) + np.testing.assert_almost_equal(spectral_spread(noiseWave, Fs), 165.48999545678365, decimal=5) + + def test_spectral_skewness(self): + np.testing.assert_almost_equal(spectral_skewness(const0, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_skewness(const1, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_skewness(constNeg, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_skewness(constF, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_skewness(lin, Fs), 1.4986055403796703, decimal=5) + np.testing.assert_almost_equal(spectral_skewness(lin0, Fs), 0.8056481576984844, decimal=5) + np.testing.assert_almost_equal(spectral_skewness(wave, Fs), 10746623.828906002, decimal=1) + np.testing.assert_almost_equal(spectral_skewness(offsetWave, Fs), 1.5000000137542306, decimal=1) + np.testing.assert_almost_equal(spectral_skewness(noiseWave, Fs), 0.4126776686583098, decimal=1) + + def test_spectral_kurtosis(self): + np.testing.assert_almost_equal(spectral_kurtosis(const0, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_kurtosis(const1, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_kurtosis(constNeg, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_kurtosis(constF, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_kurtosis(lin, Fs), 4.209140226148914, decimal=0) + np.testing.assert_almost_equal(spectral_kurtosis(lin0, Fs), 2.378341102603641, decimal=5) + np.testing.assert_almost_equal(spectral_kurtosis(wave, Fs), 123297212118194.1, decimal=1) + np.testing.assert_almost_equal(spectral_kurtosis(offsetWave, Fs), 3.2500028252333513, decimal=5) + np.testing.assert_almost_equal(spectral_kurtosis(noiseWave, Fs), 1.7248024846010621, decimal=5) + + + def test_spectral_slope(self): + np.testing.assert_almost_equal(spectral_slope(const0, Fs), 0.0) + np.testing.assert_almost_equal(spectral_slope(const1, Fs), -0.0009090909090909091) + np.testing.assert_almost_equal(spectral_slope(constNeg, Fs), -0.0009090909090909091) + np.testing.assert_almost_equal(spectral_slope(constF, Fs), -0.0009090909090909091) + np.testing.assert_almost_equal(spectral_slope(lin, Fs), -0.0005574279006023302) + np.testing.assert_almost_equal(spectral_slope(lin0, Fs), -0.00023672490168659717, decimal=1) + np.testing.assert_almost_equal(spectral_slope(wave, Fs), -2.3425149700598465e-05, decimal=5) + np.testing.assert_almost_equal(spectral_slope(offsetWave, Fs), -2.380838323353288e-05, decimal=5) + np.testing.assert_almost_equal(spectral_slope(noiseWave, Fs), -6.586047565550932e-06, decimal=5) + + def test_spectral_decrease(self): + np.testing.assert_almost_equal(spectral_decrease(const0, Fs), 0.0) + np.testing.assert_almost_equal(spectral_decrease(const1, Fs), 0.0) + np.testing.assert_almost_equal(spectral_decrease(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(spectral_decrease(constF, Fs), 0.0) + np.testing.assert_almost_equal(spectral_decrease(lin, Fs), -2.2331549790804033) + np.testing.assert_almost_equal(spectral_decrease(lin0, Fs), 0.49895105698521264, decimal=5) + np.testing.assert_almost_equal(spectral_decrease(wave, Fs), 0.19999999999999687, decimal=5) + np.testing.assert_almost_equal(spectral_decrease(offsetWave, Fs), -26.97129371996163, decimal=5) + np.testing.assert_almost_equal(spectral_decrease(noiseWave, Fs), 0.06049066756953234, decimal=5) + + def test_spectral_roll_on(self): + np.testing.assert_almost_equal(spectral_roll_on(const0, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_on(const1, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_on(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_on(constF, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_on(lin, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_on(lin0, Fs), 50.0, decimal=1) + np.testing.assert_almost_equal(spectral_roll_on(wave, Fs), 5.0, decimal=5) + np.testing.assert_almost_equal(spectral_roll_on(offsetWave, Fs), 0.0, decimal=5) + np.testing.assert_almost_equal(spectral_roll_on(noiseWave, Fs), 5.0, decimal=5) + + def test_spectral_roll_off(self): + np.testing.assert_almost_equal(spectral_roll_off(const0, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_off(const1, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_off(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_off(constF, Fs), 0.0) + np.testing.assert_almost_equal(spectral_roll_off(lin, Fs), 450.0) + np.testing.assert_almost_equal(spectral_roll_off(lin0, Fs), 450.0, decimal=5) + np.testing.assert_almost_equal(spectral_roll_off(wave, Fs), 5.0, decimal=5) + np.testing.assert_almost_equal(spectral_roll_off(offsetWave, Fs), 5.0, decimal=5) + np.testing.assert_almost_equal(spectral_roll_off(noiseWave, Fs), 465.0, decimal=5) + + def test_spectral_distance(self): + np.testing.assert_almost_equal(spectral_distance(const0, Fs), 0.0) + np.testing.assert_almost_equal(spectral_distance(const1, Fs), -110.0) + np.testing.assert_almost_equal(spectral_distance(constNeg, Fs), -110.0) + np.testing.assert_almost_equal(spectral_distance(constF, Fs), -275.0) + np.testing.assert_almost_equal(spectral_distance(lin, Fs), -1403.842529396485) + np.testing.assert_almost_equal(spectral_distance(lin0, Fs), -377.7289783120891, decimal=5) + np.testing.assert_almost_equal(spectral_distance(wave, Fs), -122750.0, decimal=1) + np.testing.assert_almost_equal(spectral_distance(offsetWave, Fs), -623750.0, decimal=5) + np.testing.assert_almost_equal(spectral_distance(noiseWave, Fs), -125372.23803384512, decimal=5) + + def test_spect_variation(self): + np.testing.assert_almost_equal(spectral_variation(const0, Fs), 1.0) + np.testing.assert_almost_equal(spectral_variation(const1, Fs), 1.0) + np.testing.assert_almost_equal(spectral_variation(constNeg, Fs), 1.0) + np.testing.assert_almost_equal(spectral_variation(constF, Fs), 1.0) + np.testing.assert_almost_equal(spectral_variation(lin, Fs), 0.04330670010243309) + np.testing.assert_almost_equal(spectral_variation(lin0, Fs), 0.3930601189429277, decimal=5) + np.testing.assert_almost_equal(spectral_variation(wave, Fs), 0.9999999999999997, decimal=5) + np.testing.assert_almost_equal(spectral_variation(offsetWave, Fs), 0.9999999999999999, decimal=5) + np.testing.assert_almost_equal(spectral_variation(noiseWave, Fs), 0.9775800433849368, decimal=5) + + def test_spectral_positive_turning(self): + np.testing.assert_almost_equal(spectral_positive_turning(const0, Fs), 0.0) + np.testing.assert_almost_equal(spectral_positive_turning(const1, Fs), 0.0) + np.testing.assert_almost_equal(spectral_positive_turning(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(spectral_positive_turning(constF, Fs), 0.0) + np.testing.assert_almost_equal(spectral_positive_turning(lin, Fs), 0.0) + np.testing.assert_almost_equal(spectral_positive_turning(lin0, Fs), 1.0, decimal=5) + np.testing.assert_almost_equal(spectral_positive_turning(wave, Fs), 161, decimal=0) + np.testing.assert_almost_equal(spectral_positive_turning(offsetWave, Fs), 160, decimal=1) + np.testing.assert_almost_equal(spectral_positive_turning(noiseWave, Fs), 173.0, decimal=1) + + def test_human_range_energy(self): + np.testing.assert_almost_equal(human_range_energy(const0, Fs), 0.0) + np.testing.assert_almost_equal(human_range_energy(const1, Fs), 0.0) + np.testing.assert_almost_equal(human_range_energy(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(human_range_energy(constF, Fs), 0.0) + np.testing.assert_almost_equal(human_range_energy(lin, Fs), 0.0) + np.testing.assert_almost_equal(human_range_energy(lin0, Fs), 0.0) + np.testing.assert_almost_equal(human_range_energy(wave, Fs), 2.838300923247935e-33) + np.testing.assert_almost_equal(human_range_energy(offsetWave, Fs), 1.6194431630448383e-33) + np.testing.assert_almost_equal(human_range_energy(noiseWave, Fs), 4.5026865350839304e-05) + + def test_mfcc(self): + np.testing.assert_almost_equal(mfcc(const0, Fs), (-1e-08, -2.5654632210061364e-08, -4.099058125255727e-08, + -5.56956514302075e-08, -6.947048992011573e-08, + -8.203468073398136e-08, + -9.313245317896842e-08, -1.0253788861142992e-07, + -1.1005951948899701e-07, + -1.1554422709759472e-07, -1.1888035860690259e-07, + -1.2000000000000002e-07)) + np.testing.assert_almost_equal(mfcc(const1, Fs), (0.14096637144714785, 0.4029720554090289, 0.2377457745400458, + 0.9307791929462678, -0.8138023913445843, -0.36127671623673, + 0.17779314470940918, 1.5842014538963525, -5.868875380858009, + -1.3484207382203723, -1.5899059472962034, 2.9774371742123975)) + np.testing.assert_almost_equal(mfcc(constNeg, Fs), (0.14096637144714785, 0.4029720554090289, 0.2377457745400458, + 0.9307791929462678, -0.8138023913445843, -0.36127671623673, + 0.17779314470940918, 1.5842014538963525, -5.868875380858009, + -1.3484207382203723, -1.5899059472962034, 2.9774371742123975)) + np.testing.assert_almost_equal(mfcc(constF, Fs), (0.1409663714471363, 0.40297205540906766, 0.23774577454002216, + 0.9307791929463864, -0.8138023913445535, -0.3612767162368284, + 0.17779314470931407, 1.584201453896316, -5.868875380858139, + -1.3484207382203004, -1.589905947296293, 2.977437174212552)) + np.testing.assert_almost_equal(mfcc(lin, Fs), (63.41077963677539, 42.33256774689686, 22.945623346731722, + -9.267967765468333, -30.918618746635172, -69.45624761250505, + -81.74881720705784, -112.32234611356338, -127.73335353282954, + -145.3505024599537, -152.08439229251312, -170.61228411241296)) + np.testing.assert_almost_equal(mfcc(lin0, Fs), (4.472854975902669, 9.303621966161266, 12.815317252229947, + 12.65260020301481, 9.763110307405048, 3.627814979708572, + 1.0051648150842092, -8.07514557618858, -24.79987026383853, + -36.55749714126207, -49.060094200797785, -61.45654150658956)) + np.testing.assert_almost_equal(mfcc(wave, Fs), (115.31298449242963, -23.978080415791883, 64.49711308839377, + -70.83883973188331, -17.4881594184545, -122.5191336465161, + -89.73379214517978, -164.5583844690884, -153.29482394321641, + -204.0607944643521, -189.9059214788022, -219.38937674972897)) + np.testing.assert_almost_equal(mfcc(offsetWave, Fs), (0.02803261518615674, 0.21714705316418328, 0.4010268706527706, + 1.0741653432632032, -0.26756380975236493, + -0.06446520044381611, 1.2229170142535633, 2.2173729990650166, + -5.161787305125577, -1.777027230578585, -2.2267834681371506, + 1.266610194040295)) + np.testing.assert_almost_equal(mfcc(noiseWave, Fs), (-59.93874366630627, -20.646010360067542, -5.9381521505819, + 13.868391975194648, 65.73380784148053, 67.65563377433688, + 35.223042940942214, 73.01746718829553, 137.50395589362876, + 111.61718917042731, 82.69709467796633, 110.67135918512074)) + + + def test_power_bandwidth(self): + np.testing.assert_almost_equal(power_bandwidth(const0, Fs), 0.0) + np.testing.assert_almost_equal(power_bandwidth(const1, Fs), 0.0) + np.testing.assert_almost_equal(power_bandwidth(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(power_bandwidth(constF, Fs), 0.0) + np.testing.assert_almost_equal(power_bandwidth(lin, Fs), 0.0) + np.testing.assert_almost_equal(power_bandwidth(lin0, Fs), 0.0) + np.testing.assert_almost_equal(power_bandwidth(wave, Fs), 2.0) + np.testing.assert_almost_equal(power_bandwidth(offsetWave, Fs), 2.0) + np.testing.assert_almost_equal(power_bandwidth(noiseWave, Fs), 2.0) + + def test_fft_mean_coeff(self): + np.testing.assert_almost_equal(fft_mean_coeff(const0, Fs, nfreq=10), + (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(fft_mean_coeff(const1, Fs, nfreq=10), + (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(fft_mean_coeff(constNeg, Fs, nfreq=10), + (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(fft_mean_coeff(constF, Fs, nfreq=10), + (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(fft_mean_coeff(lin, Fs, nfreq=10), (0.00408221375370652, 0.29732082717207287, + 0.04400486791011177, 0.006686945426272411, + 0.00027732608206304087, 0.0003337183893114616, + 0.0008722727267959805, 0.0007221373313148659, + 0.00024061479410220662, 2.1097101108186473e-07)) + np.testing.assert_almost_equal(fft_mean_coeff(lin0, Fs, nfreq=10), (0.004523228535962903, 0.3294413597474491, + 0.04875885641009613, 0.007409357813044217, + 0.00030728651752137475, 0.0003697710684891545, + 0.0009665071765052403, 0.0008001521676618994, + 0.00026660919014094884, 2.337628931654879e-07)) + np.testing.assert_almost_equal(fft_mean_coeff(wave, Fs, nfreq=10), (2.0234880089914443e-06, 0.0001448004568848076, + 2.1047578415647817e-05, 3.2022732210152474e-06, + 1.52158292419209e-07, 1.7741879185514087e-07, + 4.2795757073284126e-07, 3.5003942541628605e-07, + 1.1626895252132188e-07, 1.6727906953620535e-10)) + np.testing.assert_almost_equal(fft_mean_coeff(offsetWave, Fs, nfreq=10), (2.0234880089914642e-06, + 0.00014480045688480763, + 2.104757841564781e-05, + 3.2022732210152483e-06, + 1.5215829241920897e-07, + 1.7741879185514156e-07, + 4.27957570732841e-07, + 3.500394254162859e-07, + 1.1626895252132173e-07, + 1.6727906953620255e-10)) + np.testing.assert_almost_equal(fft_mean_coeff(noiseWave, Fs, nfreq=10), (3.2947755935395495e-06, + 0.00014466702099241778, + 3.838265852158549e-05, + 1.6729032217627548e-05, + 1.6879950037320804e-05, + 1.571169205601392e-05, + 1.679718723715948e-05, + 1.810371503556574e-05, + 2.0106126483830693e-05, + 8.91285109135437e-06)) + + + def test_lpcc(self): + np.testing.assert_almost_equal(lpcc(const0), (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + np.testing.assert_almost_equal(lpcc(const1), ((0.04123300285294014, 1.0090886040206166, 0.5477967308058846, + 0.38934442309407374, 0.3182978464880446, 0.28521488787857235, + 0.2753824147772057, 0.2852148878785723, 0.3182978464880446, + 0.3893444230940738, 0.5477967308058846, 1.0090886040206166))) + np.testing.assert_almost_equal(lpcc(constNeg), (0.04123300285294014, 1.0090886040206166, 0.5477967308058846, + 0.38934442309407374, 0.3182978464880446, 0.28521488787857235, + 0.2753824147772057, 0.2852148878785723, 0.3182978464880446, + 0.3893444230940738, 0.5477967308058846, 1.0090886040206166)) + np.testing.assert_almost_equal(lpcc(constF), (0.04123300285293459, 1.0090886040206097, 0.54779673080588, + 0.3893444230940775, 0.31829784648804227, 0.2852148878785703, + 0.2753824147772089, 0.28521488787857036, 0.31829784648804227, + 0.3893444230940775, 0.54779673080588, 1.0090886040206097)) + np.testing.assert_almost_equal(lpcc(lin), (0.0008115287870079275, 0.949808211511519, 0.469481269387107, + 0.31184557567242355, 0.24105584503772784, 0.2081345982990198, + 0.198356078000162, 0.2081345982990197, 0.24105584503772784, + 0.31184557567242355, 0.469481269387107, 0.9498082115115191)) + np.testing.assert_almost_equal(lpcc(lin0), (0.14900616258072136, 0.7120654174490035, 0.28220640800360736, + 0.13200549895670105, 0.0674236160580709, 0.03817662578918231, + 0.029619974765142276, 0.03817662578918224, 0.0674236160580709, + 0.13200549895670105, 0.28220640800360736, 0.7120654174490035)) + np.testing.assert_almost_equal(lpcc(wave), (0.3316269831953852, 2.2936534454791397, 1.3657365894469182, + 1.0070201818573588, 0.8468783257961441, 0.8794963357759213, + 0.6999667686345086, 0.8794963357759211, 0.8468783257961441, + 1.0070201818573588, 1.3657365894469182, 2.2936534454791397)) + np.testing.assert_almost_equal(lpcc(offsetWave), (0.6113077446051783, 1.650942970269406, 1.191078896704431, + 1.0313503136863278, 0.9597088652698047, 0.9261323880465244, + 0.9160979308646922, 0.9261323880465244, 0.9597088652698047, + 1.031350313686328, 1.1910788967044308, 1.650942970269406)) + np.testing.assert_almost_equal(lpcc(noiseWave), (0.3907899246825849, 0.6498327698888337, 0.7444466184462464, + 0.7833967114468317, 0.7517838305481447, 0.7739966761714876, + 0.8210271929385791, 0.7739966761714876, 0.7517838305481447, + 0.7833967114468317, 0.7444466184462464, 0.6498327698888338)) + + + def test_spectral_entropy(self): + np.testing.assert_almost_equal(spectral_entropy(const0, Fs), 0.0) + np.testing.assert_almost_equal(spectral_entropy(const1, Fs), 0.0) + np.testing.assert_almost_equal(spectral_entropy(constNeg, Fs), 0.0) + np.testing.assert_almost_equal(spectral_entropy(constF, Fs), 0.0) + np.testing.assert_almost_equal(spectral_entropy(lin, Fs), 0.5983234852309258) + np.testing.assert_almost_equal(spectral_entropy(lin0, Fs), 0.5745416630615365) + np.testing.assert_almost_equal(spectral_entropy(wave, Fs), 1.5228376718814352e-29) + np.testing.assert_almost_equal(spectral_entropy(offsetWave, Fs), 1.783049297437309e-29) + np.testing.assert_almost_equal(spectral_entropy(noiseWave, Fs), 0.0301141821499739) + + def test_wavelet_entropy(self): + np.testing.assert_almost_equal(wavelet_entropy(const0), 0.0) + np.testing.assert_almost_equal(wavelet_entropy(const1), 1.9188378548746368) + np.testing.assert_almost_equal(wavelet_entropy(constNeg), 1.9188378548746368) + np.testing.assert_almost_equal(wavelet_entropy(constF), 1.9188378548746368) + np.testing.assert_almost_equal(wavelet_entropy(lin), 1.9648440772467513) + np.testing.assert_almost_equal(wavelet_entropy(lin0), 2.0713919678725117) + np.testing.assert_almost_equal(wavelet_entropy(wave), 1.7277528462213683) + np.testing.assert_almost_equal(wavelet_entropy(offsetWave), 1.7965939302139549) + np.testing.assert_almost_equal(wavelet_entropy(noiseWave), 2.0467527462416153) + + + def test_wavelet_abs_mean(self): + np.testing.assert_almost_equal(wavelet_abs_mean(const0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(wavelet_abs_mean(const1), + (0.081894185676901, 0.24260084511769256, 0.4653470776794248, + 0.8500400580778283, 1.3602249381214044, 1.8378460432593602, + 2.2080039502231164, 2.4676456085810874, 2.638131856418627)) + np.testing.assert_almost_equal(wavelet_abs_mean(constNeg), + (0.081894185676901, 0.24260084511769256, 0.4653470776794248, + 0.8500400580778283, 1.3602249381214044, 1.8378460432593602, + 2.2080039502231164, 2.4676456085810874, 2.638131856418627)) + np.testing.assert_almost_equal(wavelet_abs_mean(constF), + (0.20473546419225214, 0.6065021127942314, 1.1633676941985622, + 2.1251001451945712, 3.4005623453035114, 4.5946151081484015, + 5.5200098755577915, 6.169114021452717, 6.5953296410465665)) + np.testing.assert_almost_equal(wavelet_abs_mean(lin), (0.7370509925842613, 2.183416725919023, 4.1974435700809565, + 7.744819422931153, 12.504051331233388, 16.982183932901865, + 20.46332353598833, 22.91143100556329, 24.52363151471446)) + np.testing.assert_almost_equal(wavelet_abs_mean(lin0), + (0.0430987066803135, 0.12767505547269026, 0.23510912407745171, + 0.3479590829560181, 0.4400900851788993, 0.5024773453284851, + 0.5396989380329178, 0.5591602904810937, 0.5669696013289379)) + np.testing.assert_almost_equal(wavelet_abs_mean(wave), (5.138703105035948e-05, 0.00015178141653400073, + 0.00027925117450851024, 0.0004278724786267016, + 0.0005932191214607947, 0.0007717034331954587, + 0.0009601854175466062, 0.0011557903088208192, + 0.0013558175034366186)) + np.testing.assert_almost_equal(wavelet_abs_mean(offsetWave), (0.0032504208945027323, 0.009623752088931016, + 0.017761411181034453, 0.027372614777691914, + 0.03826512918833778, 0.050306487368868114, + 0.06339897203822373, 0.07746693331944604, + 0.09244971907566273)) + np.testing.assert_almost_equal(wavelet_abs_mean(noiseWave), (4.631139377647647e-05, 7.893225282164063e-05, + 0.00033257747958655794, 0.0005792253883615155, + 0.0007699898255271558, 0.0009106252575513913, + 0.0010387197644970154, 0.0011789334866018457, + 0.0013341945911985783)) + + + def test_wavelet_std(self): + np.testing.assert_almost_equal(wavelet_std(const0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(wavelet_std(const1), (0.1767186264889806, 0.28069306259219023, 0.3235061868750311, + 0.3115893726751135, 0.31446140614407014, 0.3582016825631658, + 0.4133090941627322, 0.4598585090675407, 0.4935514064162697)) + np.testing.assert_almost_equal(wavelet_std(constNeg), (0.1767186264889806, 0.28069306259219023, 0.3235061868750311, + 0.3115893726751135, 0.31446140614407014, 0.3582016825631658, + 0.4133090941627322, 0.4598585090675407, 0.4935514064162697)) + np.testing.assert_almost_equal(wavelet_std(constF), (0.44179656622245145, 0.7017326564804757, 0.8087654671875778, + 0.7789734316877838, 0.7861535153601755, 0.8955042064079146, + 1.0332727354068305, 1.1496462726688517, 1.2338785160406742)) + np.testing.assert_almost_equal(wavelet_std(lin), (2.721791561180164, 5.325234998810811, 8.137581399111415, + 10.529795250703716, 11.836525442245224, 12.296195571788726, + 12.315744378517108, 12.135259348389042, 11.869294506387352)) + np.testing.assert_almost_equal(wavelet_std(lin0), (2.239406940011677, 4.7878443746478245, 7.797954379287043, + 10.418506686200207, 11.746946049852674, 12.045972295386465, + 11.828477896749822, 11.408150997410496, 10.932763618021895)) + np.testing.assert_almost_equal(wavelet_std(wave), (0.001939366875349316, 0.009733675496927717, 0.025635801097107388, + 0.05125305898778544, 0.08783649118731567, 0.13636963970273208, + 0.197613166916789, 0.2721306670702481, 0.360305525758368)) + np.testing.assert_almost_equal(wavelet_std(offsetWave), + (0.05459142980660159, 0.10410347082332229, 0.155831467554863, + 0.2101395066938644, 0.268489203478025, 0.33264452641566, + 0.4044076212671741, 0.4854392072251105, 0.5771385517659353)) + np.testing.assert_almost_equal(wavelet_std(noiseWave), + (0.08974931069698587, 0.09625674025798765, 0.10445386849293256, + 0.11395751571203461, 0.13232763520967267, 0.16659967802754122, + 0.2187573594673847, 0.2877270278501564, 0.3722670641715661)) + + + def test_wavelet_var(self): + np.testing.assert_almost_equal(wavelet_var(const0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(wavelet_var(const1), (0.031229472948151833, 0.07878859538738324, 0.10465625294642253, + 0.09708793716407076, 0.09888597595410582, 0.128308445391083, + 0.17082440731761822, 0.21146984836182142, 0.24359299077547786)) + np.testing.assert_almost_equal(wavelet_var(constNeg), + (0.031229472948151833, 0.07878859538738324, 0.10465625294642253, + 0.09708793716407076, 0.09888597595410582, 0.128308445391083, + 0.17082440731761822, 0.21146984836182142, 0.24359299077547786)) + np.testing.assert_almost_equal(wavelet_var(constF), (0.19518420592594893, 0.49242872117114533, 0.654101580915141, + 0.6067996072754422, 0.6180373497131617, 0.8019277836942689, + 1.0676525457351138, 1.3216865522613839, 1.5224561923467361)) + np.testing.assert_almost_equal(wavelet_var(lin), (7.408149302511555, 28.35812779255958, 66.22023102716409, + 110.87658802174253, 140.10333454491848, 151.19642553967668, + 151.67755959697575, 147.26451945266362, 140.88015207935698)) + np.testing.assert_almost_equal(wavelet_var(lin0), (5.014943442972464, 22.923453755846815, 60.808092501441976, + 108.5452815703984, 137.99074149814933, 145.10544854121827, + 139.91288935389912, 130.1459091797181, 119.5253203275432)) + np.testing.assert_almost_equal(wavelet_var(wave), + (3.761143877202169e-06, 9.474443867949103e-05, 0.0006571942978904524, + 0.0026268760556054137, 0.007715249184099382, 0.018596678632652963, + 0.03905096373888271, 0.07405509996009821, 0.12982007189201397)) + np.testing.assert_almost_equal(wavelet_var(offsetWave), + (0.0029802242083291084, 0.010837532637462314, 0.02428344628030232, + 0.044158612273540676, 0.07208645238426431, 0.11065238095429873, + 0.16354552413897414, 0.2356512239113438, 0.33308890793448115)) + np.testing.assert_almost_equal(wavelet_var(noiseWave), + (0.008054938770584103, 0.0092653600450937, 0.01091061064313885, + 0.012986315387258616, 0.017510603040184203, 0.027755452718880403, + 0.04785478232114257, 0.08278684255548469, 0.1385827670669169)) + + + def test_wavelet_energy(self): + np.testing.assert_almost_equal(wavelet_energy(const0), (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) + np.testing.assert_almost_equal(wavelet_energy(const1), (0.19477199643643478, 0.3710037269882903, 0.56674875884399, + 0.9053485723747671, 1.3961009484422982, 1.8724279756816202, + 2.2463539016634275, 2.510128422593423, 2.683902509896041)) + np.testing.assert_almost_equal(wavelet_energy(constNeg), (0.19477199643643478, 0.3710037269882903, 0.56674875884399, + 0.9053485723747671, 1.3961009484422982, + 1.8724279756816202, + 2.2463539016634275, 2.510128422593423, 2.683902509896041)) + np.testing.assert_almost_equal(wavelet_energy(constF), (0.48692999109108687, 0.9275093174707258, 1.4168718971099752, + 2.263371430936918, 3.4902523711057456, 4.6810699392040505, + 5.615884754158569, 6.275321056483556, 6.709756274740101)) + np.testing.assert_almost_equal(wavelet_energy(lin), (2.819821531264169, 5.7554701277638936, 9.156350995411767, + 13.071297407509103, 17.21785800380053, 20.966425462405052, + 23.883575313078858, 25.926785187819767, 27.244974853151422)) + np.testing.assert_almost_equal(wavelet_energy(lin0), (2.2398216316238173, 4.789546395603321, 7.8014978562880115, + 10.424315665491429, 11.75518697346929, 12.056447736534448, + 11.84078393931808, 11.421846147193937, 10.947455177180416)) + np.testing.assert_almost_equal(wavelet_energy(wave), + (0.0019400475520363772, 0.00973485882167256, 0.025637321995655413, + 0.051254844946242696, 0.08783849436907175, 0.13637182318514984, + 0.19761549963228792, 0.2721331214889804, 0.3603080766970352)) + np.testing.assert_almost_equal(wavelet_energy(offsetWave), + (0.054688110630378595, 0.10454735406375197, 0.15684040935755078, + 0.21191477606176637, 0.27120227229148447, 0.3364269959823273, + 0.4093469845918956, 0.49158147815928066, 0.584496243351187)) + np.testing.assert_almost_equal(wavelet_energy(noiseWave), + (0.08974932264551803, 0.09625677262091348, 0.10445439794914707, + 0.11395898775133596, 0.13232987540429264, 0.16660216672432593, + 0.2187598255162308, 0.2877294431226156, 0.37226945502166053)) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/tests_tools/test_features.json b/tests/tests_tools/test_features.json index afa4320..b68f34d 100644 --- a/tests/tests_tools/test_features.json +++ b/tests/tests_tools/test_features.json @@ -1,4 +1,25 @@ { + "new_domain": { + "new_feature_with_multiple_tag": { + "complexity": "constant", + "description": "A new feature with multiple tags", + "function": "new_feature_with_multiple_tag", + "parameters": "", + "tag": [ + "inertial", + "emg" + ], + "use": "yes" + }, + "new_feature_with_tag": { + "complexity": "constant", + "description": "A new feature with a tag", + "function": "new_feature_with_tag", + "parameters": "", + "tag": "inertial", + "use": "yes" + } + }, "spectral": { "FFT mean coefficient": { "complexity": "constant", @@ -290,6 +311,26 @@ } }, "statistical": { + "Absolute energy": { + "complexity": "log", + "description": "Computes the absolute energy of the signal.", + "function": "tsfel.abs_energy", + "n_features": 1, + "parameters": "", + "tag": "audio", + "use": "yes" + }, + "Average power": { + "complexity": "constant", + "description": "Computes the average power of the signal.", + "function": "tsfel.average_power", + "n_features": 1, + "parameters": { + "fs": 100 + }, + "tag": "audio", + "use": "yes" + }, "ECDF": { "complexity": "log", "description": "Computes the values of ECDF (empirical cumulative distribution function) along the time axis.", @@ -320,6 +361,17 @@ }, "use": "yes" }, + "Entropy": { + "complexity": "log", + "description": "Computes the entropy of the signal using the Shannon Entropy.", + "function": "tsfel.entropy", + "n_features": 1, + "parameters": { + "prob": "standard" + }, + "tag": "eeg", + "use": "yes" + }, "Histogram": { "complexity": "log", "description": "Computes histogram of the signal.", @@ -396,6 +448,14 @@ "parameters": "", "use": "yes" }, + "Peak to peak distance": { + "complexity": "constant", + "description": "Computes the peak to peak distance.", + "function": "tsfel.pk_pk_distance", + "n_features": 1, + "parameters": "", + "use": "yes" + }, "Root mean square": { "complexity": "constant", "description": "Computes root mean square of the signal.", @@ -450,15 +510,6 @@ } }, "temporal": { - "Absolute energy": { - "complexity": "log", - "description": "Computes the absolute energy of the signal.", - "function": "tsfel.abs_energy", - "n_features": 1, - "parameters": "", - "tag": "audio", - "use": "yes" - }, "Area under the curve": { "complexity": "log", "description": "Computes the area under the curve of the signal computed with trapezoid rule.", @@ -488,17 +539,6 @@ }, "use": "yes" }, - "Entropy": { - "complexity": "log", - "description": "Computes the entropy of the signal using the Shannon Entropy.", - "function": "tsfel.entropy", - "n_features": 1, - "parameters": { - "prob": "standard" - }, - "tag": "eeg", - "use": "yes" - }, "Mean absolute diff": { "complexity": "constant", "description": "Computes mean absolute differences of the signal.", @@ -550,14 +590,6 @@ }, "use": "yes" }, - "Peak to peak distance": { - "complexity": "constant", - "description": "Computes the peak to peak distance.", - "function": "tsfel.pk_pk_distance", - "n_features": 1, - "parameters": "", - "use": "yes" - }, "Positive turning points": { "complexity": "constant", "description": "Computes number of positive turning points of the signal.", @@ -591,17 +623,6 @@ "parameters": "", "use": "yes" }, - "Total energy": { - "complexity": "constant", - "description": "Computes the total energy of the signal.", - "function": "tsfel.total_energy", - "n_features": 1, - "parameters": { - "fs": 100 - }, - "tag": "audio", - "use": "yes" - }, "Zero crossing rate": { "complexity": "constant", "description": "Computes Zero-crossing rate of the signal.", diff --git a/tsfel/feature_extraction/calc_features.py b/tsfel/feature_extraction/calc_features.py index 2e4a192..e6d3718 100644 --- a/tsfel/feature_extraction/calc_features.py +++ b/tsfel/feature_extraction/calc_features.py @@ -107,53 +107,56 @@ def dataset_features_extractor(main_directory, feat_dict, verbose=1, **kwargs): folders = [f for f in glob.glob(main_directory + "**/", recursive=True)] - for fl in folders: - sensor_data = {} - if search_criteria: - for c in search_criteria: - if os.path.isfile(fl + c): - key = c.split('.')[0] - sensor_data[key] = pd.read_csv(fl + c, header=None) - else: - all_files = np.concatenate((glob.glob(fl + '/*.txt'), glob.glob(fl + '/*.csv'))) - for c in all_files: - key = c.split(os.sep)[-1].split('.')[0] - try: - data_file = pd.read_csv(c, header=None) - except pd.io.common.CParserError: - continue + if folders: + for fl in folders: + sensor_data = {} + if search_criteria: + for c in search_criteria: + if os.path.isfile(fl + c): + key = c.split('.')[0] + sensor_data[key] = pd.read_csv(fl + c, header=None) + else: + all_files = np.concatenate((glob.glob(fl + '/*.txt'), glob.glob(fl + '/*.csv'))) + for c in all_files: + key = c.split(os.sep)[-1].split('.')[0] + try: + data_file = pd.read_csv(c, header=None) + except pd.io.common.CParserError: + continue - if np.dtype('O') in np.array(data_file.dtypes): - continue + if np.dtype('O') in np.array(data_file.dtypes): + continue - sensor_data[key] = pd.read_csv(c, header=None) + sensor_data[key] = pd.read_csv(c, header=None) - if not sensor_data: - continue + if not sensor_data: + continue - pp_sensor_data = sensor_data if pre_process is None else pre_process(sensor_data) + pp_sensor_data = sensor_data if pre_process is None else pre_process(sensor_data) - data_new = merge_time_series(pp_sensor_data, resample_rate, time_unit) + data_new = merge_time_series(pp_sensor_data, resample_rate, time_unit) - windows = signal_window_splitter(data_new, window_size, overlap) + windows = signal_window_splitter(data_new, window_size, overlap) - if features_path: - features = time_series_features_extractor(feat_dict, windows, fs=resample_rate, verbose=0, - features_path=features_path, header_names=names, n_jobs=n_jobs) - else: - features = time_series_features_extractor(feat_dict, windows, fs=resample_rate, verbose=0, - header_names=names, n_jobs=n_jobs) + if features_path: + features = time_series_features_extractor(feat_dict, windows, fs=resample_rate, verbose=0, + features_path=features_path, header_names=names, n_jobs=n_jobs) + else: + features = time_series_features_extractor(feat_dict, windows, fs=resample_rate, verbose=0, + header_names=names, n_jobs=n_jobs) - fl = '/'.join(fl.split(os.sep)) - invalid_char = '<>:"\|?* ' - for char in invalid_char: - fl = fl.replace(char, '') + fl = '/'.join(fl.split(os.sep)) + invalid_char = '<>:"\|?* ' + for char in invalid_char: + fl = fl.replace(char, '') - pathlib.Path(output_directory + fl).mkdir(parents=True, exist_ok=True) - features.to_csv(output_directory + fl + '/Features.csv', sep=',', encoding='utf-8') + pathlib.Path(output_directory + fl).mkdir(parents=True, exist_ok=True) + features.to_csv(output_directory + fl + '/Features.csv', sep=',', encoding='utf-8') - if verbose == 1: - print('Features files saved in: ', output_directory) + if verbose == 1: + print('Features files saved in: ', output_directory) + else: + raise FileNotFoundError("There is no folder(s) in directory: " + main_directory) def calc_features(wind_sig, dict_features, fs, **kwargs): @@ -165,7 +168,7 @@ def calc_features(wind_sig, dict_features, fs, **kwargs): Input from which features are computed, window dict_features : dict Dictionary with features - fs : int or None + fs : float or None Sampling frequency \**kwargs: * *features_path* (``string``) -- @@ -255,6 +258,12 @@ def time_series_features_extractor(dict_features, signal_windows, fs=None, verbo if names is not None: names = list(names) + else: + # Name of each column to be concatenated with feature name + if isinstance(signal_windows, pd.DataFrame): + names = signal_windows.columns.values + elif isinstance(signal_windows[0], pd.DataFrame): + names = signal_windows[0].columns.values if window_size is not None: signal_windows = signal_window_splitter(signal_windows, window_size, overlap) @@ -264,58 +273,72 @@ def time_series_features_extractor(dict_features, signal_windows, fs=None, verbo features_final = pd.DataFrame() - if isinstance(signal_windows, pd.DataFrame): - features_final = calc_window_features(dict_features, signal_windows, fs, verbose=verbose, single_window=True, - features_path=features_path, - header_names=names) - else: - if isinstance(signal_windows[0], numbers.Real): - feat_val = calc_window_features(dict_features, signal_windows, fs, verbose=verbose, single_window=True, - features_path=features_path, - header_names=names) - feat_val.reset_index(drop=True) - return feat_val + if isinstance(signal_windows, list) and isinstance(signal_windows[0], numbers.Real): + signal_windows = np.array(signal_windows) + + # more than one window + if isinstance(signal_windows, list): + # Starting the display of progress bar for notebooks interfaces + if (get_ipython().__class__.__name__ == "ZMQInteractiveShell") or ( + get_ipython().__class__.__name__ == "Shell" + ): + + out = display(progress_bar_notebook(0, len(signal_windows)), display_id=True) else: - # Starting the display of progress bar for notebooks interfaces - if (get_ipython().__class__.__name__ == 'ZMQInteractiveShell') or ( - get_ipython().__class__.__name__ == 'Shell'): + out = None - out = display(progress_bar_notebook(0, len(signal_windows)), display_id=True) + if isinstance(n_jobs, int): + # Multiprocessing use + if n_jobs == -1: + cpu_count = mp.cpu_count() else: - out = None - - if isinstance(n_jobs, int): - # Multiprocessing use - if n_jobs == -1: - cpu_count = mp.cpu_count() - else: - cpu_count = n_jobs - - pool = mp.Pool(cpu_count) - features = pool.imap(partial(calc_features, dict_features=dict_features, fs=fs, - features_path=features_path, header_names=names), signal_windows) - for i, feat in enumerate(features): - if verbose == 1: - display_progress_bar(i, signal_windows, out) - features_final = pd.concat([features_final, feat], axis=0) - - pool.close() - pool.join() - - elif n_jobs is None: - # Without multiprocessing - for i, feat in enumerate(signal_windows): - features_final = pd.concat( - [ - features_final, - calc_window_features( - dict_features, feat, fs, features_path=features_path, header_names=names) - ], axis=0) - if verbose == 1: - display_progress_bar(i, signal_windows, out) - else: - raise SystemExit('n_jobs value is not valid. ' - 'Choose an integer value or None for no multiprocessing.') + cpu_count = n_jobs + + pool = mp.Pool(cpu_count) + features = pool.imap( + partial( + calc_features, + dict_features=dict_features, + fs=fs, + features_path=features_path, + header_names=names, + ), + signal_windows, + ) + + for i, feat in enumerate(features): + if verbose == 1: + display_progress_bar(i, len(signal_windows), out) + features_final = pd.concat([features_final, feat], axis=0) + + pool.close() + pool.join() + + elif n_jobs is None: + for i, feat in enumerate(signal_windows): + features_final = pd.concat( + [ + features_final, + calc_window_features( + dict_features, feat, fs, features_path=features_path, header_names=names) + ], axis=0) + if verbose == 1: + display_progress_bar(i, len(signal_windows), out) + else: + raise SystemExit( + "n_jobs value is not valid. " "Choose an integer value or None for no multiprocessing." + ) + # single window + else: + features_final = calc_window_features( + dict_features, + signal_windows, + fs, + verbose=verbose, + features_path=features_path, + header_names=names, + single_window=True, + ) if verbose == 1: print("\n"+"*** Feature extraction finished ***") @@ -334,7 +357,7 @@ def calc_window_features(dict_features, signal_window, fs, verbose=1, single_win Dictionary with features signal_window: pandas DataFrame Input from which features are computed, window - fs : int + fs : float Sampling frequency verbose : int Level of function communication @@ -357,10 +380,22 @@ def calc_window_features(dict_features, signal_window, fs, verbose=1, single_win """ features_path = kwargs.get('features_path', None) - names = kwargs.get('header_names', None) + header_names = kwargs.get('header_names', None) + + # To handle object type signals + signal_window = np.array(signal_window).astype(float) + + single_axis = True if len(signal_window.shape) == 1 else False + + if header_names is None: + header_names = np.array([0]) if single_axis else np.arange(signal_window.shape[-1]) + else: + if (len(header_names) != signal_window.shape[-1] and not single_axis) or \ + (len(header_names) != 1 and single_axis): + raise Exception("header_names dimension does not match input columns.") # Execute imports - exec("import tsfel") + exec("from tsfel import *") domain = dict_features.keys() if features_path: @@ -370,10 +405,6 @@ def calc_window_features(dict_features, signal_window, fs, verbose=1, single_win exec("from " + features_path.split(os.sep)[-1][:-3]+" import *") # Create global arrays - func_total = [] - func_names = [] - imports_total = [] - parameters_total = [] feature_results = [] feature_names = [] @@ -385,7 +416,6 @@ def calc_window_features(dict_features, signal_window, fs, verbose=1, single_win if (get_ipython().__class__.__name__ == 'ZMQInteractiveShell') or ( get_ipython().__class__.__name__ == 'Shell'): - print(len(feat_nb)) out = display(progress_bar_notebook(0, len(feat_nb)), display_id=True) else: out = None @@ -399,84 +429,55 @@ def calc_window_features(dict_features, signal_window, fs, verbose=1, single_win if verbose == 1 and single_window: i_feat = i_feat + 1 - display_progress_bar(i_feat, feat_nb, out) + display_progress_bar(i_feat, len(feat_nb), out) # Only returns used functions - if dict_features[_type][feat]['use'] == 'yes': - - # Read Function Name (generic name) - func_names = [feat] + if dict_features[_type][feat]["use"] == "yes": # Read Function (real name of function) - func_total = [dict_features[_type][feat]['function']] + func_total = dict_features[_type][feat]["function"] + + if func_total.find("tsfel.") == 0: + func_total = func_total.replace("tsfel.", "") # Check for parameters - if dict_features[_type][feat]['parameters'] != '': - param = dict_features[_type][feat]['parameters'] + parameters_total = {} + + if dict_features[_type][feat]["parameters"] != "": + parameters_total = dict_features[_type][feat]["parameters"] # Check assert fs parameter: - if 'fs' in param: + if "fs" in parameters_total: # Select which fs to use if fs is None: - # Check if features dict has default sampling frequency value - if type(param['fs']) is int or type(param['fs']) is float: - parameters_total = [str(key) + '=' + str(value) for key, value in param.items()] - else: - raise Exception('No sampling frequency assigned.') + if not (type(parameters_total["fs"]) is int or type(parameters_total["fs"]) is float): + raise Exception("No sampling frequency assigned.") else: - parameters_total = [str(key) + '=' + str(value) for key, value in param.items() - if key not in 'fs'] - parameters_total += ['fs =' + str(fs)] + parameters_total["fs"] = fs - # feature has no fs parameter - else: - parameters_total = [] - for key, value in param.items(): - if type(value) is str: - value = '"'+value+'"' - parameters_total.append([str(key) + '=' + str(value)]) - else: - parameters_total = '' - - # To handle object type signals - signal_window = np.array(signal_window).astype(float) - - # Name of each column to be concatenate with feature name - if not isinstance(signal_window, pd.DataFrame): - signal_window = pd.DataFrame(data=signal_window) - - if names is not None: - if len(names) != len(list(signal_window.columns.values)): - raise Exception('header_names dimension does not match input columns.') - else: - header_names = names - else: - header_names = signal_window.columns.values + # Eval feature results + if single_axis: + eval_result = locals()[func_total](signal_window, **parameters_total) + eval_result = np.array([eval_result]) for ax in range(len(header_names)): - window = signal_window.iloc[:, ax] - execf = func_total[0] + '(window' - - if parameters_total != '': - execf += ', ' + str(parameters_total).translate(str.maketrans({'[': '', ']': '', "'": ''})) - - execf += ')' - eval_result = eval(execf, locals()) - + sig_ax = signal_window if single_axis else signal_window[:, ax] + eval_result_ax = locals()[func_total](sig_ax, **parameters_total) # Function returns more than one element - if type(eval_result) == tuple: - if np.isnan(eval_result[0]): - eval_result = np.zeros(len(eval_result)) - for rr in range(len(eval_result)): - feature_results += [eval_result[rr]] - feature_names += [str(header_names[ax]) + '_' + func_names[0] + '_' + str(rr)] + if type(eval_result_ax) == tuple: + if np.isnan(eval_result_ax[0]): + eval_result_ax = np.zeros(len(eval_result_ax)) + for rr in range(len(eval_result_ax)): + feature_results += [eval_result_ax[rr]] + feature_names += [str(header_names[ax]) + "_" + feat + "_" + str(rr)] else: - feature_results += [eval_result] - feature_names += [str(header_names[ax]) + '_' + func_names[0]] + feature_results += [eval_result_ax] + feature_names += [str(header_names[ax]) + "_" + feat] - features = pd.DataFrame(data=np.array(feature_results).reshape(1, len(feature_results)), - columns=np.array(feature_names)) + features = pd.DataFrame( + data=np.array(feature_results).reshape(1, len(feature_results)), columns=np.array(feature_names) + ) return features diff --git a/tsfel/feature_extraction/features.json b/tsfel/feature_extraction/features.json index 031809d..7f6e010 100644 --- a/tsfel/feature_extraction/features.json +++ b/tsfel/feature_extraction/features.json @@ -290,6 +290,26 @@ } }, "statistical": { + "Absolute energy": { + "complexity": "log", + "description": "Computes the absolute energy of the signal.", + "function": "tsfel.abs_energy", + "parameters": "", + "n_features": 1, + "use": "yes", + "tag": "audio" + }, + "Average power": { + "complexity": "constant", + "description": "Computes the average power of the signal.", + "function": "tsfel.average_power", + "parameters": { + "fs": 100 + }, + "n_features": 1, + "use": "yes", + "tag": "audio" + }, "ECDF": { "complexity": "log", "description": "Computes the values of ECDF (empirical cumulative distribution function) along the time axis.", @@ -320,6 +340,17 @@ "n_features": "percentile", "use": "yes" }, + "Entropy": { + "complexity": "log", + "description": "Computes the entropy of the signal using the Shannon Entropy.", + "function": "tsfel.entropy", + "parameters": { + "prob": "standard" + }, + "n_features": 1, + "use": "yes", + "tag": "eeg" + }, "Histogram": { "complexity": "log", "description": "Computes histogram of the signal.", @@ -396,6 +427,14 @@ "n_features": 1, "use": "yes" }, + "Peak to peak distance": { + "complexity": "constant", + "description": "Computes the peak to peak distance.", + "function": "tsfel.pk_pk_distance", + "parameters": "", + "n_features": 1, + "use": "yes" + }, "Root mean square": { "complexity": "constant", "description": "Computes root mean square of the signal.", @@ -434,15 +473,6 @@ } }, "temporal": { - "Absolute energy": { - "complexity": "log", - "description": "Computes the absolute energy of the signal.", - "function": "tsfel.abs_energy", - "parameters": "", - "n_features": 1, - "use": "yes", - "tag": "audio" - }, "Area under the curve": { "complexity": "log", "description": "Computes the area under the curve of the signal computed with trapezoid rule.", @@ -472,17 +502,6 @@ "n_features": 1, "use": "yes" }, - "Entropy": { - "complexity": "log", - "description": "Computes the entropy of the signal using the Shannon Entropy.", - "function": "tsfel.entropy", - "parameters": { - "prob": "standard" - }, - "n_features": 1, - "use": "yes", - "tag": "eeg" - }, "Mean absolute diff": { "complexity": "constant", "description": "Computes mean absolute differences of the signal.", @@ -534,14 +553,6 @@ "n_features": 1, "use": "yes" }, - "Peak to peak distance": { - "complexity": "constant", - "description": "Computes the peak to peak distance.", - "function": "tsfel.pk_pk_distance", - "parameters": "", - "n_features": 1, - "use": "yes" - }, "Positive turning points": { "complexity": "constant", "description": "Computes number of positive turning points of the signal.", @@ -575,17 +586,6 @@ "n_features": 1, "use": "yes" }, - "Total energy": { - "complexity": "constant", - "description": "Computes the total energy of the signal.", - "function": "tsfel.total_energy", - "parameters": { - "fs": 100 - }, - "n_features": 1, - "use": "yes", - "tag": "audio" - }, "Zero crossing rate": { "complexity": "constant", "description": "Computes Zero-crossing rate of the signal.", diff --git a/tsfel/feature_extraction/features.py b/tsfel/feature_extraction/features.py index 1ae3ec7..fa678ca 100644 --- a/tsfel/feature_extraction/features.py +++ b/tsfel/feature_extraction/features.py @@ -198,7 +198,7 @@ def distance(signal): """Computes signal traveled distance. Calculates the total distance traveled by the signal - using the hipotenusa between 2 datapoints. + using the hypotenuse between 2 datapoints. Feature computational cost: 1 @@ -261,31 +261,6 @@ def zero_cross(signal): return len(np.where(np.diff(np.sign(signal)))[0]) -@set_domain("domain", "temporal") -@set_domain("tag", "audio") -def total_energy(signal, fs): - """Computes the total energy of the signal. - - Feature computational cost: 1 - - Parameters - ---------- - signal : nd-array - Signal from which total energy is computed - fs : int - Sampling frequency - - Returns - ------- - float - Total energy - - """ - time = compute_time(signal, fs) - - return np.sum(np.array(signal) ** 2) / (time[-1] - time[0]) - - @set_domain("domain", "temporal") def slope(signal): """Computes the slope of the signal. @@ -320,7 +295,7 @@ def auc(signal, fs): ---------- signal : nd-array Input from which the area under the curve is computed - fs : int + fs : float Sampling Frequency Returns ------- @@ -334,6 +309,36 @@ def auc(signal, fs): @set_domain("domain", "temporal") +def neighbourhood_peaks(signal, n=10): + """Computes the number of peaks from a defined neighbourhood of the signal. + + Reference: Christ, M., Braun, N., Neuffer, J. and Kempa-Liehr A.W. (2018). Time Series FeatuRe Extraction on basis + of Scalable Hypothesis tests (tsfresh -- A Python package). Neurocomputing 307 (2018) 72-77 + + Parameters + ---------- + signal : nd-array + Input from which the number of neighbourhood peaks is computed + n : int + Number of peak's neighbours to the left and to the right + + Returns + ------- + int + The number of peaks from a defined neighbourhood of the signal + """ + signal = np.array(signal) + subsequence = signal[n:-n] + # initial iteration + peaks = ((subsequence > np.roll(signal, 1)[n:-n]) & (subsequence > np.roll(signal, -1)[n:-n])) + for i in range(2, n + 1): + peaks &= (subsequence > np.roll(signal, i)[n:-n]) + peaks &= (subsequence > np.roll(signal, -i)[n:-n]) + return np.sum(peaks) + + +# ############################################ STATISTICAL DOMAIN #################################################### # +@set_domain("domain", "statistical") @set_domain("tag", "audio") def abs_energy(signal): """Computes the absolute energy of the signal. @@ -354,29 +359,34 @@ def abs_energy(signal): return np.sum(np.abs(signal) ** 2) -@set_domain("domain", "temporal") -def pk_pk_distance(signal): - """Computes the peak to peak distance. +@set_domain("domain", "statistical") +@set_domain("tag", "audio") +def average_power(signal, fs): + """Computes the average power of the signal. Feature computational cost: 1 Parameters ---------- signal : nd-array - Input from which the area under the curve is computed + Signal from which average power is computed + fs : float + Sampling frequency Returns ------- float - peak to peak distance + Average power """ - return np.abs(np.max(signal) - np.min(signal)) + time = compute_time(signal, fs) + return np.sum(np.array(signal) ** 2) / (time[-1] - time[0]) -@set_domain("domain", "temporal") + +@set_domain("domain", "statistical") @set_domain("tag", "eeg") -def entropy(signal, prob='standard'): +def entropy(signal, prob="standard"): """Computes the entropy of the signal using the Shannon Entropy. Description in Article: @@ -399,12 +409,12 @@ def entropy(signal, prob='standard'): """ - if prob == 'standard': + if prob == "standard": value, counts = np.unique(signal, return_counts=True) p = counts / counts.sum() - elif prob == 'kde': + elif prob == "kde": p = kde(signal) - elif prob == 'gauss': + elif prob == "gauss": p = gaussian(signal) if np.sum(p) == 0: @@ -419,39 +429,7 @@ def entropy(signal, prob='standard'): elif np.sum(p * np.log2(p)) / np.log2(len(signal)) == 0: return 0.0 else: - return - np.sum(p * np.log2(p)) / np.log2(len(signal)) - - -@set_domain("domain", "temporal") -def neighbourhood_peaks(signal, n=10): - """Computes the number of peaks from a defined neighbourhood of the signal. - - Reference: Christ, M., Braun, N., Neuffer, J. and Kempa-Liehr A.W. (2018). Time Series FeatuRe Extraction on basis - of Scalable Hypothesis tests (tsfresh -- A Python package). Neurocomputing 307 (2018) 72-77 - - Parameters - ---------- - signal : nd-array - Input from which the number of neighbourhood peaks is computed - n : int - Number of peak's neighbours to the left and to the right - - Returns - ------- - int - The number of peaks from a defined neighbourhood of the signal - """ - signal = np.array(signal) - subsequence = signal[n:-n] - # initial iteration - peaks = ((subsequence > np.roll(signal, 1)[n:-n]) & (subsequence > np.roll(signal, -1)[n:-n])) - for i in range(2, n + 1): - peaks &= (subsequence > np.roll(signal, i)[n:-n]) - peaks &= (subsequence > np.roll(signal, -i)[n:-n]) - return np.sum(peaks) - - -# ############################################ STATISTICAL DOMAIN #################################################### # + return -np.sum(p * np.log2(p)) / np.log2(len(signal)) @set_domain("domain", "statistical") @@ -724,6 +702,26 @@ def calc_var(signal): return np.var(signal) +@set_domain("domain", "statistical") +def pk_pk_distance(signal): + """Computes the peak to peak distance. + + Feature computational cost: 1 + + Parameters + ---------- + signal : nd-array + Input from which peak to peak is computed + + Returns + ------- + float + peak to peak distance + + """ + return np.abs(np.max(signal) - np.min(signal)) + + @set_domain("domain", "statistical") def ecdf(signal, d=10): """Computes the values of ECDF (empirical cumulative distribution function) along the time axis. @@ -749,9 +747,39 @@ def ecdf(signal, d=10): return tuple(y[:d]) +@set_domain("domain", "statistical") +def ecdf_slope(signal, p_init=0.5, p_end=0.75): + """Computes the slope of the ECDF between two percentiles. + Possibility to return infinity values. + + Feature computational cost: 1 + + Parameters + ---------- + signal : nd-array + Input from which ECDF is computed + p_init : float + Initial percentile + p_end : float + End percentile + + Returns + ------- + float + The slope of the ECDF between two percentiles + """ + signal = np.array(signal) + # check if signal is constant + if np.sum(np.diff(signal)) == 0: + return np.inf + else: + x_init, x_end = ecdf_percentile(signal, percentile=[p_init, p_end]) + return (p_end - p_init) / (x_end - x_init) + + @set_domain("domain", "statistical") def ecdf_percentile(signal, percentile=[0.2, 0.8]): - """Computes the percentile values of the ECDF. + """Computes the percentile value of the ECDF. Feature computational cost: 1 @@ -846,7 +874,7 @@ def spectral_distance(signal, fs): ---------- signal : nd-array Signal from which spectral distance is computed - fs : int + fs : float Sampling frequency Returns @@ -878,7 +906,7 @@ def fundamental_frequency(signal, fs): ---------- signal : nd-array Input from which fundamental frequency is computed - fs : int + fs : float Sampling frequency Returns @@ -915,7 +943,7 @@ def max_power_spectrum(signal, fs): ---------- signal : nd-array Input from which maximum power spectrum is computed - fs : scalar + fs : float Sampling frequency Returns @@ -940,7 +968,7 @@ def max_frequency(signal, fs): ---------- signal : nd-array Input from which maximum frequency is computed - fs : int + fs : float Sampling frequency Returns @@ -1033,7 +1061,7 @@ def spectral_decrease(signal, fs): ---------- signal : nd-array Signal from which spectral decrease is computed - fs : int + fs : float Sampling frequency Returns @@ -1074,7 +1102,7 @@ def spectral_kurtosis(signal, fs): ---------- signal : nd-array Signal from which spectral kurtosis is computed - fs : int + fs : float Sampling frequency Returns @@ -1105,7 +1133,7 @@ def spectral_skewness(signal, fs): ---------- signal : nd-array Signal from which spectral skewness is computed - fs : int + fs : float Sampling frequency Returns @@ -1138,7 +1166,7 @@ def spectral_spread(signal, fs): ---------- signal : nd-array Signal from which spectral spread is computed. - fs : int + fs : float Sampling frequency Returns @@ -1173,7 +1201,7 @@ def spectral_slope(signal, fs): ---------- signal : nd-array Signal from which spectral slope is computed - fs : int + fs : float Sampling frequency Returns @@ -1215,7 +1243,7 @@ def spectral_variation(signal, fs): ---------- signal : nd-array Signal from which spectral variation is computed. - fs : int + fs : float Sampling frequency Returns @@ -1248,7 +1276,7 @@ def spectral_positive_turning(signal, fs): ---------- signal : nd-array Input from which the number of positive turning points of the fft magnitude are computed - fs : int + fs : float Sampling frequency Returns @@ -1281,7 +1309,7 @@ def spectral_roll_off(signal, fs): ---------- signal : nd-array Signal from which spectral roll-off is computed - fs : int + fs : float Sampling frequency Returns @@ -1310,7 +1338,7 @@ def spectral_roll_on(signal, fs): ---------- signal : nd-array Signal from which spectral roll-on is computed - fs : int + fs : float Sampling frequency Returns @@ -1340,7 +1368,7 @@ def human_range_energy(signal, fs): ---------- signal : nd-array Signal from which human range energy ratio is computed - fs : int + fs : float Sampling frequency Returns @@ -1381,7 +1409,7 @@ def mfcc(signal, fs, pre_emphasis=0.97, nfft=512, nfilt=40, num_ceps=12, cep_lif ---------- signal : nd-array Input from which MEL coefficients is computed - fs : int + fs : float Sampling frequency pre_emphasis : float Pre-emphasis coefficient for pre-emphasis filter application @@ -1402,9 +1430,9 @@ def mfcc(signal, fs, pre_emphasis=0.97, nfft=512, nfilt=40, num_ceps=12, cep_lif """ filter_banks = filterbank(signal, fs, pre_emphasis, nfft, nfilt) - mel_coeff = scipy.fft.dct(filter_banks, type=2, axis=0, norm='ortho')[1:(num_ceps + 1)] # Keep 2-13 + mel_coeff = scipy.fft.dct(filter_banks, type=2, axis=0, norm="ortho")[1 : (num_ceps + 1)] # Keep 2-13 - mel_coeff -= (np.mean(mel_coeff, axis=0) + 1e-8) + mel_coeff -= np.mean(mel_coeff, axis=0) + 1e-8 # liftering ncoeff = len(mel_coeff) @@ -1431,7 +1459,7 @@ def power_bandwidth(signal, fs): ---------- signal : nd-array Input from which the power bandwidth computed - fs : int + fs : float Sampling frequency Returns @@ -1474,7 +1502,7 @@ def fft_mean_coeff(signal, fs, nfreq=256): ---------- signal : nd-array Input from which fft mean coefficients are computed - fs : int + fs : float Sampling frequency nfreq : int The number of frequencies @@ -1540,7 +1568,7 @@ def spectral_entropy(signal, fs): ---------- signal : nd-array Input from which spectral entropy is computed - fs : int + fs : float Sampling frequency Returns diff --git a/tsfel/feature_extraction/features_utils.py b/tsfel/feature_extraction/features_utils.py index 399da36..fcafdf7 100644 --- a/tsfel/feature_extraction/features_utils.py +++ b/tsfel/feature_extraction/features_utils.py @@ -37,7 +37,7 @@ def calc_fft(signal, fs): ---------- signal : nd-array The input signal from which fft is computed - fs : int + fs : float Sampling frequency Returns @@ -49,10 +49,10 @@ def calc_fft(signal, fs): """ - fmag = np.abs(np.fft.fft(signal)) - f = np.linspace(0, fs // 2, len(signal) // 2) + fmag = np.abs(np.fft.rfft(signal)) + f = np.fft.rfftfreq(len(signal), d=1/fs) - return f[:len(signal) // 2].copy(), fmag[:len(signal) // 2].copy() + return f.copy(), fmag.copy() def filterbank(signal, fs, pre_emphasis=0.97, nfft=512, nfilt=40): @@ -68,7 +68,7 @@ def filterbank(signal, fs, pre_emphasis=0.97, nfft=512, nfilt=40): ---------- signal : nd-array Input from which filterbank is computed - fs : int + fs : float Sampling frequency pre_emphasis : float Pre-emphasis coefficient for pre-emphasis filter application diff --git a/tsfel/utils/__init__.py b/tsfel/utils/__init__.py index b0db8d1..afd3ece 100644 --- a/tsfel/utils/__init__.py +++ b/tsfel/utils/__init__.py @@ -1,4 +1,3 @@ -from tsfel.utils.gSheetsFilters import * from tsfel.utils.calculate_complexity import * from tsfel.utils.signal_processing import * from tsfel.utils.add_personal_features import * diff --git a/tsfel/utils/client_secret.json b/tsfel/utils/client_secret.json deleted file mode 100644 index 6c4f247..0000000 --- a/tsfel/utils/client_secret.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "service_account", - "project_id": "featext", - "private_key_id": "56fbb4d1800d41b28215f1634e2b835b62dcc773", - "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCTdqVM3hTn4asb\nXqOAh3Cdcu/b/M6rMfMZhJcq0Nrg32KzaxqaUjwCx8SpQNZePrxj/bIVLSSqt1ei\nf3RZ9e/EWcCbac8tJYbnfmLf1/9pvdD79+ptgwJ6YWYrdUkcZ7L2LpoDxexiatBm\nYnizqhD97xiJgBlOLSDpO3KL0ScqbtZjmj+SaM3vzkfppScccgU2M3IFXUirN2dR\naamDwqEOTrS7nQBByugFLUgtnEtWguiBAA2uk9ACFhzdUqOMq61KBvmEaWF09rWA\nLcm8S1naCrVVtxnQVzlrWBCeaAijrgx8XPMXADNQciMqraa+n+wHaIlwuWGRm3Pm\neunviFrPAgMBAAECggEAB9owBeVVOvChS2UqXB6H6JAleAnlS7Fuk2ztQlpVd7Jr\nNCPorvRONMLWnfhaiMPIl6NW8uwnruaoj1VkjTTu5RCJlJPeBrZ7fywTpn2joKUx\n2uNCDPSrCVOt/JiTmG1oVrF3Sw8kYnWFxTzKseXpzLhksyrYSYvEXBcOXhPB4IGP\nAtY8Zs0Fzl8YSEnkc66775A7qG4A27Sr3RH3hyw34TBOsnCepyVVGRWN66wBLxH7\noj6ZGvYK26pcbwv+Obhv8E3d+Mog8KhZqPSLLKSm5uioPsHVYIWmVkxf+kdRgCBS\n6ObVpVofL98UDTEY9XWc/Qa64i12Wm4xKeV8Qlf86QKBgQDIULNztGkP32cG3xVM\n0fb8dpj2TwokztHaC2+HKzim3zFK6E0ufC61UAgF+UE3c57aE4KiLTyTrFI/JXgp\nFDUGzom8nB8QOLJjfisDUfahJscfW2jvjQywkwX4shELJqpC+4j+9ZtC98WWv9qW\n2888BDOaOez/jQbZ7FslUp3+SQKBgQC8dMiTpvCPaAZlWdvCbcBr0O3z09bPdXrf\nZ6kNRDYlvRq/3Y77wShMFFoHMXayWPZau9FwvEWwwMF+4996Zwos2BckOMVuG0g4\nvXxazCjwlqqKn8r2K0fPSYVlmNEincK2LZeBB7stdAWdXn6raLUP3+PtxPheW6Ap\n/GcnY99wVwKBgQCTMWG76tyssi9FiFVhfoOr3gXmMAw3IdZoD7EjNOpLDIRvE6Xr\nO4si5i0PHqoCci5O9rkuLGlv5dcF2aWjIdsZJlllw567z72diE9ZADhnEFSPQR8p\nr46cjVx883O8quu/jo+LMbSmD+UcMdwQsHJmGnxEnr38xoc7SQdstHmuKQKBgQCo\nCiYTambUKHiThMVsn7pVKM4UfU7sW5+9dswJlUoG6pDghimJmFlbRUZlZZimPKcm\njpSZRneJvMaMY5oQpbIv/FreJHT+0frbBTLOL39Nz7qvsv4h9MOqNK9qwRGyISPO\nl+ag2gjv5aVgBjNCmjHgvs2ZZOnmESNGbNZ6DBbfLwKBgDwV+6FLcapBHXxwWeFO\nb2NhpwBDDoO0c/WTXb8LGeYV4wXqUHATl/4TIqPXADwv2T3omwZJnFDnghvZ3iou\nL/1uaWMyAKJMyC0ggDRo8KJHcK3A70RBODmh6cZAhHCDuolnabVuY9iS3/1vP4B1\nAiVnnxn2S4ELaChffcaGyZJu\n-----END PRIVATE KEY-----\n", - "client_email": "featext@featext.iam.gserviceaccount.com", - "client_id": "106680319408245288206", - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token", - "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", - "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/featext%40featext.iam.gserviceaccount.com" -} diff --git a/tsfel/utils/gSheetsFilters.py b/tsfel/utils/gSheetsFilters.py deleted file mode 100644 index 54bd5dd..0000000 --- a/tsfel/utils/gSheetsFilters.py +++ /dev/null @@ -1,225 +0,0 @@ -import ast -import warnings - -import gspread -import numpy as np -from oauth2client.service_account import ServiceAccountCredentials - -import tsfel -from tsfel.feature_extraction.features_settings import load_json -from tsfel.utils.calculate_complexity import compute_complexity - - -def filter_features(features, filters): - """Filtering features based on Google sheet. - - Parameters - ---------- - features : dict - Dictionary with features - filters : dict - Filters from Google sheets - - Returns - ------- - dict - Filtered features - - """ - features_all = list(np.concatenate([list(features[dk].keys()) for dk in sorted(features.keys())])) - list_shown, feat_shown = list(features.keys()), features_all - cost_shown = features_all - if filters['2'] != {}: - list_hidden = filters['2']['hiddenValues'] - list_shown = [dk for dk in features.keys() if dk not in list_hidden] - if filters['1'] != {}: - feat_hidden = filters['1']['hiddenValues'] - feat_shown = [ff for ff in features_all if ff not in feat_hidden] - if filters['3'] != {}: - cost_numbers = filters['3']['hiddenValues'] - cost_hidden = list(np.concatenate([['constant', 'log'] if int(cn) == 1 else - ['squared', 'nlog'] if int(cn) == 3 else ['linear'] - if int(cn) == 2 else ['unknown'] for cn in cost_numbers])) - cost_shown = [] - for dk in features.keys(): - cost_shown += [ff for ff in features[dk].keys() if features[dk][ff]['complexity'] not in cost_hidden] - features_filtered = list(np.concatenate([list(features[dk].keys()) - for dk in sorted(features.keys()) if dk in list_shown])) - features_filtered = [ff for ff in features_filtered if ff in feat_shown] - features_filtered = [cc for cc in features_filtered if cc in cost_shown] - - return features_filtered - - -def extract_sheet(gsheet_name, **kwargs): - """Interaction between features.json and Google sheets. - - Parameters - ---------- - gsheet_name : str - Google Sheet name - \**kwargs: - See below: - * *path_json* (``string``) -- - Json path - Returns - ------- - dict - Features - - """ - # Path to Tsfel - lib_path = tsfel.__path__ - - # Access features.json - path_json = kwargs.get('path_json', lib_path[0] + '/feature_extraction/features.json') - - # Read features.json into a dictionary of features and parameters - dict_features = load_json(path_json) - - # Number of features from json file - len_json = 0 - for domain in list(dict_features.keys()): - len_json += len(dict_features[domain].keys()) - - # Access Google sheet - # Scope and credentials using the content of client_secret.json file - scope = ['https://spreadsheets.google.com/feeds', - 'https://www.googleapis.com/auth/drive'] - creds = ServiceAccountCredentials.from_json_keyfile_name(lib_path[0] + '/utils/client_secret.json', scope) - - # Create a gspread client authorizing it using those credentials - client = gspread.authorize(creds) - - # and pass it to the spreadsheet name, getting access to sheet1 - confManager = client.open(gsheet_name) - sheet = confManager.sheet1 - metadata = confManager.fetch_sheet_metadata() - - # Reading from Google Sheet - # Features - list_of_features = sheet.col_values(2)[4:] - - try: - filters = metadata['sheets'][sheet.id]['basicFilter']['criteria'] - list_filt_features = filter_features(dict_features, filters) - except KeyError: - print('No filters running. Check Google Sheet filters.') - list_filt_features = list_of_features.copy() - - use_or_not = ['TRUE' if lf in list_filt_features else 'FALSE' for lf in list_of_features] - - assert len(list_of_features) <= (len_json), \ - "To insert a new feature, please add it to data/features.json with the code in src/utils/features.py" - - # adds a new feature in Google sheet if it is missing from features.json - if len(list_of_features) < (len_json): - - # new feature was added - for domain in dict_features.keys(): - for feat in dict_features[domain].keys(): - if feat not in list_of_features: - feat_dict = dict_features[domain][feat] - param = '' - fs = 'no' - - # Read parameters from features.json - if feat_dict['parameters']: - param = feat_dict['parameters'].copy() - if 'fs' in feat_dict['parameters']: - fs = 'yes' - param.pop('fs') - if len(param) == 0: - param = '' - - curve = feat_dict['complexity'] - curves_all = ['linear', 'log', 'squared', 'nlog', 'constant'] - complexity = compute_complexity(feat, domain, - path_json) if curve not in curves_all else 1 if curve in [ - 'constant', 'log'] else 2 if curve == 'linear' else 3 - new_feat = ['', feat, domain, complexity, fs, str(param), - feat_dict['description']] - - # checks if the Google sheet has no features - if sheet.findall(domain) == []: - idx_row = 4 - else: - idx_row = sheet.findall(domain)[-1].row - - # Add new feature at the end of feature domain - sheet.insert_row(new_feat, idx_row + 1) - print(feat + " feature was added to Google Sheet.") - - # Update list of features and domains from Google sheet - list_of_features = sheet.col_values(2)[4:] - - # Update filtered features from Google sheet. Check if filters exist. - try: - filters = metadata['sheets'][sheet.id]['basicFilter']['criteria'] - list_filt_features = filter_features(dict_features, filters) - except KeyError: - list_filt_features = list_of_features.copy() - - use_or_not = ['TRUE' if lf in list_filt_features else 'FALSE' for lf in list_of_features] - - assert 'TRUE' in use_or_not, 'Please select a feature to extract!' + '\n' - - # Reading from Google Sheet - # Domain - list_domain = sheet.col_values(3)[4:] - # Parameters and fs - gs_param_list = sheet.col_values(6)[4:] - gs_fs_list = sheet.col_values(5)[4:] - # Check for invalid fs parameter - try: - gs_fs = int(sheet.cell(4, 9).value) - except ValueError: - warnings.warn('Invalid sampling frequency. Setting a default 100Hz sampling frequency.') - gs_fs = 100 - sheet.update_cell(4, 9, str(gs_fs)) - - # Fix for empty cells in parameters column - if len(gs_param_list) < len(list_of_features): - empty = [''] * (len(list_of_features) - len(gs_param_list)) - gs_param_list = gs_param_list + empty - - # Update dict of features with changes from Google sheet - for ii, feature in enumerate(list_of_features): - domain = list_domain[ii] - try: - if use_or_not[ii] == 'TRUE': - dict_features[domain][feature]['use'] = 'yes' - # Check features parameters from Google sheet - if gs_param_list[ii] != '': - if dict_features[domain][feature]['parameters'] == '' or ('fs' in list( - dict(dict_features[domain][feature]['parameters'])) and len(list( - dict(dict_features[domain][feature]['parameters']))) == 1): - warnings.warn('The ' + feature + ' feature does not require parameters.') - else: - try: - param_sheet = ast.literal_eval(gs_param_list[ii]) - if not isinstance(param_sheet, dict): - warnings.warn('Invalid parameter format. Using the following parameters for ' + feature + ' feature: ' - + str(dict_features[domain][feature]['parameters'])) - else: - # update dic of features based on Google sheet - dict_features[domain][feature]['parameters'] = param_sheet - except ValueError: - warnings.warn('Invalid parameter format. Using the following parameters for ' + feature + ' feature: ' - + str(dict_features[domain][feature]['parameters'])) - elif dict_features[domain][feature]['parameters'] != '' and ('fs' not in list( - dict(dict_features[domain][feature]['parameters'])) or len(list( - dict(dict_features[domain][feature]['parameters']))) != 1): - warnings.warn('Using the following parameters for ' + feature + ' feature: ' - + str(dict_features[domain][feature]['parameters'])) - # Check features that use sampling frequency parameter - if gs_fs_list[ii] != 'no': - # update dict of features based on Google sheet fs - dict_features[domain][feature]['parameters']['fs'] = gs_fs - - else: - dict_features[domain][feature]['use'] = 'no' - except KeyError: - print('Unknown domain at cell', int(ii + 5)) - - return dict_features diff --git a/tsfel/utils/progress_bar.py b/tsfel/utils/progress_bar.py index db3a87e..cea58de 100644 --- a/tsfel/utils/progress_bar.py +++ b/tsfel/utils/progress_bar.py @@ -2,7 +2,7 @@ from IPython import get_ipython -def progress_bar_terminal(iteration, total, prefix='', suffix='', decimals=0, length=100, fill='█', printend="\r"): +def progress_bar_terminal(iteration, total, prefix="", suffix="", decimals=0, length=100, fill="█", printend="\r"): """Call in a loop to create terminal progress bar. Parameters @@ -27,15 +27,15 @@ def progress_bar_terminal(iteration, total, prefix='', suffix='', decimals=0, le percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total))) filledlength = int(length * iteration // total) - bar = fill * filledlength + '-' * (length - filledlength) - print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end=printend) + bar = fill * filledlength + "-" * (length - filledlength) + print("\r%s |%s| %s%% %s" % (prefix, bar, percent, suffix), end=printend) # Print New Line on Complete if iteration == total: print() def progress_bar_notebook(iteration, total=100): - """ Progress bar for notebooks. + """Progress bar for notebooks. Parameters ---------- @@ -49,11 +49,12 @@ def progress_bar_notebook(iteration, total=100): Progress bar for notebooks """ - result = int((iteration/total)*100) - return HTML(""" + result = int((iteration / total) * 100) + return HTML( + """

Progress: {result}% Complete -

+

- """.format(value=iteration, max_value=total, result=result)) + """.format( + value=iteration, max_value=total, result=result + ) + ) def display_progress_bar(iteration, total, out): - """ Displays progress bar according to python interface. + """Displays progress bar according to python interface. Parameters ---------- @@ -78,10 +82,12 @@ def display_progress_bar(iteration, total, out): """ - if (get_ipython().__class__.__name__ == 'ZMQInteractiveShell') or ( - get_ipython().__class__.__name__ == 'Shell') and out is not None: - out.update(progress_bar_notebook(iteration + 1, len(total))) + if ( + (get_ipython().__class__.__name__ == "ZMQInteractiveShell") + or (get_ipython().__class__.__name__ == "Shell") + and out is not None + ): + out.update(progress_bar_notebook(iteration + 1, total)) else: - progress_bar_terminal(iteration + 1, len(total), prefix='Progress:', suffix='Complete', - length=50) - return + progress_bar_terminal(iteration + 1, total, prefix="Progress:", suffix="Complete", length=50) + return \ No newline at end of file diff --git a/tsfel/utils/signal_processing.py b/tsfel/utils/signal_processing.py index bd80d04..1f267c4 100644 --- a/tsfel/utils/signal_processing.py +++ b/tsfel/utils/signal_processing.py @@ -81,7 +81,7 @@ def correlated_features(features, threshold=0.95): correlated features names """ - corr_matrix = features.corr() + corr_matrix = features.corr().abs() # Select upper triangle of correlation matrix upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool)) # Find index and column name of features with correlation greater than 0.95