Compare commits

..

8 Commits

9 changed files with 193 additions and 143 deletions

150
poetry.lock generated
View File

@ -153,20 +153,6 @@ files = [
{file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
] ]
[[package]]
name = "exceptiongroup"
version = "1.2.2"
description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
]
[package.extras]
test = ["pytest (>=6)"]
[[package]] [[package]]
name = "executing" name = "executing"
version = "2.1.0" version = "2.1.0"
@ -183,53 +169,59 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth
[[package]] [[package]]
name = "fonttools" name = "fonttools"
version = "4.53.1" version = "4.54.1"
description = "Tools to manipulate font files" description = "Tools to manipulate font files"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "fonttools-4.53.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397"}, {file = "fonttools-4.54.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ed7ee041ff7b34cc62f07545e55e1468808691dddfd315d51dd82a6b37ddef2"},
{file = "fonttools-4.53.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3"}, {file = "fonttools-4.54.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41bb0b250c8132b2fcac148e2e9198e62ff06f3cc472065dff839327945c5882"},
{file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d"}, {file = "fonttools-4.54.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7965af9b67dd546e52afcf2e38641b5be956d68c425bef2158e95af11d229f10"},
{file = "fonttools-4.53.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0"}, {file = "fonttools-4.54.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278913a168f90d53378c20c23b80f4e599dca62fbffae4cc620c8eed476b723e"},
{file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41"}, {file = "fonttools-4.54.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0e88e3018ac809b9662615072dcd6b84dca4c2d991c6d66e1970a112503bba7e"},
{file = "fonttools-4.53.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f"}, {file = "fonttools-4.54.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4aa4817f0031206e637d1e685251ac61be64d1adef111060df84fdcbc6ab6c44"},
{file = "fonttools-4.53.1-cp310-cp310-win32.whl", hash = "sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4"}, {file = "fonttools-4.54.1-cp310-cp310-win32.whl", hash = "sha256:7e3b7d44e18c085fd8c16dcc6f1ad6c61b71ff463636fcb13df7b1b818bd0c02"},
{file = "fonttools-4.53.1-cp310-cp310-win_amd64.whl", hash = "sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671"}, {file = "fonttools-4.54.1-cp310-cp310-win_amd64.whl", hash = "sha256:dd9cc95b8d6e27d01e1e1f1fae8559ef3c02c76317da650a19047f249acd519d"},
{file = "fonttools-4.53.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1"}, {file = "fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5419771b64248484299fa77689d4f3aeed643ea6630b2ea750eeab219588ba20"},
{file = "fonttools-4.53.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923"}, {file = "fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:301540e89cf4ce89d462eb23a89464fef50915255ece765d10eee8b2bf9d75b2"},
{file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719"}, {file = "fonttools-4.54.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ae5091547e74e7efecc3cbf8e75200bc92daaeb88e5433c5e3e95ea8ce5aa7"},
{file = "fonttools-4.53.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3"}, {file = "fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82834962b3d7c5ca98cb56001c33cf20eb110ecf442725dc5fdf36d16ed1ab07"},
{file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb"}, {file = "fonttools-4.54.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d26732ae002cc3d2ecab04897bb02ae3f11f06dd7575d1df46acd2f7c012a8d8"},
{file = "fonttools-4.53.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2"}, {file = "fonttools-4.54.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58974b4987b2a71ee08ade1e7f47f410c367cdfc5a94fabd599c88165f56213a"},
{file = "fonttools-4.53.1-cp311-cp311-win32.whl", hash = "sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88"}, {file = "fonttools-4.54.1-cp311-cp311-win32.whl", hash = "sha256:ab774fa225238986218a463f3fe151e04d8c25d7de09df7f0f5fce27b1243dbc"},
{file = "fonttools-4.53.1-cp311-cp311-win_amd64.whl", hash = "sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02"}, {file = "fonttools-4.54.1-cp311-cp311-win_amd64.whl", hash = "sha256:07e005dc454eee1cc60105d6a29593459a06321c21897f769a281ff2d08939f6"},
{file = "fonttools-4.53.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58"}, {file = "fonttools-4.54.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:54471032f7cb5fca694b5f1a0aaeba4af6e10ae989df408e0216f7fd6cdc405d"},
{file = "fonttools-4.53.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8"}, {file = "fonttools-4.54.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fa92cb248e573daab8d032919623cc309c005086d743afb014c836636166f08"},
{file = "fonttools-4.53.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60"}, {file = "fonttools-4.54.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a911591200114969befa7f2cb74ac148bce5a91df5645443371aba6d222e263"},
{file = "fonttools-4.53.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f"}, {file = "fonttools-4.54.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93d458c8a6a354dc8b48fc78d66d2a8a90b941f7fec30e94c7ad9982b1fa6bab"},
{file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"}, {file = "fonttools-4.54.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5eb2474a7c5be8a5331146758debb2669bf5635c021aee00fd7c353558fc659d"},
{file = "fonttools-4.53.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f"}, {file = "fonttools-4.54.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9c563351ddc230725c4bdf7d9e1e92cbe6ae8553942bd1fb2b2ff0884e8b714"},
{file = "fonttools-4.53.1-cp312-cp312-win32.whl", hash = "sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670"}, {file = "fonttools-4.54.1-cp312-cp312-win32.whl", hash = "sha256:fdb062893fd6d47b527d39346e0c5578b7957dcea6d6a3b6794569370013d9ac"},
{file = "fonttools-4.53.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab"}, {file = "fonttools-4.54.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4564cf40cebcb53f3dc825e85910bf54835e8a8b6880d59e5159f0f325e637e"},
{file = "fonttools-4.53.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749"}, {file = "fonttools-4.54.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6e37561751b017cf5c40fce0d90fd9e8274716de327ec4ffb0df957160be3bff"},
{file = "fonttools-4.53.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2"}, {file = "fonttools-4.54.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:357cacb988a18aace66e5e55fe1247f2ee706e01debc4b1a20d77400354cddeb"},
{file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb"}, {file = "fonttools-4.54.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e953cc0bddc2beaf3a3c3b5dd9ab7554677da72dfaf46951e193c9653e515a"},
{file = "fonttools-4.53.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f"}, {file = "fonttools-4.54.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58d29b9a294573d8319f16f2f79e42428ba9b6480442fa1836e4eb89c4d9d61c"},
{file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d"}, {file = "fonttools-4.54.1-cp313-cp313-win32.whl", hash = "sha256:9ef1b167e22709b46bf8168368b7b5d3efeaaa746c6d39661c1b4405b6352e58"},
{file = "fonttools-4.53.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169"}, {file = "fonttools-4.54.1-cp313-cp313-win_amd64.whl", hash = "sha256:262705b1663f18c04250bd1242b0515d3bbae177bee7752be67c979b7d47f43d"},
{file = "fonttools-4.53.1-cp38-cp38-win32.whl", hash = "sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d"}, {file = "fonttools-4.54.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ed2f80ca07025551636c555dec2b755dd005e2ea8fbeb99fc5cdff319b70b23b"},
{file = "fonttools-4.53.1-cp38-cp38-win_amd64.whl", hash = "sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8"}, {file = "fonttools-4.54.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9dc080e5a1c3b2656caff2ac2633d009b3a9ff7b5e93d0452f40cd76d3da3b3c"},
{file = "fonttools-4.53.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a"}, {file = "fonttools-4.54.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d152d1be65652fc65e695e5619e0aa0982295a95a9b29b52b85775243c06556"},
{file = "fonttools-4.53.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31"}, {file = "fonttools-4.54.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8583e563df41fdecef31b793b4dd3af8a9caa03397be648945ad32717a92885b"},
{file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c"}, {file = "fonttools-4.54.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0d1d353ef198c422515a3e974a1e8d5b304cd54a4c2eebcae708e37cd9eeffb1"},
{file = "fonttools-4.53.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407"}, {file = "fonttools-4.54.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:fda582236fee135d4daeca056c8c88ec5f6f6d88a004a79b84a02547c8f57386"},
{file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb"}, {file = "fonttools-4.54.1-cp38-cp38-win32.whl", hash = "sha256:e7d82b9e56716ed32574ee106cabca80992e6bbdcf25a88d97d21f73a0aae664"},
{file = "fonttools-4.53.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122"}, {file = "fonttools-4.54.1-cp38-cp38-win_amd64.whl", hash = "sha256:ada215fd079e23e060157aab12eba0d66704316547f334eee9ff26f8c0d7b8ab"},
{file = "fonttools-4.53.1-cp39-cp39-win32.whl", hash = "sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb"}, {file = "fonttools-4.54.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f5b8a096e649768c2f4233f947cf9737f8dbf8728b90e2771e2497c6e3d21d13"},
{file = "fonttools-4.53.1-cp39-cp39-win_amd64.whl", hash = "sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb"}, {file = "fonttools-4.54.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e10d2e0a12e18f4e2dd031e1bf7c3d7017be5c8dbe524d07706179f355c5dac"},
{file = "fonttools-4.53.1-py3-none-any.whl", hash = "sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d"}, {file = "fonttools-4.54.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31c32d7d4b0958600eac75eaf524b7b7cb68d3a8c196635252b7a2c30d80e986"},
{file = "fonttools-4.53.1.tar.gz", hash = "sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4"}, {file = "fonttools-4.54.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c39287f5c8f4a0c5a55daf9eaf9ccd223ea59eed3f6d467133cc727d7b943a55"},
{file = "fonttools-4.54.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a7a310c6e0471602fe3bf8efaf193d396ea561486aeaa7adc1f132e02d30c4b9"},
{file = "fonttools-4.54.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d3b659d1029946f4ff9b6183984578041b520ce0f8fb7078bb37ec7445806b33"},
{file = "fonttools-4.54.1-cp39-cp39-win32.whl", hash = "sha256:e96bc94c8cda58f577277d4a71f51c8e2129b8b36fd05adece6320dd3d57de8a"},
{file = "fonttools-4.54.1-cp39-cp39-win_amd64.whl", hash = "sha256:e8a4b261c1ef91e7188a30571be6ad98d1c6d9fa2427244c545e2fa0a2494dd7"},
{file = "fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd"},
{file = "fonttools-4.54.1.tar.gz", hash = "sha256:957f669d4922f92c171ba01bef7f29410668db09f6c02111e22b2bce446f3285"},
] ]
[package.extras] [package.extras]
@ -297,19 +289,18 @@ files = [
[[package]] [[package]]
name = "ipython" name = "ipython"
version = "8.27.0" version = "8.28.0"
description = "IPython: Productive Interactive Computing" description = "IPython: Productive Interactive Computing"
optional = false optional = false
python-versions = ">=3.10" python-versions = ">=3.10"
files = [ files = [
{file = "ipython-8.27.0-py3-none-any.whl", hash = "sha256:f68b3cb8bde357a5d7adc9598d57e22a45dfbea19eb6b98286fa3b288c9cd55c"}, {file = "ipython-8.28.0-py3-none-any.whl", hash = "sha256:530ef1e7bb693724d3cdc37287c80b07ad9b25986c007a53aa1857272dac3f35"},
{file = "ipython-8.27.0.tar.gz", hash = "sha256:0b99a2dc9f15fd68692e898e5568725c6d49c527d36a9fb5960ffbdeaa82ff7e"}, {file = "ipython-8.28.0.tar.gz", hash = "sha256:0d0d15ca1e01faeb868ef56bc7ee5a0de5bd66885735682e8a322ae289a13d1a"},
] ]
[package.dependencies] [package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""} colorama = {version = "*", markers = "sys_platform == \"win32\""}
decorator = "*" decorator = "*"
exceptiongroup = {version = "*", markers = "python_version < \"3.11\""}
jedi = ">=0.16" jedi = ">=0.16"
matplotlib-inline = "*" matplotlib-inline = "*"
pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""}
@ -904,16 +895,16 @@ PyQt6-sip = ">=13.8,<14"
[[package]] [[package]]
name = "pyqt6-qt6" name = "pyqt6-qt6"
version = "6.7.2" version = "6.7.3"
description = "The subset of a Qt installation needed by PyQt6." description = "The subset of a Qt installation needed by PyQt6."
optional = false optional = false
python-versions = "*" python-versions = "*"
files = [ files = [
{file = "PyQt6_Qt6-6.7.2-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:065415589219a2f364aba29d6a98920bb32810286301acbfa157e522d30369e3"}, {file = "PyQt6_Qt6-6.7.3-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:f517a93b6b1a814d4aa6587adc312e812ebaf4d70415bb15cfb44268c5ad3f5f"},
{file = "PyQt6_Qt6-6.7.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7f817efa86a0e8eda9152c85b73405463fbf3266299090f32bbb2266da540ead"}, {file = "PyQt6_Qt6-6.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:8551732984fb36a5f4f3db51eafc4e8e6caf18617365830285306f2db17a94c2"},
{file = "PyQt6_Qt6-6.7.2-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:05f2c7d195d316d9e678a92ecac0252a24ed175bd2444cc6077441807d756580"}, {file = "PyQt6_Qt6-6.7.3-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:50c7482bcdcf2bb78af257fb10ed8b582f8daf91d829782393bc50ac5a0a900c"},
{file = "PyQt6_Qt6-6.7.2-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:fc93945eaef4536d68bd53566535efcbe78a7c05c2a533790a8fd022bac8bfaa"}, {file = "PyQt6_Qt6-6.7.3-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:cb525fdd393332de60887953029276a44de480fce1d785251ae639580f5e7246"},
{file = "PyQt6_Qt6-6.7.2-py3-none-win_amd64.whl", hash = "sha256:b2d7e5ddb1b9764cd60f1d730fa7bf7a1f0f61b2630967c81761d3d0a5a8a2e0"}, {file = "PyQt6_Qt6-6.7.3-py3-none-win_amd64.whl", hash = "sha256:36ea0892b8caeb983af3f285f45fb8dfbb93cfd972439f4e01b7efb2868f6230"},
] ]
[[package]] [[package]]
@ -973,11 +964,9 @@ files = [
[package.dependencies] [package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""} colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*" iniconfig = "*"
packaging = "*" packaging = "*"
pluggy = ">=1.5,<2" pluggy = ">=1.5,<2"
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras] [package.extras]
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
@ -998,13 +987,13 @@ six = ">=1.5"
[[package]] [[package]]
name = "rich" name = "rich"
version = "13.8.1" version = "13.9.2"
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
optional = false optional = false
python-versions = ">=3.7.0" python-versions = ">=3.8.0"
files = [ files = [
{file = "rich-13.8.1-py3-none-any.whl", hash = "sha256:1760a3c0848469b97b558fc61c85233e3dafb69c7a071b4d60c38099d3cd4c06"}, {file = "rich-13.9.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"},
{file = "rich-13.8.1.tar.gz", hash = "sha256:8260cda28e3db6bf04d2d1ef4dbc03ba80a824c88b0e7668a0f23126a424844a"}, {file = "rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c"},
] ]
[package.dependencies] [package.dependencies]
@ -1105,17 +1094,6 @@ pure-eval = "*"
[package.extras] [package.extras]
tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
optional = false
python-versions = ">=3.7"
files = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
[[package]] [[package]]
name = "tomlkit" name = "tomlkit"
version = "0.13.2" version = "0.13.2"
@ -1194,5 +1172,5 @@ files = [
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.10, <3.13" python-versions = ">=3.11, <3.13"
content-hash = "e5e345e3e4d28ac0e7de7727be130454201be1949be08158e744cdc6089a3f66" content-hash = "869348ffb24d0a55aee308a54cae333d5029c5aa52bc4082b720d766c63c2f9c"

View File

@ -21,7 +21,7 @@ include = [
] ]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">=3.10, <3.13" python = ">=3.11, <3.13"
uldaq = "^1.2.3" uldaq = "^1.2.3"
typer = "^0.12.5" typer = "^0.12.5"
matplotlib = "^3.9.2" matplotlib = "^3.9.2"

View File

@ -5,9 +5,6 @@ from PyQt6.QtWidgets import QApplication
from pyrelacs import info from pyrelacs import info
from pyrelacs.ui.mainwindow import PyRelacs from pyrelacs.ui.mainwindow import PyRelacs
from pyrelacs.util.logging import config_logging
log = config_logging()
from pyrelacs import ( from pyrelacs import (
resources, resources,
@ -28,6 +25,7 @@ def main():
x = int(settings.value("app/pos_x", 100)) x = int(settings.value("app/pos_x", 100))
y = int(settings.value("app/pos_y", 100)) y = int(settings.value("app/pos_y", 100))
# load config
window = PyRelacs() window = PyRelacs()
window.setMinimumWidth(200) window.setMinimumWidth(200)
window.setMinimumHeight(200) window.setMinimumHeight(200)

12
pyrelacs/config.yaml Normal file
View File

@ -0,0 +1,12 @@
Settings:
Repros: [Calibration]
Path: ~/projects/pyrelacs/test/
Metadata:
Lab: Neuroethology
PyRelacs:
Input:
Name: DAQ
Samplingrate: 40_000

View File

@ -8,9 +8,9 @@ class CircBuffer:
def __init__( def __init__(
self, self,
size: int, size: int,
mutex: QMutex,
channels: int = 1, channels: int = 1,
samplerate: int = 40_000, samplerate: int = 40_000,
mutex: QMutex = QMutex(),
): ):
self.__size = size self.__size = size
self.__channels = channels self.__channels = channels
@ -123,7 +123,7 @@ class CircBuffer:
# easy case first, we can spare the effort of further checking # easy case first, we can spare the effort of further checking
if index >= 0 and index <= self.write_index(channel): if index >= 0 and index <= self.write_index(channel):
if self.has_value(index, channel): if self.has_value(index, channel):
return (self.__buffer[channel, index], self.__time[index]) return (self.__buffer[channel, index], self.__time[channel, index])
else: else:
raise IndexError( raise IndexError(
f"Invalid index {index} on ring buffer for channel{channel}" f"Invalid index {index} on ring buffer for channel{channel}"
@ -132,7 +132,7 @@ class CircBuffer:
if index < 0: if index < 0:
index = self.write_index() - 1 index = self.write_index() - 1
if self.has_value(index, channel): if self.has_value(index, channel):
return (self.__buffer[channel, index], self.__time[index]) return (self.__buffer[channel, index], self.__time[channel, index])
else: else:
raise IndexError( raise IndexError(
f"Invalid index {index} on ring buffer for channel{channel}" f"Invalid index {index} on ring buffer for channel{channel}"

View File

@ -0,0 +1,43 @@
from IPython import embed
import nixio
from pyrelacs.dataio.circbuffer import CircBuffer
from pyrelacs.util.logging import config_logging
log = config_logging()
class NixWriter:
def __init__(self, buffer: CircBuffer) -> None:
self.buffer = buffer
def write_nix(self, *args, **kwargs):
self._write_header()
items = 0
chunk = 1000
log.debug("Starting the writing")
self.write = True
while self.write:
log.debug(items)
try:
data, _ = self.buffer.read(items, extend=chunk)
self.data_array.append(data)
except IndexError as e:
log.debug(f"{e}")
continue
items += chunk
log.debug("Stoppint the writing")
log.debug(f"Samples written {items}")
embed()
exit()
self.nix_file.close()
def _write_header(self):
self.nix_file = nixio.File.open(path="data.nix", mode=nixio.FileMode.Overwrite)
self.block = self.nix_file.create_block("recording", "testfile")
self.data_array = self.block.create_data_array(
"Analog1", "ndarray", shape=(1000,), dtype=nixio.DataType.Double
)
def stop_writing(self):
self.write = False

View File

@ -1,8 +1,5 @@
from math import sin
import time import time
from PyQt6.QtGui import QAction
import numpy as np import numpy as np
import matplotlib.pyplot as plt
from IPython import embed from IPython import embed
from pyrelacs.dataio.circbuffer import CircBuffer from pyrelacs.dataio.circbuffer import CircBuffer
from pyrelacs.util.logging import config_logging from pyrelacs.util.logging import config_logging
@ -42,6 +39,7 @@ class SinProducer:
log.debug(f"duration sinus {end_time-start_time}") log.debug(f"duration sinus {end_time-start_time}")
log.debug(f"Stimulation time {t}") log.debug(f"Stimulation time {t}")
log.debug(f"{self.buffer.totalcount()}")
# data = self.buffer.get_all() # data = self.buffer.get_all()
# log.debug(data.shape[0]) # log.debug(data.shape[0])
# log.debug(data.shape[0] / self.buffer.samplerate) # log.debug(data.shape[0] / self.buffer.samplerate)

View File

@ -1,29 +1,26 @@
import tomlkit import tomllib
import pathlib import pathlib
def load_project_settings(project_root): def load_project_settings(project_root):
print(project_root)
# Read the pyproject.toml file # Read the pyproject.toml file
with open(pathlib.Path.joinpath(project_root, "pyproject.toml"), "r") as f: pyproject_path = pathlib.Path.joinpath(project_root, "pyproject.toml")
pyproject_content = f.read() with open(pyproject_path, "rb") as f:
pyproject_content = tomllib.load(f)
# Parse the toml content info_dict = {
pyproject = tomlkit.parse(pyproject_content) "name": pyproject_content["tool"]["poetry"]["name"],
"version": pyproject_content["tool"]["poetry"]["version"],
# Access project settings "description": pyproject_content["tool"]["poetry"]["description"],
return { "authors": pyproject_content["tool"]["poetry"]["authors"],
"name": pyproject["tool"]["poetry"]["name"], "readme": pyproject_content["tool"]["poetry"]["authors"],
"version": pyproject["tool"]["poetry"]["version"], "licence": pyproject_content["tool"]["poetry"]["license"],
"description": pyproject["tool"]["poetry"]["description"], "organization": pyproject_content["project"]["organization"],
"authors": pyproject["tool"]["poetry"]["authors"], "classifiers": pyproject_content["tool"]["poetry"]["classifiers"],
"readme": pyproject["tool"]["poetry"]["authors"], "copyright": pyproject_content["project"]["copyright"],
"licence": pyproject["tool"]["poetry"]["license"], "repository": pyproject_content["tool"]["poetry"]["repository"],
"organization": pyproject["project"]["organization"],
"classifiers": pyproject["tool"]["poetry"]["classifiers"],
"copyright": pyproject["project"]["copyright"],
"repository": pyproject["tool"]["poetry"]["repository"],
} }
return info_dict
_root = pathlib.Path(__file__).parent.parent _root = pathlib.Path(__file__).parent.parent

View File

@ -13,7 +13,6 @@ from PyQt6.QtWidgets import (
QStatusBar, QStatusBar,
) )
from pyqtgraph.Qt.QtCore import QThread
import uldaq import uldaq
import nixio as nix import nixio as nix
import pyqtgraph as pg import pyqtgraph as pg
@ -21,6 +20,7 @@ import numpy as np
from pyrelacs.dataio.daq_producer import DaqProducer from pyrelacs.dataio.daq_producer import DaqProducer
from pyrelacs.dataio.nix_writer import NixWriter
from pyrelacs.dataio.sin_producer import SinProducer from pyrelacs.dataio.sin_producer import SinProducer
from pyrelacs.worker import Worker from pyrelacs.worker import Worker
from pyrelacs.repros.repros import Repro from pyrelacs.repros.repros import Repro
@ -51,13 +51,14 @@ class PyRelacs(QMainWindow):
self.figure = pg.GraphicsLayoutWidget() self.figure = pg.GraphicsLayoutWidget()
filename = path.joinpath(path.cwd(), "data.nix") # filename = path.joinpath(path.cwd(), "data.nix")
if filename.exists(): # if filename.exists():
self.nix_file = nix.File.open(str(filename), nix.FileMode.ReadOnly) # self.nix_file = nix.File.open(str(filename), nix.FileMode.ReadOnly)
filename = path.joinpath(path.cwd(), "calibration.nix") # filename = path.joinpath(path.cwd(), "calibration.nix")
self.nix_file = nix.File.open(str(filename), nix.FileMode.Overwrite) # self.nix_file = nix.File.open(str(filename), nix.FileMode.Overwrite)
#
self.calibration_plot = CalibrationPlot(self.figure, self.nix_file) # self.calibration_plot = CalibrationPlot(self.figure, self.nix_file)
# self.nix_file.close()
self.threadpool = QThreadPool() self.threadpool = QThreadPool()
self.repros = Repro() self.repros = Repro()
@ -95,12 +96,14 @@ class PyRelacs(QMainWindow):
end = time.time() end = time.time()
log.debug(f"Connection to DAQ took {end - start}") log.debug(f"Connection to DAQ took {end - start}")
if hasattr(uldaq, "daq_device"): if hasattr(PyRelacs, "daq_device"):
log.debug("Creating Daq Generator") log.debug("Creating Daq Generator")
self.daq_producer = DaqProducer(self.buffer, self.daq_device, [1, 1]) self.daq_producer = DaqProducer(self.buffer, self.daq_device, [1, 1])
else: else:
log.debug("Creating Sinus Generator") log.debug("Creating Sinus Generator")
self.sin_producer = SinProducer(self.buffer) self.sinus_producer = SinProducer(self.buffer)
self.nix_writer = NixWriter(self.buffer)
def create_actions(self): def create_actions(self):
self._rlx_exitaction = QAction(QIcon(":/icons/exit.png"), "Exit", self) self._rlx_exitaction = QAction(QIcon(":/icons/exit.png"), "Exit", self)
@ -127,12 +130,12 @@ class PyRelacs(QMainWindow):
# self._daq_connectaction.setShortcut(QKeySequence("Alt+d")) # self._daq_connectaction.setShortcut(QKeySequence("Alt+d"))
self._daq_disconnectaction.triggered.connect(self.disconnect_dac) self._daq_disconnectaction.triggered.connect(self.disconnect_dac)
self._daq_calibaction = QAction( # self._daq_calibaction = QAction(
QIcon(":/icons/calibration.png"), "Plot calibration", self # QIcon(":/icons/calibration.png"), "Plot calibration", self
) # )
self._daq_calibaction.setStatusTip("Calibrate the attenuator device") # self._daq_calibaction.setStatusTip("Calibrate the attenuator device")
# self._daq_calibaction.setShortcut(QKeySequence("Alt+d")) # # self._daq_calibaction.setShortcut(QKeySequence("Alt+d"))
self._daq_calibaction.triggered.connect(self.calibration_plot.plot) # self._daq_calibaction.triggered.connect(self.calibration_plot.plot)
self._run_action = QAction(QIcon(":/icons/record.png"), "Run", self) self._run_action = QAction(QIcon(":/icons/record.png"), "Run", self)
self._run_action.triggered.connect(self.run_daq) self._run_action.triggered.connect(self.run_daq)
@ -143,9 +146,12 @@ class PyRelacs(QMainWindow):
self._stop_recording = QAction(QIcon(":/icons/stop.png"), "Stop", self) self._stop_recording = QAction(QIcon(":/icons/stop.png"), "Stop", self)
self._stop_recording.triggered.connect(self.stop_recording) self._stop_recording.triggered.connect(self.stop_recording)
self._refresh = QAction("Recenter", self) self._recenter_plot = QAction("Recenter", self)
self._refresh.triggered.connect(self.recenter_continously_plot) self._recenter_plot.triggered.connect(self.recenter_continously_plot)
self._refresh.setShortcut(QKeySequence("Alt+r")) self._recenter_plot.setShortcut(QKeySequence("Alt+r"))
self._record = QAction(QIcon(":/icons/record.png"), "Record", self)
self._record.triggered.connect(self.record)
self.create_menu() self.create_menu()
@ -164,7 +170,7 @@ class PyRelacs(QMainWindow):
device_menu.addAction(self._daq_connectaction) device_menu.addAction(self._daq_connectaction)
device_menu.addAction(self._daq_disconnectaction) device_menu.addAction(self._daq_disconnectaction)
device_menu.addSeparator() device_menu.addSeparator()
device_menu.addAction(self._daq_calibaction) # device_menu.addAction(self._daq_calibaction)
device_menu.addAction(self._run_action) device_menu.addAction(self._run_action)
if help_menu is not None: if help_menu is not None:
@ -185,11 +191,13 @@ class PyRelacs(QMainWindow):
daq_toolbar = QToolBar("DAQ") daq_toolbar = QToolBar("DAQ")
daq_toolbar.addAction(self._daq_connectaction) daq_toolbar.addAction(self._daq_connectaction)
daq_toolbar.addAction(self._daq_disconnectaction) daq_toolbar.addAction(self._daq_disconnectaction)
daq_toolbar.addAction(self._daq_calibaction) # daq_toolbar.addAction(self._daq_calibaction)
daq_toolbar.addAction(self._run_action) daq_toolbar.addAction(self._run_action)
daq_toolbar.addAction(self._run_sinus_action) daq_toolbar.addAction(self._run_sinus_action)
daq_toolbar.addAction(self._stop_recording) daq_toolbar.addAction(self._stop_recording)
# daq_toolbar.addAction(self._refresh) daq_toolbar.addAction(self._recenter_plot)
daq_toolbar.addSeparator()
daq_toolbar.addAction(self._record)
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, daq_toolbar) self.addToolBar(Qt.ToolBarArea.TopToolBarArea, daq_toolbar)
repro_toolbar = QToolBar("Repros") repro_toolbar = QToolBar("Repros")
@ -223,7 +231,7 @@ class PyRelacs(QMainWindow):
self.continously_plot.plot() self.continously_plot.plot()
def run_sinus(self): def run_sinus(self):
sinus_pro = Worker(self.sin_producer.produce_sin) sinus_pro = Worker(self.sinus_producer.produce_sin)
sinus_pro.signals.result.connect(self.print_output) sinus_pro.signals.result.connect(self.print_output)
sinus_pro.signals.finished.connect(self.thread_complete) sinus_pro.signals.finished.connect(self.thread_complete)
sinus_pro.signals.progress.connect(self.progress_fn) sinus_pro.signals.progress.connect(self.progress_fn)
@ -231,12 +239,27 @@ class PyRelacs(QMainWindow):
self.continously_plot.plot() self.continously_plot.plot()
def record(self):
nix_writer = Worker(self.nix_writer.write_nix)
nix_writer.signals.result.connect(self.print_output)
nix_writer.signals.finished.connect(self.thread_complete)
nix_writer.signals.progress.connect(self.progress_fn)
self.threadpool.start(nix_writer)
def stop_recording(self): def stop_recording(self):
self.add_to_textfield("Stopping the recording") self.add_to_textfield("Stopping the recording")
if hasattr(PyRelacs, "sin_producer"):
self.sin_producer.stop_request()
self.continously_plot.stop_plotting() self.continously_plot.stop_plotting()
if hasattr(uldaq, "daq_device"): self.nix_writer.stop_writing()
log.debug("Stopping acquisiton")
try:
self.sinus_producer.stop_request()
log.debug("Stopping Sinus")
except AttributeError:
log.debug("Did not generate Sinus")
if hasattr(PyRelacs, "daq_device"):
log.debug("Stopping DAQ")
self.daq_producer.stop_aquisition() self.daq_producer.stop_aquisition()
def connect_dac(self): def connect_dac(self):
@ -247,8 +270,8 @@ class PyRelacs(QMainWindow):
self.daq_device.connect() self.daq_device.connect()
log.debug("connected") log.debug("connected")
except IndexError: except IndexError:
log.error("DAQ is not connected") log.info("DAQ is not connected")
log.error("Please connect a DAQ device to the system") log.info("Please connect a DAQ device to the system")
def disconnect_dac(self): def disconnect_dac(self):
try: try:
@ -274,6 +297,7 @@ class PyRelacs(QMainWindow):
self.stop_recording() self.stop_recording()
self.add_to_textfield("exiting") self.add_to_textfield("exiting")
self.disconnect_dac() self.disconnect_dac()
log.info("closing GUI")
self.close() self.close()
def on_about(self, e): def on_about(self, e):