From a67d1612775e0fe01fd11e8787394feb02f27c26 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Mon, 16 May 2022 09:18:23 -0700 Subject: [PATCH 01/24] build: add PSR as dev dependency --- poetry.lock | 430 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 430 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index fbe190f..f42a550 100644 --- a/poetry.lock +++ b/poetry.lock @@ -114,6 +114,22 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "bleach" +version = "5.0.0" +description = "An easy safelist-based HTML-sanitizing tool." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +six = ">=1.9.0" +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0)"] +dev = ["pip-tools (==6.5.1)", "pytest (==7.1.1)", "flake8 (==4.0.1)", "tox (==3.24.5)", "sphinx (==4.3.2)", "twine (==4.0.0)", "wheel (==0.37.1)", "hashin (==0.17.0)", "black (==22.3.0)", "mypy (==0.942)"] + [[package]] name = "certifi" version = "2021.10.8" @@ -155,6 +171,17 @@ python-versions = ">=3.7" [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "click-log" +version = "0.4.0" +description = "Logging integration for Click" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +click = "*" + [[package]] name = "codecov" version = "2.1.12" @@ -189,6 +216,25 @@ tomli = {version = "*", optional = true, markers = "extra == \"toml\""} [package.extras] toml = ["tomli"] +[[package]] +name = "cryptography" +version = "37.0.2" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] +docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"] +pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +sdist = ["setuptools_rust (>=0.11.4)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"] + [[package]] name = "debugpy" version = "1.6.0" @@ -213,6 +259,17 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "dotty-dict" +version = "1.3.0" +description = "Dictionary wrapper for quick access to deeply nested keys." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +setuptools_scm = "*" + [[package]] name = "entrypoints" version = "0.4" @@ -240,6 +297,28 @@ python-versions = "*" [package.extras] devel = ["colorama", "jsonschema", "json-spec", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] +[[package]] +name = "gitdb" +version = "4.0.9" +description = "Git Object Database" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +smmap = ">=3.0.1,<6" + +[[package]] +name = "gitpython" +version = "3.1.27" +description = "GitPython is a python library used to interact with Git repositories" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +gitdb = ">=4.0.1,<5" + [[package]] name = "greenlet" version = "1.1.2" @@ -291,6 +370,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "invoke" +version = "1.7.1" +description = "Pythonic task execution" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "ipykernel" version = "6.13.0" @@ -364,6 +451,18 @@ parso = ">=0.8.0,<0.9.0" qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] +[[package]] +name = "jeepney" +version = "0.8.0" +description = "Low-level, pure Python DBus protocol wrapper." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest", "pytest-trio", "pytest-asyncio (>=0.17)", "testpath", "trio", "async-timeout"] +trio = ["trio", "async-generator"] + [[package]] name = "jinja2" version = "3.1.2" @@ -454,6 +553,24 @@ traitlets = "*" [package.extras] test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] +[[package]] +name = "keyring" +version = "23.5.0" +description = "Store and access your passwords safely." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +importlib-metadata = ">=3.6" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = "<0.1.0 || >0.1.0,<0.1.1 || >0.1.1", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"] + [[package]] name = "lazy-object-proxy" version = "1.7.1" @@ -690,6 +807,17 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "pkginfo" +version = "1.8.2" +description = "Query metadatdata from sdists / bdists / installed packages." +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +testing = ["coverage", "nose"] + [[package]] name = "pluggy" version = "1.0.0" @@ -844,6 +972,48 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" [package.dependencies] six = ">=1.5" +[[package]] +name = "python-gitlab" +version = "3.4.0" +description = "Interact with GitLab API" +category = "dev" +optional = false +python-versions = ">=3.7.0" + +[package.dependencies] +requests = ">=2.25.0" +requests-toolbelt = ">=0.9.1" + +[package.extras] +autocompletion = ["argcomplete (>=1.10.0,<3)"] +yaml = ["PyYaml (>=5.2)"] + +[[package]] +name = "python-semantic-release" +version = "7.28.1" +description = "Automatic Semantic Versioning for Python projects" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +click = ">=7,<9" +click-log = ">=0.3,<1" +dotty-dict = ">=1.3.0,<2" +gitpython = ">=3.0.8,<4" +invoke = ">=1.4.1,<2" +python-gitlab = ">=2,<4" +requests = ">=2.25,<3" +semver = ">=2.10,<3" +tomlkit = ">=0.10.0,<0.11.0" +twine = ">=3,<4" + +[package.extras] +dev = ["tox", "isort", "black"] +docs = ["Sphinx (==1.3.6)"] +mypy = ["mypy", "types-requests"] +test = ["coverage (>=5,<6)", "pytest (>=5,<6)", "pytest-xdist (>=1,<2)", "pytest-mock (>=2,<3)", "responses (==0.13.3)", "mock (==1.3.0)"] + [[package]] name = "pytz" version = "2022.1" @@ -860,6 +1030,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "pywin32-ctypes" +version = "0.2.0" +description = "" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "pyyaml" version = "6.0" @@ -880,6 +1058,22 @@ python-versions = ">=3.6" cffi = {version = "*", markers = "implementation_name == \"pypy\""} py = {version = "*", markers = "implementation_name == \"pypy\""} +[[package]] +name = "readme-renderer" +version = "35.0" +description = "readme_renderer is a library for rendering \"readme\" descriptions for Warehouse" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +bleach = ">=2.1.0" +docutils = ">=0.13.1" +Pygments = ">=2.5.1" + +[package.extras] +md = ["cmarkgfm (>=0.8.0)"] + [[package]] name = "requests" version = "2.27.1" @@ -898,6 +1092,28 @@ urllib3 = ">=1.21.1,<1.27" socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +[[package]] +name = "requests-toolbelt" +version = "0.9.1" +description = "A utility belt for advanced users of python-requests" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "rfc3986" +version = "2.0.0" +description = "Validating URI References per RFC 3986" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +idna2008 = ["idna"] + [[package]] name = "scipy" version = "1.8.0" @@ -909,6 +1125,42 @@ python-versions = ">=3.8,<3.11" [package.dependencies] numpy = ">=1.17.3,<1.25.0" +[[package]] +name = "secretstorage" +version = "3.3.2" +description = "Python bindings to FreeDesktop.org Secret Service API" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" + +[[package]] +name = "semver" +version = "2.13.0" +description = "Python helper for Semantic Versioning (http://semver.org/)" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "setuptools-scm" +version = "6.4.2" +description = "the blessed package to manage your versions by scm tags" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +packaging = ">=20.0" +tomli = ">=1.0.0" + +[package.extras] +test = ["pytest (>=6.2)", "virtualenv (>20)"] +toml = ["setuptools (>=42)"] + [[package]] name = "six" version = "1.16.0" @@ -917,6 +1169,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "smmap" +version = "5.0.0" +description = "A pure Python implementation of a sliding window memory map manager" +category = "dev" +optional = false +python-versions = ">=3.6" + [[package]] name = "snowballstemmer" version = "2.2.0" @@ -1145,6 +1405,14 @@ category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "tomlkit" +version = "0.10.2" +description = "Style preserving TOML library" +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + [[package]] name = "toolz" version = "0.11.2" @@ -1161,6 +1429,23 @@ category = "main" optional = false python-versions = ">= 3.5" +[[package]] +name = "tqdm" +version = "4.64.0" +description = "Fast, Extensible Progress Meter" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["py-make (>=0.1.0)", "twine", "wheel"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "traitlets" version = "5.2.0" @@ -1172,6 +1457,26 @@ python-versions = ">=3.7" [package.extras] test = ["pytest", "pre-commit"] +[[package]] +name = "twine" +version = "3.8.0" +description = "Collection of utilities for publishing packages on PyPI" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +colorama = ">=0.4.3" +importlib-metadata = ">=3.6" +keyring = ">=15.1" +pkginfo = ">=1.8.1" +readme-renderer = ">=21.0" +requests = ">=2.20" +requests-toolbelt = ">=0.8.0,<0.9.0 || >0.9.0" +rfc3986 = ">=1.4.0" +tqdm = ">=4.14" +urllib3 = ">=1.26.0" + [[package]] name = "typing-extensions" version = "4.2.0" @@ -1209,6 +1514,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "wrapt" version = "1.14.1" @@ -1232,7 +1545,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = ">=3.9, <3.11" -content-hash = "fb53c9563ce775739c038488982af5ee693be6378004488fb0d5876550bd06a9" +content-hash = "8613b3abc288fa9a243ab25e3ebd1c6d6ba25ad9c8f3bc5a9cdc27c396ae743c" [metadata.files] alabaster = [ @@ -1275,6 +1588,10 @@ backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] +bleach = [ + {file = "bleach-5.0.0-py3-none-any.whl", hash = "sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1"}, + {file = "bleach-5.0.0.tar.gz", hash = "sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565"}, +] certifi = [ {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, @@ -1339,6 +1656,10 @@ click = [ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] +click-log = [ + {file = "click-log-0.4.0.tar.gz", hash = "sha256:3970f8570ac54491237bcdb3d8ab5e3eef6c057df29f8c3d1151a51a9c23b975"}, + {file = "click_log-0.4.0-py2.py3-none-any.whl", hash = "sha256:a43e394b528d52112af599f2fc9e4b7cf3c15f94e53581f74fa6867e68c91756"}, +] codecov = [ {file = "codecov-2.1.12-py2.py3-none-any.whl", hash = "sha256:585dc217dc3d8185198ceb402f85d5cb5dbfa0c5f350a5abcdf9e347776a5b47"}, {file = "codecov-2.1.12-py3.8.egg", hash = "sha256:782a8e5352f22593cbc5427a35320b99490eb24d9dcfa2155fd99d2b75cfb635"}, @@ -1391,6 +1712,30 @@ coverage = [ {file = "coverage-6.3.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:18d520c6860515a771708937d2f78f63cc47ab3b80cb78e86573b0a760161faf"}, {file = "coverage-6.3.2.tar.gz", hash = "sha256:03e2a7826086b91ef345ff18742ee9fc47a6839ccd517061ef8fa1976e652ce9"}, ] +cryptography = [ + {file = "cryptography-37.0.2-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181"}, + {file = "cryptography-37.0.2-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336"}, + {file = "cryptography-37.0.2-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004"}, + {file = "cryptography-37.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe"}, + {file = "cryptography-37.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804"}, + {file = "cryptography-37.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c"}, + {file = "cryptography-37.0.2-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178"}, + {file = "cryptography-37.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a"}, + {file = "cryptography-37.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15"}, + {file = "cryptography-37.0.2-cp36-abi3-win32.whl", hash = "sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0"}, + {file = "cryptography-37.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d"}, + {file = "cryptography-37.0.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9"}, + {file = "cryptography-37.0.2-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1"}, + {file = "cryptography-37.0.2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023"}, + {file = "cryptography-37.0.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06"}, + {file = "cryptography-37.0.2-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717"}, + {file = "cryptography-37.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f"}, + {file = "cryptography-37.0.2-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982"}, + {file = "cryptography-37.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4"}, + {file = "cryptography-37.0.2-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de"}, + {file = "cryptography-37.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452"}, + {file = "cryptography-37.0.2.tar.gz", hash = "sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e"}, +] debugpy = [ {file = "debugpy-1.6.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:eb1946efac0c0c3d411cea0b5ac772fbde744109fd9520fb0c5a51979faf05ad"}, {file = "debugpy-1.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e3513399177dd37af4c1332df52da5da1d0c387e5927dc4c0709e26ee7302e8f"}, @@ -1419,6 +1764,9 @@ docutils = [ {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, ] +dotty-dict = [ + {file = "dotty_dict-1.3.0.tar.gz", hash = "sha256:eb0035a3629ecd84397a68f1f42f1e94abd1c34577a19cd3eacad331ee7cbaf0"}, +] entrypoints = [ {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"}, {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"}, @@ -1431,6 +1779,14 @@ fastjsonschema = [ {file = "fastjsonschema-2.15.3-py3-none-any.whl", hash = "sha256:ddb0b1d8243e6e3abb822bd14e447a89f4ab7439342912d590444831fa00b6a0"}, {file = "fastjsonschema-2.15.3.tar.gz", hash = "sha256:0a572f0836962d844c1fc435e200b2e4f4677e4e6611a2e3bdd01ba697c275ec"}, ] +gitdb = [ + {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, + {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, +] +gitpython = [ + {file = "GitPython-3.1.27-py3-none-any.whl", hash = "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"}, + {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"}, +] greenlet = [ {file = "greenlet-1.1.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6"}, {file = "greenlet-1.1.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a"}, @@ -1504,6 +1860,10 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +invoke = [ + {file = "invoke-1.7.1-py3-none-any.whl", hash = "sha256:2dc975b4f92be0c0a174ad2d063010c8a1fdb5e9389d69871001118b4fcac4fb"}, + {file = "invoke-1.7.1.tar.gz", hash = "sha256:7b6deaf585eee0a848205d0b8c0014b9bf6f287a8eb798818a642dff1df14b19"}, +] ipykernel = [ {file = "ipykernel-6.13.0-py3-none-any.whl", hash = "sha256:2b0987af43c0d4b62cecb13c592755f599f96f29aafe36c01731aaa96df30d39"}, {file = "ipykernel-6.13.0.tar.gz", hash = "sha256:0e28273e290858393e86e152b104e5506a79c13d25b951ac6eca220051b4be60"}, @@ -1516,6 +1876,10 @@ jedi = [ {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, ] +jeepney = [ + {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, + {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, +] jinja2 = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, @@ -1536,6 +1900,10 @@ jupyter-core = [ {file = "jupyter_core-4.10.0-py3-none-any.whl", hash = "sha256:e7f5212177af7ab34179690140f188aa9bf3d322d8155ed972cbded19f55b6f3"}, {file = "jupyter_core-4.10.0.tar.gz", hash = "sha256:a6de44b16b7b31d7271130c71a6792c4040f077011961138afed5e5e73181aec"}, ] +keyring = [ + {file = "keyring-23.5.0-py3-none-any.whl", hash = "sha256:b0d28928ac3ec8e42ef4cc227822647a19f1d544f21f96457965dc01cf555261"}, + {file = "keyring-23.5.0.tar.gz", hash = "sha256:9012508e141a80bd1c0b6778d5c610dd9f8c464d75ac6774248500503f972fb9"}, +] lazy-object-proxy = [ {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, @@ -1714,6 +2082,10 @@ pickleshare = [ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] +pkginfo = [ + {file = "pkginfo-1.8.2-py2.py3-none-any.whl", hash = "sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc"}, + {file = "pkginfo-1.8.2.tar.gz", hash = "sha256:542e0d0b6750e2e21c20179803e40ab50598d8066d51097a0e382cba9eb02bff"}, +] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, @@ -1819,6 +2191,14 @@ python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] +python-gitlab = [ + {file = "python-gitlab-3.4.0.tar.gz", hash = "sha256:6180b81ee2f265ad8d8412956a1740b4d3ceca7b28ae2f707dfe62375fed0082"}, + {file = "python_gitlab-3.4.0-py3-none-any.whl", hash = "sha256:251b63f0589d51f854516948c84e9eb8df26e1e9dea595cf86b43f17c43007dd"}, +] +python-semantic-release = [ + {file = "python-semantic-release-7.28.1.tar.gz", hash = "sha256:d7f82b3d4c06b304d07689b8a1c7d0d448ff07c2ab81cd810c4f2f900f24c599"}, + {file = "python_semantic_release-7.28.1-py3-none-any.whl", hash = "sha256:319c3e811d6e10bc3f0e967419eae0e5e9ba1e6745aa2fd94dd24e3995541ca2"}, +] pytz = [ {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"}, {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"}, @@ -1839,6 +2219,10 @@ pywin32 = [ {file = "pywin32-304-cp39-cp39-win32.whl", hash = "sha256:25746d841201fd9f96b648a248f731c1dec851c9a08b8e33da8b56148e4c65cc"}, {file = "pywin32-304-cp39-cp39-win_amd64.whl", hash = "sha256:d24a3382f013b21aa24a5cfbfad5a2cd9926610c0affde3e8ab5b3d7dbcf4ac9"}, ] +pywin32-ctypes = [ + {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, + {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, +] pyyaml = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, @@ -1923,10 +2307,22 @@ pyzmq = [ {file = "pyzmq-22.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d6157793719de168b199194f6b6173f0ccd3bf3499e6870fac17086072e39115"}, {file = "pyzmq-22.3.0.tar.gz", hash = "sha256:8eddc033e716f8c91c6a2112f0a8ebc5e00532b4a6ae1eb0ccc48e027f9c671c"}, ] +readme-renderer = [ + {file = "readme_renderer-35.0-py3-none-any.whl", hash = "sha256:73b84905d091c31f36e50b4ae05ae2acead661f6a09a9abb4df7d2ddcdb6a698"}, + {file = "readme_renderer-35.0.tar.gz", hash = "sha256:a727999acfc222fc21d82a12ed48c957c4989785e5865807c65a487d21677497"}, +] requests = [ {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, ] +requests-toolbelt = [ + {file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"}, + {file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"}, +] +rfc3986 = [ + {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"}, + {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"}, +] scipy = [ {file = "scipy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:87b01c7d5761e8a266a0fbdb9d88dcba0910d63c1c671bdb4d99d29f469e9e03"}, {file = "scipy-1.8.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ae3e327da323d82e918e593460e23babdce40d7ab21490ddf9fc06dec6b91a18"}, @@ -1952,10 +2348,26 @@ scipy = [ {file = "scipy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb7088e89cd751acf66195d2f00cf009a1ea113f3019664032d9075b1e727b6c"}, {file = "scipy-1.8.0.tar.gz", hash = "sha256:31d4f2d6b724bc9a98e527b5849b8a7e589bf1ea630c33aa563eda912c9ff0bd"}, ] +secretstorage = [ + {file = "SecretStorage-3.3.2-py3-none-any.whl", hash = "sha256:755dc845b6ad76dcbcbc07ea3da75ae54bb1ea529eb72d15f83d26499a5df319"}, + {file = "SecretStorage-3.3.2.tar.gz", hash = "sha256:0a8eb9645b320881c222e827c26f4cfcf55363e8b374a021981ef886657a912f"}, +] +semver = [ + {file = "semver-2.13.0-py2.py3-none-any.whl", hash = "sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4"}, + {file = "semver-2.13.0.tar.gz", hash = "sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f"}, +] +setuptools-scm = [ + {file = "setuptools_scm-6.4.2-py3-none-any.whl", hash = "sha256:acea13255093849de7ccb11af9e1fb8bde7067783450cee9ef7a93139bddf6d4"}, + {file = "setuptools_scm-6.4.2.tar.gz", hash = "sha256:6833ac65c6ed9711a4d5d2266f8024cfa07c533a0e55f4c12f6eff280a5a9e30"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +smmap = [ + {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, + {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, +] snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, @@ -2050,6 +2462,10 @@ tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +tomlkit = [ + {file = "tomlkit-0.10.2-py3-none-any.whl", hash = "sha256:905cf92c2111ef80d355708f47ac24ad1b6fc2adc5107455940088c9bbecaedb"}, + {file = "tomlkit-0.10.2.tar.gz", hash = "sha256:30d54c0b914e595f3d10a87888599eab5321a2a69abc773bbefff51599b72db6"}, +] toolz = [ {file = "toolz-0.11.2-py3-none-any.whl", hash = "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f"}, {file = "toolz-0.11.2.tar.gz", hash = "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33"}, @@ -2097,10 +2513,18 @@ tornado = [ {file = "tornado-6.1-cp39-cp39-win_amd64.whl", hash = "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4"}, {file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"}, ] +tqdm = [ + {file = "tqdm-4.64.0-py2.py3-none-any.whl", hash = "sha256:74a2cdefe14d11442cedf3ba4e21a3b84ff9a2dbdc6cfae2c34addb2a14a5ea6"}, + {file = "tqdm-4.64.0.tar.gz", hash = "sha256:40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d"}, +] traitlets = [ {file = "traitlets-5.2.0-py3-none-any.whl", hash = "sha256:9dd4025123fbe018a2092b2ad6984792f53ea3362c698f37473258b1fa97b0bc"}, {file = "traitlets-5.2.0.tar.gz", hash = "sha256:60474f39bf1d39a11e0233090b99af3acee93bbc2281777e61dd8c87da8a0014"}, ] +twine = [ + {file = "twine-3.8.0-py3-none-any.whl", hash = "sha256:d0550fca9dc19f3d5e8eadfce0c227294df0a2a951251a4385797c8a6198b7c8"}, + {file = "twine-3.8.0.tar.gz", hash = "sha256:8efa52658e0ae770686a13b675569328f1fba9837e5de1867bfe5f46a9aefe19"}, +] typing-extensions = [ {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"}, {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"}, @@ -2117,6 +2541,10 @@ wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] +webencodings = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] wrapt = [ {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, diff --git a/pyproject.toml b/pyproject.toml index 203792f..970b554 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ codecov = "^2.1.12" myst-nb = {version = "^0.15.0", python = "^3.9"} sphinx-autoapi = "^1.8.4" sphinx-rtd-theme = "^1.0.0" +python-semantic-release = "^7.28.1" [tool.semantic_release] version_variable = "pyproject.toml:version" # version location branch = "main" # branch to make releases of From 8905d5980ba4d24451e92cc31f017d06f926a04b Mon Sep 17 00:00:00 2001 From: Daniel King Date: Mon, 16 May 2022 12:10:45 -0700 Subject: [PATCH 02/24] build: add codecov with upload token --- .github/workflows/ci-cd.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 05a8294..dcccd2c 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -26,11 +26,11 @@ jobs: - name: Test with pytest run: poetry run pytest tests/ --cov=emgdecompy --cov-report=xml -# Can't use Codecov because repo is private -# - name: Use Codecov to track coverage -# uses: codecov/codecov-action@v2 -# with: -# files: ./coverage.xml # coverage report + - name: Use Codecov to track coverage + uses: codecov/codecov-action@v2 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ./coverage.xml # coverage report - name: Build documentation run: poetry run make html --directory docs/ From e744a7c704cfdfba43fd37003d47f0bae9de231c Mon Sep 17 00:00:00 2001 From: Rada Rudyak Date: Mon, 16 May 2022 23:50:06 -0700 Subject: [PATCH 03/24] fix: small change to create_emg_data() function to not allow 1 dimensional arrays to be created --- tests/test_emgdecompy.py | 87 +++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index fefb9a8..49f764c 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -1,8 +1,9 @@ from emgdecompy import emgdecompy as emg -import random +import random import numpy as np from scipy import linalg + def test_extend_input_by_R(): """ Run unit tests on extend_input_by_R function from EMGdecomPy. @@ -15,13 +16,18 @@ def test_extend_input_by_R(): assert emg.extend_input_by_R(x, R_one)[0][-1] == 0 assert emg.extend_input_by_R(x, R_one).shape == (len(x), R_one + 1) assert emg.extend_input_by_R(x, R_one)[-1][0] == x[-1] - assert emg.extend_input_by_R(x, R_one)[0][0] == emg.extend_input_by_R(x, R_one)[1][1] + assert ( + emg.extend_input_by_R(x, R_one)[0][0] == emg.extend_input_by_R(x, R_one)[1][1] + ) assert emg.extend_input_by_R(x, R_two)[0][0] == x[0] assert emg.extend_input_by_R(x, R_two)[0][-1] == 0 assert emg.extend_input_by_R(x, R_two).shape == (len(x), R_two + 1) assert emg.extend_input_by_R(x, R_two)[-1][0] == x[-1] - assert emg.extend_input_by_R(x, R_two)[0][0] == emg.extend_input_by_R(x, R_two)[1][1] + assert ( + emg.extend_input_by_R(x, R_two)[0][0] == emg.extend_input_by_R(x, R_two)[1][1] + ) + def test_extend_all_channels(): """ @@ -31,28 +37,43 @@ def test_extend_all_channels(): R_two = 10 x_mat = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) - assert emg.extend_all_channels(x_mat, R_one).shape == (len(x_mat), len(x_mat[0]), R_one + 1) - assert emg.extend_all_channels(x_mat, R_one)[0][0][0] == emg.extend_input_all_channels(x_mat, R_one)[0][1][1] + assert emg.extend_all_channels(x_mat, R_one).shape == ( + len(x_mat), + len(x_mat[0]), + R_one + 1, + ) + assert ( + emg.extend_all_channels(x_mat, R_one)[0][0][0] + == emg.extend_input_all_channels(x_mat, R_one)[0][1][1] + ) assert emg.extend_all_channels(x_mat, R_one)[0][0][-1] == 0 assert sum(emg.extend_all_channels(x_mat, R_one)[-1][-1]) == sum(x_mat[-1]) - assert emg.extend_all_channels(x_mat, R_two).shape == (len(x_mat), len(x_mat[0]), R_two + 1) - assert emg.extend_all_channels(x_mat, R_two)[0][0][0] == emg.extend_input_all_channels(x_mat, R_two)[0][1][1] + assert emg.extend_all_channels(x_mat, R_two).shape == ( + len(x_mat), + len(x_mat[0]), + R_two + 1, + ) + assert ( + emg.extend_all_channels(x_mat, R_two)[0][0][0] + == emg.extend_input_all_channels(x_mat, R_two)[0][1][1] + ) assert emg.extend_all_channels(x_mat, R_two)[0][0][-1] == 0 assert sum(emg.extend_all_channels(x_mat, R_two)[-1][-1]) == sum(x_mat[-1]) + def create_emg_data(m=13, n=5, q=10): """ Creates array (m, n) of arrays (1, q) with one empty subarray. - + Parameters --------- m : int Number of rows to set as outer array size. The default size is 13. n : int - Number of entries for outer array to have in each row. The default size is 5. + Number of entries for outer array to have in each row. The default size is 5. q : int - Number of entries for inner array to have in each row. The default size is 10; the default shape is (1, 10). + Number of entries for inner array to have in each row. The default size is 10; the default shape is (1, 10). Returns ------- @@ -64,78 +85,80 @@ def create_emg_data(m=13, n=5, q=10): fake_data = np.zeros([m, n], dtype=object) + # list of five sets of fake data for i in range(0, m): - fake_data[i, :] = [np.random.randn(1,q)] # same sequence for each row in array + fake_data[i, :] = [np.random.randn(1, q)] # same sequence for each row in array fake_data[empty_row, empty_col] = np.array([]) - + return fake_data + def test_flatten_signal(): """ Run unit tests on flatten_signal function from EMGdecomPy. """ - # create fake data + # create fake data fake_data = [] - for i in range(0,4): - m = np.random.randint(1, 150) - n = np.random.randint(1, 150) - q = np.random.randint(1, 150) + for i in range(0, 4): + m = np.random.randint(2, 150) + n = np.random.randint(2, 150) + q = np.random.randint(2, 150) fake_data.append(create_emg_data(m, n, q)) - # run tests on fake datasets for i in fake_data: - + # test that input is correct assert type(i) == np.ndarray, "Input is not type numpy.ndarray" - assert i.shape != (1,1), "Input array is already one-dimensional." + assert i.shape != (1, 1), "Input array is already one-dimensional." flat = emg.flatten_signal(i) - - # shape of fake data + + # shape of fake data m, n = i.shape q = flat.shape[1] - - # test that inner arrays are correct length + + # test that inner arrays are correct length assert i[0][0].shape[1] == q, "Dimensions of inner array not the same." - - # test that empty channel has been removed + + # test that empty channel has been removed assert (m * n) != flat.shape[0], "Empty array not removed" + def test_center_matrix(): """ Run unit tests on center_matrix function from EMGdecomPy. """ x1 = np.array([[1, 2, 3], [4, 6, 8]]) x2 = np.array([[[1, 2, 3], [4, 6, 8]], [[10, 13, 16], [17, 21, 25]]]) - + # assert center_matrix works on a 2D array assert (emg.center_matrix(x1)[0] == x1[0] - x1[0].mean()).all() assert (emg.center_matrix(x1)[1] == x1[1] - x1[1].mean()).all() - + # assert center_matrix works on a 3D array assert (emg.center_matrix(x2)[0][0] == x2[0][0] - x2[0][0].mean()).all() assert (emg.center_matrix(x2)[0][1] == x2[0][1] - x2[0][1].mean()).all() assert (emg.center_matrix(x2)[1][0] == x2[1][0] - x2[1][0].mean()).all() assert (emg.center_matrix(x2)[1][1] == x2[1][1] - x2[1][1].mean()).all() + def test_whiten(): """ Run unit test on whitening function from EMGdecomPy. """ - x = np.array([[1, 2, 3, 4], - [5, 6, 7, 8]]) + x = np.array([[1, 2, 3, 4], [5, 6, 7, 8]]) x_cent = emg.center_matrix(x) cov_mat = np.cov(x_cent, rowvar=True, bias=True) w, v = linalg.eig(cov_mat) - #w += w[:len(w) / 2].mean() + # w += w[:len(w) / 2].mean() D = np.diag(w) D = np.sqrt(linalg.inv(D)) D = D.real.round(4) W = np.dot(np.dot(v, D), v.T) np.dot(W, x_cent) - assert np.allclose(np.dot(W, x_cent), emg.whiten(x)) \ No newline at end of file + assert np.allclose(np.dot(W, x_cent), emg.whiten(x)) From a7c0da45dd6f07dc81c05a7409505e6723cbbac1 Mon Sep 17 00:00:00 2001 From: Rada Rudyak Date: Tue, 17 May 2022 00:18:25 -0700 Subject: [PATCH 04/24] fix: tweak test_flatten_signal to test for empty arrays pre-flatten --- tests/test_emgdecompy.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index 49f764c..5aa5be4 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -122,7 +122,11 @@ def test_flatten_signal(): q = flat.shape[1] # test that inner arrays are correct length - assert i[0][0].shape[1] == q, "Dimensions of inner array not the same." + # test that inner arrays are correct length + if 0 not in i[0][0].shape: + assert i[0][0].shape[1] == q, "Dimensions of inner array not the same." + else: + assert i[0][1].shape[1] == q, "Dimensions of inner array not the same." # test that empty channel has been removed assert (m * n) != flat.shape[0], "Empty array not removed" From 97d67c9ef6c663e4aab3c31167dd6775a1a313c1 Mon Sep 17 00:00:00 2001 From: Rada Rudyak Date: Tue, 17 May 2022 00:19:24 -0700 Subject: [PATCH 05/24] fix: tweak create_emg_data to use np.empty so that shape is consistent with real data --- tests/test_emgdecompy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index 5aa5be4..f435ff9 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -89,7 +89,7 @@ def create_emg_data(m=13, n=5, q=10): for i in range(0, m): fake_data[i, :] = [np.random.randn(1, q)] # same sequence for each row in array - fake_data[empty_row, empty_col] = np.array([]) + fake_data[empty_row, empty_col] = np.empty([0,0]) return fake_data From 539b38630789fcac6e257530db95b23f49d45e46 Mon Sep 17 00:00:00 2001 From: Jasmine Ortega Date: Tue, 17 May 2022 16:20:41 -0700 Subject: [PATCH 06/24] test: update extend_input_by_R tests --- tests/test_emgdecompy.py | 41 ++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index fefb9a8..c5ee923 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -5,23 +5,32 @@ def test_extend_input_by_R(): """ - Run unit tests on extend_input_by_R function from EMGdecomPy. + Run unit tests on extend_input_by_R function from emg-decomPy """ - R_one = 5 - R_two = 10 - x = np.array([1, 2, 3, 4, 5, 6, 7]) - - assert emg.extend_input_by_R(x, R_one)[0][0] == x[0] - assert emg.extend_input_by_R(x, R_one)[0][-1] == 0 - assert emg.extend_input_by_R(x, R_one).shape == (len(x), R_one + 1) - assert emg.extend_input_by_R(x, R_one)[-1][0] == x[-1] - assert emg.extend_input_by_R(x, R_one)[0][0] == emg.extend_input_by_R(x, R_one)[1][1] - - assert emg.extend_input_by_R(x, R_two)[0][0] == x[0] - assert emg.extend_input_by_R(x, R_two)[0][-1] == 0 - assert emg.extend_input_by_R(x, R_two).shape == (len(x), R_two + 1) - assert emg.extend_input_by_R(x, R_two)[-1][0] == x[-1] - assert emg.extend_input_by_R(x, R_two)[0][0] == emg.extend_input_by_R(x, R_two)[1][1] + + for i in range(0, 15): + R = np.random.randint(1, 100) # to extend + + assert R % 1 == 0, "Value of R is not an integer." + assert R > 0 , "Value of R must be greater than zero." + + # length of input array + if R == 1: + q = 1 + + else: + q = np.random.randint(1, R) + + middle = round(q/2) + x = np.random.rand(q) # create input array + + testing = emg.extend_input_by_R(x, R) + + assert testing[1][0] == 0, "Array not extended properly." # check first value + assert testing[middle][middle] == x[0] # check middle value + assert testing[q-1][q-1] == x[0], "Array not extended properly." # check end value + assert testing.shape == (R+1, x.shape[0]), "Shape of extended array incorrect" + def test_extend_all_channels(): """ From 79490f462fa946c123b747b38187e2cc919c0fc7 Mon Sep 17 00:00:00 2001 From: Jasmine Ortega Date: Tue, 17 May 2022 16:27:59 -0700 Subject: [PATCH 07/24] docs: fix doc string for test_extend_by_R() --- tests/test_emgdecompy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index c5ee923..568feec 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -5,7 +5,7 @@ def test_extend_input_by_R(): """ - Run unit tests on extend_input_by_R function from emg-decomPy + Run unit tests on extend_input_by_R function from EMGdecomPy. """ for i in range(0, 15): From bcc735cbed770547beacf584a1579ab481e3ba00 Mon Sep 17 00:00:00 2001 From: Rada Rudyak Date: Tue, 17 May 2022 16:28:58 -0700 Subject: [PATCH 08/24] docs: add clarification comment to test_flatten() according to Jasmine's feedback --- tests/test_emgdecompy.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index f435ff9..2684b9d 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -89,7 +89,7 @@ def create_emg_data(m=13, n=5, q=10): for i in range(0, m): fake_data[i, :] = [np.random.randn(1, q)] # same sequence for each row in array - fake_data[empty_row, empty_col] = np.empty([0,0]) + fake_data[empty_row, empty_col] = np.empty([0, 0]) return fake_data @@ -122,7 +122,9 @@ def test_flatten_signal(): q = flat.shape[1] # test that inner arrays are correct length - # test that inner arrays are correct length + + # if the first element is null array that was removed in flat, + # check the second element's shape for consistency if 0 not in i[0][0].shape: assert i[0][0].shape[1] == q, "Dimensions of inner array not the same." else: From 6c3ac94e8f56b96ae9f216f177027bb116a80906 Mon Sep 17 00:00:00 2001 From: Jasmine Ortega Date: Wed, 18 May 2022 13:38:08 -0700 Subject: [PATCH 09/24] test: update unit tests for extend_input_all_channels() --- tests/test_emgdecompy.py | 48 +++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index 568feec..b3e6050 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -36,20 +36,46 @@ def test_extend_all_channels(): """ Run unit tests on extend_input_all_channels function from EMGdecomPy. """ - R_one = 5 - R_two = 10 - x_mat = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + for i in range(0, 15): + + # initalize dimensions of test data + x = np.random.randint(2, 100) + y = np.random.randint(2, 100) + z = np.random.randint(2, 1000) + + # create test data + flatten + fake = emg.create_emg_data(x, y, z) + flat = emg.flatten_signal(fake) + + # input array must be two dimensional + assert sum(flat.shape) > flat.shape[0], "Input array is not of shape M x K" + + m, k = flat.shape + + # ensure that correct shape can be outputted + assert m > 0, "Input array cannot be empty." + assert k > 1, "Input array must contain more than one channel." + + # Negro, et al used R = 16 + R = np.random.randint(1, 30) + + # test input parameters of extend_all_channels() + assert R > 0, "Value of R must be greater than 0." + assert R % 1 == 0, "Value of R must be an integer." - assert emg.extend_all_channels(x_mat, R_one).shape == (len(x_mat), len(x_mat[0]), R_one + 1) - assert emg.extend_all_channels(x_mat, R_one)[0][0][0] == emg.extend_input_all_channels(x_mat, R_one)[0][1][1] - assert emg.extend_all_channels(x_mat, R_one)[0][0][-1] == 0 - assert sum(emg.extend_all_channels(x_mat, R_one)[-1][-1]) == sum(x_mat[-1]) + # extend channels + ext = emg.extend_all_channels(flat, R) - assert emg.extend_all_channels(x_mat, R_two).shape == (len(x_mat), len(x_mat[0]), R_two + 1) - assert emg.extend_all_channels(x_mat, R_two)[0][0][0] == emg.extend_input_all_channels(x_mat, R_two)[0][1][1] - assert emg.extend_all_channels(x_mat, R_two)[0][0][-1] == 0 - assert sum(emg.extend_all_channels(x_mat, R_two)[-1][-1]) == sum(x_mat[-1]) + # test output + assert np.count_nonzero(ext[0]) == k, "Values extended incorrectly at ext[0]" + assert ext.shape == (m * (R+1), k), "Output array does not have shape M(R+1) x K" + if R > k: # if extension factor is bigger than length of array to extend, the last row is all zeros + assert np.count_nonzero(ext[-1]) == 0, "Values incorrectly extended at ext[-1]" + else: + # otherwise there should be R zeros in last row + assert np.count_nonzero(ext[-1]) + R == k, "Values incorrectly extended at ext[-1]" + def create_emg_data(m=13, n=5, q=10): """ Creates array (m, n) of arrays (1, q) with one empty subarray. From ce5fdd8dc8869a3c55cc044105adebef975d503b Mon Sep 17 00:00:00 2001 From: Jasmine Ortega Date: Wed, 18 May 2022 13:48:20 -0700 Subject: [PATCH 10/24] docs: minor docstring inconsistencies in extend_all_channels() --- src/emgdecompy/emgdecompy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emgdecompy/emgdecompy.py b/src/emgdecompy/emgdecompy.py index b50658d..c3ceecd 100644 --- a/src/emgdecompy/emgdecompy.py +++ b/src/emgdecompy/emgdecompy.py @@ -91,9 +91,9 @@ def extend_all_channels(x_mat, R): Examples -------- - >>> R = 5 + >>> R = 3 >>> x_mat = np.array([[1, 2, 3, 4,], [5, 6, 7, 8,]]) - >>> extend_input_all_channels(x_mat, 3) + >>> extend_all_channels(x_mat, R) array([[1., 2., 3., 4.], [0., 1., 2., 3.], [0., 0., 1., 2.], From 7a6c50b1ec4437934eec4282475b56f42bb2f86a Mon Sep 17 00:00:00 2001 From: Jasmine Ortega Date: Wed, 18 May 2022 14:01:55 -0700 Subject: [PATCH 11/24] fix: rearrange functions so create_emg_data() defined before called in test functions --- tests/test_emgdecompy.py | 60 ++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index b3e6050..b86cc6d 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -3,6 +3,36 @@ import numpy as np from scipy import linalg +def create_emg_data(m=13, n=5, q=10): + """ + Creates array (m, n) of arrays (1, q) with one empty subarray. + + Parameters + --------- + m : int + Number of rows to set as outer array size. The default size is 13. + n : int + Number of entries for outer array to have in each row. The default size is 5. + q : int + Number of entries for inner array to have in each row. The default size is 10; the default shape is (1, 10). + + Returns + ------- + raw : numpy.ndarray + """ + # intialize which subarray will be empty + empty_row = np.random.randint(0, m) + empty_col = np.random.randint(0, n) + + fake_data = np.zeros([m, n], dtype=object) + + for i in range(0, m): + fake_data[i, :] = [np.random.randn(1,q)] # same sequence for each row in array + + fake_data[empty_row, empty_col] = np.array([]) + + return fake_data + def test_extend_input_by_R(): """ Run unit tests on extend_input_by_R function from EMGdecomPy. @@ -75,36 +105,6 @@ def test_extend_all_channels(): else: # otherwise there should be R zeros in last row assert np.count_nonzero(ext[-1]) + R == k, "Values incorrectly extended at ext[-1]" - -def create_emg_data(m=13, n=5, q=10): - """ - Creates array (m, n) of arrays (1, q) with one empty subarray. - - Parameters - --------- - m : int - Number of rows to set as outer array size. The default size is 13. - n : int - Number of entries for outer array to have in each row. The default size is 5. - q : int - Number of entries for inner array to have in each row. The default size is 10; the default shape is (1, 10). - - Returns - ------- - raw : numpy.ndarray - """ - # intialize which subarray will be empty - empty_row = np.random.randint(0, m) - empty_col = np.random.randint(0, n) - - fake_data = np.zeros([m, n], dtype=object) - - for i in range(0, m): - fake_data[i, :] = [np.random.randn(1,q)] # same sequence for each row in array - - fake_data[empty_row, empty_col] = np.array([]) - - return fake_data def test_flatten_signal(): """ From fe93f12b76edff9cf58cb68020c45659268cef6e Mon Sep 17 00:00:00 2001 From: Jasmine Ortega Date: Wed, 18 May 2022 14:11:40 -0700 Subject: [PATCH 12/24] fix: incorrectly called create_emg_data() --- tests/test_emgdecompy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index b86cc6d..c006948 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -74,7 +74,7 @@ def test_extend_all_channels(): z = np.random.randint(2, 1000) # create test data + flatten - fake = emg.create_emg_data(x, y, z) + fake = create_emg_data(x, y, z) flat = emg.flatten_signal(fake) # input array must be two dimensional From 4fb93e4ca5c89734669412efe59a90f1675a3f63 Mon Sep 17 00:00:00 2001 From: Jasmine Ortega Date: Wed, 18 May 2022 15:26:06 -0700 Subject: [PATCH 13/24] test: add more robust tests for test_extend_input_by_R() --- tests/test_emgdecompy.py | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index c006948..746fc5a 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -35,32 +35,43 @@ def create_emg_data(m=13, n=5, q=10): def test_extend_input_by_R(): """ - Run unit tests on extend_input_by_R function from EMGdecomPy. + Run unit tests on extend_input_by_R function from emg-decomPy """ for i in range(0, 15): - R = np.random.randint(1, 100) # to extend - - assert R % 1 == 0, "Value of R is not an integer." - assert R > 0 , "Value of R must be greater than zero." + # extension factor + R = np.random.randint(1, 100) # length of input array - if R == 1: - q = 1 + q = np.random.randint(1, 100) - else: - q = np.random.randint(1, R) + # create input array + x = np.random.rand(q) + + # check input parameters + assert R % 1 == 0, "Value of R must be an integer." + assert R > 0 , "Value of R must be greater than zero." + assert sum(x.shape) == x.shape[0], f"Input array must be one-dimensional eg. ({k},)" - middle = round(q/2) - x = np.random.rand(q) # create input array + k = x.shape[0] testing = emg.extend_input_by_R(x, R) - assert testing[1][0] == 0, "Array not extended properly." # check first value - assert testing[middle][middle] == x[0] # check middle value - assert testing[q-1][q-1] == x[0], "Array not extended properly." # check end value + # check values are properly extended + assert testing[1][0] == 0, "Array not extended properly." # first extended array assert testing.shape == (R+1, x.shape[0]), "Shape of extended array incorrect" + if R >= k: + + # if R >=k, last few arrays will be all zeroes + assert testing[k-1][-1] == x[0], "Array not extended properly." + assert np.count_nonzero(testing[k]) == 0, f"Extended array should contain all zeros at testing[{k}]" + assert np.count_nonzero(testing[-1]) == 0, "Extended array should contain all zeros in last row" + + else: + assert testing[R][R] == x[0], "Array not extended not properly." + assert np.count_nonzero(testing[-1]) + R == k, "Array not extended not properly." + def test_extend_all_channels(): """ From f3022da9f77a3d282607c887396845625684c6a6 Mon Sep 17 00:00:00 2001 From: Jasmine Ortega Date: Wed, 18 May 2022 15:28:50 -0700 Subject: [PATCH 14/24] docs: update package name in test_extend_input_by_R --- tests/test_emgdecompy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_emgdecompy.py b/tests/test_emgdecompy.py index 746fc5a..7e6afc7 100644 --- a/tests/test_emgdecompy.py +++ b/tests/test_emgdecompy.py @@ -35,7 +35,7 @@ def create_emg_data(m=13, n=5, q=10): def test_extend_input_by_R(): """ - Run unit tests on extend_input_by_R function from emg-decomPy + Run unit tests on extend_input_by_R function from EMGdecomPy. """ for i in range(0, 15): From 233aac0bd2dceaa03af9385dd60960e9f7ceb767 Mon Sep 17 00:00:00 2001 From: Daniel King <63321764+danfke@users.noreply.github.com> Date: Wed, 18 May 2022 16:09:05 -0700 Subject: [PATCH 15/24] fix: correct package name --- .github/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index dcccd2c..0c4f122 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -84,7 +84,7 @@ jobs: pip install \ --index-url https://test.pypi.org/simple/ \ --extra-index-url https://pypi.org/simple \ - emg-decompy + emgdecompy - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 From 3fb899c946f959409e86efdc45ce5208adb53edf Mon Sep 17 00:00:00 2001 From: Daniel King <63321764+danfke@users.noreply.github.com> Date: Wed, 18 May 2022 16:14:38 -0700 Subject: [PATCH 16/24] build: Change PSR token --- .github/workflows/ci-cd.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 0c4f122..c10bbe4 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -56,6 +56,7 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 + token: PSR_PUSH_TOKEN - name: Install poetry uses: snok/install-poetry@v1 @@ -66,7 +67,7 @@ jobs: - name: Use Python Semantic Release to prepare release env: # This token is created automatically by GH Actions - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.PSR_PUSH_TOKEN }} run: | git config user.name github-actions git config user.email github-actions@github.com From e0f10683c9d52e4d4ca115005b60f8f762a71c07 Mon Sep 17 00:00:00 2001 From: Daniel King <63321764+danfke@users.noreply.github.com> Date: Wed, 18 May 2022 16:19:21 -0700 Subject: [PATCH 17/24] build: get rid of token under check-out repository --- .github/workflows/ci-cd.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index c10bbe4..e8d6c0b 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -56,7 +56,6 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - token: PSR_PUSH_TOKEN - name: Install poetry uses: snok/install-poetry@v1 From 5fbbab7cca0b9ab48f4882a8fd7ad96036b33f2c Mon Sep 17 00:00:00 2001 From: Daniel King <63321764+danfke@users.noreply.github.com> Date: Wed, 18 May 2022 16:35:40 -0700 Subject: [PATCH 18/24] build: change PSR token back to GITHUB_TOKEN --- .github/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index e8d6c0b..0c4f122 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -66,7 +66,7 @@ jobs: - name: Use Python Semantic Release to prepare release env: # This token is created automatically by GH Actions - GH_TOKEN: ${{ secrets.PSR_PUSH_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | git config user.name github-actions git config user.email github-actions@github.com From a778710bea0a1c3fd8129241aec38fe6924e0042 Mon Sep 17 00:00:00 2001 From: Daniel King <63321764+danfke@users.noreply.github.com> Date: Wed, 18 May 2022 16:36:24 -0700 Subject: [PATCH 19/24] docs: add codecov badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 288eca6..e100be3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # emgdecompy [![ci-cd](https://github.com/UBC-SPL-MDS/emg-decomPy/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/UBC-SPL-MDS/emg-decomPy/actions/workflows/ci-cd.yml) +[![codecov](https://codecov.io/gh/UBC-SPL-MDS/EMGdecomPy/branch/main/graph/badge.svg?token=78ZU40UEOE)](https://codecov.io/gh/UBC-SPL-MDS/EMGdecomPy) + A package for decomposing raw EMG signals into individual motor unit activity. From 703b8dc433fe1c6d4e25a2d7bb80eae02650ac3c Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2022 18:31:05 -0700 Subject: [PATCH 20/24] build: add sklearn dependency --- poetry.lock | 80 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index f42a550..6239556 100644 --- a/poetry.lock +++ b/poetry.lock @@ -477,6 +477,14 @@ MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] +[[package]] +name = "joblib" +version = "1.1.0" +description = "Lightweight pipelining with Python functions" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "jsonschema" version = "4.5.1" @@ -1114,6 +1122,26 @@ python-versions = ">=3.7" [package.extras] idna2008 = ["idna"] +[[package]] +name = "scikit-learn" +version = "1.1.0" +description = "A set of python modules for machine learning and data mining" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +joblib = ">=1.0.0" +numpy = ">=1.17.3" +scipy = ">=1.3.2" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=3.1.2)", "pandas (>=1.0.5)", "memory-profiler (>=0.57.0)"] +docs = ["matplotlib (>=3.1.2)", "scikit-image (>=0.14.5)", "pandas (>=1.0.5)", "seaborn (>=0.9.0)", "memory-profiler (>=0.57.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "numpydoc (>=1.2.0)", "Pillow (>=7.1.2)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=3.1.2)", "scikit-image (>=0.14.5)", "pandas (>=1.0.5)", "seaborn (>=0.9.0)"] +tests = ["matplotlib (>=3.1.2)", "scikit-image (>=0.14.5)", "pandas (>=1.0.5)", "pytest (>=5.0.1)", "pytest-cov (>=2.9.0)", "flake8 (>=3.8.2)", "black (>=22.3.0)", "mypy (>=0.770)", "pyamg (>=4.0.0)", "numpydoc (>=1.2.0)"] + [[package]] name = "scipy" version = "1.8.0" @@ -1169,6 +1197,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "sklearn" +version = "0.0" +description = "A set of python modules for machine learning and data mining" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +scikit-learn = "*" + [[package]] name = "smmap" version = "5.0.0" @@ -1397,6 +1436,14 @@ python-versions = "*" [package.extras] widechars = ["wcwidth"] +[[package]] +name = "threadpoolctl" +version = "3.1.0" +description = "threadpoolctl" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "tomli" version = "2.0.1" @@ -1545,7 +1592,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = ">=3.9, <3.11" -content-hash = "8613b3abc288fa9a243ab25e3ebd1c6d6ba25ad9c8f3bc5a9cdc27c396ae743c" +content-hash = "8a3d9d1719812425200d838857223227855dc2040addba212ee506a747577183" [metadata.files] alabaster = [ @@ -1884,6 +1931,10 @@ jinja2 = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] +joblib = [ + {file = "joblib-1.1.0-py2.py3-none-any.whl", hash = "sha256:f21f109b3c7ff9d95f8387f752d0d9c34a02aa2f7060c2135f465da0e5160ff6"}, + {file = "joblib-1.1.0.tar.gz", hash = "sha256:4158fcecd13733f8be669be0683b96ebdbbd38d23559f54dca7205aea1bf1e35"}, +] jsonschema = [ {file = "jsonschema-4.5.1-py3-none-any.whl", hash = "sha256:71b5e39324422543546572954ce71c67728922c104902cb7ce252e522235b33f"}, {file = "jsonschema-4.5.1.tar.gz", hash = "sha256:7c6d882619340c3347a1bf7315e147e6d3dae439033ae6383d6acb908c101dfc"}, @@ -2323,6 +2374,26 @@ rfc3986 = [ {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"}, {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"}, ] +scikit-learn = [ + {file = "scikit-learn-1.1.0.tar.gz", hash = "sha256:80f9904f5b1356adfc32406725dd94c8cc9c8d265047d98390033a6c238cbb29"}, + {file = "scikit_learn-1.1.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:47c31f7e9a5689c3a2cbdf72e78570b33fa9abb42a1ca10d787516de9c4e37a4"}, + {file = "scikit_learn-1.1.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:892be17fc261dff4097c061880586226d47ccd0426d9283091e2ca65da36e645"}, + {file = "scikit_learn-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d8e83d24df9595d4ccca961a2038e331aa7e17534af0b5b15d28e6d65723d1d"}, + {file = "scikit_learn-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:068ee35f08681079a9aece49236f40837dbffebe047b0813bf71873fa976b132"}, + {file = "scikit_learn-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:e4d41245915d0fc6fea26029349ff187b2992ef6588863e8570fc95a24697fd0"}, + {file = "scikit_learn-1.1.0-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:502865e025d3222530e350783a59cc37538effde64767721d830ceaae8bb3d42"}, + {file = "scikit_learn-1.1.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:18aabbb26cbc1cf52583c1f1ecf6b5ff540d334f173e23122db43f97adbe0b2b"}, + {file = "scikit_learn-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:292525a17645bff043d33d427e93db8cec8d66b5022ead7971ce8bfdf7553feb"}, + {file = "scikit_learn-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff60f63f1584d7daebfc93e69addd39760de49ae4325db5638c324cfde41c6c7"}, + {file = "scikit_learn-1.1.0-cp38-cp38-win32.whl", hash = "sha256:c10cd62443a9968c71fb9f1c7844f3f28189666f789d5a204dbad7463169b172"}, + {file = "scikit_learn-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:cab8a8bef603f0fced7b245f7c4f77826602fd94f7c54ccb09b36b177dde246d"}, + {file = "scikit_learn-1.1.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:dc6681e2f99a4a5bc0682dc4e87192daeb0e9e64da36b35e672b56156e0cc867"}, + {file = "scikit_learn-1.1.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:05f9f004afe1b415922b2ff9453a191e3082acf1065aa0f0b238250f9e147606"}, + {file = "scikit_learn-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c819d2820b783f390dda2136508483d6f4302dfba98fc974ce759e55b2247d80"}, + {file = "scikit_learn-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2318fc717c9ff7eb3834bbb2c3be63768e97bb3221bbf70c01537e34e4fb8a1c"}, + {file = "scikit_learn-1.1.0-cp39-cp39-win32.whl", hash = "sha256:25b8d471169711dee7667969e7db3d33c372c13701cd2ab6783d0e85b2aab300"}, + {file = "scikit_learn-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:1ef67ac0d44d9ecb36bc33ccc421f683aaeb42bdd72d8a97601eaded3b43f2e4"}, +] scipy = [ {file = "scipy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:87b01c7d5761e8a266a0fbdb9d88dcba0910d63c1c671bdb4d99d29f469e9e03"}, {file = "scipy-1.8.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ae3e327da323d82e918e593460e23babdce40d7ab21490ddf9fc06dec6b91a18"}, @@ -2364,6 +2435,9 @@ six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +sklearn = [ + {file = "sklearn-0.0.tar.gz", hash = "sha256:e23001573aa194b834122d2b9562459bf5ae494a2d59ca6b8aa22c85a44c0e31"}, +] smmap = [ {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, @@ -2458,6 +2532,10 @@ tabulate = [ {file = "tabulate-0.8.9-py3-none-any.whl", hash = "sha256:d7c013fe7abbc5e491394e10fa845f8f32fe54f8dc60c6622c6cf482d25d47e4"}, {file = "tabulate-0.8.9.tar.gz", hash = "sha256:eb1d13f25760052e8931f2ef80aaf6045a6cceb47514db8beab24cded16f13a7"}, ] +threadpoolctl = [ + {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, + {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, +] tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, diff --git a/pyproject.toml b/pyproject.toml index 970b554..0eccf0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ pandas = "^1.4.2" altair = "^4.2.0" numpy = "^1.22.3" altair-data-server = "^0.4.1" +sklearn = "^0.0" [tool.poetry.dev-dependencies] pytest = "^7.1.2" From 83d517454b7615f1b7e4cdc4580799643b87b3c6 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2022 18:31:24 -0700 Subject: [PATCH 21/24] feat: add refinement function draft --- src/emgdecompy/emgdecompy.py | 62 +++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/emgdecompy/emgdecompy.py b/src/emgdecompy/emgdecompy.py index c3ceecd..e1f490d 100644 --- a/src/emgdecompy/emgdecompy.py +++ b/src/emgdecompy/emgdecompy.py @@ -3,7 +3,10 @@ import pandas as pd import altair as alt import numpy as np - +from scipy.signal import find_peaks +from sklearn.cluster import KMeans +from sklearn.metrics import silhouette_score +from scipy.stats import variation def flatten_signal(raw): """ @@ -190,3 +193,60 @@ def whiten(x): wzca = np.dot(np.dot(np.dot(v, diagw), v.T), x_cent) return wzca + +def refinement(w_i, z): + # Initialize inter-spike interval coefficient of variations for n and n-1 as random numbers + cv_curr, cv_prev = np.random.ranf(), np.random.ranf() + + if cv_curr > cv_prev: + cv_curr, cv_prev = cv_prev, cv_curr + + n = 0 + + while cv_curr < cv_prev: + + # a. Estimate the i-th source + s_i = np.dot(w_i, z) # w_i and w_i.T are equal as far as I know + + # Estimate pulse train pt_n with peak detection applied to the square of the source vector + + s_i = np.square(s_i) + + peak_indices, _ = find_peaks(s_i, distance=41) #41 samples is ~equiv to 20 ms at a 2048 Hz sampling rate + + # b. Use KMeans to separate large peaks from relatively small peaks, which are discarded + kmeans = KMeans(n_clusters=2) + kmeans.fit(peak_indices) + clust_a = np.argmax(kmeans.cluster_centers_) + peak_a = ~kmeans.labels_.astype(bool) # Determine which peaks are large + + if clust_a == 1: + peak_a = ~peak_a + + peak_a = peak_indices[peak_a] + + # Create pulse train, where values are 0 except for when MU fires, which have values of 1 + pt_n = np.zeros_like(s_i) + pt_n[peak_a] = 1 + + # c. Update inter-spike interval coefficients of variation + isi = np.diff(peak_a) #inter-spike intervals + cv_prev = cv_curr + cv_curr = variation(isi) + + # d. Update separation vector + j = len(peak_a) + + w_i = (1 / j) * z[:, peak_a].sum(axis=1) + + n += 1 + + # Add way to save pulse train + + # If silhouette score is greater than threshold, accept estimated source and add w_i to B + sil = silhouette_score(peak_indices, kmeans.labels_) # Definition is slightly different than in paper, may change + + if sil < th_sil: + w_i = np.zeros_like(w_i) + + return w_i # May change implementation to update B here \ No newline at end of file From 42f581e52c90a2e0f7d8c5ca2d11ddfe91132105 Mon Sep 17 00:00:00 2001 From: Daniel King <63321764+danfke@users.noreply.github.com> Date: Wed, 18 May 2022 22:11:29 -0700 Subject: [PATCH 22/24] docs: update creator names --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e100be3..005c1a2 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Interested in contributing? Check out the contributing guidelines. Please note t ## License -`emgdecompy` was created by Daniel King. It is licensed under the terms of the MIT license. +`emgdecompy` was created by Daniel King, Jasmine Ortega, Rada Rudyak, and Rowan Sivanandam. It is licensed under the terms of the MIT license. ## Credits From d45b1d05af8ed5a43cf71bd07d886a5a12dbe30e Mon Sep 17 00:00:00 2001 From: semantic-release Date: Thu, 19 May 2022 05:15:34 +0000 Subject: [PATCH 23/24] 0.2.0 Automatically generated by python-semantic-release --- CHANGELOG.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50be865..c79fe83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,89 @@ +## v0.2.0 (2022-05-19) +### Feature +* Add whiten function to emg-decompy.py ([`3682a09`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/3682a0977e1eca8268e109d5dea808963674d1a7)) +* Create functions script, debug extension functions, write docstrings ([`af7e346`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/af7e3469e4abea67eb44884cf423f1fb1fe2a0e7)) + +### Fix +* Correct package name ([`233aac0`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/233aac0bd2dceaa03af9385dd60960e9f7ceb767)) +* Incorrectly called create_emg_data() ([`fe93f12`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/fe93f12b76edff9cf58cb68020c45659268cef6e)) +* Rearrange functions so create_emg_data() defined before called in test functions ([`7a6c50b`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/7a6c50b1ec4437934eec4282475b56f42bb2f86a)) +* Tweak create_emg_data to use np.empty so that shape is consistent with real data ([`97d67c9`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/97d67c9ef6c663e4aab3c31167dd6775a1a313c1)) +* Tweak test_flatten_signal to test for empty arrays pre-flatten ([`a7c0da4`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/a7c0da45dd6f07dc81c05a7409505e6723cbbac1)) +* Small change to create_emg_data() function to not allow 1 dimensional arrays to be created ([`e744a7c`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/e744a7c704cfdfba43fd37003d47f0bae9de231c)) +* Change output dimensions so there are no 'channels' ([`3cacf69`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/3cacf69dc747bbabbe75505822f78e208dba72ce)) +* Add reg factor to whiten but leave commented out ([`7491d10`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/7491d10378f6ea6f23f9604273fd04d2368d90c9)) +* Fix transpose error ([`265592e`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/265592e5a45324e62f48190f4e44cd8c286dbb1d)) +* Correct test name for extend_all_channels ([`8f787ec`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/8f787eceb08468705dc07ea0c8cfb540ce9a4aef)) +* Import linalg from scipy ([`0ad2d15`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/0ad2d152557c656add1bf44e603d0a2d3bab4c19)) +* Properly call center_matrix function ([`db209b3`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/db209b3b47062d3c38a0f4abc604ae3b53d8b01e)) +* Output correct dimensions for extend_all_channels() ([`deba7a4`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/deba7a4b0f2d5ae8e14026607c3ec774f9ce6d25)) +* Get rid of codecov because repo is private ([`dd2bb66`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/dd2bb66954bed78714abe962e1bac58e769e74c6)) +* Extend() function now outputs what we agreed upon ([`98cfa16`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/98cfa16bc36207cd5d7f89aa4263d202ef750d61)) +* Figures were all showing weird, adding fig.pos='h' fixed it ([`db47734`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/db477347e20d5fd1b098a968664c3f2cb4454d27)) +* Correct package name ([`f4bf67f`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/f4bf67f01b7e27d1c169e8f7668644eaaed161a8)) +* Correct package name ([`76ae9fb`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/76ae9fbd31c14dd3c16d75eed39750f4bf4b9336)) +* Import packages, reference package name in functions ([`62d839a`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/62d839ad84c9ddd6d66d49ec141cf240dfbce419)) +* Remove packages line ([`1d0a6be`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/1d0a6be7eeb5bc9c7f363f893e966a1034bc7c24)) +* Correct package name ([`0163446`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/0163446f8afebdbb52cd22c379a35ea622d80e89)) +* Fix merge conflict and import emgdecompy ([`0005d9f`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/0005d9fb573367ece1a3f7eb5616bd349d7daefa)) +* Changing file name to new package ([`a8c18d5`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/a8c18d585c1a1f6d31324208f5e0cbc70a9c611d)) +* Changing package name in all documents ([`22f3129`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/22f3129ce2d37fd585a38c66dd78fd19fd43d4c0)) +* Put vector extension tests within functions ([`9b2fd18`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/9b2fd187c6821ff2f8733a6847a085a65157343f)) + +### Documentation +* Update creator names ([`42f581e`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/42f581e52c90a2e0f7d8c5ca2d11ddfe91132105)) +* Add codecov badge ([`a778710`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/a778710bea0a1c3fd8129241aec38fe6924e0042)) +* Update package name in test_extend_input_by_R ([`f3022da`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/f3022da9f77a3d282607c887396845625684c6a6)) +* Minor docstring inconsistencies in extend_all_channels() ([`ce5fdd8`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/ce5fdd8dc8869a3c55cc044105adebef975d503b)) +* Add clarification comment to test_flatten() according to Jasmine's feedback ([`bcc735c`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/bcc735cbed770547beacf584a1579ab481e3ba00)) +* Fix doc string for test_extend_by_R() ([`79490f4`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/79490f462fa946c123b747b38187e2cc919c0fc7)) +* Fix reference on page 2 ([`ee57a46`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/ee57a467b95ee92df39bc3dcf252146a7c31c590)) +* Make docstrings simpler and improve code commenting ([`5b397c0`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/5b397c0607d72df06b16160fa71c7e07dd0c2434)) +* Correct format of examples in center_matrix and make it simpler ([`200bd66`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/200bd6655a663221907b8776865d511fbf17bf85)) +* Correct docstring for extend_input_by_R ([`3e8e9df`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/3e8e9df975228029caa32f3e6eb9bad2301d4a58)) +* Fix grammar in docstrings ([`1190161`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/1190161f5c5e63e5af1c5774a561a303d25a0226)) +* Correct examples line in docstrings ([`9a4441a`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/9a4441af7f5e0282a6301b3e6a693bf31fa83556)) +* Correct spelling of fibre in summary ([`ea95835`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/ea95835c487ab4beaec90a2be9c2a71cbdce73b6)) +* Bold figure cross-references' ([`45a361f`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/45a361ff13ad7e677d474db1907d0a0250c014ff)) +* Made corrections to wordings, citations, figure locations ([`9c48f68`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/9c48f689152b73261b8974571f43dfa86bd9884d)) +* Replace emg hardware image ([`dc33fae`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/dc33faee41497ed10d001c978f48cac759f5d739)) +* Replace ot screenshot with higher quality one ([`ab702a6`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/ab702a68a9f1387c77d77b555cd4bae50d8e725d)) +* Replace ot screenshot with higher quality one ([`80cfd4b`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/80cfd4bbc13703eae55d96db9f7412f3b6dd9b7a)) +* Add visual of algorithm ([`e88f15d`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/e88f15d4c8b78f6c999ac41bb4be93b34531610a)) +* Edit Timeline ([`c4b210b`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/c4b210b1a0ef511902ce8c0c94307018821094d0)) +* Add more citations and figures ([`80de991`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/80de99168ac46dc829d178f74830edd9a3cf14d1)) +* Update timeline ([`afd53d2`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/afd53d2492b52a2d432bb6a812ca6182ef841ab6)) +* Add raw EMG image ([`b638e46`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/b638e46fb9bf4d91d84f21e2461b21625ac78c5f)) +* Fix Tools sections based on Alexi's feedback ([`6f64943`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/6f64943da4338915c61a88798acfd7098b6a8a26)) +* Fix package name ([`eb2b26a`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/eb2b26ae30761a5e78eff405be74ebcf958f81a1)) +* Add Alexi's corrections ([`5317c70`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/5317c7048ddb7b0c6f4bf65a70f396f75542c0cb)) +* Fix badge formatting ([`f4aa37d`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/f4aa37d84bdfb08e17e90e52b2d165a43688c183)) +* Add ci-cd badge ([`1d3cbf9`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/1d3cbf9c74c6608a1b7d03234e903818bd68e10a)) +* Change package description ([`16bf912`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/16bf91282eb532923487b43bfb0bb91bde34b0b7)) +* Bottleneck is spelled with an e lol ([`9fb41bc`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/9fb41bcf3982791ea1a7ad82f3384277fe336210)) +* Improve docstring based on Daniel's advice ([`7848f49`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/7848f49e0b35078a93e28ba28024fdd13a13b72c)) +* Add proposal section to README ([`89618b6`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/89618b66b3de0ced78df0435a48067308cbf998a)) +* Create layout of proposal and render to pdf ([`423d6b3`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/423d6b314338de95b8ac827adfd83dd07b9e632c)) +* Make corrections ([`adaa064`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/adaa0648e5959313c804fbc46abfec7684378cb1)) +* Add bibtex references ([`b299959`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/b299959789f45c7f26b01ba5e87cb2d65519a5d2)) +* Fix section on the interactive learning component ([`e8fc753`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/e8fc753f0d41f4ff9baa13415d3b96c641239ec6)) +* Make some edits and add bibtex ([`6b79ea7`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/6b79ea709d32ff665abe282748ad4f200bb5e3cd)) +* Remove obsolete citations file ([`1483e64`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/1483e6409ce389084dfe50d9a358d9574722bbc2)) +* Fix line breaks ([`a1707a6`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/a1707a6cd0a4698fb40cab04b3ea23cfc8f82761)) +* Make corrections to techniques section and add bibtex ([`d4af629`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/d4af629aaf795aa95645cd632a34e0030de27c03)) +* Remove html output ([`9107441`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/9107441ee64cafee5a7b3e3ed80f0b417ad103a5)) +* Move titles from child docs to parent doc ([`0abf1d6`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/0abf1d6696fc18037fe94e7978d535510948457b)) +* Create bibtex file ([`f5c6920`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/f5c692040951357e3cf3ef6643723771d22e8f1c)) +* Add title to data science technique section ([`f3ff884`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/f3ff884aa0cc0a1dbe5c6cb65dc4d17910099dce)) +* Add yaml metadata ([`0a625c1`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/0a625c1cff2f5028070b4aeb7735e39e263af122)) +* Add proposal intro rmd ([`472635a`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/472635a024c725f713f995a6b904d857b7c32e86)) +* Rewrite tools section to use sentenses instead of bullet points ([`503a4c2`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/503a4c2bdf83500a0750d02998eb90314e09c387)) +* Create proposal folder and components ([`042a808`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/042a8086c45bbc27bb9a76a1fcfba0a845f81f48)) +* Create teamwork contract ([`272638c`](https://github.com/UBC-SPL-MDS/EMGdecomPy/commit/272638c07cc0bf64372c88c4ccb4ec13de913c12)) + ## v0.1.0 (03/05/2022) - First release of `emgdecompy`! \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 970b554..210fa76 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "emgdecompy" -version = "0.1.0" +version = "0.2.0" description = "A package for decomposing raw EMG signals into individual motor unit activity." authors = ["Daniel King"] license = "MIT" From 9fd71c50aea805995066c2bb4eb231d13c718ba7 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Thu, 19 May 2022 17:29:25 -0700 Subject: [PATCH 24/24] feat: add pulse train save functionality and made code clearer --- src/emgdecompy/emgdecompy.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/emgdecompy/emgdecompy.py b/src/emgdecompy/emgdecompy.py index e1f490d..bd35aa9 100644 --- a/src/emgdecompy/emgdecompy.py +++ b/src/emgdecompy/emgdecompy.py @@ -194,7 +194,7 @@ def whiten(x): return wzca -def refinement(w_i, z): +def refinement(w_i, z, i, max_iter, th_sil, name=""): # Initialize inter-spike interval coefficient of variations for n and n-1 as random numbers cv_curr, cv_prev = np.random.ranf(), np.random.ranf() @@ -209,7 +209,6 @@ def refinement(w_i, z): s_i = np.dot(w_i, z) # w_i and w_i.T are equal as far as I know # Estimate pulse train pt_n with peak detection applied to the square of the source vector - s_i = np.square(s_i) peak_indices, _ = find_peaks(s_i, distance=41) #41 samples is ~equiv to 20 ms at a 2048 Hz sampling rate @@ -217,13 +216,13 @@ def refinement(w_i, z): # b. Use KMeans to separate large peaks from relatively small peaks, which are discarded kmeans = KMeans(n_clusters=2) kmeans.fit(peak_indices) - clust_a = np.argmax(kmeans.cluster_centers_) - peak_a = ~kmeans.labels_.astype(bool) # Determine which peaks are large + centroid_a = np.argmax(kmeans.cluster_centers_) # Determine which cluster contains large peaks + peak_a = ~kmeans.labels_.astype(bool) # Determine which peaks are large (part of cluster a) - if clust_a == 1: + if centroid_a == 1: peak_a = ~peak_a - peak_a = peak_indices[peak_a] + peak_a = peak_indices[peak_a] # Get the indices of the peaks in cluster a # Create pulse train, where values are 0 except for when MU fires, which have values of 1 pt_n = np.zeros_like(s_i) @@ -241,12 +240,13 @@ def refinement(w_i, z): n += 1 - # Add way to save pulse train + # Save pulse train + pd.DataFrame(pt_n, columns=["pulse_train"]).rename_axis("sample").to_csv(f"{name}_PT_{i}") # If silhouette score is greater than threshold, accept estimated source and add w_i to B sil = silhouette_score(peak_indices, kmeans.labels_) # Definition is slightly different than in paper, may change if sil < th_sil: - w_i = np.zeros_like(w_i) + return # If below threshold, reject estimated source and return nothing return w_i # May change implementation to update B here \ No newline at end of file