diff --git a/.github/workflows/on-pull-request.yml b/.github/workflows/on-pull-request.yml index 39ff501a..722b220e 100644 --- a/.github/workflows/on-pull-request.yml +++ b/.github/workflows/on-pull-request.yml @@ -35,7 +35,8 @@ jobs: poetry- - name: Set up the project - run: poetry install + run: poetry install --extras configbuilder + - name: Check formatting run: poetry run poe check-format diff --git a/CHANGELOG.md b/CHANGELOG.md index a13afa87..6dab4c5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] +### Added +- simulator - ``create_simulator_controller_connections`` can now be used to create the connections between a subset of a large cluster. + +### Changed +- config/waveform_tools - Added sampling rate argument with default value set to 1GS/s to the waveforms. +- simulator - ``create_simulator_controller_connections`` now creates the connections with a different algorithm that uses all available optical connections. +- simulator - ``create_simulator_controller_connections`` order of input parameters has changed. + +### Deprecated +- simulator - ``qualang_tools.simulator_tools`` has been deprecated and was moved to ``qualang_tools.simulator``. + +## [0.16.0] - 2024-01-25 ### Fixed - ConfigBuilder - `Element` now correctly accepts default arguments. - External_frameworks/qcodes - Fix bug with the setpoints when streaming the raw adc traces. @@ -17,8 +29,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Video_mode - New module to update some pre-defined parameters of a QUA program while fetching data from the OPX. ### Changed +- Eased package dependencies, requires python 3.8 or above - Unit - `demod2volts` now has a `single_demod` flag to correctly convert the data from single demodulation. +## Deprecated +- ConfigBuilder and ConfigGUI are not being activity developed and may not have all config options + + ## [0.15.2] - 2023-09-06 ### Added - results - Add `wait_until_job_is_paused()` to block python console until the OPX sequence reaches a `pause()` statement. @@ -294,7 +311,8 @@ operation (readout pulse for instance) already defined in the configuration. ### Added - This release exposes the baking, RB and XEB functionality. -[Unreleased]: https://github.com/qua-platform/py-qua-tools/compare/v0.15.2...HEAD +[Unreleased]: https://github.com/qua-platform/py-qua-tools/compare/v0.16.0...HEAD +[0.15.2]: https://github.com/qua-platform/py-qua-tools/compare/v0.15.2...v0.16.0 [0.15.2]: https://github.com/qua-platform/py-qua-tools/compare/v0.15.1...v0.15.2 [0.15.1]: https://github.com/qua-platform/py-qua-tools/compare/v0.15.0...v0.15.1 [0.15.0]: https://github.com/qua-platform/py-qua-tools/compare/v0.14.0...v0.15.0 diff --git a/README.md b/README.md index b3827881..0a3ea65f 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ It includes: * [Analysis Tools](qualang_tools/analysis/README.md) - This library includes tools for analyzing data from experiments. It currently has a two-states discriminator for analyzing the ground and excited IQ blobs. * [Multi-user tools](qualang_tools/multi_user/README.md) - This library includes tools for working with the QOP in a multi-user or multi-process setting. +* [Simulator tools](qualang_tools/simulator/README.md) - This library includes tools for creating simulations. * [Bakery](qualang_tools/bakery/README.md) - This library introduces a new framework for creating arbitrary waveforms and storing them in the usual configuration file. It allows defining waveforms in a QUA-like manner while working with 1ns resolution (or higher). @@ -35,9 +36,9 @@ storing them in the usual configuration file. It allows defining waveforms in a * [Config Tools](qualang_tools/config/README.md) - This package includes tools related to the QOP configuration file, including: * [Integration Weights Tools](qualang_tools/config/README_integration_weights_tools.md) - This package includes tools for the creation and manipulation of integration weights. * [Waveform Tools](qualang_tools/config/README_waveform_tools.md) - This package includes tools for creating waveforms useful for experiments with the QOP. - * [Config GUI](qualang_tools/config/README_config_GUI.md) - This package contains a GUI for creating and visualizing the configuration file. - * [Config Builder](qualang_tools/config/README_config_builder.md) - This package contains an API for creating and manipulation configuration files. * [Config Helper Tools](qualang_tools/config/README_helper_tools.md) - This package includes tools for writing and updating the configuration. + * [Config GUI](qualang_tools/config/README_config_GUI.md) - This package contains a GUI for creating and visualizing the configuration file - No longer being actively developed. + * [Config Builder](qualang_tools/config/README_config_builder.md) - This package contains an API for creating and manipulation configuration files - No longer being actively developed. * [Control Panel](qualang_tools/control_panel/README.md)- This package includes tools for directly controlling the OPX. * [ManualOutputControl](qualang_tools/control_panel/README_manual_output_control.md) - This module allows controlling the outputs from the OPX in CW mode. Once created, it has an API for defining which channels are on. Analog channels also have an API for defining their amplitude and frequency. @@ -48,10 +49,20 @@ storing them in the usual configuration file. It allows defining waveforms in a Install the current version using `pip`, the `--upgrade` flag ensures that you will get the latest version. -```commandline +```bash pip install --upgrade qualang-tools ``` +Note that in order use the `Config GUI` or `Config Builder`, you need to install using +```bash +pip install --upgrade qualang-tools[configbuilder] +``` + +Note that in order use the `Interactive Plot Library`, you need to install using +```bash +pip install --upgrade qualang-tools[interplot] +``` + ## Support and Contribution Have an idea for another tool? A way to improve an existing one? Found a bug in our code? diff --git a/poetry.lock b/poetry.lock index 41a8dc43..501fdc5b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,63 +1,104 @@ +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. + [[package]] name = "appnope" version = "0.1.2" description = "Disable App Nap on macOS >= 10.9" -category = "main" optional = true python-versions = "*" +files = [ + {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, + {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, +] [[package]] name = "atomicwrites" version = "1.4.0" description = "Atomic file writes." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] [[package]] name = "attrs" version = "21.2.0" description = "Classes Without Boilerplate" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, + {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, +] [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] +dev = ["coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] +tests-no-zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] [[package]] name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" -category = "main" optional = true python-versions = "*" +files = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] [[package]] name = "betterproto" version = "2.0.0b5" description = "A better Protobuf / gRPC generator & library" -category = "main" optional = false python-versions = ">=3.6.2,<4.0" +files = [ + {file = "betterproto-2.0.0b5-py3-none-any.whl", hash = "sha256:d3e6115c7d5136f1d5974e565b7560273f66b43065e74218e472321ee1258f4c"}, + {file = "betterproto-2.0.0b5.tar.gz", hash = "sha256:00a301c70a2db4d3cdd2b261522ae1d34972fb04b655a154d67daaaf4131102e"}, +] [package.dependencies] grpclib = ">=0.4.1,<0.5.0" python-dateutil = ">=2.8,<3.0" [package.extras] -compiler = ["black (>=19.3b0)", "jinja2 (>=3.0.3)", "isort (>=5.10.1,<6.0.0)"] +compiler = ["black (>=19.3b0)", "isort (>=5.10.1,<6.0.0)", "jinja2 (>=3.0.3)"] [[package]] name = "black" version = "22.3.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.6.2" +files = [ + {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, + {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, + {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, + {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, + {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, + {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, + {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, + {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, + {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, + {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, + {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, + {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, + {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, + {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, + {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, + {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, + {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, + {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, + {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, +] [package.dependencies] click = ">=8.0.0" @@ -65,7 +106,6 @@ mypy-extensions = ">=0.4.3" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] @@ -78,53 +118,150 @@ uvloop = ["uvloop (>=0.15.2)"] name = "brotli" version = "1.0.9" description = "Python bindings for the Brotli compression library" -category = "main" optional = false python-versions = "*" +files = [ + {file = "Brotli-1.0.9-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:268fe94547ba25b58ebc724680609c8ee3e5a843202e9a381f6f9c5e8bdb5c70"}, + {file = "Brotli-1.0.9-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:c2415d9d082152460f2bd4e382a1e85aed233abc92db5a3880da2257dc7daf7b"}, + {file = "Brotli-1.0.9-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5913a1177fc36e30fcf6dc868ce23b0453952c78c04c266d3149b3d39e1410d6"}, + {file = "Brotli-1.0.9-cp27-cp27m-win32.whl", hash = "sha256:afde17ae04d90fbe53afb628f7f2d4ca022797aa093e809de5c3cf276f61bbfa"}, + {file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7cb81373984cc0e4682f31bc3d6be9026006d96eecd07ea49aafb06897746452"}, + {file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:db844eb158a87ccab83e868a762ea8024ae27337fc7ddcbfcddd157f841fdfe7"}, + {file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9744a863b489c79a73aba014df554b0e7a0fc44ef3f8a0ef2a52919c7d155031"}, + {file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a72661af47119a80d82fa583b554095308d6a4c356b2a554fdc2799bc19f2a43"}, + {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ee83d3e3a024a9618e5be64648d6d11c37047ac48adff25f12fa4226cf23d1c"}, + {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:19598ecddd8a212aedb1ffa15763dd52a388518c4550e615aed88dc3753c0f0c"}, + {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:44bb8ff420c1d19d91d79d8c3574b8954288bdff0273bf788954064d260d7ab0"}, + {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e23281b9a08ec338469268f98f194658abfb13658ee98e2b7f85ee9dd06caa91"}, + {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3496fc835370da351d37cada4cf744039616a6db7d13c430035e901443a34daa"}, + {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83bb06a0192cccf1eb8d0a28672a1b79c74c3a8a5f2619625aeb6f28b3a82bb"}, + {file = "Brotli-1.0.9-cp310-cp310-win32.whl", hash = "sha256:26d168aac4aaec9a4394221240e8a5436b5634adc3cd1cdf637f6645cecbf181"}, + {file = "Brotli-1.0.9-cp310-cp310-win_amd64.whl", hash = "sha256:622a231b08899c864eb87e85f81c75e7b9ce05b001e59bbfbf43d4a71f5f32b2"}, + {file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cc0283a406774f465fb45ec7efb66857c09ffefbe49ec20b7882eff6d3c86d3a"}, + {file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:11d3283d89af7033236fa4e73ec2cbe743d4f6a81d41bd234f24bf63dde979df"}, + {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c1306004d49b84bd0c4f90457c6f57ad109f5cc6067a9664e12b7b79a9948ad"}, + {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1375b5d17d6145c798661b67e4ae9d5496920d9265e2f00f1c2c0b5ae91fbde"}, + {file = "Brotli-1.0.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cab1b5964b39607a66adbba01f1c12df2e55ac36c81ec6ed44f2fca44178bf1a"}, + {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ed6a5b3d23ecc00ea02e1ed8e0ff9a08f4fc87a1f58a2530e71c0f48adf882f"}, + {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cb02ed34557afde2d2da68194d12f5719ee96cfb2eacc886352cb73e3808fc5d"}, + {file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b3523f51818e8f16599613edddb1ff924eeb4b53ab7e7197f85cbc321cdca32f"}, + {file = "Brotli-1.0.9-cp311-cp311-win32.whl", hash = "sha256:ba72d37e2a924717990f4d7482e8ac88e2ef43fb95491eb6e0d124d77d2a150d"}, + {file = "Brotli-1.0.9-cp311-cp311-win_amd64.whl", hash = "sha256:3ffaadcaeafe9d30a7e4e1e97ad727e4f5610b9fa2f7551998471e3736738679"}, + {file = "Brotli-1.0.9-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:c83aa123d56f2e060644427a882a36b3c12db93727ad7a7b9efd7d7f3e9cc2c4"}, + {file = "Brotli-1.0.9-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2ae9f5f67f89aade1fab0f7fd8f2832501311c363a21579d02defa844d9296"}, + {file = "Brotli-1.0.9-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:68715970f16b6e92c574c30747c95cf8cf62804569647386ff032195dc89a430"}, + {file = "Brotli-1.0.9-cp35-cp35m-win32.whl", hash = "sha256:defed7ea5f218a9f2336301e6fd379f55c655bea65ba2476346340a0ce6f74a1"}, + {file = "Brotli-1.0.9-cp35-cp35m-win_amd64.whl", hash = "sha256:88c63a1b55f352b02c6ffd24b15ead9fc0e8bf781dbe070213039324922a2eea"}, + {file = "Brotli-1.0.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:503fa6af7da9f4b5780bb7e4cbe0c639b010f12be85d02c99452825dd0feef3f"}, + {file = "Brotli-1.0.9-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:40d15c79f42e0a2c72892bf407979febd9cf91f36f495ffb333d1d04cebb34e4"}, + {file = "Brotli-1.0.9-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:93130612b837103e15ac3f9cbacb4613f9e348b58b3aad53721d92e57f96d46a"}, + {file = "Brotli-1.0.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87fdccbb6bb589095f413b1e05734ba492c962b4a45a13ff3408fa44ffe6479b"}, + {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6d847b14f7ea89f6ad3c9e3901d1bc4835f6b390a9c71df999b0162d9bb1e20f"}, + {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:495ba7e49c2db22b046a53b469bbecea802efce200dffb69b93dd47397edc9b6"}, + {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4688c1e42968ba52e57d8670ad2306fe92e0169c6f3af0089be75bbac0c64a3b"}, + {file = "Brotli-1.0.9-cp36-cp36m-win32.whl", hash = "sha256:61a7ee1f13ab913897dac7da44a73c6d44d48a4adff42a5701e3239791c96e14"}, + {file = "Brotli-1.0.9-cp36-cp36m-win_amd64.whl", hash = "sha256:1c48472a6ba3b113452355b9af0a60da5c2ae60477f8feda8346f8fd48e3e87c"}, + {file = "Brotli-1.0.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b78a24b5fd13c03ee2b7b86290ed20efdc95da75a3557cc06811764d5ad1126"}, + {file = "Brotli-1.0.9-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:9d12cf2851759b8de8ca5fde36a59c08210a97ffca0eb94c532ce7b17c6a3d1d"}, + {file = "Brotli-1.0.9-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6c772d6c0a79ac0f414a9f8947cc407e119b8598de7621f39cacadae3cf57d12"}, + {file = "Brotli-1.0.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29d1d350178e5225397e28ea1b7aca3648fcbab546d20e7475805437bfb0a130"}, + {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7bbff90b63328013e1e8cb50650ae0b9bac54ffb4be6104378490193cd60f85a"}, + {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ec1947eabbaf8e0531e8e899fc1d9876c179fc518989461f5d24e2223395a9e3"}, + {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12effe280b8ebfd389022aa65114e30407540ccb89b177d3fbc9a4f177c4bd5d"}, + {file = "Brotli-1.0.9-cp37-cp37m-win32.whl", hash = "sha256:f909bbbc433048b499cb9db9e713b5d8d949e8c109a2a548502fb9aa8630f0b1"}, + {file = "Brotli-1.0.9-cp37-cp37m-win_amd64.whl", hash = "sha256:97f715cf371b16ac88b8c19da00029804e20e25f30d80203417255d239f228b5"}, + {file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e16eb9541f3dd1a3e92b89005e37b1257b157b7256df0e36bd7b33b50be73bcb"}, + {file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:160c78292e98d21e73a4cc7f76a234390e516afcd982fa17e1422f7c6a9ce9c8"}, + {file = "Brotli-1.0.9-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b663f1e02de5d0573610756398e44c130add0eb9a3fc912a09665332942a2efb"}, + {file = "Brotli-1.0.9-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5b6ef7d9f9c38292df3690fe3e302b5b530999fa90014853dcd0d6902fb59f26"}, + {file = "Brotli-1.0.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a674ac10e0a87b683f4fa2b6fa41090edfd686a6524bd8dedbd6138b309175c"}, + {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e2d9e1cbc1b25e22000328702b014227737756f4b5bf5c485ac1d8091ada078b"}, + {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b336c5e9cf03c7be40c47b5fd694c43c9f1358a80ba384a21969e0b4e66a9b17"}, + {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85f7912459c67eaab2fb854ed2bc1cc25772b300545fe7ed2dc03954da638649"}, + {file = "Brotli-1.0.9-cp38-cp38-win32.whl", hash = "sha256:35a3edbe18e876e596553c4007a087f8bcfd538f19bc116917b3c7522fca0429"}, + {file = "Brotli-1.0.9-cp38-cp38-win_amd64.whl", hash = "sha256:269a5743a393c65db46a7bb982644c67ecba4b8d91b392403ad8a861ba6f495f"}, + {file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2aad0e0baa04517741c9bb5b07586c642302e5fb3e75319cb62087bd0995ab19"}, + {file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5cb1e18167792d7d21e21365d7650b72d5081ed476123ff7b8cac7f45189c0c7"}, + {file = "Brotli-1.0.9-cp39-cp39-manylinux1_i686.whl", hash = "sha256:16d528a45c2e1909c2798f27f7bf0a3feec1dc9e50948e738b961618e38b6a7b"}, + {file = "Brotli-1.0.9-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:56d027eace784738457437df7331965473f2c0da2c70e1a1f6fdbae5402e0389"}, + {file = "Brotli-1.0.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bf919756d25e4114ace16a8ce91eb340eb57a08e2c6950c3cebcbe3dff2a5e7"}, + {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e4c4e92c14a57c9bd4cb4be678c25369bf7a092d55fd0866f759e425b9660806"}, + {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e48f4234f2469ed012a98f4b7874e7f7e173c167bed4934912a29e03167cf6b1"}, + {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ed4c92a0665002ff8ea852353aeb60d9141eb04109e88928026d3c8a9e5433c"}, + {file = "Brotli-1.0.9-cp39-cp39-win32.whl", hash = "sha256:cfc391f4429ee0a9370aa93d812a52e1fee0f37a81861f4fdd1f4fb28e8547c3"}, + {file = "Brotli-1.0.9-cp39-cp39-win_amd64.whl", hash = "sha256:854c33dad5ba0fbd6ab69185fec8dab89e13cda6b7d191ba111987df74f38761"}, + {file = "Brotli-1.0.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9749a124280a0ada4187a6cfd1ffd35c350fb3af79c706589d98e088c5044267"}, + {file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:73fd30d4ce0ea48010564ccee1a26bfe39323fde05cb34b5863455629db61dc7"}, + {file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02177603aaca36e1fd21b091cb742bb3b305a569e2402f1ca38af471777fb019"}, + {file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"}, + {file = "Brotli-1.0.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b43775532a5904bc938f9c15b77c613cb6ad6fb30990f3b0afaea82797a402d8"}, + {file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5bf37a08493232fbb0f8229f1824b366c2fc1d02d64e7e918af40acd15f3e337"}, + {file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:330e3f10cd01da535c70d09c4283ba2df5fb78e915bea0a28becad6e2ac010be"}, + {file = "Brotli-1.0.9-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e1abbeef02962596548382e393f56e4c94acd286bd0c5afba756cffc33670e8a"}, + {file = "Brotli-1.0.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3148362937217b7072cf80a2dcc007f09bb5ecb96dae4617316638194113d5be"}, + {file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:336b40348269f9b91268378de5ff44dc6fbaa2268194f85177b53463d313842a"}, + {file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b09a16a1950b9ef495a0f8b9d0a87599a9d1f179e2d4ac014b2ec831f87e7"}, + {file = "Brotli-1.0.9-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c8e521a0ce7cf690ca84b8cc2272ddaf9d8a50294fd086da67e517439614c755"}, + {file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"}, +] [[package]] name = "certifi" version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, +] [[package]] name = "click" version = "8.0.3" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, + {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" version = "0.4.4" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] [[package]] name = "cycler" version = "0.11.0" description = "Composable style cycles" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, + {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, +] [[package]] name = "dash" version = "2.0.0" description = "A Python framework for building reactive web-apps. Developed by Plotly." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "dash-2.0.0-py3-none-any.whl", hash = "sha256:23f331533663641a5c70a15c46da26d29ef5335f9aeb8bc03d09de865fc7cd62"}, + {file = "dash-2.0.0.tar.gz", hash = "sha256:29277c24e2f795b069cb102ce1ab0cd3ad5cf9d3b4fd16c03da9671a5eea28a4"}, +] [package.dependencies] dash-core-components = "2.0.0" @@ -135,16 +272,19 @@ flask-compress = "*" plotly = ">=5.0.0" [package.extras] -dev = ["dash-flow-example (==0.0.5)", "dash-dangerously-set-inner-html", "mock (==4.0.3)", "flake8 (==3.9.2)", "PyYAML (==5.4.1)", "pylint (==2.10.2)", "black (==21.6b0)", "fire (==0.4.0)", "coloredlogs (==15.0.1)", "flask-talisman (==0.8.1)", "isort (==4.3.21)", "orjson (==3.3.1)", "orjson (==3.6.1)"] -testing = ["pytest (>=6.0.2)", "pytest-sugar (>=0.9.4)", "pytest-mock (>=3.2.0)", "lxml (>=4.6.2)", "selenium (>=3.141.0)", "percy (>=2.0.2)", "requests[security] (>=2.21.0)", "beautifulsoup4 (>=4.8.2)", "waitress (>=1.4.4)", "diskcache (>=5.2.1)", "multiprocess (>=0.70.12)", "redis (>=3.5.3)", "psutil (>=5.8.0)", "celery[redis] (>=5.1.2)", "flaky (>=3.7.0)", "cryptography (<3.4)"] +dev = ["PyYAML (==5.4.1)", "black (==21.6b0)", "coloredlogs (==15.0.1)", "dash-dangerously-set-inner-html", "dash-flow-example (==0.0.5)", "fire (==0.4.0)", "flake8 (==3.9.2)", "flask-talisman (==0.8.1)", "isort (==4.3.21)", "mock (==4.0.3)", "orjson (==3.3.1)", "orjson (==3.6.1)", "pylint (==2.10.2)"] +testing = ["beautifulsoup4 (>=4.8.2)", "celery[redis] (>=5.1.2)", "cryptography (<3.4)", "diskcache (>=5.2.1)", "flaky (>=3.7.0)", "lxml (>=4.6.2)", "multiprocess (>=0.70.12)", "percy (>=2.0.2)", "psutil (>=5.8.0)", "pytest (>=6.0.2)", "pytest-mock (>=3.2.0)", "pytest-sugar (>=0.9.4)", "redis (>=3.5.3)", "requests[security] (>=2.21.0)", "selenium (>=3.141.0)", "waitress (>=1.4.4)"] [[package]] name = "dash-bootstrap-components" version = "1.0.2" description = "Bootstrap themed components for use in Plotly Dash" -category = "main" -optional = false +optional = true python-versions = ">=3.6, <4" +files = [ + {file = "dash-bootstrap-components-1.0.2.tar.gz", hash = "sha256:d385fa959159cdfd11885a753341fba67bad8622c84e5f61585930953f55f54f"}, + {file = "dash_bootstrap_components-1.0.2-py3-none-any.whl", hash = "sha256:4b862c6b2f6667da686fd2015a0b12a286920df8cce7dd6719fb1469025f6c68"}, +] [package.dependencies] dash = ">=2.0.0" @@ -156,17 +296,23 @@ pandas = ["numpy", "pandas"] name = "dash-core-components" version = "2.0.0" description = "Core component suite for Dash" -category = "main" optional = false python-versions = "*" +files = [ + {file = "dash_core_components-2.0.0-py3-none-any.whl", hash = "sha256:52b8e8cce13b18d0802ee3acbc5e888cb1248a04968f962d63d070400af2e346"}, + {file = "dash_core_components-2.0.0.tar.gz", hash = "sha256:c6733874af975e552f95a1398a16c2ee7df14ce43fa60bb3718a3c6e0b63ffee"}, +] [[package]] name = "dash-cytoscape" version = "0.3.0" description = "A Component Library for Dash aimed at facilitating network visualization in Python, wrapped around Cytoscape.js" -category = "main" -optional = false +optional = true python-versions = "*" +files = [ + {file = "dash_cytoscape-0.3.0-py3-none-any.whl", hash = "sha256:718dc1568b9e7bfe7f64376aa903c64a1a1fe6daed4e559b254456f18dd3135f"}, + {file = "dash_cytoscape-0.3.0.tar.gz", hash = "sha256:a71ad4fe095570b71d4ad7c0d29199e9780c2e6796173d3b25fccc2cc58c855f"}, +] [package.dependencies] dash = "*" @@ -175,33 +321,44 @@ dash = "*" name = "dash-dangerously-set-inner-html" version = "0.0.2" description = "A dash component for specifying raw HTML" -category = "main" -optional = false +optional = true python-versions = "*" +files = [ + {file = "dash_dangerously_set_inner_html-0.0.2.tar.gz", hash = "sha256:d7fe990755851fc4d2e22c8f10b7aea055cabf380bbceefba589779b269fea64"}, +] [[package]] name = "dash-html-components" version = "2.0.0" description = "Vanilla HTML components for Dash" -category = "main" optional = false python-versions = "*" +files = [ + {file = "dash_html_components-2.0.0-py3-none-any.whl", hash = "sha256:b42cc903713c9706af03b3f2548bda4be7307a7cf89b7d6eae3da872717d1b63"}, + {file = "dash_html_components-2.0.0.tar.gz", hash = "sha256:8703a601080f02619a6390998e0b3da4a5daabe97a1fd7a9cebc09d015f26e50"}, +] [[package]] name = "dash-table" version = "5.0.0" description = "Dash table" -category = "main" optional = false python-versions = "*" +files = [ + {file = "dash_table-5.0.0-py3-none-any.whl", hash = "sha256:19036fa352bb1c11baf38068ec62d172f0515f73ca3276c79dee49b95ddc16c9"}, + {file = "dash_table-5.0.0.tar.gz", hash = "sha256:18624d693d4c8ef2ddec99a6f167593437a7ea0bf153aa20f318c170c5bc7308"}, +] [[package]] name = "datadog-api-client" version = "2.11.0" description = "Collection of all Datadog Public endpoints" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "datadog-api-client-2.11.0.tar.gz", hash = "sha256:e0e9291074b8bc45873ba857b89e5b53752f812f14885eac35a01ddab574532d"}, + {file = "datadog_api_client-2.11.0-py3-none-any.whl", hash = "sha256:26b0e9bd190dbc15d1f3c27e777eb2eaf32e61dd16c1ef3ef52d88dd9c207b55"}, +] [package.dependencies] certifi = "*" @@ -212,24 +369,98 @@ urllib3 = ">=1.15" [package.extras] apm = ["ddtrace (>=1.2.0)"] async = ["aiosonic"] -tests = ["aiosonic", "glom", "jinja2", "pytest", "pytest-bdd (==6.0.1)", "pytest-asyncio", "pytest-randomly", "pytest-recording", "python-dateutil", "mypy", "types-python-dateutil", "zstandard"] +tests = ["aiosonic", "glom", "jinja2", "mypy", "pytest", "pytest-asyncio", "pytest-bdd (==6.0.1)", "pytest-randomly", "pytest-recording", "python-dateutil", "types-python-dateutil", "zstandard"] zstandard = ["zstandard"] [[package]] name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = true python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] [[package]] name = "dependency-injector" version = "4.41.0" description = "Dependency injection framework for Python" -category = "main" optional = false python-versions = "*" +files = [ + {file = "dependency-injector-4.41.0.tar.gz", hash = "sha256:939dfc657104bc3e66b67afd3fb2ebb0850c9a1e73d0d26066f2bbdd8735ff9c"}, + {file = "dependency_injector-4.41.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2381a251b04244125148298212550750e6e1403e9b2850cc62e0e829d050ad3"}, + {file = "dependency_injector-4.41.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75280dfa23f7c88e1bf56c3920d58a43516816de6f6ab2a6650bb8a0f27d5c2c"}, + {file = "dependency_injector-4.41.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63bfba21f8bff654a80e9b9d06dd6c43a442990b73bf89cd471314c11c541ec2"}, + {file = "dependency_injector-4.41.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3535d06416251715b45f8412482b58ec1c6196a4a3baa207f947f0b03a7c4b44"}, + {file = "dependency_injector-4.41.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d09c08c944a25dabfb454238c1a889acd85102b93ae497de523bf9ab7947b28a"}, + {file = "dependency_injector-4.41.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:586a0821720b15932addbefb00f7370fbcd5831d6ebbd6494d774b44ff96d23a"}, + {file = "dependency_injector-4.41.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7fa4970f12a3fc95d8796938b11c41276ad1ff4c447b0e589212eab3fc527a90"}, + {file = "dependency_injector-4.41.0-cp310-cp310-win32.whl", hash = "sha256:d557e40673de984f78dab13ebd68d27fbb2f16d7c4e3b663ea2fa2f9fae6765b"}, + {file = "dependency_injector-4.41.0-cp310-cp310-win_amd64.whl", hash = "sha256:3744c327d18408e74781bd6d8b7738745ee80ef89f2c8daecf9ebd098cb84972"}, + {file = "dependency_injector-4.41.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:89c67edffe7007cf33cee79ecbca38f48efcc2add5c280717af434db6c789377"}, + {file = "dependency_injector-4.41.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:786f7aac592e191c9caafc47732161d807bad65c62f260cd84cd73c7e2d67d6d"}, + {file = "dependency_injector-4.41.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8b61a15bc46a3aa7b29bd8a7384b650aa3a7ef943491e93c49a0540a0b3dda4"}, + {file = "dependency_injector-4.41.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4f113e5d4c3070973ad76e5bda7317e500abae6083d78689f0b6e37cf403abf"}, + {file = "dependency_injector-4.41.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5fa3ed8f0700e47a0e7363f949b4525ffa8277aa1c5b10ca5b41fce4dea61bb9"}, + {file = "dependency_injector-4.41.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05e15ea0f2b14c1127e8b0d1597fef13f98845679f63bf670ba12dbfc12a16ef"}, + {file = "dependency_injector-4.41.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3055b3fc47a0d6e5f27defb4166c0d37543a4967c279549b154afaf506ce6efc"}, + {file = "dependency_injector-4.41.0-cp311-cp311-win32.whl", hash = "sha256:37d5954026e3831663518d78bdf4be9c2dbfea691edcb73c813aa3093aa4363a"}, + {file = "dependency_injector-4.41.0-cp311-cp311-win_amd64.whl", hash = "sha256:f89a507e389b7e4d4892dd9a6f5f4da25849e24f73275478634ac594d621ab3f"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ac79f3c05747f9724bd56c06985e78331fc6c85eb50f3e3f1a35e0c60f9977e9"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75e7a733b372db3144a34020c4233f6b94db2c6342d6d16bc5245b1b941ee2bd"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40936d9384363331910abd59dd244158ec3572abf9d37322f15095315ac99893"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a31d9d60be4b585585081109480cfb2ef564d3b851cb32a139bf8408411a93a"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:953bfac819d32dc72b963767589e0ed372e5e9e78b03fb6b89419d0500d34bbe"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:8f0090ff14038f17a026ca408a3a0b0e7affb6aa7498b2b59d670f40ac970fbe"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:6b29abac56ce347d2eb58a560723e1663ee2125cf5cc38866ed92b84319927ec"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-win32.whl", hash = "sha256:059fbb48333148143e8667a5323d162628dfe27c386bd0ed3deeecfc390338bf"}, + {file = "dependency_injector-4.41.0-cp36-cp36m-win_amd64.whl", hash = "sha256:16de2797dcfcc2263b8672bf0751166f7c7b369ca2ff9246ceb67b65f8e1d802"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c71d30b6708438050675f338edb9a25bea6c258478dbe5ec8405286756a2d347"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d283aee588a72072439e6721cb64aa6cba5bc18c576ef0ab28285a6ec7a9d655"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc852da612c7e347f2fcf921df2eca2718697a49f648a28a63db3ab504fd9510"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02620454ee8101f77a317f3229935ce687480883d72a40858ff4b0c87c935cce"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7a92680bea1c260e5c0d2d6cd60b0c913cba76a456a147db5ac047ecfcfcc758"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:168334cba3f1cbf55299ef38f0f2e31879115cc767b780c859f7814a52d80abb"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:48b6886a87b4ceb9b9f78550f77b2a5c7d2ce33bc83efd886556ad468cc9c85a"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-win32.whl", hash = "sha256:87be84084a1b922c4ba15e2e5aa900ee24b78a5467997cb7aec0a1d6cdb4a00b"}, + {file = "dependency_injector-4.41.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8b8cf1c6c56f5c18bdbd9f5e93b52ca29cb4d99606d4056e91f0c761eef496dc"}, + {file = "dependency_injector-4.41.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a8686fa330c83251c75c8238697686f7a0e0f6d40658538089165dc72df9bcff"}, + {file = "dependency_injector-4.41.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d670a844268dcd758195e58e9a5b39fc74bb8648aba99a13135a4a10ec9cfac"}, + {file = "dependency_injector-4.41.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3b9d41e0eff4c8e16fea1e33de66ff0030fe51137ca530f3c52ce110447914"}, + {file = "dependency_injector-4.41.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a724e0a737baadb4378f5dc1b079867cc3a88552fcca719b3dba84716828b2"}, + {file = "dependency_injector-4.41.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3588bd887b051d16b8bcabaae1127eb14059a0719a8fe34c8a75ba59321b352c"}, + {file = "dependency_injector-4.41.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:409441122f40e1b4b8582845fdd76deb9dc5c9d6eb74a057b85736ef9e9c671f"}, + {file = "dependency_injector-4.41.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7dcba8665cafec825b7095d5dd80afb5cf14404450eca3fe8b66e1edbf4dbc10"}, + {file = "dependency_injector-4.41.0-cp38-cp38-win32.whl", hash = "sha256:8b51efeaebacaf79ef68edfc65e9687699ccffb3538c4a3ab30d0d77e2db7189"}, + {file = "dependency_injector-4.41.0-cp38-cp38-win_amd64.whl", hash = "sha256:1662e2ef60ac6e681b9e11b5d8b7c17a0f733688916cf695f9540f8f50a61b1e"}, + {file = "dependency_injector-4.41.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:51217cb384b468d7cc355544cec20774859f00812f9a1a71ed7fa701c957b2a7"}, + {file = "dependency_injector-4.41.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3890a12423ae3a9eade035093beba487f8d092ee6c6cb8706f4e7080a56e819"}, + {file = "dependency_injector-4.41.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99ed73b1521bf249e2823a08a730c9f9413a58f4b4290da022e0ad4fb333ba3d"}, + {file = "dependency_injector-4.41.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:300838e9d4f3fbf539892a5a4072851728e23b37a1f467afcf393edd994d88f0"}, + {file = "dependency_injector-4.41.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:56d37b9d2f50a18f059d9abdbea7669a7518bd42b81603c21a27910a2b3f1657"}, + {file = "dependency_injector-4.41.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4a44ca3ce5867513a70b31855b218be3d251f5068ce1c480cc3a4ad24ffd3280"}, + {file = "dependency_injector-4.41.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:67b369592c57549ccdcad0d5fef1ddb9d39af7fed8083d76e789ab0111fc6389"}, + {file = "dependency_injector-4.41.0-cp39-cp39-win32.whl", hash = "sha256:740a8e8106a04d3f44b52b25b80570fdac96a8a3934423de7c9202c5623e7936"}, + {file = "dependency_injector-4.41.0-cp39-cp39-win_amd64.whl", hash = "sha256:22b11dbf696e184f0b3d5ac4e5418aeac3c379ba4ea758c04a83869b7e5d1cbf"}, + {file = "dependency_injector-4.41.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b365a8548e9a49049fa6acb24d3cd939f619eeb8e300ca3e156e44402dcc07ec"}, + {file = "dependency_injector-4.41.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5168dc59808317dc4cdd235aa5d7d556d33e5600156acaf224cead236b48a3e8"}, + {file = "dependency_injector-4.41.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3229d83e99e255451605d5276604386e06ad948e3d60f31ddd796781c77f76f"}, + {file = "dependency_injector-4.41.0-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1baee908f21190bdc46a65ce4c417a5175e9397ca62354928694fce218f84487"}, + {file = "dependency_injector-4.41.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b37f36ecb0c1227f697e1d4a029644e3eda8dd0f0716aa63ad04d96dbb15bbbb"}, + {file = "dependency_injector-4.41.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b0c9c966ff66c77364a2d43d08de9968aff7e3903938fe912ba49796b2133344"}, + {file = "dependency_injector-4.41.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12e91ac0333e7e589421943ff6c6bf9cf0d9ac9703301cec37ccff3723406332"}, + {file = "dependency_injector-4.41.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2440b32474d4e747209528ca3ae48f42563b2fbe3d74dbfe949c11dfbfef7c4"}, + {file = "dependency_injector-4.41.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54032d62610cf2f4421c9d92cef52957215aaa0bca403cda580c58eb3f726eda"}, + {file = "dependency_injector-4.41.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:76b94c8310929e54136f3cb3de3adc86d1a657b3984299f40bf1cd2ba0bae548"}, + {file = "dependency_injector-4.41.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6ee9810841c6e0599356cb884d16453bfca6ab739d0e4f0248724ed8f9ee0d79"}, + {file = "dependency_injector-4.41.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b98945edae88e777091bf0848f869fb94bd76dfa4066d7c870a5caa933391d0"}, + {file = "dependency_injector-4.41.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a2dee5d4abdd21f1a30a51d46645c095be9dcc404c7c6e9f81d0a01415a49e64"}, + {file = "dependency_injector-4.41.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d03f5fa0fa98a18bd0dfce846db80e2798607f0b861f1f99c97f441f7669d7a2"}, + {file = "dependency_injector-4.41.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f2842e15bae664a9f69932e922b02afa055c91efec959cb1896f6c499bf68180"}, +] [package.dependencies] six = ">=1.7.0,<=1.16.0" @@ -244,9 +475,12 @@ yaml = ["pyyaml"] name = "deprecation" version = "2.1.0" description = "A library to handle automated deprecations" -category = "main" optional = false python-versions = "*" +files = [ + {file = "deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a"}, + {file = "deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff"}, +] [package.dependencies] packaging = "*" @@ -255,9 +489,12 @@ packaging = "*" name = "dill" version = "0.3.4" description = "serialize all of python" -category = "main" optional = true python-versions = ">=2.7, !=3.0.*" +files = [ + {file = "dill-0.3.4-py2.py3-none-any.whl", hash = "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f"}, + {file = "dill-0.3.4.zip", hash = "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675"}, +] [package.extras] graph = ["objgraph (>=1.7.2)"] @@ -266,20 +503,26 @@ graph = ["objgraph (>=1.7.2)"] name = "docutils" version = "0.14" description = "Docutils -- Python Documentation Utilities" -category = "main" optional = false python-versions = "*" +files = [ + {file = "docutils-0.14-py2-none-any.whl", hash = "sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"}, + {file = "docutils-0.14-py3-none-any.whl", hash = "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6"}, + {file = "docutils-0.14.tar.gz", hash = "sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274"}, +] [[package]] name = "flake8" version = "4.0.1" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = ">=3.6" +files = [ + {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, + {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, +] [package.dependencies] -importlib-metadata = {version = "<4.3", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.8.0,<2.9.0" pyflakes = ">=2.4.0,<2.5.0" @@ -288,9 +531,12 @@ pyflakes = ">=2.4.0,<2.5.0" name = "flask" version = "2.0.2" description = "A simple framework for building complex web applications." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "Flask-2.0.2-py3-none-any.whl", hash = "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a"}, + {file = "Flask-2.0.2.tar.gz", hash = "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2"}, +] [package.dependencies] click = ">=7.1.2" @@ -306,9 +552,12 @@ dotenv = ["python-dotenv"] name = "flask-compress" version = "1.10.1" description = "Compress responses in your Flask app with gzip, deflate or brotli." -category = "main" optional = false python-versions = "*" +files = [ + {file = "Flask-Compress-1.10.1.tar.gz", hash = "sha256:28352387efbbe772cfb307570019f81957a13ff718d994a9125fa705efb73680"}, + {file = "Flask_Compress-1.10.1-py3-none-any.whl", hash = "sha256:a6c2d1ff51771e9b39d7a612754f4cb4e8af20cebe16b02fd19d98d8dd6966e5"}, +] [package.dependencies] brotli = "*" @@ -318,14 +567,17 @@ flask = "*" name = "fonttools" version = "4.28.5" description = "Tools to manipulate font files" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "fonttools-4.28.5-py3-none-any.whl", hash = "sha256:edf251d5d2cc0580d5f72de4621c338d8c66c5f61abb50cf486640f73c8194d5"}, + {file = "fonttools-4.28.5.zip", hash = "sha256:545c05d0f7903a863c2020e07b8f0a57517f2c40d940bded77076397872d14ca"}, +] [package.extras] -all = ["fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "zopfli (>=0.1.4)", "lz4 (>=1.7.4.2)", "matplotlib", "sympy", "skia-pathops (>=0.5.0)", "brotlicffi (>=0.8.0)", "scipy", "brotli (>=1.0.1)", "munkres", "unicodedata2 (>=13.0.0)", "xattr"] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "unicodedata2 (>=13.0.0)", "xattr", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["scipy", "munkres"] +interpolatable = ["munkres", "scipy"] lxml = ["lxml (>=4.0,<5)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] @@ -333,15 +585,60 @@ symfont = ["sympy"] type1 = ["xattr"] ufo = ["fs (>=2.2.0,<3)"] unicode = ["unicodedata2 (>=13.0.0)"] -woff = ["zopfli (>=0.1.4)", "brotlicffi (>=0.8.0)", "brotli (>=1.0.1)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] [[package]] name = "grpcio" version = "1.43.0" description = "HTTP/2-based RPC framework" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "grpcio-1.43.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:a4e786a8ee8b30b25d70ee52cda6d1dbba2a8ca2f1208d8e20ed8280774f15c8"}, + {file = "grpcio-1.43.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:af9c3742f6c13575c0d4147a8454da0ff5308c4d9469462ff18402c6416942fe"}, + {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:fdac966699707b5554b815acc272d81e619dd0999f187cd52a61aef075f870ee"}, + {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e463b4aa0a6b31cf2e57c4abc1a1b53531a18a570baeed39d8d7b65deb16b7e"}, + {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11d05402e0ac3a284443d8a432d3dfc76a6bd3f7b5858cddd75617af2d7bd9b"}, + {file = "grpcio-1.43.0-cp310-cp310-win32.whl", hash = "sha256:c36f418c925a41fccada8f7ae9a3d3e227bfa837ddbfddd3d8b0ac252d12dda9"}, + {file = "grpcio-1.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:772b943f34374744f70236bbbe0afe413ed80f9ae6303503f85e2b421d4bca92"}, + {file = "grpcio-1.43.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:cbc9b83211d905859dcf234ad39d7193ff0f05bfc3269c364fb0d114ee71de59"}, + {file = "grpcio-1.43.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:fb7229fa2a201a0c377ff3283174ec966da8f9fd7ffcc9a92f162d2e7fc9025b"}, + {file = "grpcio-1.43.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:17b75f220ee6923338155b4fcef4c38802b9a57bc57d112c9599a13a03e99f8d"}, + {file = "grpcio-1.43.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:6620a5b751b099b3b25553cfc03dfcd873cda06f9bb2ff7e9948ac7090e20f05"}, + {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:1898f999383baac5fcdbdef8ea5b1ef204f38dc211014eb6977ac6e55944d738"}, + {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47b6821238d8978014d23b1132713dac6c2d72cbb561cf257608b1673894f90a"}, + {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80398e9fb598060fa41050d1220f5a2440fe74ff082c36dda41ac3215ebb5ddd"}, + {file = "grpcio-1.43.0-cp36-cp36m-win32.whl", hash = "sha256:0110310eff07bb69782f53b7a947490268c4645de559034c43c0a635612e250f"}, + {file = "grpcio-1.43.0-cp36-cp36m-win_amd64.whl", hash = "sha256:45401d00f2ee46bde75618bf33e9df960daa7980e6e0e7328047191918c98504"}, + {file = "grpcio-1.43.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:af78ac55933811e6a25141336b1f2d5e0659c2f568d44d20539b273792563ca7"}, + {file = "grpcio-1.43.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8b2b9dc4d7897566723b77422e11c009a0ebd397966b165b21b89a62891a9fdf"}, + {file = "grpcio-1.43.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:77ef653f966934b3bfdd00e4f2064b68880eb40cf09b0b99edfa5ee22a44f559"}, + {file = "grpcio-1.43.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e95b5d62ec26d0cd0b90c202d73e7cb927c369c3358e027225239a4e354967dc"}, + {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:04239e8f71db832c26bbbedb4537b37550a39d77681d748ab4678e58dd6455d6"}, + {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b4a7152187a49767a47d1413edde2304c96f41f7bc92cc512e230dfd0fba095"}, + {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8cc936a29c65ab39714e1ba67a694c41218f98b6e2a64efb83f04d9abc4386b"}, + {file = "grpcio-1.43.0-cp37-cp37m-win32.whl", hash = "sha256:577e024c8dd5f27cd98ba850bc4e890f07d4b5942e5bc059a3d88843a2f48f66"}, + {file = "grpcio-1.43.0-cp37-cp37m-win_amd64.whl", hash = "sha256:138f57e3445d4a48d9a8a5af1538fdaafaa50a0a3c243f281d8df0edf221dc02"}, + {file = "grpcio-1.43.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:08cf25f2936629db062aeddbb594bd76b3383ab0ede75ef0461a3b0bc3a2c150"}, + {file = "grpcio-1.43.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:01f4b887ed703fe82ebe613e1d2dadea517891725e17e7a6134dcd00352bd28c"}, + {file = "grpcio-1.43.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0aa8285f284338eb68962fe1a830291db06f366ea12f213399b520c062b01f65"}, + {file = "grpcio-1.43.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:0edbfeb6729aa9da33ce7e28fb7703b3754934115454ae45e8cc1db601756fd3"}, + {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:c354017819201053d65212befd1dcb65c2d91b704d8977e696bae79c47cd2f82"}, + {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50cfb7e1067ee5e00b8ab100a6b7ea322d37ec6672c0455106520b5891c4b5f5"}, + {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f1aeb65ed17dfb2f6cd717cc109910fe395133af7257a9c729c0b9604eac10"}, + {file = "grpcio-1.43.0-cp38-cp38-win32.whl", hash = "sha256:fa26a8bbb3fe57845acb1329ff700d5c7eaf06414c3e15f4cb8923f3a466ef64"}, + {file = "grpcio-1.43.0-cp38-cp38-win_amd64.whl", hash = "sha256:ade8b79a6b6aea68adb9d4bfeba5d647667d842202c5d8f3ba37ac1dc8e5c09c"}, + {file = "grpcio-1.43.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:124e718faf96fe44c98b05f3f475076be8b5198bb4c52a13208acf88a8548ba9"}, + {file = "grpcio-1.43.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2f96142d0abc91290a63ba203f01649e498302b1b6007c67bad17f823ecde0cf"}, + {file = "grpcio-1.43.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:31e6e489ccd8f08884b9349a39610982df48535881ec34f05a11c6e6b6ebf9d0"}, + {file = "grpcio-1.43.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:0e731f660e1e68238f56f4ce11156f02fd06dc58bc7834778d42c0081d4ef5ad"}, + {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:1f16725a320460435a8a5339d8b06c4e00d307ab5ad56746af2e22b5f9c50932"}, + {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4b4543e13acb4806917d883d0f70f21ba93b29672ea81f4aaba14821aaf9bb0"}, + {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:594aaa0469f4fca7773e80d8c27bf1298e7bbce5f6da0f084b07489a708f16ab"}, + {file = "grpcio-1.43.0-cp39-cp39-win32.whl", hash = "sha256:5449ae564349e7a738b8c38583c0aad954b0d5d1dd3cea68953bfc32eaee11e3"}, + {file = "grpcio-1.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:bdf41550815a831384d21a498b20597417fd31bd084deb17d31ceb39ad9acc79"}, + {file = "grpcio-1.43.0.tar.gz", hash = "sha256:735d9a437c262ab039d02defddcb9f8f545d7009ae61c0114e19dda3843febe5"}, +] [package.dependencies] six = ">=1.5.2" @@ -353,9 +650,11 @@ protobuf = ["grpcio-tools (>=1.43.0)"] name = "grpclib" version = "0.4.3" description = "Pure-Python gRPC implementation for asyncio" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "grpclib-0.4.3.tar.gz", hash = "sha256:eadf2002fc5a25158b707c0338a6c0b96dd7fbdc6df66f7e515e7f041d56a940"}, +] [package.dependencies] h2 = ">=3.1.0,<5" @@ -368,9 +667,12 @@ protobuf = ["protobuf (>=3.15.0)"] name = "h2" version = "4.1.0" description = "HTTP/2 State-Machine based protocol implementation" -category = "main" optional = false python-versions = ">=3.6.1" +files = [ + {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, + {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, +] [package.dependencies] hpack = ">=4.0,<5" @@ -380,49 +682,45 @@ hyperframe = ">=6.0,<7" name = "hpack" version = "4.0.0" description = "Pure-Python HPACK header compression" -category = "main" optional = false python-versions = ">=3.6.1" +files = [ + {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, + {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, +] [[package]] name = "hyperframe" version = "6.0.1" description = "HTTP/2 framing layer for Python" -category = "main" optional = false python-versions = ">=3.6.1" - -[[package]] -name = "importlib-metadata" -version = "4.2.0" -description = "Read metadata from Python packages" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} -zipp = ">=0.5" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +files = [ + {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, + {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, +] [[package]] name = "iniconfig" version = "1.1.1" description = "iniconfig: brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = "*" +files = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] [[package]] name = "ipython" version = "7.31.1" description = "IPython: Productive Interactive Computing" -category = "main" optional = true python-versions = ">=3.7" +files = [ + {file = "ipython-7.31.1-py3-none-any.whl", hash = "sha256:55df3e0bd0f94e715abd968bedd89d4e8a7bce4bf498fb123fed4f5398fea874"}, + {file = "ipython-7.31.1.tar.gz", hash = "sha256:b5548ec5329a4bcf054a5deed5099b0f9622eb9ea51aaa7104d215fece201d8c"}, +] [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} @@ -435,6 +733,7 @@ pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" pygments = "*" +setuptools = ">=18.5" traitlets = ">=4.2" [package.extras] @@ -443,26 +742,32 @@ doc = ["Sphinx (>=1.3)"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] -notebook = ["notebook", "ipywidgets"] +notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] +test = ["ipykernel", "nbformat", "nose (>=0.10.1)", "numpy (>=1.17)", "pygments", "requests", "testpath"] [[package]] name = "itsdangerous" version = "2.0.1" description = "Safely pass data to untrusted environments and back." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "itsdangerous-2.0.1-py3-none-any.whl", hash = "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c"}, + {file = "itsdangerous-2.0.1.tar.gz", hash = "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0"}, +] [[package]] name = "jedi" version = "0.18.1" description = "An autocompletion tool for Python that can be used for text editors." -category = "main" optional = true python-versions = ">=3.6" +files = [ + {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, + {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, +] [package.dependencies] parso = ">=0.8.0,<0.9.0" @@ -475,9 +780,12 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] name = "jinja2" version = "3.0.3" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"}, + {file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"}, +] [package.dependencies] MarkupSafe = ">=2.0" @@ -489,899 +797,20 @@ i18n = ["Babel (>=2.7)"] name = "joblib" version = "1.1.0" description = "Lightweight pipelining with Python functions" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "joblib-1.1.0-py2.py3-none-any.whl", hash = "sha256:f21f109b3c7ff9d95f8387f752d0d9c34a02aa2f7060c2135f465da0e5160ff6"}, + {file = "joblib-1.1.0.tar.gz", hash = "sha256:4158fcecd13733f8be669be0683b96ebdbbd38d23559f54dca7205aea1bf1e35"}, +] [[package]] name = "kiwisolver" version = "1.3.2" description = "A fast implementation of the Cassowary constraint solver" -category = "main" optional = false python-versions = ">=3.7" - -[[package]] -name = "markupsafe" -version = "2.0.1" -description = "Safely add untrusted strings to HTML/XML markup." -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "marshmallow" -version = "3.14.1" -description = "A lightweight library for converting complex datatypes to and from native Python datatypes." -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -dev = ["pytest", "pytz", "simplejson", "mypy (==0.910)", "flake8 (==4.0.1)", "flake8-bugbear (==21.9.2)", "pre-commit (>=2.4,<3.0)", "tox"] -docs = ["sphinx (==4.3.0)", "sphinx-issues (==1.2.0)", "alabaster (==0.7.12)", "sphinx-version-warning (==1.1.2)", "autodocsumm (==0.2.7)"] -lint = ["mypy (==0.910)", "flake8 (==4.0.1)", "flake8-bugbear (==21.9.2)", "pre-commit (>=2.4,<3.0)"] -tests = ["pytest", "pytz", "simplejson"] - -[[package]] -name = "marshmallow-polyfield" -version = "5.10" -description = "An unofficial extension to Marshmallow to allow for polymorphic fields" -category = "main" -optional = false -python-versions = ">=3.5" - -[package.dependencies] -marshmallow = ">=3.0.0b10" - -[[package]] -name = "matplotlib" -version = "3.5.1" -description = "Python plotting package" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -cycler = ">=0.10" -fonttools = ">=4.22.0" -kiwisolver = ">=1.0.1" -numpy = ">=1.17" -packaging = ">=20.0" -pillow = ">=6.2.0" -pyparsing = ">=2.2.1" -python-dateutil = ">=2.7" -setuptools_scm = ">=4" - -[[package]] -name = "matplotlib-inline" -version = "0.1.3" -description = "Inline Matplotlib backend for Jupyter" -category = "main" -optional = true -python-versions = ">=3.5" - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "mccabe" -version = "0.6.1" -description = "McCabe checker, plugin for flake8" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "multidict" -version = "5.2.0" -description = "multidict implementation" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "nest-asyncio" -version = "1.5.6" -description = "Patch asyncio to allow nested event loops" -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "numpy" -version = "1.21.5" -description = "NumPy is the fundamental package for array computing with Python." -category = "main" -optional = false -python-versions = ">=3.7,<3.11" - -[[package]] -name = "packaging" -version = "21.3" -description = "Core utilities for Python packages" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" - -[[package]] -name = "pandas" -version = "1.3.5" -description = "Powerful data structures for data analysis, time series, and statistics" -category = "main" -optional = false -python-versions = ">=3.7.1" - -[package.dependencies] -numpy = [ - {version = ">=1.17.3", markers = "platform_machine != \"aarch64\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, - {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, -] -python-dateutil = ">=2.7.3" -pytz = ">=2017.3" - -[package.extras] -test = ["hypothesis (>=3.58)", "pytest (>=6.0)", "pytest-xdist"] - -[[package]] -name = "parso" -version = "0.8.3" -description = "A Python Parser" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] - -[[package]] -name = "pastel" -version = "0.2.1" -description = "Bring colors to your terminal." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "pathspec" -version = "0.9.0" -description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[[package]] -name = "pexpect" -version = "4.8.0" -description = "Pexpect allows easy control of interactive console applications." -category = "main" -optional = true -python-versions = "*" - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "pillow" -version = "8.4.0" -description = "Python Imaging Library (Fork)" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "platformdirs" -version = "2.4.0" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] -test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] - -[[package]] -name = "plotly" -version = "5.13.1" -description = "An open-source, interactive data visualization library for Python" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -tenacity = ">=6.2.0" - -[[package]] -name = "pluggy" -version = "0.13.1" -description = "plugin and hook calling mechanisms for python" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - -[package.extras] -dev = ["pre-commit", "tox"] - -[[package]] -name = "poethepoet" -version = "0.11.0" -description = "A task runner that works well with poetry." -category = "dev" -optional = false -python-versions = ">=3.6.2,<4.0.0" - -[package.dependencies] -pastel = ">=0.2.1,<0.3.0" -tomli = ">=1.2.2,<2.0.0" - -[[package]] -name = "pretty-errors" -version = "1.2.25" -description = "Prettifies Python exception output to make it legible." -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -colorama = "*" - -[[package]] -name = "prompt-toolkit" -version = "3.0.24" -description = "Library for building powerful interactive command lines in Python" -category = "main" -optional = true -python-versions = ">=3.6.2" - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "protobuf" -version = "3.19.1" -description = "Protocol Buffers" -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "pycodestyle" -version = "2.8.0" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "pyflakes" -version = "2.4.0" -description = "passive checker of Python programs" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "pygments" -version = "2.11.2" -description = "Pygments is a syntax highlighting package written in Python." -category = "main" -optional = true -python-versions = ">=3.5" - -[[package]] -name = "pyparsing" -version = "3.0.6" -description = "Python parsing module" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pypiwin32" -version = "223" -description = "" -category = "main" -optional = true -python-versions = "*" - -[package.dependencies] -pywin32 = ">=223" - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -category = "main" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2021.3" -description = "World timezone definitions, modern and historical" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "pywin32" -version = "303" -description = "Python for Window Extensions" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "qm-octave" -version = "1.1.0" -description = "SDK to control an Octave with QUA" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" - -[package.dependencies] -betterproto = "2.0.0b5" -grpcio = ">=1.39.0,<2.0.0" -grpclib = {version = ">=0.4.3rc3,<0.5.0", markers = "python_version >= \"3.10\" and python_version < \"4.0\""} -nest-asyncio = ">=1.5.4,<2.0.0" -numpy = ">=1.21.0" -protobuf = ">=3.17.3,<4.0.0" - -[[package]] -name = "qm-qua" -version = "1.1.1" -description = "QUA language SDK to control a Quantum Computer" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" - -[package.dependencies] -betterproto = "2.0.0b5" -datadog-api-client = ">=2.6.0,<3.0.0" -dependency_injector = ">=4.41.0,<5.0.0" -deprecation = ">=2.1.0,<3.0.0" -grpcio = ">=1.39.0,<2.0.0" -grpclib = {version = ">=0.4.3rc3,<0.5.0", markers = "python_version >= \"3.10\" and python_version < \"4.0\""} -marshmallow = ">=3.0.0,<4.0.0" -marshmallow-polyfield = ">=5.7,<6.0" -numpy = ">=1.17.0,<2.0.0" -plotly = ">=5.13.0,<6.0.0" -pretty_errors = ">=1.2.25,<2.0.0" -protobuf = ">=3.17.3,<4.0.0" -qm-octave = ">=1.1.0,<2.0.0" -tinydb = ">=4.6.1,<5.0.0" - -[package.extras] -simulation = ["certifi"] - -[[package]] -name = "scikit-learn" -version = "1.0.2" -description = "A set of python modules for machine learning and data mining" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -joblib = ">=0.11" -numpy = ">=1.14.6" -scipy = ">=1.1.0" -threadpoolctl = ">=2.0.0" - -[package.extras] -benchmark = ["matplotlib (>=2.2.3)", "pandas (>=0.25.0)", "memory-profiler (>=0.57.0)"] -docs = ["matplotlib (>=2.2.3)", "scikit-image (>=0.14.5)", "pandas (>=0.25.0)", "seaborn (>=0.9.0)", "memory-profiler (>=0.57.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "numpydoc (>=1.0.0)", "Pillow (>=7.1.2)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] -examples = ["matplotlib (>=2.2.3)", "scikit-image (>=0.14.5)", "pandas (>=0.25.0)", "seaborn (>=0.9.0)"] -tests = ["matplotlib (>=2.2.3)", "scikit-image (>=0.14.5)", "pandas (>=0.25.0)", "pytest (>=5.0.1)", "pytest-cov (>=2.9.0)", "flake8 (>=3.8.2)", "black (>=21.6b0)", "mypy (>=0.770)", "pyamg (>=4.0.0)"] - -[[package]] -name = "scipy" -version = "1.7.3" -description = "SciPy: Scientific Library for Python" -category = "main" -optional = false -python-versions = ">=3.7,<3.11" - -[package.dependencies] -numpy = ">=1.16.5,<1.23.0" - -[[package]] -name = "setuptools-scm" -version = "6.3.2" -description = "the blessed package to manage your versions by scm tags" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -packaging = ">=20.0" -tomli = ">=1.0.0" - -[package.extras] -toml = ["setuptools (>=42)", "tomli (>=1.0.0)"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "tenacity" -version = "8.0.1" -description = "Retry code until it succeeds" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -doc = ["reno", "sphinx", "tornado (>=4.5)"] - -[[package]] -name = "threadpoolctl" -version = "3.1.0" -description = "threadpoolctl" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "tinydb" -version = "4.7.1" -description = "TinyDB is a tiny, document oriented database optimized for your happiness :)" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "tomli" -version = "1.2.3" -description = "A lil' TOML parser" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "traitlets" -version = "5.1.1" -description = "Traitlets Python configuration system" -category = "main" -optional = true -python-versions = ">=3.7" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "typed-ast" -version = "1.5.1" -description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "typing-extensions" -version = "4.0.1" -description = "Backported and Experimental Type Hints for Python 3.6+" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "urllib3" -version = "1.26.15" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" - -[package.extras] -brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "urllib3-secure-extra", "ipaddress"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - -[[package]] -name = "waitress" -version = "2.0.0" -description = "Waitress WSGI server" -category = "main" -optional = false -python-versions = ">=3.6.0" - -[package.extras] -docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"] -testing = ["pytest", "pytest-cover", "coverage (>=5.0)"] - -[[package]] -name = "wcwidth" -version = "0.2.5" -description = "Measures the displayed width of unicode strings in a terminal" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "werkzeug" -version = "2.0.2" -description = "The comprehensive WSGI web application library." -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -watchdog = ["watchdog"] - -[[package]] -name = "zipp" -version = "3.6.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] - -[extras] -interplot = ["dill", "pypiwin32", "ipython"] - -[metadata] -lock-version = "1.1" -python-versions = ">=3.7.1,<4.0" -content-hash = "cfc9e607223c2bd7ccd6bdc0a7f8bf72d1af3827f49ee2df3ee00917a0beb570" - -[metadata.files] -appnope = [ - {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, - {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, -] -atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, -] -attrs = [ - {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, - {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, -] -backcall = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] -betterproto = [] -black = [ - {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, - {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, - {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, - {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, - {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, - {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, - {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, - {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, - {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, - {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, - {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, - {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, - {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, - {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, - {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, - {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, - {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, - {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, - {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, - {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, - {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, - {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, - {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, -] -brotli = [ - {file = "Brotli-1.0.9-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:268fe94547ba25b58ebc724680609c8ee3e5a843202e9a381f6f9c5e8bdb5c70"}, - {file = "Brotli-1.0.9-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:c2415d9d082152460f2bd4e382a1e85aed233abc92db5a3880da2257dc7daf7b"}, - {file = "Brotli-1.0.9-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5913a1177fc36e30fcf6dc868ce23b0453952c78c04c266d3149b3d39e1410d6"}, - {file = "Brotli-1.0.9-cp27-cp27m-win32.whl", hash = "sha256:afde17ae04d90fbe53afb628f7f2d4ca022797aa093e809de5c3cf276f61bbfa"}, - {file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7cb81373984cc0e4682f31bc3d6be9026006d96eecd07ea49aafb06897746452"}, - {file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:db844eb158a87ccab83e868a762ea8024ae27337fc7ddcbfcddd157f841fdfe7"}, - {file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9744a863b489c79a73aba014df554b0e7a0fc44ef3f8a0ef2a52919c7d155031"}, - {file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a72661af47119a80d82fa583b554095308d6a4c356b2a554fdc2799bc19f2a43"}, - {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ee83d3e3a024a9618e5be64648d6d11c37047ac48adff25f12fa4226cf23d1c"}, - {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:19598ecddd8a212aedb1ffa15763dd52a388518c4550e615aed88dc3753c0f0c"}, - {file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:44bb8ff420c1d19d91d79d8c3574b8954288bdff0273bf788954064d260d7ab0"}, - {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e23281b9a08ec338469268f98f194658abfb13658ee98e2b7f85ee9dd06caa91"}, - {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3496fc835370da351d37cada4cf744039616a6db7d13c430035e901443a34daa"}, - {file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83bb06a0192cccf1eb8d0a28672a1b79c74c3a8a5f2619625aeb6f28b3a82bb"}, - {file = "Brotli-1.0.9-cp310-cp310-win32.whl", hash = "sha256:26d168aac4aaec9a4394221240e8a5436b5634adc3cd1cdf637f6645cecbf181"}, - {file = "Brotli-1.0.9-cp310-cp310-win_amd64.whl", hash = "sha256:622a231b08899c864eb87e85f81c75e7b9ce05b001e59bbfbf43d4a71f5f32b2"}, - {file = "Brotli-1.0.9-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:c83aa123d56f2e060644427a882a36b3c12db93727ad7a7b9efd7d7f3e9cc2c4"}, - {file = "Brotli-1.0.9-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2ae9f5f67f89aade1fab0f7fd8f2832501311c363a21579d02defa844d9296"}, - {file = "Brotli-1.0.9-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:68715970f16b6e92c574c30747c95cf8cf62804569647386ff032195dc89a430"}, - {file = "Brotli-1.0.9-cp35-cp35m-win32.whl", hash = "sha256:defed7ea5f218a9f2336301e6fd379f55c655bea65ba2476346340a0ce6f74a1"}, - {file = "Brotli-1.0.9-cp35-cp35m-win_amd64.whl", hash = "sha256:88c63a1b55f352b02c6ffd24b15ead9fc0e8bf781dbe070213039324922a2eea"}, - {file = "Brotli-1.0.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:503fa6af7da9f4b5780bb7e4cbe0c639b010f12be85d02c99452825dd0feef3f"}, - {file = "Brotli-1.0.9-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:40d15c79f42e0a2c72892bf407979febd9cf91f36f495ffb333d1d04cebb34e4"}, - {file = "Brotli-1.0.9-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:93130612b837103e15ac3f9cbacb4613f9e348b58b3aad53721d92e57f96d46a"}, - {file = "Brotli-1.0.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87fdccbb6bb589095f413b1e05734ba492c962b4a45a13ff3408fa44ffe6479b"}, - {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6d847b14f7ea89f6ad3c9e3901d1bc4835f6b390a9c71df999b0162d9bb1e20f"}, - {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:495ba7e49c2db22b046a53b469bbecea802efce200dffb69b93dd47397edc9b6"}, - {file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4688c1e42968ba52e57d8670ad2306fe92e0169c6f3af0089be75bbac0c64a3b"}, - {file = "Brotli-1.0.9-cp36-cp36m-win32.whl", hash = "sha256:61a7ee1f13ab913897dac7da44a73c6d44d48a4adff42a5701e3239791c96e14"}, - {file = "Brotli-1.0.9-cp36-cp36m-win_amd64.whl", hash = "sha256:1c48472a6ba3b113452355b9af0a60da5c2ae60477f8feda8346f8fd48e3e87c"}, - {file = "Brotli-1.0.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b78a24b5fd13c03ee2b7b86290ed20efdc95da75a3557cc06811764d5ad1126"}, - {file = "Brotli-1.0.9-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:9d12cf2851759b8de8ca5fde36a59c08210a97ffca0eb94c532ce7b17c6a3d1d"}, - {file = "Brotli-1.0.9-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6c772d6c0a79ac0f414a9f8947cc407e119b8598de7621f39cacadae3cf57d12"}, - {file = "Brotli-1.0.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29d1d350178e5225397e28ea1b7aca3648fcbab546d20e7475805437bfb0a130"}, - {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7bbff90b63328013e1e8cb50650ae0b9bac54ffb4be6104378490193cd60f85a"}, - {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ec1947eabbaf8e0531e8e899fc1d9876c179fc518989461f5d24e2223395a9e3"}, - {file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12effe280b8ebfd389022aa65114e30407540ccb89b177d3fbc9a4f177c4bd5d"}, - {file = "Brotli-1.0.9-cp37-cp37m-win32.whl", hash = "sha256:f909bbbc433048b499cb9db9e713b5d8d949e8c109a2a548502fb9aa8630f0b1"}, - {file = "Brotli-1.0.9-cp37-cp37m-win_amd64.whl", hash = "sha256:97f715cf371b16ac88b8c19da00029804e20e25f30d80203417255d239f228b5"}, - {file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e16eb9541f3dd1a3e92b89005e37b1257b157b7256df0e36bd7b33b50be73bcb"}, - {file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:160c78292e98d21e73a4cc7f76a234390e516afcd982fa17e1422f7c6a9ce9c8"}, - {file = "Brotli-1.0.9-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b663f1e02de5d0573610756398e44c130add0eb9a3fc912a09665332942a2efb"}, - {file = "Brotli-1.0.9-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5b6ef7d9f9c38292df3690fe3e302b5b530999fa90014853dcd0d6902fb59f26"}, - {file = "Brotli-1.0.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a674ac10e0a87b683f4fa2b6fa41090edfd686a6524bd8dedbd6138b309175c"}, - {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e2d9e1cbc1b25e22000328702b014227737756f4b5bf5c485ac1d8091ada078b"}, - {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b336c5e9cf03c7be40c47b5fd694c43c9f1358a80ba384a21969e0b4e66a9b17"}, - {file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85f7912459c67eaab2fb854ed2bc1cc25772b300545fe7ed2dc03954da638649"}, - {file = "Brotli-1.0.9-cp38-cp38-win32.whl", hash = "sha256:35a3edbe18e876e596553c4007a087f8bcfd538f19bc116917b3c7522fca0429"}, - {file = "Brotli-1.0.9-cp38-cp38-win_amd64.whl", hash = "sha256:269a5743a393c65db46a7bb982644c67ecba4b8d91b392403ad8a861ba6f495f"}, - {file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2aad0e0baa04517741c9bb5b07586c642302e5fb3e75319cb62087bd0995ab19"}, - {file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5cb1e18167792d7d21e21365d7650b72d5081ed476123ff7b8cac7f45189c0c7"}, - {file = "Brotli-1.0.9-cp39-cp39-manylinux1_i686.whl", hash = "sha256:16d528a45c2e1909c2798f27f7bf0a3feec1dc9e50948e738b961618e38b6a7b"}, - {file = "Brotli-1.0.9-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:56d027eace784738457437df7331965473f2c0da2c70e1a1f6fdbae5402e0389"}, - {file = "Brotli-1.0.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bf919756d25e4114ace16a8ce91eb340eb57a08e2c6950c3cebcbe3dff2a5e7"}, - {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e4c4e92c14a57c9bd4cb4be678c25369bf7a092d55fd0866f759e425b9660806"}, - {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e48f4234f2469ed012a98f4b7874e7f7e173c167bed4934912a29e03167cf6b1"}, - {file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ed4c92a0665002ff8ea852353aeb60d9141eb04109e88928026d3c8a9e5433c"}, - {file = "Brotli-1.0.9-cp39-cp39-win32.whl", hash = "sha256:cfc391f4429ee0a9370aa93d812a52e1fee0f37a81861f4fdd1f4fb28e8547c3"}, - {file = "Brotli-1.0.9-cp39-cp39-win_amd64.whl", hash = "sha256:854c33dad5ba0fbd6ab69185fec8dab89e13cda6b7d191ba111987df74f38761"}, - {file = "Brotli-1.0.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9749a124280a0ada4187a6cfd1ffd35c350fb3af79c706589d98e088c5044267"}, - {file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"}, - {file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"}, -] -certifi = [] -click = [ - {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, - {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, -] -colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, -] -cycler = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, -] -dash = [ - {file = "dash-2.0.0-py3-none-any.whl", hash = "sha256:23f331533663641a5c70a15c46da26d29ef5335f9aeb8bc03d09de865fc7cd62"}, - {file = "dash-2.0.0.tar.gz", hash = "sha256:29277c24e2f795b069cb102ce1ab0cd3ad5cf9d3b4fd16c03da9671a5eea28a4"}, -] -dash-bootstrap-components = [ - {file = "dash-bootstrap-components-1.0.2.tar.gz", hash = "sha256:d385fa959159cdfd11885a753341fba67bad8622c84e5f61585930953f55f54f"}, - {file = "dash_bootstrap_components-1.0.2-py3-none-any.whl", hash = "sha256:4b862c6b2f6667da686fd2015a0b12a286920df8cce7dd6719fb1469025f6c68"}, -] -dash-core-components = [ - {file = "dash_core_components-2.0.0-py3-none-any.whl", hash = "sha256:52b8e8cce13b18d0802ee3acbc5e888cb1248a04968f962d63d070400af2e346"}, - {file = "dash_core_components-2.0.0.tar.gz", hash = "sha256:c6733874af975e552f95a1398a16c2ee7df14ce43fa60bb3718a3c6e0b63ffee"}, -] -dash-cytoscape = [ - {file = "dash_cytoscape-0.3.0-py3-none-any.whl", hash = "sha256:718dc1568b9e7bfe7f64376aa903c64a1a1fe6daed4e559b254456f18dd3135f"}, - {file = "dash_cytoscape-0.3.0.tar.gz", hash = "sha256:a71ad4fe095570b71d4ad7c0d29199e9780c2e6796173d3b25fccc2cc58c855f"}, -] -dash-dangerously-set-inner-html = [ - {file = "dash_dangerously_set_inner_html-0.0.2.tar.gz", hash = "sha256:d7fe990755851fc4d2e22c8f10b7aea055cabf380bbceefba589779b269fea64"}, -] -dash-html-components = [ - {file = "dash_html_components-2.0.0-py3-none-any.whl", hash = "sha256:b42cc903713c9706af03b3f2548bda4be7307a7cf89b7d6eae3da872717d1b63"}, - {file = "dash_html_components-2.0.0.tar.gz", hash = "sha256:8703a601080f02619a6390998e0b3da4a5daabe97a1fd7a9cebc09d015f26e50"}, -] -dash-table = [ - {file = "dash_table-5.0.0-py3-none-any.whl", hash = "sha256:19036fa352bb1c11baf38068ec62d172f0515f73ca3276c79dee49b95ddc16c9"}, - {file = "dash_table-5.0.0.tar.gz", hash = "sha256:18624d693d4c8ef2ddec99a6f167593437a7ea0bf153aa20f318c170c5bc7308"}, -] -datadog-api-client = [] -decorator = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] -dependency-injector = [] -deprecation = [ - {file = "deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a"}, - {file = "deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff"}, -] -dill = [ - {file = "dill-0.3.4-py2.py3-none-any.whl", hash = "sha256:7e40e4a70304fd9ceab3535d36e58791d9c4a776b38ec7f7ec9afc8d3dca4d4f"}, - {file = "dill-0.3.4.zip", hash = "sha256:9f9734205146b2b353ab3fec9af0070237b6ddae78452af83d2fca84d739e675"}, -] -docutils = [ - {file = "docutils-0.14-py2-none-any.whl", hash = "sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"}, - {file = "docutils-0.14-py3-none-any.whl", hash = "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6"}, - {file = "docutils-0.14.tar.gz", hash = "sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274"}, -] -flake8 = [ - {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, - {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, -] -flask = [ - {file = "Flask-2.0.2-py3-none-any.whl", hash = "sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a"}, - {file = "Flask-2.0.2.tar.gz", hash = "sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2"}, -] -flask-compress = [ - {file = "Flask-Compress-1.10.1.tar.gz", hash = "sha256:28352387efbbe772cfb307570019f81957a13ff718d994a9125fa705efb73680"}, - {file = "Flask_Compress-1.10.1-py3-none-any.whl", hash = "sha256:a6c2d1ff51771e9b39d7a612754f4cb4e8af20cebe16b02fd19d98d8dd6966e5"}, -] -fonttools = [ - {file = "fonttools-4.28.5-py3-none-any.whl", hash = "sha256:edf251d5d2cc0580d5f72de4621c338d8c66c5f61abb50cf486640f73c8194d5"}, - {file = "fonttools-4.28.5.zip", hash = "sha256:545c05d0f7903a863c2020e07b8f0a57517f2c40d940bded77076397872d14ca"}, -] -grpcio = [ - {file = "grpcio-1.43.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:a4e786a8ee8b30b25d70ee52cda6d1dbba2a8ca2f1208d8e20ed8280774f15c8"}, - {file = "grpcio-1.43.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:af9c3742f6c13575c0d4147a8454da0ff5308c4d9469462ff18402c6416942fe"}, - {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:fdac966699707b5554b815acc272d81e619dd0999f187cd52a61aef075f870ee"}, - {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e463b4aa0a6b31cf2e57c4abc1a1b53531a18a570baeed39d8d7b65deb16b7e"}, - {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11d05402e0ac3a284443d8a432d3dfc76a6bd3f7b5858cddd75617af2d7bd9b"}, - {file = "grpcio-1.43.0-cp310-cp310-win32.whl", hash = "sha256:c36f418c925a41fccada8f7ae9a3d3e227bfa837ddbfddd3d8b0ac252d12dda9"}, - {file = "grpcio-1.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:772b943f34374744f70236bbbe0afe413ed80f9ae6303503f85e2b421d4bca92"}, - {file = "grpcio-1.43.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:cbc9b83211d905859dcf234ad39d7193ff0f05bfc3269c364fb0d114ee71de59"}, - {file = "grpcio-1.43.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:fb7229fa2a201a0c377ff3283174ec966da8f9fd7ffcc9a92f162d2e7fc9025b"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:17b75f220ee6923338155b4fcef4c38802b9a57bc57d112c9599a13a03e99f8d"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:6620a5b751b099b3b25553cfc03dfcd873cda06f9bb2ff7e9948ac7090e20f05"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:1898f999383baac5fcdbdef8ea5b1ef204f38dc211014eb6977ac6e55944d738"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47b6821238d8978014d23b1132713dac6c2d72cbb561cf257608b1673894f90a"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80398e9fb598060fa41050d1220f5a2440fe74ff082c36dda41ac3215ebb5ddd"}, - {file = "grpcio-1.43.0-cp36-cp36m-win32.whl", hash = "sha256:0110310eff07bb69782f53b7a947490268c4645de559034c43c0a635612e250f"}, - {file = "grpcio-1.43.0-cp36-cp36m-win_amd64.whl", hash = "sha256:45401d00f2ee46bde75618bf33e9df960daa7980e6e0e7328047191918c98504"}, - {file = "grpcio-1.43.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:af78ac55933811e6a25141336b1f2d5e0659c2f568d44d20539b273792563ca7"}, - {file = "grpcio-1.43.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8b2b9dc4d7897566723b77422e11c009a0ebd397966b165b21b89a62891a9fdf"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:77ef653f966934b3bfdd00e4f2064b68880eb40cf09b0b99edfa5ee22a44f559"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e95b5d62ec26d0cd0b90c202d73e7cb927c369c3358e027225239a4e354967dc"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:04239e8f71db832c26bbbedb4537b37550a39d77681d748ab4678e58dd6455d6"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b4a7152187a49767a47d1413edde2304c96f41f7bc92cc512e230dfd0fba095"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8cc936a29c65ab39714e1ba67a694c41218f98b6e2a64efb83f04d9abc4386b"}, - {file = "grpcio-1.43.0-cp37-cp37m-win32.whl", hash = "sha256:577e024c8dd5f27cd98ba850bc4e890f07d4b5942e5bc059a3d88843a2f48f66"}, - {file = "grpcio-1.43.0-cp37-cp37m-win_amd64.whl", hash = "sha256:138f57e3445d4a48d9a8a5af1538fdaafaa50a0a3c243f281d8df0edf221dc02"}, - {file = "grpcio-1.43.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:08cf25f2936629db062aeddbb594bd76b3383ab0ede75ef0461a3b0bc3a2c150"}, - {file = "grpcio-1.43.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:01f4b887ed703fe82ebe613e1d2dadea517891725e17e7a6134dcd00352bd28c"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0aa8285f284338eb68962fe1a830291db06f366ea12f213399b520c062b01f65"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:0edbfeb6729aa9da33ce7e28fb7703b3754934115454ae45e8cc1db601756fd3"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:c354017819201053d65212befd1dcb65c2d91b704d8977e696bae79c47cd2f82"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50cfb7e1067ee5e00b8ab100a6b7ea322d37ec6672c0455106520b5891c4b5f5"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f1aeb65ed17dfb2f6cd717cc109910fe395133af7257a9c729c0b9604eac10"}, - {file = "grpcio-1.43.0-cp38-cp38-win32.whl", hash = "sha256:fa26a8bbb3fe57845acb1329ff700d5c7eaf06414c3e15f4cb8923f3a466ef64"}, - {file = "grpcio-1.43.0-cp38-cp38-win_amd64.whl", hash = "sha256:ade8b79a6b6aea68adb9d4bfeba5d647667d842202c5d8f3ba37ac1dc8e5c09c"}, - {file = "grpcio-1.43.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:124e718faf96fe44c98b05f3f475076be8b5198bb4c52a13208acf88a8548ba9"}, - {file = "grpcio-1.43.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2f96142d0abc91290a63ba203f01649e498302b1b6007c67bad17f823ecde0cf"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:31e6e489ccd8f08884b9349a39610982df48535881ec34f05a11c6e6b6ebf9d0"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:0e731f660e1e68238f56f4ce11156f02fd06dc58bc7834778d42c0081d4ef5ad"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:1f16725a320460435a8a5339d8b06c4e00d307ab5ad56746af2e22b5f9c50932"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4b4543e13acb4806917d883d0f70f21ba93b29672ea81f4aaba14821aaf9bb0"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:594aaa0469f4fca7773e80d8c27bf1298e7bbce5f6da0f084b07489a708f16ab"}, - {file = "grpcio-1.43.0-cp39-cp39-win32.whl", hash = "sha256:5449ae564349e7a738b8c38583c0aad954b0d5d1dd3cea68953bfc32eaee11e3"}, - {file = "grpcio-1.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:bdf41550815a831384d21a498b20597417fd31bd084deb17d31ceb39ad9acc79"}, - {file = "grpcio-1.43.0.tar.gz", hash = "sha256:735d9a437c262ab039d02defddcb9f8f545d7009ae61c0114e19dda3843febe5"}, -] -grpclib = [] -h2 = [ - {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, - {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, -] -hpack = [ - {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, - {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, -] -hyperframe = [ - {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, - {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, -] -importlib-metadata = [ - {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, - {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, -] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -ipython = [ - {file = "ipython-7.31.1-py3-none-any.whl", hash = "sha256:55df3e0bd0f94e715abd968bedd89d4e8a7bce4bf498fb123fed4f5398fea874"}, - {file = "ipython-7.31.1.tar.gz", hash = "sha256:b5548ec5329a4bcf054a5deed5099b0f9622eb9ea51aaa7104d215fece201d8c"}, -] -itsdangerous = [ - {file = "itsdangerous-2.0.1-py3-none-any.whl", hash = "sha256:5174094b9637652bdb841a3029700391451bd092ba3db90600dea710ba28e97c"}, - {file = "itsdangerous-2.0.1.tar.gz", hash = "sha256:9e724d68fc22902a1435351f84c3fb8623f303fffcc566a4cb952df8c572cff0"}, -] -jedi = [ - {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, - {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, -] -jinja2 = [ - {file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"}, - {file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"}, -] -joblib = [ - {file = "joblib-1.1.0-py2.py3-none-any.whl", hash = "sha256:f21f109b3c7ff9d95f8387f752d0d9c34a02aa2f7060c2135f465da0e5160ff6"}, - {file = "joblib-1.1.0.tar.gz", hash = "sha256:4158fcecd13733f8be669be0683b96ebdbbd38d23559f54dca7205aea1bf1e35"}, -] -kiwisolver = [ +files = [ {file = "kiwisolver-1.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1d819553730d3c2724582124aee8a03c846ec4362ded1034c16fb3ef309264e6"}, {file = "kiwisolver-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d93a1095f83e908fc253f2fb569c2711414c0bfd451cab580466465b235b470"}, {file = "kiwisolver-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4550a359c5157aaf8507e6820d98682872b9100ce7607f8aa070b4b8af6c298"}, @@ -1427,12 +856,22 @@ kiwisolver = [ {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:bcadb05c3d4794eb9eee1dddf1c24215c92fb7b55a80beae7a60530a91060560"}, {file = "kiwisolver-1.3.2.tar.gz", hash = "sha256:fc4453705b81d03568d5b808ad8f09c77c47534f6ac2e72e733f9ca4714aa75c"}, ] -markupsafe = [ + +[[package]] +name = "markupsafe" +version = "2.0.1" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.6" +files = [ {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, + {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, @@ -1444,6 +883,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, + {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, @@ -1455,6 +897,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, + {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, @@ -1467,6 +912,9 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, + {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, @@ -1479,19 +927,52 @@ markupsafe = [ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, + {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, ] -marshmallow = [ + +[[package]] +name = "marshmallow" +version = "3.14.1" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.6" +files = [ {file = "marshmallow-3.14.1-py3-none-any.whl", hash = "sha256:04438610bc6dadbdddb22a4a55bcc7f6f8099e69580b2e67f5a681933a1f4400"}, {file = "marshmallow-3.14.1.tar.gz", hash = "sha256:4c05c1684e0e97fe779c62b91878f173b937fe097b356cd82f793464f5bc6138"}, ] -marshmallow-polyfield = [ + +[package.extras] +dev = ["flake8 (==4.0.1)", "flake8-bugbear (==21.9.2)", "mypy (==0.910)", "pre-commit (>=2.4,<3.0)", "pytest", "pytz", "simplejson", "tox"] +docs = ["alabaster (==0.7.12)", "autodocsumm (==0.2.7)", "sphinx (==4.3.0)", "sphinx-issues (==1.2.0)", "sphinx-version-warning (==1.1.2)"] +lint = ["flake8 (==4.0.1)", "flake8-bugbear (==21.9.2)", "mypy (==0.910)", "pre-commit (>=2.4,<3.0)"] +tests = ["pytest", "pytz", "simplejson"] + +[[package]] +name = "marshmallow-polyfield" +version = "5.10" +description = "An unofficial extension to Marshmallow to allow for polymorphic fields" +optional = false +python-versions = ">=3.5" +files = [ {file = "marshmallow-polyfield-5.10.tar.gz", hash = "sha256:75d0e31b725650e91428f975a66ed30f703cc6f9fcfe45b8436ee6d676921691"}, {file = "marshmallow_polyfield-5.10-py3-none-any.whl", hash = "sha256:a0a91730c6d21bfac1563990c7ba1413928e7499af669619d4fb38d1fb25c4e9"}, ] -matplotlib = [ + +[package.dependencies] +marshmallow = ">=3.0.0b10" + +[[package]] +name = "matplotlib" +version = "3.5.1" +description = "Python plotting package" +optional = false +python-versions = ">=3.7" +files = [ {file = "matplotlib-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:456cc8334f6d1124e8ff856b42d2cc1c84335375a16448189999496549f7182b"}, {file = "matplotlib-3.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8a77906dc2ef9b67407cec0bdbf08e3971141e535db888974a915be5e1e3efc6"}, {file = "matplotlib-3.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e70ae6475cfd0fad3816dcbf6cac536dc6f100f7474be58d59fa306e6e768a4"}, @@ -1528,15 +1009,49 @@ matplotlib = [ {file = "matplotlib-3.5.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14334b9902ec776461c4b8c6516e26b450f7ebe0b3ef8703bf5cdfbbaecf774a"}, {file = "matplotlib-3.5.1.tar.gz", hash = "sha256:b2e9810e09c3a47b73ce9cab5a72243a1258f61e7900969097a817232246ce1c"}, ] -matplotlib-inline = [ + +[package.dependencies] +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.0.1" +numpy = ">=1.17" +packaging = ">=20.0" +pillow = ">=6.2.0" +pyparsing = ">=2.2.1" +python-dateutil = ">=2.7" + +[[package]] +name = "matplotlib-inline" +version = "0.1.3" +description = "Inline Matplotlib backend for Jupyter" +optional = true +python-versions = ">=3.5" +files = [ {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"}, {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, ] -mccabe = [ + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = "*" +files = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] -multidict = [ + +[[package]] +name = "multidict" +version = "5.2.0" +description = "multidict implementation" +optional = false +python-versions = ">=3.6" +files = [ {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3822c5894c72e3b35aae9909bef66ec83e44522faf767c0ad39e0e2de11d3b55"}, {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:28e6d883acd8674887d7edc896b91751dc2d8e87fbdca8359591a13872799e4e"}, {file = "multidict-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b61f85101ef08cbbc37846ac0e43f027f7844f3fade9b7f6dd087178caedeee7"}, @@ -1610,48 +1125,87 @@ multidict = [ {file = "multidict-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9631c642e08b9fff1c6255487e62971d8b8e821808ddd013d8ac058087591ac"}, {file = "multidict-5.2.0.tar.gz", hash = "sha256:0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce"}, ] -mypy-extensions = [ + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +optional = false +python-versions = "*" +files = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] -nest-asyncio = [] -numpy = [ - {file = "numpy-1.21.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:301e408a052fdcda5cdcf03021ebafc3c6ea093021bf9d1aa47c54d48bdad166"}, - {file = "numpy-1.21.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7e8f6216f180f3fd4efb73de5d1eaefb5f5a1ee5b645c67333033e39440e63a"}, - {file = "numpy-1.21.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc7a7d7b0ed72589fd8b8486b9b42a564f10b8762be8bd4d9df94b807af4a089"}, - {file = "numpy-1.21.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58ca1d7c8aef6e996112d0ce873ac9dfa1eaf4a1196b4ff7ff73880a09923ba7"}, - {file = "numpy-1.21.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4b2fb01f1b4ddbe2453468ea0719f4dbb1f5caa712c8b21bb3dd1480cd30d9"}, - {file = "numpy-1.21.5-cp310-cp310-win_amd64.whl", hash = "sha256:cc1b30205d138d1005adb52087ff45708febbef0e420386f58664f984ef56954"}, - {file = "numpy-1.21.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:08de8472d9f7571f9d51b27b75e827f5296295fa78817032e84464be8bb905bc"}, - {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4fe6a006557b87b352c04596a6e3f12a57d6e5f401d804947bd3188e6b0e0e76"}, - {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3d893b0871322eaa2f8c7072cdb552d8e2b27645b7875a70833c31e9274d4611"}, - {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:341dddcfe3b7b6427a28a27baa59af5ad51baa59bfec3264f1ab287aa3b30b13"}, - {file = "numpy-1.21.5-cp37-cp37m-win32.whl", hash = "sha256:ca9c23848292c6fe0a19d212790e62f398fd9609aaa838859be8459bfbe558aa"}, - {file = "numpy-1.21.5-cp37-cp37m-win_amd64.whl", hash = "sha256:025b497014bc33fc23897859350f284323f32a2fff7654697f5a5fc2a19e9939"}, - {file = "numpy-1.21.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a5098df115340fb17fc93867317a947e1dcd978c3888c5ddb118366095851f8"}, - {file = "numpy-1.21.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:311283acf880cfcc20369201bd75da907909afc4666966c7895cbed6f9d2c640"}, - {file = "numpy-1.21.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b545ebadaa2b878c8630e5bcdb97fc4096e779f335fc0f943547c1c91540c815"}, - {file = "numpy-1.21.5-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c5562bcc1a9b61960fc8950ade44d00e3de28f891af0acc96307c73613d18f6e"}, - {file = "numpy-1.21.5-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eed2afaa97ec33b4411995be12f8bdb95c87984eaa28d76cf628970c8a2d689a"}, - {file = "numpy-1.21.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61bada43d494515d5b122f4532af226fdb5ee08fe5b5918b111279843dc6836a"}, - {file = "numpy-1.21.5-cp38-cp38-win32.whl", hash = "sha256:7b9d6b14fc9a4864b08d1ba57d732b248f0e482c7b2ff55c313137e3ed4d8449"}, - {file = "numpy-1.21.5-cp38-cp38-win_amd64.whl", hash = "sha256:dbce7adeb66b895c6aaa1fad796aaefc299ced597f6fbd9ceddb0dd735245354"}, - {file = "numpy-1.21.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:507c05c7a37b3683eb08a3ff993bd1ee1e6c752f77c2f275260533b265ecdb6c"}, - {file = "numpy-1.21.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:00c9fa73a6989895b8815d98300a20ac993c49ac36c8277e8ffeaa3631c0dbbb"}, - {file = "numpy-1.21.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69a5a8d71c308d7ef33ef72371c2388a90e3495dbb7993430e674006f94797d5"}, - {file = "numpy-1.21.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2d8adfca843bc46ac199a4645233f13abf2011a0b2f4affc5c37cd552626f27b"}, - {file = "numpy-1.21.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c293d3c0321996cd8ffe84215ffe5d269fd9d1d12c6f4ffe2b597a7c30d3e593"}, - {file = "numpy-1.21.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c978544be9e04ed12016dd295a74283773149b48f507d69b36f91aa90a643e5"}, - {file = "numpy-1.21.5-cp39-cp39-win32.whl", hash = "sha256:2a9add27d7fc0fdb572abc3b2486eb3b1395da71e0254c5552b2aad2a18b5441"}, - {file = "numpy-1.21.5-cp39-cp39-win_amd64.whl", hash = "sha256:1964db2d4a00348b7a60ee9d013c8cb0c566644a589eaa80995126eac3b99ced"}, - {file = "numpy-1.21.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a7c4b701ca418cd39e28ec3b496e6388fe06de83f5f0cb74794fa31cfa384c02"}, - {file = "numpy-1.21.5.zip", hash = "sha256:6a5928bc6241264dce5ed509e66f33676fc97f464e7a919edc672fb5532221ee"}, -] -packaging = [ + +[[package]] +name = "nest-asyncio" +version = "1.5.6" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.5.6-py3-none-any.whl", hash = "sha256:b9a953fb40dceaa587d109609098db21900182b16440652454a146cffb06e8b8"}, + {file = "nest_asyncio-1.5.6.tar.gz", hash = "sha256:d267cc1ff794403f7df692964d1d2a3fa9418ffea2a3f6859a439ff482fef290"}, +] + +[[package]] +name = "numpy" +version = "1.24.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, + {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, + {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, + {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, + {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, + {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, + {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, + {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, + {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, + {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, +] + +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.6" +files = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] -pandas = [ + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + +[[package]] +name = "pandas" +version = "1.3.5" +description = "Powerful data structures for data analysis, time series, and statistics" +optional = true +python-versions = ">=3.7.1" +files = [ {file = "pandas-1.3.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:62d5b5ce965bae78f12c1c0df0d387899dd4211ec0bdc52822373f13a3a022b9"}, {file = "pandas-1.3.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:adfeb11be2d54f275142c8ba9bf67acee771b7186a5745249c7d5a06c670136b"}, {file = "pandas-1.3.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:60a8c055d58873ad81cae290d974d13dd479b82cbb975c3e1fa2cf1920715296"}, @@ -1678,27 +1232,89 @@ pandas = [ {file = "pandas-1.3.5-cp39-cp39-win_amd64.whl", hash = "sha256:32e1a26d5ade11b547721a72f9bfc4bd113396947606e00d5b4a5b79b3dcb006"}, {file = "pandas-1.3.5.tar.gz", hash = "sha256:1e4285f5de1012de20ca46b188ccf33521bff61ba5c5ebd78b4fb28e5416a9f1"}, ] -parso = [ + +[package.dependencies] +numpy = [ + {version = ">=1.17.3", markers = "(platform_machine != \"aarch64\" and platform_machine != \"arm64\") and python_version < \"3.10\""}, + {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, + {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, +] +python-dateutil = ">=2.7.3" +pytz = ">=2017.3" + +[package.extras] +test = ["hypothesis (>=3.58)", "pytest (>=6.0)", "pytest-xdist"] + +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +optional = true +python-versions = ">=3.6" +files = [ {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] -pastel = [ + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "pastel" +version = "0.2.1" +description = "Bring colors to your terminal." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, ] -pathspec = [ + +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] -pexpect = [ + +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +optional = true +python-versions = "*" +files = [ {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, ] -pickleshare = [ + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +optional = true +python-versions = "*" +files = [ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] -pillow = [ + +[[package]] +name = "pillow" +version = "8.4.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.6" +files = [ {file = "Pillow-8.4.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:81f8d5c81e483a9442d72d182e1fb6dcb9723f289a57e8030811bac9ea3fef8d"}, {file = "Pillow-8.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3f97cfb1e5a392d75dd8b9fd274d205404729923840ca94ca45a0af57e13dbe6"}, {file = "Pillow-8.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb9fc393f3c61f9054e1ed26e6fe912c7321af2f41ff49d3f83d05bacf22cc78"}, @@ -1741,25 +1357,100 @@ pillow = [ {file = "Pillow-8.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc"}, {file = "Pillow-8.4.0.tar.gz", hash = "sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed"}, ] -platformdirs = [ + +[[package]] +name = "platformdirs" +version = "2.4.0" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.6" +files = [ {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"}, {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"}, ] -plotly = [] -pluggy = [ + +[package.extras] +docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] +test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] + +[[package]] +name = "plotly" +version = "5.13.1" +description = "An open-source, interactive data visualization library for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "plotly-5.13.1-py2.py3-none-any.whl", hash = "sha256:f776a5c664908450c6c1727f61e8e2e22798d9c6c69d37a9057735365084a2fa"}, + {file = "plotly-5.13.1.tar.gz", hash = "sha256:90ee9a1fee0dda30e2830e129855081ea17bd1b06a553a62b62de15caff1a219"}, +] + +[package.dependencies] +tenacity = ">=6.2.0" + +[[package]] +name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] -poethepoet = [ + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +name = "poethepoet" +version = "0.11.0" +description = "A task runner that works well with poetry." +optional = false +python-versions = ">=3.6.2,<4.0.0" +files = [ {file = "poethepoet-0.11.0-py3-none-any.whl", hash = "sha256:4aac200f52e0faa309a655c064f2a522d9d18b64f717de9805151421166ba4d8"}, {file = "poethepoet-0.11.0.tar.gz", hash = "sha256:a0618e198600db801588bae627982682f8bd5304a49a75c6dbc430feade5a8a9"}, ] -pretty-errors = [] -prompt-toolkit = [ + +[package.dependencies] +pastel = ">=0.2.1,<0.3.0" +tomli = ">=1.2.2,<2.0.0" + +[[package]] +name = "pretty-errors" +version = "1.2.25" +description = "Prettifies Python exception output to make it legible." +optional = false +python-versions = "*" +files = [ + {file = "pretty_errors-1.2.25-py3-none-any.whl", hash = "sha256:8ce68ccd99e0f2a099265c8c1f1c23b7c60a15d69bb08816cb336e237d5dc983"}, + {file = "pretty_errors-1.2.25.tar.gz", hash = "sha256:a16ba5c752c87c263bf92f8b4b58624e3b1e29271a9391f564f12b86e93c6755"}, +] + +[package.dependencies] +colorama = "*" + +[[package]] +name = "prompt-toolkit" +version = "3.0.24" +description = "Library for building powerful interactive command lines in Python" +optional = true +python-versions = ">=3.6.2" +files = [ {file = "prompt_toolkit-3.0.24-py3-none-any.whl", hash = "sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506"}, {file = "prompt_toolkit-3.0.24.tar.gz", hash = "sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6"}, ] -protobuf = [ + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "protobuf" +version = "3.19.1" +description = "Protocol Buffers" +optional = false +python-versions = ">=3.5" +files = [ {file = "protobuf-3.19.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d80f80eb175bf5f1169139c2e0c5ada98b1c098e2b3c3736667f28cbbea39fc8"}, {file = "protobuf-3.19.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a529e7df52204565bcd33738a7a5f288f3d2d37d86caa5d78c458fa5fabbd54d"}, {file = "protobuf-3.19.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28ccea56d4dc38d35cd70c43c2da2f40ac0be0a355ef882242e8586c6d66666f"}, @@ -1785,47 +1476,146 @@ protobuf = [ {file = "protobuf-3.19.1-py2.py3-none-any.whl", hash = "sha256:e813b1c9006b6399308e917ac5d298f345d95bb31f46f02b60cd92970a9afa17"}, {file = "protobuf-3.19.1.tar.gz", hash = "sha256:62a8e4baa9cb9e064eb62d1002eca820857ab2138440cb4b3ea4243830f94ca7"}, ] -ptyprocess = [ + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = true +python-versions = "*" +files = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] -py = [ + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] -pycodestyle = [ + +[[package]] +name = "pycodestyle" +version = "2.8.0" +description = "Python style guide checker" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, ] -pyflakes = [ + +[[package]] +name = "pyflakes" +version = "2.4.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, ] -pygments = [ + +[[package]] +name = "pygments" +version = "2.11.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = true +python-versions = ">=3.5" +files = [ {file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"}, {file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"}, ] -pyparsing = [ + +[[package]] +name = "pyparsing" +version = "3.0.6" +description = "Python parsing module" +optional = false +python-versions = ">=3.6" +files = [ {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, ] -pypiwin32 = [ + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pypiwin32" +version = "223" +description = "" +optional = true +python-versions = "*" +files = [ {file = "pypiwin32-223-py3-none-any.whl", hash = "sha256:67adf399debc1d5d14dffc1ab5acacb800da569754fafdc576b2a039485aa775"}, {file = "pypiwin32-223.tar.gz", hash = "sha256:71be40c1fbd28594214ecaecb58e7aa8b708eabfa0125c8a109ebd51edbd776a"}, ] -pytest = [ + +[package.dependencies] +pywin32 = ">=223" + +[[package]] +name = "pytest" +version = "6.2.5" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.6" +files = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, ] -python-dateutil = [ + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ {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"}, ] -pytz = [ + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytz" +version = "2021.3" +description = "World timezone definitions, modern and historical" +optional = true +python-versions = "*" +files = [ {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, ] -pywin32 = [ + +[[package]] +name = "pywin32" +version = "303" +description = "Python for Window Extensions" +optional = true +python-versions = "*" +files = [ {file = "pywin32-303-cp310-cp310-win32.whl", hash = "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb"}, {file = "pywin32-303-cp310-cp310-win_amd64.whl", hash = "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51"}, {file = "pywin32-303-cp311-cp311-win32.whl", hash = "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee"}, @@ -1839,9 +1629,63 @@ pywin32 = [ {file = "pywin32-303-cp39-cp39-win32.whl", hash = "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352"}, {file = "pywin32-303-cp39-cp39-win_amd64.whl", hash = "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34"}, ] -qm-octave = [] -qm-qua = [] -scikit-learn = [ + +[[package]] +name = "qm-octave" +version = "1.1.0" +description = "SDK to control an Octave with QUA" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "qm_octave-1.1.0-py3-none-any.whl", hash = "sha256:ff4c631bfdaf19c389ced7d84550e2f7d3d131b268bb67132211295e3cc6b468"}, + {file = "qm_octave-1.1.0.tar.gz", hash = "sha256:374626b144f1597af9c1a70d93001b44cc421b80c4303aea95e36d031f90b601"}, +] + +[package.dependencies] +betterproto = "2.0.0b5" +grpcio = ">=1.39.0,<2.0.0" +grpclib = {version = ">=0.4.3rc3,<0.5.0", markers = "python_version >= \"3.10\" and python_version < \"4.0\""} +nest-asyncio = ">=1.5.4,<2.0.0" +numpy = ">=1.21.0" +protobuf = ">=3.17.3,<4.0.0" + +[[package]] +name = "qm-qua" +version = "1.1.1" +description = "QUA language SDK to control a Quantum Computer" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "qm_qua-1.1.1-py3-none-any.whl", hash = "sha256:c6e9c68690b40b3b97034dc1d4c39c23b9f9cb0ab1f34d18813a80490361730d"}, + {file = "qm_qua-1.1.1.tar.gz", hash = "sha256:05a13841462f522afa61b6f63ff88d845a4734b81c1eb6b1c4083ed0e371ef95"}, +] + +[package.dependencies] +betterproto = "2.0.0b5" +datadog-api-client = ">=2.6.0,<3.0.0" +dependency_injector = ">=4.41.0,<5.0.0" +deprecation = ">=2.1.0,<3.0.0" +grpcio = ">=1.39.0,<2.0.0" +grpclib = {version = ">=0.4.3rc3,<0.5.0", markers = "python_version >= \"3.10\" and python_version < \"4.0\""} +marshmallow = ">=3.0.0,<4.0.0" +marshmallow-polyfield = ">=5.7,<6.0" +numpy = ">=1.17.0,<2.0.0" +plotly = ">=5.13.0,<6.0.0" +pretty_errors = ">=1.2.25,<2.0.0" +protobuf = ">=3.17.3,<4.0.0" +qm-octave = ">=1.1.0,<2.0.0" +tinydb = ">=4.6.1,<5.0.0" + +[package.extras] +simulation = ["certifi"] + +[[package]] +name = "scikit-learn" +version = "1.0.2" +description = "A set of python modules for machine learning and data mining" +optional = false +python-versions = ">=3.7" +files = [ {file = "scikit-learn-1.0.2.tar.gz", hash = "sha256:b5870959a5484b614f26d31ca4c17524b1b0317522199dc985c3b4256e030767"}, {file = "scikit_learn-1.0.2-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:da3c84694ff693b5b3194d8752ccf935a665b8b5edc33a283122f4273ca3e687"}, {file = "scikit_learn-1.0.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:75307d9ea39236cad7eea87143155eea24d48f93f3a2f9389c817f7019f00705"}, @@ -1875,105 +1719,228 @@ scikit-learn = [ {file = "scikit_learn-1.0.2-cp39-cp39-win32.whl", hash = "sha256:e174242caecb11e4abf169342641778f68e1bfaba80cd18acd6bc84286b9a534"}, {file = "scikit_learn-1.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:b54a62c6e318ddbfa7d22c383466d38d2ee770ebdb5ddb668d56a099f6eaf75f"}, ] -scipy = [ - {file = "scipy-1.7.3-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17"}, - {file = "scipy-1.7.3-1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:b0e0aeb061a1d7dcd2ed59ea57ee56c9b23dd60100825f98238c06ee5cc4467e"}, - {file = "scipy-1.7.3-1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:b78a35c5c74d336f42f44106174b9851c783184a85a3fe3e68857259b37b9ffb"}, - {file = "scipy-1.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:173308efba2270dcd61cd45a30dfded6ec0085b4b6eb33b5eb11ab443005e088"}, - {file = "scipy-1.7.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:21b66200cf44b1c3e86495e3a436fc7a26608f92b8d43d344457c54f1c024cbc"}, - {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceebc3c4f6a109777c0053dfa0282fddb8893eddfb0d598574acfb734a926168"}, - {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7eaea089345a35130bc9a39b89ec1ff69c208efa97b3f8b25ea5d4c41d88094"}, - {file = "scipy-1.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:304dfaa7146cffdb75fbf6bb7c190fd7688795389ad060b970269c8576d038e9"}, - {file = "scipy-1.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:033ce76ed4e9f62923e1f8124f7e2b0800db533828c853b402c7eec6e9465d80"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4d242d13206ca4302d83d8a6388c9dfce49fc48fdd3c20efad89ba12f785bf9e"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8499d9dd1459dc0d0fe68db0832c3d5fc1361ae8e13d05e6849b358dc3f2c279"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca36e7d9430f7481fc7d11e015ae16fbd5575615a8e9060538104778be84addf"}, - {file = "scipy-1.7.3-cp37-cp37m-win32.whl", hash = "sha256:e2c036492e673aad1b7b0d0ccdc0cb30a968353d2c4bf92ac8e73509e1bf212c"}, - {file = "scipy-1.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:866ada14a95b083dd727a845a764cf95dd13ba3dc69a16b99038001b05439709"}, - {file = "scipy-1.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:65bd52bf55f9a1071398557394203d881384d27b9c2cad7df9a027170aeaef93"}, - {file = "scipy-1.7.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:f99d206db1f1ae735a8192ab93bd6028f3a42f6fa08467d37a14eb96c9dd34a3"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5f2cfc359379c56b3a41b17ebd024109b2049f878badc1e454f31418c3a18436"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb7ae2c4dbdb3c9247e07acc532f91077ae6dbc40ad5bd5dca0bb5a176ee9bda"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c2d250074cfa76715d58830579c64dff7354484b284c2b8b87e5a38321672c"}, - {file = "scipy-1.7.3-cp38-cp38-win32.whl", hash = "sha256:87069cf875f0262a6e3187ab0f419f5b4280d3dcf4811ef9613c605f6e4dca95"}, - {file = "scipy-1.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:7edd9a311299a61e9919ea4192dd477395b50c014cdc1a1ac572d7c27e2207fa"}, - {file = "scipy-1.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eef93a446114ac0193a7b714ce67659db80caf940f3232bad63f4c7a81bc18df"}, - {file = "scipy-1.7.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:eb326658f9b73c07081300daba90a8746543b5ea177184daed26528273157294"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:93378f3d14fff07572392ce6a6a2ceb3a1f237733bd6dcb9eb6a2b29b0d19085"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edad1cf5b2ce1912c4d8ddad20e11d333165552aba262c882e28c78bbc09dbf6"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d1cc2c19afe3b5a546ede7e6a44ce1ff52e443d12b231823268019f608b9b12"}, - {file = "scipy-1.7.3-cp39-cp39-win32.whl", hash = "sha256:2c56b820d304dffcadbbb6cbfbc2e2c79ee46ea291db17e288e73cd3c64fefa9"}, - {file = "scipy-1.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f78181a153fa21c018d346f595edd648344751d7f03ab94b398be2ad083ed3e"}, - {file = "scipy-1.7.3.tar.gz", hash = "sha256:ab5875facfdef77e0a47d5fd39ea178b58e60e454a4c85aa1e52fcb80db7babf"}, -] -setuptools-scm = [ - {file = "setuptools_scm-6.3.2-py3-none-any.whl", hash = "sha256:4c64444b1d49c4063ae60bfe1680f611c8b13833d556fd1d6050c0023162a119"}, - {file = "setuptools_scm-6.3.2.tar.gz", hash = "sha256:a49aa8081eeb3514eb9728fa5040f2eaa962d6c6f4ec9c32f6c1fba88f88a0f2"}, -] -six = [ + +[package.dependencies] +joblib = ">=0.11" +numpy = ">=1.14.6" +scipy = ">=1.1.0" +threadpoolctl = ">=2.0.0" + +[package.extras] +benchmark = ["matplotlib (>=2.2.3)", "memory-profiler (>=0.57.0)", "pandas (>=0.25.0)"] +docs = ["Pillow (>=7.1.2)", "matplotlib (>=2.2.3)", "memory-profiler (>=0.57.0)", "numpydoc (>=1.0.0)", "pandas (>=0.25.0)", "scikit-image (>=0.14.5)", "seaborn (>=0.9.0)", "sphinx (>=4.0.1)", "sphinx-gallery (>=0.7.0)", "sphinx-prompt (>=1.3.0)", "sphinxext-opengraph (>=0.4.2)"] +examples = ["matplotlib (>=2.2.3)", "pandas (>=0.25.0)", "scikit-image (>=0.14.5)", "seaborn (>=0.9.0)"] +tests = ["black (>=21.6b0)", "flake8 (>=3.8.2)", "matplotlib (>=2.2.3)", "mypy (>=0.770)", "pandas (>=0.25.0)", "pyamg (>=4.0.0)", "pytest (>=5.0.1)", "pytest-cov (>=2.9.0)", "scikit-image (>=0.14.5)"] + +[[package]] +name = "scipy" +version = "1.9.3" +description = "Fundamental algorithms for scientific computing in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0"}, + {file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9"}, + {file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb"}, + {file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc"}, + {file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0"}, + {file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58"}, + {file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027"}, +] + +[package.dependencies] +numpy = ">=1.18.5,<1.26.0" + +[package.extras] +dev = ["flake8", "mypy", "pycodestyle", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-panels (>=0.5.2)", "sphinx-tabs"] +test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] + +[[package]] +name = "setuptools" +version = "69.0.2" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-69.0.2-py3-none-any.whl", hash = "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2"}, + {file = "setuptools-69.0.2.tar.gz", hash = "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -tenacity = [ + +[[package]] +name = "tenacity" +version = "8.0.1" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.6" +files = [ {file = "tenacity-8.0.1-py3-none-any.whl", hash = "sha256:f78f4ea81b0fabc06728c11dc2a8c01277bfc5181b321a4770471902e3eb844a"}, {file = "tenacity-8.0.1.tar.gz", hash = "sha256:43242a20e3e73291a28bcbcacfd6e000b02d3857a9a9fff56b297a27afdc932f"}, ] -threadpoolctl = [ + +[package.extras] +doc = ["reno", "sphinx", "tornado (>=4.5)"] + +[[package]] +name = "threadpoolctl" +version = "3.1.0" +description = "threadpoolctl" +optional = false +python-versions = ">=3.6" +files = [ {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"}, {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"}, ] -tinydb = [] -toml = [ + +[[package]] +name = "tinydb" +version = "4.7.1" +description = "TinyDB is a tiny, document oriented database optimized for your happiness :)" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "tinydb-4.7.1-py3-none-any.whl", hash = "sha256:1534e498ca23f55c43b0f1e7c0cf174049498ab45a887c82ba9831e0f9868df3"}, + {file = "tinydb-4.7.1.tar.gz", hash = "sha256:8955c239a79b8a6c8f637900152e2de38690848199d71d870c33c16405433ca5"}, +] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] -tomli = [ + +[[package]] +name = "tomli" +version = "1.2.3" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.6" +files = [ {file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"}, {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"}, ] -traitlets = [ + +[[package]] +name = "traitlets" +version = "5.1.1" +description = "Traitlets Python configuration system" +optional = true +python-versions = ">=3.7" +files = [ {file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"}, {file = "traitlets-5.1.1.tar.gz", hash = "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7"}, ] -typed-ast = [ - {file = "typed_ast-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d8314c92414ce7481eee7ad42b353943679cf6f30237b5ecbf7d835519e1212"}, - {file = "typed_ast-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b53ae5de5500529c76225d18eeb060efbcec90ad5e030713fe8dab0fb4531631"}, - {file = "typed_ast-1.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:24058827d8f5d633f97223f5148a7d22628099a3d2efe06654ce872f46f07cdb"}, - {file = "typed_ast-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a6d495c1ef572519a7bac9534dbf6d94c40e5b6a608ef41136133377bba4aa08"}, - {file = "typed_ast-1.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:de4ecae89c7d8b56169473e08f6bfd2df7f95015591f43126e4ea7865928677e"}, - {file = "typed_ast-1.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:256115a5bc7ea9e665c6314ed6671ee2c08ca380f9d5f130bd4d2c1f5848d695"}, - {file = "typed_ast-1.5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7c42707ab981b6cf4b73490c16e9d17fcd5227039720ca14abe415d39a173a30"}, - {file = "typed_ast-1.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:71dcda943a471d826ea930dd449ac7e76db7be778fcd722deb63642bab32ea3f"}, - {file = "typed_ast-1.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4f30a2bcd8e68adbb791ce1567fdb897357506f7ea6716f6bbdd3053ac4d9471"}, - {file = "typed_ast-1.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ca9e8300d8ba0b66d140820cf463438c8e7b4cdc6fd710c059bfcfb1531d03fb"}, - {file = "typed_ast-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9caaf2b440efb39ecbc45e2fabde809cbe56272719131a6318fd9bf08b58e2cb"}, - {file = "typed_ast-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c9bcad65d66d594bffab8575f39420fe0ee96f66e23c4d927ebb4e24354ec1af"}, - {file = "typed_ast-1.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:591bc04e507595887160ed7aa8d6785867fb86c5793911be79ccede61ae96f4d"}, - {file = "typed_ast-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:a80d84f535642420dd17e16ae25bb46c7f4c16ee231105e7f3eb43976a89670a"}, - {file = "typed_ast-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:38cf5c642fa808300bae1281460d4f9b7617cf864d4e383054a5ef336e344d32"}, - {file = "typed_ast-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b6ab14c56bc9c7e3c30228a0a0b54b915b1579613f6e463ba6f4eb1382e7fd4"}, - {file = "typed_ast-1.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2b8d7007f6280e36fa42652df47087ac7b0a7d7f09f9468f07792ba646aac2d"}, - {file = "typed_ast-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:b6d17f37f6edd879141e64a5db17b67488cfeffeedad8c5cec0392305e9bc775"}, - {file = "typed_ast-1.5.1.tar.gz", hash = "sha256:484137cab8ecf47e137260daa20bafbba5f4e3ec7fda1c1e69ab299b75fa81c5"}, -] -typing-extensions = [ + +[package.extras] +test = ["pytest"] + +[[package]] +name = "typing-extensions" +version = "4.0.1" +description = "Backported and Experimental Type Hints for Python 3.6+" +optional = false +python-versions = ">=3.6" +files = [ {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, ] -urllib3 = [] -waitress = [ + +[[package]] +name = "urllib3" +version = "1.26.15" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, + {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "waitress" +version = "2.0.0" +description = "Waitress WSGI server" +optional = false +python-versions = ">=3.6.0" +files = [ {file = "waitress-2.0.0-py3-none-any.whl", hash = "sha256:29af5a53e9fb4e158f525367678b50053808ca6c21ba585754c77d790008c746"}, {file = "waitress-2.0.0.tar.gz", hash = "sha256:69e1f242c7f80273490d3403c3976f3ac3b26e289856936d1f620ed48f321897"}, ] -wcwidth = [ + +[package.extras] +docs = ["Sphinx (>=1.8.1)", "docutils", "pylons-sphinx-themes (>=1.0.9)"] +testing = ["coverage (>=5.0)", "pytest", "pytest-cover"] + +[[package]] +name = "wcwidth" +version = "0.2.5" +description = "Measures the displayed width of unicode strings in a terminal" +optional = true +python-versions = "*" +files = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] -werkzeug = [ + +[[package]] +name = "werkzeug" +version = "2.0.2" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.6" +files = [ {file = "Werkzeug-2.0.2-py3-none-any.whl", hash = "sha256:63d3dc1cf60e7b7e35e97fa9861f7397283b75d765afcaefd993d6046899de8f"}, {file = "Werkzeug-2.0.2.tar.gz", hash = "sha256:aa2bb6fc8dee8d6c504c0ac1e7f5f7dc5810a9903e793b6f715a9f015bdadb9a"}, ] -zipp = [ - {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, - {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, -] + +[package.extras] +watchdog = ["watchdog"] + +[extras] +configbuilder = ["dash", "dash-bootstrap-components", "dash-core-components", "dash-cytoscape", "dash-dangerously-set-inner-html", "dash-html-components", "dash-table", "docutils", "pandas", "waitress"] +interplot = ["dill", "ipython", "pypiwin32"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.8,<4.0" +content-hash = "fcee840fb928cf78fe30cab9cb07f6694042ad275fc9a21f5a7070ab62fa9a71" diff --git a/pyproject.toml b/pyproject.toml index 613ce1bc..c4839d78 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "qualang-tools" -version = "v0.15.2" +version = "v0.16.0" description = "The qualang_tools package includes various tools related to QUA programs in Python" license = "BSD-3-Clause" authors = [ @@ -18,21 +18,21 @@ readme = "README.md" homepage = "https://github.com/qua-platform/py-qua-tools" [tool.poetry.dependencies] -python = ">=3.7.1,<4.0" +python = ">=3.8,<4.0" matplotlib = "^3.4.2" numpy = "^1.17.0" -pandas = ">=1.2.4" qm-qua = ">=1.1.0" scipy = "^1.7.1" -dash = "^2.0.0" -dash-html-components = "^2.0.0" -dash-core-components = "^2.0.0" -dash-bootstrap-components = "^1.0.0" -dash-cytoscape = "^0.3.0" -dash-table = "^5.0.0" -docutils = ">=0.14.0" -dash-dangerously-set-inner-html = "^0.0.2" -waitress = "^2.0.0" +pandas = { version = ">=1.2.4", optional = true } +dash = { version = "^2.0.0", optional = true } +dash-html-components = { version = "^2.0.0", optional = true } +dash-core-components = { version = "^2.0.0", optional = true } +dash-bootstrap-components = { version = "^1.0.0", optional = true } +dash-cytoscape = { version = "^0.3.0", optional = true } +dash-table = { version = "^5.0.0", optional = true } +dash-dangerously-set-inner-html = { version = "^0.0.2", optional = true } +docutils = { version = ">=0.14.0", optional = true } +waitress = { version = "^2.0.0", optional = true } dill = { version = "^0.3.4", optional = true } pypiwin32 = { version = "^223", optional = true } ipython = { version = "^7.31.1", optional = true } @@ -43,12 +43,14 @@ pytest = "^6.2.5" black = "^22.3" poethepoet = "^0.11.0" flake8 = "^4.0.1" +setuptools = "^69.0.2" [tool.poetry.extras] interplot = ["dill", "pypiwin32", "ipython"] +configbuilder = ["pandas", "dash", "dash-html-components", "dash-core-components", "dash-bootstrap-components", "dash-cytoscape", "dash-table", "dash-dangerously-set-inner-html", "docutils", "waitress"] [tool.black] -line-length = 88 # Defaults +line-length = 120 exclude = "qualang_tools/bakery/randomized_benchmark_c1.py" [tool.poe.tasks] diff --git a/qualang_tools/__init__.py b/qualang_tools/__init__.py index c22f2a9b..d18d9159 100644 --- a/qualang_tools/__init__.py +++ b/qualang_tools/__init__.py @@ -1,5 +1,5 @@ __all__ = [ - "simulator_tools", + "simulator", "bakery", "config", "control_panel", diff --git a/qualang_tools/addons/InteractivePlotLib.py b/qualang_tools/addons/InteractivePlotLib.py index 46b04944..85a764f2 100644 --- a/qualang_tools/addons/InteractivePlotLib.py +++ b/qualang_tools/addons/InteractivePlotLib.py @@ -94,16 +94,8 @@ def extract_data_from_mesh(obj): def extract_data_from_pcolor(obj): array = obj.get_array() - x_ext = np.unique( - np.array( - [[vertex[0] for vertex in path.vertices] for path in obj._paths] - ).flatten() - ) - y_ext = np.unique( - np.array( - [[vertex[1] for vertex in path.vertices] for path in obj._paths] - ).flatten() - ) + x_ext = np.unique(np.array([[vertex[0] for vertex in path.vertices] for path in obj._paths]).flatten()) + y_ext = np.unique(np.array([[vertex[1] for vertex in path.vertices] for path in obj._paths]).flatten()) x_ext2 = (x_ext[:-1] + x_ext[1:]) / 2 if len(y_ext) > 1: y_ext2 = (y_ext[:-1] + y_ext[1:]) / 2 @@ -140,12 +132,8 @@ def __init__(self, fig, doc, master_obj): self.fig.canvas.mpl_disconnect(self.fig.canvas.manager.key_press_handler_id) self.cid = self.fig.canvas.mpl_connect("button_press_event", self.mouse_click) self.cid2 = self.fig.canvas.mpl_connect("key_press_event", self.keyboard_click) - self.cid3 = self.fig.canvas.mpl_connect( - "key_release_event", self.keyboard_release - ) - self.cid4 = self.fig.canvas.mpl_connect( - "button_release_event", self.mouse_release - ) + self.cid3 = self.fig.canvas.mpl_connect("key_release_event", self.keyboard_release) + self.cid4 = self.fig.canvas.mpl_connect("button_release_event", self.mouse_release) self.lines = [] self.rectangle = None @@ -158,54 +146,26 @@ def user_interaction(self, type, event): if type == "mouse_click": xlim = self.ax.get_xlim() ylim = self.ax.get_ylim() - bbox = self.ax.get_window_extent().transformed( # axes bounding box - self.fig.dpi_scale_trans.inverted() - ) + bbox = self.ax.get_window_extent().transformed(self.fig.dpi_scale_trans.inverted()) # axes bounding box if event.y < bbox.ymin * self.fig.dpi: - if ( - event.x - < (bbox.xmin + (bbox.xmax - bbox.xmin) / 5) * self.fig.dpi - ): - self.state = InteractivePlotLibFigure.StateMachineLim( - self, "xstart" - ) - elif ( - event.x - > (bbox.xmax - (bbox.xmax - bbox.xmin) / 5) * self.fig.dpi - ): - self.state = InteractivePlotLibFigure.StateMachineLim( - self, "xend" - ) + if event.x < (bbox.xmin + (bbox.xmax - bbox.xmin) / 5) * self.fig.dpi: + self.state = InteractivePlotLibFigure.StateMachineLim(self, "xstart") + elif event.x > (bbox.xmax - (bbox.xmax - bbox.xmin) / 5) * self.fig.dpi: + self.state = InteractivePlotLibFigure.StateMachineLim(self, "xend") else: - self.state = InteractivePlotLibFigure.StateMachineLabel( - self, "xlabel" - ) + self.state = InteractivePlotLibFigure.StateMachineLabel(self, "xlabel") elif event.y > bbox.ymax * self.fig.dpi: - self.state = InteractivePlotLibFigure.StateMachineLabel( - self, "title" - ) + self.state = InteractivePlotLibFigure.StateMachineLabel(self, "title") elif event.x < bbox.xmin * self.fig.dpi: - if ( - event.y - < (bbox.ymin + (bbox.ymax - bbox.ymin) / 5) * self.fig.dpi - ): - self.state = InteractivePlotLibFigure.StateMachineLim( - self, "ystart" - ) - elif ( - event.y - > (bbox.ymax - (bbox.ymax - bbox.ymin) / 5) * self.fig.dpi - ): - self.state = InteractivePlotLibFigure.StateMachineLim( - self, "yend" - ) + if event.y < (bbox.ymin + (bbox.ymax - bbox.ymin) / 5) * self.fig.dpi: + self.state = InteractivePlotLibFigure.StateMachineLim(self, "ystart") + elif event.y > (bbox.ymax - (bbox.ymax - bbox.ymin) / 5) * self.fig.dpi: + self.state = InteractivePlotLibFigure.StateMachineLim(self, "yend") else: - self.state = InteractivePlotLibFigure.StateMachineLabel( - self, "ylabel" - ) + self.state = InteractivePlotLibFigure.StateMachineLabel(self, "ylabel") elif event.x > bbox.xmax * self.fig.dpi: self.state = InteractivePlotLibFigure.StateMachineLegend(self) @@ -234,21 +194,13 @@ def user_interaction(self, type, event): self.line_selected.obj.set_ydata(y) print("FITTTTT") - if self.line_selected is None and isinstance( - self.ax.get_children()[0], PolyCollection - ): + if self.line_selected is None and isinstance(self.ax.get_children()[0], PolyCollection): self.plot_type = "pcolor" - self.line_selected = InteractivePlotLibFigure.PcolorSelected( - self, self.ax.get_children()[0] - ) + self.line_selected = InteractivePlotLibFigure.PcolorSelected(self, self.ax.get_children()[0]) - if self.line_selected is None and isinstance( - self.ax.get_children()[0], QuadMesh - ): + if self.line_selected is None and isinstance(self.ax.get_children()[0], QuadMesh): self.plot_type = "mesh" - self.line_selected = InteractivePlotLibFigure.MeshSelected( - self, self.ax.get_children()[0] - ) + self.line_selected = InteractivePlotLibFigure.MeshSelected(self, self.ax.get_children()[0]) elif type == "keyboard_click": if event.key == "ctrl+v": @@ -257,9 +209,7 @@ def user_interaction(self, type, event): clip.CloseClipboard() lines = data.split("\r\n")[:-1] if len(lines[0].split("\t")) <= 2: - out = np.array( - ([i.split("\t") for i in data.split("\r\n")[:-1]]), "double" - ) + out = np.array(([i.split("\t") for i in data.split("\r\n")[:-1]]), "double") if np.shape(out)[1] == 2: self.ax.plot(out[:, 0], out[:, 1], linewidth=1) elif np.shape(out)[1] == 1: @@ -274,12 +224,8 @@ def user_interaction(self, type, event): self.ax.legend([np.array(lines[1].split("\t")[0], "double")]) else: x_values = np.array(lines[0].split("\t")[1:], "double") - y_values = np.array( - [i.split("\t")[0] for i in lines[1:]], "double" - ) - out_2d = np.array( - ([i.split("\t")[1:] for i in lines[1:]]), "double" - ) + y_values = np.array([i.split("\t")[0] for i in lines[1:]], "double") + out_2d = np.array(([i.split("\t")[1:] for i in lines[1:]]), "double") print(x_values) print(y_values) print(out_2d) @@ -332,9 +278,7 @@ def user_interaction(self, type, event): self.master_obj.figure() if event.key == "alt+l": - self.ax.get_legend().set_visible( - not self.ax.get_legend().get_visible() - ) + self.ax.get_legend().set_visible(not self.ax.get_legend().get_visible()) if event.key == "p" and self.plot_type == "plot": self.convert_to_pcolormesh() @@ -344,9 +288,7 @@ def user_interaction(self, type, event): if event.key == "t": self.line_selected.transpose() - if event.key == "l" and ( - self.plot_type == "pcolor" or self.plot_type == "mesh" - ): + if event.key == "l" and (self.plot_type == "pcolor" or self.plot_type == "mesh"): self.line_selected.convert_to_lines() self.line_selected = None self.plot_type = "plot" @@ -406,9 +348,7 @@ def convert_to_pcolormesh(self): self.ax.get_legend().remove() def detect_curve_click(self, base_x, base_y, base_xlim, base_ylim, width, height): - scale_convert = InteractivePlotLibFigure.ConvertLogLin( - [self.ax.get_xscale(), self.ax.get_yscale()] - ) + scale_convert = InteractivePlotLibFigure.ConvertLogLin([self.ax.get_xscale(), self.ax.get_yscale()]) line_list = self.get_lines_fit_extended() candidate = {"line_index": -1, "distance_2": np.inf, "xy": (0, 0)} x0 = scale_convert.convert[0](base_x) @@ -422,12 +362,7 @@ def detect_curve_click(self, base_x, base_y, base_xlim, base_ylim, width, height for j, line in enumerate(line_list): x = scale_convert.bound[0](line.get_xdata()) y = scale_convert.bound[1](line.get_ydata()) - idx = ( - (x >= base_xlim[0]) - & (x <= base_xlim[1]) - & (y >= base_ylim[0]) - & (y <= base_ylim[1]) - ) + idx = (x >= base_xlim[0]) & (x <= base_xlim[1]) & (y >= base_ylim[0]) & (y <= base_ylim[1]) idx = np.where(idx)[0] idx = list(set.union(set(idx), set(idx + 1), set(idx - 1))) idx = [i for i in idx if i >= 0 and i < len(x)] @@ -457,9 +392,7 @@ def detect_curve_click(self, base_x, base_y, base_xlim, base_ylim, width, height ) else: for i in range(len(x_n) - 1): - d_2, x4, y4 = self.p4( - (x_n[i], y_n[i]), (x_n[i + 1], y_n[i + 1]), (x0_n, y0_n) - ) + d_2, x4, y4 = self.p4((x_n[i], y_n[i]), (x_n[i + 1], y_n[i + 1]), (x0_n, y0_n)) if d_2 < candidate["distance_2"]: candidate["line_index"] = j @@ -485,20 +418,15 @@ def remove_fit(self): lines = self.ax.get_lines() for line in lines: if hasattr(line, "InteractivePlotLib_Type") and ( - line.InteractivePlotLib_Type == "Fit" - or line.InteractivePlotLib_Type == "Fit_markers" + line.InteractivePlotLib_Type == "Fit" or line.InteractivePlotLib_Type == "Fit_markers" ): line.remove() def predefined_fit_pcolor(self, req="n", Type="pcolor"): if Type == "pcolor": - data, x2d, y2d, x_ext2, y_ext2, x_ext, y_ext = extract_data_from_pcolor( - self.line_selected.obj - ) + data, x2d, y2d, x_ext2, y_ext2, x_ext, y_ext = extract_data_from_pcolor(self.line_selected.obj) else: - data, x2d, y2d, x_ext2, y_ext2 = extract_data_from_mesh( - self.line_selected.obj - ) + data, x2d, y2d, x_ext2, y_ext2 = extract_data_from_mesh(self.line_selected.obj) fit_line_x = [] fit_line_y = [] @@ -605,12 +533,8 @@ def delete(self_2d): ind_x = np.array([True] * len(x_list)) ind_y = np.array([True] * len(y_list)) - ind_x = (x_list >= self_2d.sup_self.rectangle.x[0]) & ( - x_list <= self_2d.sup_self.rectangle.x[1] - ) - ind_y = (y_list >= self_2d.sup_self.rectangle.y[0]) & ( - y_list <= self_2d.sup_self.rectangle.y[1] - ) + ind_x = (x_list >= self_2d.sup_self.rectangle.x[0]) & (x_list <= self_2d.sup_self.rectangle.x[1]) + ind_y = (y_list >= self_2d.sup_self.rectangle.y[0]) & (y_list <= self_2d.sup_self.rectangle.y[1]) self_2d.sup_self.rectangle = None x_list = x_list[ind_x] y_list = y_list[ind_y] @@ -651,12 +575,8 @@ def copy_to_clipboard(self_2d): ind_y = np.array([True] * len(y_list)) data_s = "" if self_2d.sup_self.rectangle: - ind_x = (x_list >= self_2d.sup_self.rectangle.x[0]) & ( - x_list <= self_2d.sup_self.rectangle.x[1] - ) - ind_y = (y_list >= self_2d.sup_self.rectangle.y[0]) & ( - y_list <= self_2d.sup_self.rectangle.y[1] - ) + ind_x = (x_list >= self_2d.sup_self.rectangle.x[0]) & (x_list <= self_2d.sup_self.rectangle.x[1]) + ind_y = (y_list >= self_2d.sup_self.rectangle.y[0]) & (y_list <= self_2d.sup_self.rectangle.y[1]) self_2d.sup_self.rectangle = None x_list = x_list[ind_x] y_list = y_list[ind_y] @@ -668,11 +588,7 @@ def copy_to_clipboard(self_2d): data_s += f" ,{','.join([str(i) for i in x_list])}\r\n".replace(",", "\t") for j in range(len(y_list)): - data_s += ( - f"{y_list[j]},{','.join([str(i) for i in data[j]])}\r\n".replace( - ",", "\t" - ) - ) + data_s += f"{y_list[j]},{','.join([str(i) for i in data[j]])}\r\n".replace(",", "\t") clip.OpenClipboard() clip.EmptyClipboard() clip.SetClipboardData(win32con.CF_UNICODETEXT, data_s) @@ -733,20 +649,11 @@ def generate_voronoi(self_voronoi): y = (points[0][1] + points[1][1]) / 2 (l,) = sup_self.ax.plot([max(xlim), min(xlim)], [y, y], "m") else: - slope = (points[0][1] - points[1][1]) / ( - points[0][0] - points[1][0] - ) + slope = (points[0][1] - points[1][1]) / (points[0][0] - points[1][0]) prep_slope = -1 / slope - point0 = ( - np.array( - [points[0][0] + points[1][0], points[0][1] + points[1][1]] - ) - / 2 - ) + point0 = np.array([points[0][0] + points[1][0], points[0][1] + points[1][1]]) / 2 xy = line_in_lim(point0, prep_slope, xlim, ylim) - (l,) = sup_self.ax.plot( - [xy[0][0], xy[1][0]], [xy[0][1], xy[1][1]], "m" - ) + (l,) = sup_self.ax.plot([xy[0][0], xy[1][0]], [xy[0][1], xy[1][1]], "m") self_voronoi.graphical_objects.append(l) if len(points) > 2: @@ -758,9 +665,7 @@ def generate_voronoi(self_voronoi): for simplex in vor.ridge_vertices: simplex = np.asarray(simplex) if np.all(simplex >= 0): - (l,) = sup_self.ax.plot( - vor.vertices[simplex, 0], vor.vertices[simplex, 1], "r-" - ) + (l,) = sup_self.ax.plot(vor.vertices[simplex, 0], vor.vertices[simplex, 1], "r-") self_voronoi.graphical_objects.append(l) center = points.mean(axis=0) @@ -773,9 +678,9 @@ def generate_voronoi(self_voronoi): n = np.array([-t[1], t[0]]) # normal midpoint = points[pointidx].mean(axis=0) point = vor.vertices[i] - far_point = point + np.sign( - np.dot(midpoint - center, n) - ) * n * np.sqrt(np.diff(xlim) ** 2 + np.diff(ylim) ** 2) + far_point = point + np.sign(np.dot(midpoint - center, n)) * n * np.sqrt( + np.diff(xlim) ** 2 + np.diff(ylim) ** 2 + ) (l,) = sup_self.ax.plot( [vor.vertices[i, 0], far_point[0]], @@ -784,9 +689,7 @@ def generate_voronoi(self_voronoi): ) self_voronoi.graphical_objects.append(l) - data, x, y, _, _ = extract_data_from_mesh( - self_voronoi.sup_self.ax.get_children()[0] - ) + data, x, y, _, _ = extract_data_from_mesh(self_voronoi.sup_self.ax.get_children()[0]) x_mean = (x[1:] + x[:-1]) / 2 y_mean = (y[1:] + y[:-1]) / 2 @@ -834,9 +737,7 @@ def __init__(self_mesh, sup_self, obj): self_mesh.y2, ) = extract_data_from_mesh(obj) - self_mesh.plot = lambda x, y, data: self_mesh.sup_self.ax.pcolormesh( - x, y, data - ) + self_mesh.plot = lambda x, y, data: self_mesh.sup_self.ax.pcolormesh(x, y, data) class PcolorSelected(proto_2d_graphics): def __init__(self_pcolor, sup_self, obj): @@ -849,9 +750,7 @@ def __init__(self_pcolor, sup_self, obj): self_pcolor.y = y2 self_pcolor.x2 = x self_pcolor.y2 = y - self_pcolor.plot = lambda x, y, data: self_pcolor.sup_self.ax.pcolormesh( - x, y, data - ) + self_pcolor.plot = lambda x, y, data: self_pcolor.sup_self.ax.pcolormesh(x, y, data) class LineSelected: def __init__(self_line, sup_self, obj, line_index_selected, xy): @@ -913,9 +812,7 @@ def delete(self_line): if self_line.sup_self.rectangle: x_list = self_line.obj.get_xdata() y_list = self_line.obj.get_ydata() - x_list, y_list, _ = self_line.sup_self.rectangle.filter_neg( - x_list, y_list - ) + x_list, y_list, _ = self_line.sup_self.rectangle.filter_neg(x_list, y_list) self_line.obj.set_xdata(x_list) self_line.obj.set_ydata(y_list) self_line.sup_self.rectangle = None @@ -941,9 +838,7 @@ def correct_order(self_line, change): local_order = sup_self.correct_order[self_line.line_index_selected] new_order = local_order + change - if new_order > np.max(sup_self.correct_order) or new_order < np.min( - sup_self.correct_order - ): + if new_order > np.max(sup_self.correct_order) or new_order < np.min(sup_self.correct_order): return # test local_idx = self_line.line_index_selected @@ -1037,9 +932,7 @@ def __init__(self_state, sup_self): self_state.lines = sup_self.get_lines() if sup_self.ax.get_legend(): sup_self.ax.get_legend().set_visible(True) - self_state.legend = [ - i.get_text() for i in sup_self.ax.get_legend().texts - ] + self_state.legend = [i.get_text() for i in sup_self.ax.get_legend().texts] self_state.legend_original = self_state.legend[:] self_state.index = 0 self_state.text_obj = InteractivePlotLibFigure.InteractiveText( @@ -1110,9 +1003,7 @@ def __init__(self_state, sup_self, type="xlabel"): ha = "left" else: pass - self_state.text_box = InteractivePlotLibFigure.TextObj( - sup_self.ax, loc, text, ha=ha, va=va - ) + self_state.text_box = InteractivePlotLibFigure.TextObj(sup_self.ax, loc, text, ha=ha, va=va) self_state.text_obj = InteractivePlotLibFigure.InteractiveText( "", self_state.text_box.update_text, format_text=lambda x: x ) @@ -1134,21 +1025,13 @@ def event(self_state, type, event): ylim = self_state.sup_self.ax.get_ylim() try: if self_state.type == "xstart": - self_state.sup_self.ax.set_xlim( - np.sort([float(self_state.text_obj.text), xlim[1]]) - ) + self_state.sup_self.ax.set_xlim(np.sort([float(self_state.text_obj.text), xlim[1]])) elif self_state.type == "xend": - self_state.sup_self.ax.set_xlim( - np.sort([xlim[0], float(self_state.text_obj.text)]) - ) + self_state.sup_self.ax.set_xlim(np.sort([xlim[0], float(self_state.text_obj.text)])) elif self_state.type == "ystart": - self_state.sup_self.ax.set_ylim( - np.sort([float(self_state.text_obj.text), ylim[1]]) - ) + self_state.sup_self.ax.set_ylim(np.sort([float(self_state.text_obj.text), ylim[1]])) elif self_state.type == "yend": - self_state.sup_self.ax.set_ylim( - np.sort([ylim[0], float(self_state.text_obj.text)]) - ) + self_state.sup_self.ax.set_ylim(np.sort([ylim[0], float(self_state.text_obj.text)])) except BaseException: pass @@ -1182,9 +1065,7 @@ def set_label(t): return sup_self.ax.set_title(t) text_help = "commands: \n:lin[ear]\n:log\n:u[nits]\n:[func]" - self_state.help_box = InteractivePlotLibFigure.HelperText( - self_state.sup_self.ax, text_help - ) + self_state.help_box = InteractivePlotLibFigure.HelperText(self_state.sup_self.ax, text_help) self_state.text_obj = InteractivePlotLibFigure.InteractiveText( text, set_label, lambda x: x, lambda x: self_state.run_command(x, type) @@ -1197,21 +1078,15 @@ def run_command(self_state, command, type): value_unit_split = self_state.text_obj.text.split("[") new_units = value_unit_split[1].split("]")[0] print(f"old:{self_state.old_units},new:{new_units}") - convert_function = self_state.convert_units( - self_state.old_units, new_units - ) + convert_function = self_state.convert_units(self_state.old_units, new_units) if type == "xlabel": for line in self_state.sup_self.ax.get_lines(): line.set_xdata(convert_function(line.get_xdata())) - self_state.sup_self.ax.set_xlim( - convert_function(self_state.sup_self.ax.get_xlim()) - ) + self_state.sup_self.ax.set_xlim(convert_function(self_state.sup_self.ax.get_xlim())) elif type == "ylabel": for line in self_state.sup_self.ax.get_lines(): line.set_ydata(convert_function(line.get_ydata())) - self_state.sup_self.ax.set_ylim( - convert_function(self_state.sup_self.ax.get_ylim()) - ) + self_state.sup_self.ax.set_ylim(convert_function(self_state.sup_self.ax.get_ylim())) else: if command == ":lin" or command == ":linear": self_state.text_obj.text = self_state.text_obj.original_text @@ -1232,9 +1107,7 @@ def run_command(self_state, command, type): value_unit_split = self_state.text_obj.original_text.split("[") self_state.old_units = value_unit_split[1].split("]")[0] self_state.text_obj.text = value_unit_split[0] + "[]" - self_state.text_obj.curser_location = ( - len(self_state.text_obj.text) - 1 - ) + self_state.text_obj.curser_location = len(self_state.text_obj.text) - 1 self_state.text_obj.command_mode = True self_state.text_obj.update_text() self_state.command_stage = "unit_conversion" @@ -1254,9 +1127,7 @@ def convert_function(x): for line in self_state.sup_self.ax.get_lines(): line.set_xdata(convert_function(line.get_xdata())) self_state.sup_self.ax.set_xlim( - convert_function( - np.array(self_state.sup_self.ax.get_xlim()) - ) + convert_function(np.array(self_state.sup_self.ax.get_xlim())) ) elif type == "ylabel": @@ -1264,9 +1135,7 @@ def convert_function(x): for line in self_state.sup_self.ax.get_lines(): line.set_ydata(convert_function(line.get_ydata())) self_state.sup_self.ax.set_ylim( - convert_function( - np.array(self_state.sup_self.ax.get_ylim()) - ) + convert_function(np.array(self_state.sup_self.ax.get_ylim())) ) self_state.text_obj.text = self_state.text_obj.original_text self_state.text_obj.update_text() @@ -1453,32 +1322,18 @@ def event(self_state, type, event): self_state.done = self_state.text_obj.done() if self_state.done: if self_state.text_obj.text == "colorbar": - if ( - self_state.sup_self.plot_type == "mesh" - or self_state.sup_self.plot_type == "pcolor" - ): + if self_state.sup_self.plot_type == "mesh" or self_state.sup_self.plot_type == "pcolor": plt.colorbar() if self_state.text_obj.text == "log": - if ( - self_state.sup_self.plot_type == "mesh" - or self_state.sup_self.plot_type == "pcolor" - ): + if self_state.sup_self.plot_type == "mesh" or self_state.sup_self.plot_type == "pcolor": self_state.sup_self.line_selected.obj.set_norm(Colors.LogNorm()) elif self_state.sup_self.plot_type == "plot": self_state.sup_self.ax.set_yscale("log") - if ( - self_state.text_obj.text == "lin" - or self_state.text_obj.text == "linear" - ): - if ( - self_state.sup_self.plot_type == "mesh" - or self_state.sup_self.plot_type == "pcolor" - ): - self_state.sup_self.line_selected.obj.set_norm( - Colors.Normalize() - ) + if self_state.text_obj.text == "lin" or self_state.text_obj.text == "linear": + if self_state.sup_self.plot_type == "mesh" or self_state.sup_self.plot_type == "pcolor": + self_state.sup_self.line_selected.obj.set_norm(Colors.Normalize()) elif self_state.sup_self.plot_type == "plot": self_state.sup_self.ax.set_yscale("linear") @@ -1513,21 +1368,11 @@ def __init__(self, ax, x, y): self.obj = ax.add_patch(rect) def filter(self, x, y): - ind_bool = ( - (x >= self.x[0]) - * (x <= self.x[1]) - * (y >= self.y[0]) - * (y <= self.y[1]) - ) + ind_bool = (x >= self.x[0]) * (x <= self.x[1]) * (y >= self.y[0]) * (y <= self.y[1]) return np.array(x)[ind_bool], np.array(y)[ind_bool], ind_bool def filter_neg(self, x, y): - ind_bool = ( - (x <= self.x[0]) - | (x >= self.x[1]) - | (y <= self.y[0]) - | (y >= self.y[1]) - ) + ind_bool = (x <= self.x[0]) | (x >= self.x[1]) | (y <= self.y[0]) | (y >= self.y[1]) return np.array(x)[ind_bool], np.array(y)[ind_bool], ind_bool def __del__(self): @@ -1537,9 +1382,7 @@ class StateMachineVoronoi(ProtoStateMachine): def __init__(self_state, sup_self): super().__init__(sup_self) text = "click to add node\n click&drag to move" - self_state.help_box = InteractivePlotLibFigure.HelperText( - self_state.sup_self.ax, text - ) + self_state.help_box = InteractivePlotLibFigure.HelperText(self_state.sup_self.ax, text) self_state.x = [None, None] self_state.y = [None, None] @@ -1554,13 +1397,8 @@ def event(self_state, type, event): if type == "mouse_release": self_state.x[1] = event.xdata self_state.y[1] = event.ydata - if ( - self_state.x[1] == self_state.x[0] - and self_state.y[1] == self_state.y[0] - ): - self_state.sup_self.voronoi_obj.add_marker( - self_state.x[0], self_state.y[0] - ) + if self_state.x[1] == self_state.x[0] and self_state.y[1] == self_state.y[0]: + self_state.sup_self.voronoi_obj.add_marker(self_state.x[0], self_state.y[0]) else: self_state.sup_self.voronoi_obj.move_marker( self_state.x[0], @@ -1576,9 +1414,7 @@ class StateMachineRect(ProtoStateMachine): def __init__(self_state, sup_self): super().__init__(sup_self) text = "Select rectangle\nclick & drag" - self_state.help_box = InteractivePlotLibFigure.HelperText( - self_state.sup_self.ax, text - ) + self_state.help_box = InteractivePlotLibFigure.HelperText(self_state.sup_self.ax, text) self_state.x = [None, None] self_state.y = [None, None] @@ -1590,10 +1426,9 @@ def event(self_state, type, event): if type == "mouse_release": self_state.x[1] = event.xdata self_state.y[1] = event.ydata - if ( - self_state.x[1] == self_state.x[0] - and self_state.y[1] == self_state.y[0] - ): + + if self_state.x[1] == self_state.x[0] and self_state.y[1] == self_state.y[0]: + self_state.x = self_state.sup_self.ax.get_xlim() if self_state.sup_self.plot_type == "pcolor": _, _, _, _, _, _, y_ext = extract_data_from_pcolor( @@ -1632,9 +1467,7 @@ def __init__(self_state, sup_self): self_state.text_box.update_text, format_text=lambda x: f"Fit type: {x}", ) - self_state.help_box = InteractivePlotLibFigure.HelperText( - self_state.sup_self.ax, text - ) + self_state.help_box = InteractivePlotLibFigure.HelperText(self_state.sup_self.ax, text) def event(self_state, type, event): if type == "keyboard_click": @@ -1648,13 +1481,8 @@ def event(self_state, type, event): self_state.help_box.remove() print(self_state.text_obj.text) if self_state.sup_self.plot_type == "plot": - InteractivePlotLibFigure.predefined_fit( - self_state.sup_self, self_state.text_obj.text - ) - elif ( - self_state.sup_self.plot_type == "pcolor" - or self_state.sup_self.plot_type == "mesh" - ): + InteractivePlotLibFigure.predefined_fit(self_state.sup_self, self_state.text_obj.text) + elif self_state.sup_self.plot_type == "pcolor" or self_state.sup_self.plot_type == "mesh": InteractivePlotLibFigure.predefined_fit_pcolor( self_state.sup_self, self_state.text_obj.text, @@ -1685,11 +1513,7 @@ def __init__( def update_text(self_text): buf = self_text.text if not self_text.is_done: - buf = ( - buf[: self_text.curser_location] - + "|" - + buf[self_text.curser_location :] - ) + buf = buf[: self_text.curser_location] + "|" + buf[self_text.curser_location :] self_text.update_text_fun(self_text.format_text(buf)) self_text.first_key_stroke = False @@ -1701,9 +1525,7 @@ def done(self_text): def react_to_key_press(self_text, key): # print(self_text.first_key_stroke) if key == "enter": - if ( - len(self_text.text) > 0 and self_text.text[0] == ":" - ) or self_text.command_mode: + if (len(self_text.text) > 0 and self_text.text[0] == ":") or self_text.command_mode: is_done = self_text.command_func(self_text.text) if is_done: return self_text.done() @@ -1719,8 +1541,7 @@ def react_to_key_press(self_text, key): elif key == "backspace": if (len(self_text.text) > 0) and (self_text.curser_location > 0): self_text.text = ( - self_text.text[: self_text.curser_location - 1] - + self_text.text[self_text.curser_location :] + self_text.text[: self_text.curser_location - 1] + self_text.text[self_text.curser_location :] ) self_text.curser_location -= 1 @@ -1742,9 +1563,7 @@ def react_to_key_press(self_text, key): elif len(key) == 1: self_text.text = ( - self_text.text[: self_text.curser_location] - + key - + self_text.text[self_text.curser_location :] + self_text.text[: self_text.curser_location] + key + self_text.text[self_text.curser_location :] ) self_text.curser_location += 1 @@ -1784,31 +1603,17 @@ def __init__(self, ax, text=""): class HelperText(TextObj): def __init__(self, ax, text=""): - super().__init__( - ax, (max(ax.get_xlim()), max(ax.get_ylim())), text, ha="right" - ) + super().__init__(ax, (max(ax.get_xlim()), max(ax.get_ylim())), text, ha="right") class Marker: def __init__(self_marker, ax, loc, text="", color=".g"): if not text: - x_text = ( - f"{loc[0]:0.3f}" - if ((np.abs(loc[0]) > 1e-2) and (np.abs(loc[0]) < 1e2)) - else f"{loc[0]:0.2e}" - ) - y_text = ( - f"{loc[1]:0.3f}" - if ((np.abs(loc[1]) > 1e-2) and (np.abs(loc[1]) < 1e2)) - else f"{loc[1]:0.2e}" - ) + x_text = f"{loc[0]:0.3f}" if ((np.abs(loc[0]) > 1e-2) and (np.abs(loc[0]) < 1e2)) else f"{loc[0]:0.2e}" + y_text = f"{loc[1]:0.3f}" if ((np.abs(loc[1]) > 1e-2) and (np.abs(loc[1]) < 1e2)) else f"{loc[1]:0.2e}" text = f"[{x_text},{y_text}]" - self_marker.text = InteractivePlotLibFigure.TextObj( - ax, loc, text, "left", "bottom" - ) - self_marker.text.text_obj.set_bbox( - dict(facecolor="white", alpha=0.5, edgecolor="none") - ) + self_marker.text = InteractivePlotLibFigure.TextObj(ax, loc, text, "left", "bottom") + self_marker.text.text_obj.set_bbox(dict(facecolor="white", alpha=0.5, edgecolor="none")) (self_marker.point,) = ax.plot(loc[0], loc[1], color) setattr(self_marker.point, "InteractivePlotLib_Type", "Marker") plt.pause(0.001) @@ -1918,17 +1723,12 @@ def save(self, unfiltered_variables): info[variable] = unfiltered_variables[variable] if type(info[variable]) is list: for i in range(len(info[variable])): - if ( - str(type(info[variable][i])).split("'")[1].split(".")[0] - == "matplotlib" - ): + if str(type(info[variable][i])).split("'")[1].split(".")[0] == "matplotlib": info[variable][i] = [] info["code"] = code dill.dump( info, - open( - (Data_path + "/scan{}_{}.dat").format(scan_number, current_time), "wb" - ), + open((Data_path + "/scan{}_{}.dat").format(scan_number, current_time), "wb"), ) print(variables) return scan_number @@ -2227,12 +2027,7 @@ def get_xdata_ydata_from_axes(self, line): x_data = np.array(line.get_xdata()) y_data = np.array(line.get_ydata()) - idx = ( - (x_data >= xlim[0]) - & (x_data <= xlim[1]) - & (y_data >= ylim[0]) - & (y_data <= ylim[1]) - ) + idx = (x_data >= xlim[0]) & (x_data <= xlim[1]) & (y_data >= ylim[0]) & (y_data <= ylim[1]) x_data = x_data[idx] y_data = y_data[idx] return x_data, y_data @@ -2276,9 +2071,7 @@ def fit_polygon(self, line, options): self.ddx0 = np.array(np.real([i for i in np.roots(self.ddp) if np.isreal(i)])) self.ddy0 = [self.fit_func(i) for i in self.ddx0] points_of_interest_x = np.hstack([0, self.x0, self.dx0, self.ddx0]) - points_of_interest_y = np.hstack( - [self.y0, [0] * len(self.x0), self.dy0, self.ddy0] - ) + points_of_interest_y = np.hstack([self.y0, [0] * len(self.x0), self.dy0, self.ddy0]) self.plot_points_of_interest(points_of_interest_x, points_of_interest_y) @@ -2406,9 +2199,7 @@ def even_or_odd(func): scale_data_y / popt[3], ] - self.fit_func = ( - lambda x: func((x - output[0]) / output[1]) * output[3] + output[2] - ) + self.fit_func = lambda x: func((x - output[0]) / output[1]) * output[3] + output[2] (l,) = plt.plot(x_data, self.fit_func(x_data), "m", linewidth=2) self.fit_line_obj = l setattr(self.fit_line_obj, "InteractivePlotLib_Type", "Fit") @@ -2421,9 +2212,7 @@ def even_or_odd(func): self.y_scale = output[3] self.y_mid = self.fit_func(0) points_of_interest_x = np.hstack([self.x_shift, 0]) - points_of_interest_y = np.hstack( - [self.fit_func(self.x_shift), self.fit_func(0)] - ) + points_of_interest_y = np.hstack([self.fit_func(self.x_shift), self.fit_func(0)]) self.plot_points_of_interest(points_of_interest_x, points_of_interest_y) try: diff --git a/qualang_tools/addons/calibration/calibrations.py b/qualang_tools/addons/calibration/calibrations.py index e6b69ea8..b574cb88 100644 --- a/qualang_tools/addons/calibration/calibrations.py +++ b/qualang_tools/addons/calibration/calibrations.py @@ -33,19 +33,15 @@ def _check_operation(self, operation, element): if operation in self.config["elements"][element]["operations"]: return True else: - raise Exception( - f"The operation '{operation}' is not in the current config for element '{element}'." - ) + raise Exception(f"The operation '{operation}' is not in the current config for element '{element}'.") def _check_iw(self, int_weights): for iw in int_weights: if ( iw - not in self.config["pulses"][ - self.config["elements"][self.readout_elmt]["operations"][ - self.readout_op - ] - ]["integration_weights"] + not in self.config["pulses"][self.config["elements"][self.readout_elmt]["operations"][self.readout_op]][ + "integration_weights" + ] ): raise Exception( f"The integration weight '{iw}' is not in the current config for operation '{self.readout_op}'." @@ -55,9 +51,7 @@ def _check_iw(self, int_weights): def _check_outputs(self, outputs): for out in outputs: if out not in self.config["elements"][self.readout_elmt]["outputs"]: - raise Exception( - f"The output '{out}' is not in the current config for element '{self.readout_elmt}'." - ) + raise Exception(f"The output '{out}' is not in the current config for element '{self.readout_elmt}'.") return True def _check_plot_options(self, plot_options): @@ -74,9 +68,7 @@ def _check_plot_options(self, plot_options): def _user_variables_checks(self, calibration, scan_variables, iterations): # Check calibration if calibration in self.calibration_list: - raise Exception( - "For the moment, it is not possible to run the same calibration twice in a row." - ) + raise Exception("For the moment, it is not possible to run the same calibration twice in a row.") # Check variables for var in scan_variables: if var[0] not in available_variables: @@ -87,9 +79,7 @@ def _user_variables_checks(self, calibration, scan_variables, iterations): if not (type(iterations) is int and iterations > 0): raise Exception("interations must be a python positive integer.") - def _user_variables_init( - self, calibration, scan_variables, iterations, cooldown_time - ): + def _user_variables_init(self, calibration, scan_variables, iterations, cooldown_time): self.calibration_list.append(calibration) self.results[calibration] = { "scan_variables": [], @@ -111,9 +101,7 @@ def _user_variables_init( elif cooldown_time == 0: self.user_specifics[calibration]["cooldown_time"] = None else: - raise Exception( - "cooldown_time must be a python positive integer larger than 4." - ) + raise Exception("cooldown_time must be a python positive integer larger than 4.") def _get_qua_variables(self, current_calib): n = declare(int) # Averaging index @@ -135,15 +123,9 @@ def _get_qua_variables(self, current_calib): var2_name = var_name elif var_name == "amplitude": if current_calib == "Ramsey": - raise Exception( - "Amplitude scan is not available for Ramsey measurements." - ) - elif ( - current_calib == "Resonator_spec" - ) and self.flux_line_elmt is None: - raise Exception( - "Amplitude scan is not available for resonator spectroscopy without flux line." - ) + raise Exception("Amplitude scan is not available for Ramsey measurements.") + elif (current_calib == "Resonator_spec") and self.flux_line_elmt is None: + raise Exception("Amplitude scan is not available for resonator spectroscopy without flux line.") if var1 is None: var1 = declare(fixed) var1_scan = self.scan_var[current_calib][var_name] @@ -154,19 +136,14 @@ def _get_qua_variables(self, current_calib): var2_name = var_name elif var_name == "duration": if (self.scan_var[current_calib][var_name] < 4).any(): - raise Exception( - "No scanned duration can be lower than 4 clock cycles." - ) + raise Exception("No scanned duration can be lower than 4 clock cycles.") if current_calib in ["Rabi", "Ramsey"]: - pulse = self.config["elements"][self.qubit_elmt]["operations"][ - self.qubit_op - ] + pulse = self.config["elements"][self.qubit_elmt]["operations"][self.qubit_op] for inpt in self.config["pulses"][pulse]["waveforms"]: wf = self.config["pulses"][pulse]["waveforms"][inpt] if self.config["waveforms"][wf]["type"] == "arbitrary": if ( - self.scan_var[current_calib][var_name] - < self.config["pulses"][pulse]["length"] // 4 + self.scan_var[current_calib][var_name] < self.config["pulses"][pulse]["length"] // 4 ).any(): raise Exception( "The scanned duration must be greater than the one defined in the configuration for arbitrary waveforms. Arbitrary waveforms can only be stretched and not compressed on the fly." @@ -261,20 +238,14 @@ def _plot_1d(self, x, amplitude, phase, x_label, title): plt.yticks(fontsize=self.plot_options["fontsize"]) def _get_IQ_data_and_plot(self, job, calib, plot, dim): - pulse = self.config["elements"][self.readout_elmt]["operations"][ - self.readout_op - ] + pulse = self.config["elements"][self.readout_elmt]["operations"][self.readout_op] res_handles = job.result_handles if dim == 1: if plot == "live": - results = fetching_tool( - job, data_list=["I", "Q", "iteration"], mode="live" - ) + results = fetching_tool(job, data_list=["I", "Q", "iteration"], mode="live") # Live plotting fig = plt.figure(figsize=self.plot_options["figsize"]) - interrupt_on_close( - fig, job - ) # Interrupts the job when closing the figure + interrupt_on_close(fig, job) # Interrupts the job when closing the figure while results.is_processing(): I, Q, iteration = results.fetch_all() I = u.demod2volts(I, self.config["pulses"][pulse]["length"]) @@ -287,9 +258,7 @@ def _get_IQ_data_and_plot(self, job, calib, plot, dim): ) self.results[calib]["amplitude"] = np.sqrt(I**2 + Q**2) - self.results[calib]["phase"] = signal.detrend( - np.unwrap(np.angle(I + 1j * Q)) - ) + self.results[calib]["phase"] = signal.detrend(np.unwrap(np.angle(I + 1j * Q))) self._plot_1d( x=self.scan_var[calib][list(self.scan_var[calib].keys())[0]], @@ -312,9 +281,7 @@ def _get_IQ_data_and_plot(self, job, calib, plot, dim): ) self.results[calib]["amplitude"] = np.sqrt(I**2 + Q**2) - self.results[calib]["phase"] = signal.detrend( - np.unwrap(np.angle(I + 1j * Q)) - ) + self.results[calib]["phase"] = signal.detrend(np.unwrap(np.angle(I + 1j * Q))) if plot == "full": plt.figure(figsize=self.plot_options["figsize"]) @@ -328,15 +295,11 @@ def _get_IQ_data_and_plot(self, job, calib, plot, dim): elif dim == 2: res_handles = job.result_handles if plot == "live": - results = fetching_tool( - job, data_list=["I", "Q", "iteration"], mode="live" - ) + results = fetching_tool(job, data_list=["I", "Q", "iteration"], mode="live") # Live plotting fig = plt.figure(figsize=self.plot_options["figsize"]) - interrupt_on_close( - fig, job - ) # Interrupts the job when closing the figure + interrupt_on_close(fig, job) # Interrupts the job when closing the figure while results.is_processing(): I, Q, iteration = results.fetch_all() I = u.demod2volts(I, self.config["pulses"][pulse]["length"]) @@ -349,9 +312,7 @@ def _get_IQ_data_and_plot(self, job, calib, plot, dim): ) self.results[calib]["amplitude"] = np.sqrt(I**2 + Q**2) - self.results[calib]["phase"] = signal.detrend( - np.unwrap(np.angle(I + 1j * Q)) - ) + self.results[calib]["phase"] = signal.detrend(np.unwrap(np.angle(I + 1j * Q))) self._plot_2d( x=self.scan_var[calib][list(self.scan_var[calib].keys())[0]], @@ -375,9 +336,7 @@ def _get_IQ_data_and_plot(self, job, calib, plot, dim): ) self.results[calib]["amplitude"] = np.sqrt(I**2 + Q**2) - self.results[calib]["phase"] = signal.detrend( - np.unwrap(np.angle(I + 1j * Q)) - ) + self.results[calib]["phase"] = signal.detrend(np.unwrap(np.angle(I + 1j * Q))) if plot == "full": plt.figure(figsize=self.plot_options["figsize"]) @@ -453,9 +412,7 @@ def __init__( "figsize": (12, 15), } - def set_resonator_spectroscopy( - self, scan_variables, iterations=1, cooldown_time=None - ): + def set_resonator_spectroscopy(self, scan_variables, iterations=1, cooldown_time=None): """Sets the resonator spectroscopy calibration. This program will measure the resonator response for different readout pulse frequencies defined in scan_variables. @@ -466,9 +423,7 @@ def set_resonator_spectroscopy( """ calibration = "Resonator_spec" self._user_variables_checks(calibration, scan_variables, iterations) - self._user_variables_init( - calibration, scan_variables, iterations, cooldown_time - ) + self._user_variables_init(calibration, scan_variables, iterations, cooldown_time) def set_rabi(self, scan_variables, iterations=1, cooldown_time=None): """Performs a Rabi-like measurement by sending a pulse to the qubit and measuring the resonator response. @@ -484,9 +439,7 @@ def set_rabi(self, scan_variables, iterations=1, cooldown_time=None): """ calibration = "Rabi" self._user_variables_checks(calibration, scan_variables, iterations) - self._user_variables_init( - calibration, scan_variables, iterations, cooldown_time - ) + self._user_variables_init(calibration, scan_variables, iterations, cooldown_time) def set_T1(self, scan_variables, iterations=1, cooldown_time=None): """Performs a T1 measurement by sending a pi-pulse to the qubit and measuring the resonator response after a varying time. @@ -500,15 +453,11 @@ def set_T1(self, scan_variables, iterations=1, cooldown_time=None): """ calibration = "T1" self._user_variables_checks(calibration, scan_variables, iterations) - self._user_variables_init( - calibration, scan_variables, iterations, cooldown_time - ) + self._user_variables_init(calibration, scan_variables, iterations, cooldown_time) if (len(scan_variables) > 1) or (scan_variables[0][0] != "duration"): raise Exception("Only 'duration' scans are available for T1 calibration.") - def set_ramsey( - self, scan_variables, iterations=1, cooldown_time=None, idle_time=None - ): + def set_ramsey(self, scan_variables, iterations=1, cooldown_time=None, idle_time=None): """Performs a Ramsey-like measurement (pi/2 - idle time - pi/2). The available scanning parameters are: 'duration' (idle time in clock cycles unit (4 ns)), @@ -522,18 +471,14 @@ def set_ramsey( """ calibration = "Ramsey" self._user_variables_checks(calibration, scan_variables, iterations) - self._user_variables_init( - calibration, scan_variables, iterations, cooldown_time - ) + self._user_variables_init(calibration, scan_variables, iterations, cooldown_time) # Check idle time if idle_time is None or (idle_time >= 4 and type(idle_time) is int): self.user_specifics[calibration]["idle_time"] = idle_time elif cooldown_time == 0: self.user_specifics[calibration]["cooldown_time"] = None else: - raise Exception( - "idle_time must be 0 or a python positive integer larger than 4." - ) + raise Exception("idle_time must be 0 or a python positive integer larger than 4.") def set_raw_traces(self, scan_variables=(), iterations=1, cooldown_time=None): """Acquires the raw and averaged traces from the two inputs of the OPX. @@ -545,13 +490,9 @@ def set_raw_traces(self, scan_variables=(), iterations=1, cooldown_time=None): """ calibration = "raw_traces" self._user_variables_checks(calibration, scan_variables, iterations) - self._user_variables_init( - calibration, scan_variables, iterations, cooldown_time - ) + self._user_variables_init(calibration, scan_variables, iterations, cooldown_time) - def set_time_of_flight( - self, scan_variables=(), iterations=1, cooldown_time=None, threshold=10 / 4096 - ): + def set_time_of_flight(self, scan_variables=(), iterations=1, cooldown_time=None, threshold=10 / 4096): """Measures the time of flight and offsets of the two inputs of the OPX. :param scan_variables: None @@ -562,14 +503,10 @@ def set_time_of_flight( """ calibration = "time_of_flight" self._user_variables_checks(calibration, scan_variables, iterations) - self._user_variables_init( - calibration, scan_variables, iterations, cooldown_time - ) + self._user_variables_init(calibration, scan_variables, iterations, cooldown_time) self.user_specifics[calibration]["threshold"] = threshold - def run_calibrations( - self, quantum_machine, plot=None, fits=False, plot_options=None - ): + def run_calibrations(self, quantum_machine, plot=None, fits=False, plot_options=None): """Execute the implemented calibrations. :param quantum_machine: @@ -629,9 +566,7 @@ def simulate_calibrations(self, machine, simulation_duration): elif calib == "Ramsey": prog = self._ramsey(scan_dimension=len(self.scan_var[calib]) - 1) elif calib == "Resonator_spec": - prog = self._resonator_spec( - scan_dimension=len(self.scan_var[calib]) - 1 - ) + prog = self._resonator_spec(scan_dimension=len(self.scan_var[calib]) - 1) elif calib == "raw_traces": prog = self._raw_traces() elif calib == "time_of_flight": @@ -643,9 +578,7 @@ def simulate_calibrations(self, machine, simulation_duration): elif isinstance(machine, QuantumMachine): job = machine.simulate(prog, simulation_config) else: - raise Exception( - "'machine' must be either a QuantumMachine or a QuantumMachinesManager instance." - ) + raise Exception("'machine' must be either a QuantumMachine or a QuantumMachinesManager instance.") plt.figure() job.get_simulated_samples().con1.plot() self.simulation = False @@ -660,12 +593,8 @@ def _resonator_spec(self, scan_dimension, plot=False, fits=False): raise Exception( "Amplitude scan of the resonator spectroscopy is only implemented for flux tunable transmons so please provide the flux line element." ) - elif var1_name != "frequency" or ( - var1_name == "amplitude" and self.flux_line_elmt is None - ): - raise Exception( - "Resonator spectroscopy is only implemented for frequency scan." - ) + elif var1_name != "frequency" or (var1_name == "amplitude" and self.flux_line_elmt is None): + raise Exception("Resonator spectroscopy is only implemented for frequency scan.") I = declare(fixed) Q = declare(fixed) @@ -684,9 +613,7 @@ def _resonator_spec(self, scan_dimension, plot=False, fits=False): if var1_name == "frequency": update_frequency(self.readout_elmt, var1) # Align, measure and save data - self._align_measure_save( - I, Q, I_st, Q_st, calib, align_flag=False - ) + self._align_measure_save(I, Q, I_st, Q_st, calib, align_flag=False) save(n, n_st) with stream_processing(): @@ -738,18 +665,12 @@ def _resonator_spec(self, scan_dimension, plot=False, fits=False): elif var2_name == "frequency": update_frequency(self.readout_elmt, var2) # Align, measure and save data - self._align_measure_save( - I, Q, I_st, Q_st, calib, align_flag=False - ) + self._align_measure_save(I, Q, I_st, Q_st, calib, align_flag=False) save(n, n_st) with stream_processing(): - I_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save( - "I" - ) - Q_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save( - "Q" - ) + I_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save("I") + Q_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save("Q") n_st.save("iteration") if self.simulation: @@ -851,12 +772,8 @@ def _rabi(self, scan_dimension, plot=False, fits=False): save(n, n_st) with stream_processing(): - I_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save( - "I" - ) - Q_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save( - "Q" - ) + I_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save("I") + Q_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save("Q") n_st.save("iteration") if self.simulation: @@ -921,9 +838,7 @@ def _ramsey(self, scan_dimension, plot=False, fits=False): if var1_name == "duration": wait(var1, self.qubit_elmt) elif self.user_specifics[calib]["idle_time"] is not None: - wait( - self.user_specifics[calib]["idle_time"], self.qubit_elmt - ) + wait(self.user_specifics[calib]["idle_time"], self.qubit_elmt) # Second pi/2 pulse play(self.qubit_op, self.qubit_elmt) # Align, measure and save data @@ -988,12 +903,8 @@ def _ramsey(self, scan_dimension, plot=False, fits=False): save(n, n_st) with stream_processing(): - I_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save( - "I" - ) - Q_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save( - "Q" - ) + I_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save("I") + Q_st.buffer(len(var1_scan)).buffer(len(var2_scan)).average().save("Q") n_st.save("iteration") if self.simulation: @@ -1047,12 +958,8 @@ def _raw_traces(self, plot=False): while res_handles.is_processing(): adc1 = u.raw2volts(res_handles.get("adc1").fetch_all()) adc2 = u.raw2volts(res_handles.get("adc2").fetch_all()) - adc1_single_run = u.raw2volts( - res_handles.get("adc1_single_run").fetch_all() - ) - adc2_single_run = u.raw2volts( - res_handles.get("adc2_single_run").fetch_all() - ) + adc1_single_run = u.raw2volts(res_handles.get("adc1_single_run").fetch_all()) + adc2_single_run = u.raw2volts(res_handles.get("adc2_single_run").fetch_all()) self.results[calib]["adc1"] = {"raw": adc1_single_run, "averaged": adc1} self.results[calib]["adc2"] = {"raw": adc2_single_run, "averaged": adc2} @@ -1066,29 +973,21 @@ def _raw_traces(self, plot=False): plt.plot(adc1_single_run, "b") plt.plot(adc2_single_run, "r") plt.xlabel("Time [ns]", fontsize=self.plot_options["fontsize"]) - plt.ylabel( - "Signal amplitude [V]", fontsize=self.plot_options["fontsize"] - ) + plt.ylabel("Signal amplitude [V]", fontsize=self.plot_options["fontsize"]) plt.subplot(122) plt.cla() plt.title("Averaged run", fontsize=self.plot_options["fontsize"] + 2) plt.plot(adc1, "b") plt.plot(adc2, "r") plt.xlabel("Time [ns]", fontsize=self.plot_options["fontsize"]) - plt.ylabel( - "Signal amplitude [V]", fontsize=self.plot_options["fontsize"] - ) + plt.ylabel("Signal amplitude [V]", fontsize=self.plot_options["fontsize"]) plt.pause(0.01) else: res_handles.wait_for_all_values() adc1 = u.raw2volts(res_handles.get("adc1").fetch_all()) adc2 = u.raw2volts(res_handles.get("adc2").fetch_all()) - adc1_single_run = u.raw2volts( - res_handles.get("adc1_single_run").fetch_all() - ) - adc2_single_run = u.raw2volts( - res_handles.get("adc2_single_run").fetch_all() - ) + adc1_single_run = u.raw2volts(res_handles.get("adc1_single_run").fetch_all()) + adc2_single_run = u.raw2volts(res_handles.get("adc2_single_run").fetch_all()) self.results[calib]["adc1"] = {"raw": adc1_single_run, "averaged": adc1} self.results[calib]["adc2"] = {"raw": adc2_single_run, "averaged": adc2} @@ -1103,17 +1002,13 @@ def _raw_traces(self, plot=False): plt.plot(adc1_single_run, "b") plt.plot(adc2_single_run, "r") plt.xlabel("Time [ns]", fontsize=self.plot_options["fontsize"]) - plt.ylabel( - "Signal amplitude [V]", fontsize=self.plot_options["fontsize"] - ) + plt.ylabel("Signal amplitude [V]", fontsize=self.plot_options["fontsize"]) plt.subplot(122) plt.title("Averaged run", fontsize=self.plot_options["fontsize"] + 2) plt.plot(adc1, "b") plt.plot(adc2, "r") plt.xlabel("Time [ns]", fontsize=self.plot_options["fontsize"]) - plt.ylabel( - "Signal amplitude [V]", fontsize=self.plot_options["fontsize"] - ) + plt.ylabel("Signal amplitude [V]", fontsize=self.plot_options["fontsize"]) def _time_of_flight(self, plot=False): calib = "time_of_flight" @@ -1141,9 +1036,7 @@ def _time_of_flight(self, plot=False): res_handles = job.result_handles if plot == "live": - raise Exception( - "Live plotting is not available for time of flight calibration" - ) + raise Exception("Live plotting is not available for time of flight calibration") else: adc1 = None adc2 = None @@ -1154,21 +1047,8 @@ def _time_of_flight(self, plot=False): adc1 = u.raw2volts(res_handles.get("adc1").fetch_all()) self.results[calib]["adc1"] = adc1 # Find the pulse edge and derive tof - if ( - len( - np.where( - np.abs(np.diff(adc1)) - > self.user_specifics[calib]["threshold"] - )[0] - ) - > 0 - ): - tof1 = np.min( - np.where( - np.abs(np.diff(adc1)) - > self.user_specifics[calib]["threshold"] - ) - ) + if len(np.where(np.abs(np.diff(adc1)) > self.user_specifics[calib]["threshold"])[0]) > 0: + tof1 = np.min(np.where(np.abs(np.diff(adc1)) > self.user_specifics[calib]["threshold"])) print(f"TOF to add = {tof1} ns for out1") else: tof1 = None @@ -1177,21 +1057,8 @@ def _time_of_flight(self, plot=False): adc2 = u.raw2volts(res_handles.get("adc2").fetch_all()) self.results[calib]["adc2"] = adc2 # Find the pulse edge and derive tof - if ( - len( - np.where( - np.abs(np.diff(adc2)) - > self.user_specifics[calib]["threshold"] - )[0] - ) - > 0 - ): - tof2 = np.min( - np.where( - np.abs(np.diff(adc2)) - > self.user_specifics[calib]["threshold"] - ) - ) + if len(np.where(np.abs(np.diff(adc2)) > self.user_specifics[calib]["threshold"])[0]) > 0: + tof2 = np.min(np.where(np.abs(np.diff(adc2)) > self.user_specifics[calib]["threshold"])) print(f"TOF to add = {tof2} ns for out2") else: tof2 = None @@ -1219,7 +1086,5 @@ def _time_of_flight(self, plot=False): plt.axvline(x=tof2, color="r", linestyle=":") plt.axhline(y=np.mean(adc2[:tof2]), color="r", linestyle="--") plt.xlabel("Time [ns]", fontsize=self.plot_options["fontsize"]) - plt.ylabel( - "Signal amplitude [V]", fontsize=self.plot_options["fontsize"] - ) + plt.ylabel("Signal amplitude [V]", fontsize=self.plot_options["fontsize"]) plt.legend() diff --git a/qualang_tools/bakery/bakery.py b/qualang_tools/bakery/bakery.py index 5a0ce566..497555cf 100644 --- a/qualang_tools/bakery/bakery.py +++ b/qualang_tools/bakery/bakery.py @@ -73,8 +73,7 @@ def __init__( self.override = override if override and sampling_rate < 1e9: raise ValueError( - "Waveform can not be simultaneously overridable and compressed with lower than 1e9" - "sampling rate" + "Waveform can not be simultaneously overridable and compressed with lower than 1e9" "sampling rate" ) self.length_constraint = self._retrieve_constraint_length(baking_index) self.override_waveforms_dict = {"waveforms": {}} @@ -131,10 +130,7 @@ def _init_dict(self): "freq": 0, "time_track": 0, # Value used for negative waits, to know where to add the samples (negative int) } - if ( - "mixInputs" in self._local_config["elements"][qe] - or "RF_inputs" in self._local_config["elements"][qe] - ): + if "mixInputs" in self._local_config["elements"][qe] or "RF_inputs" in self._local_config["elements"][qe]: sample_dict[qe] = {"I": [], "Q": []} elif "singleInput" in self._local_config["elements"][qe]: @@ -145,9 +141,7 @@ def _init_dict(self): def _update_config(self, qe, qe_samples) -> None: # Generates new Op, pulse, and waveform for each qe to be added in the original config file - self._config["elements"][qe]["operations"][ - f"baked_Op_{self._ctr}" - ] = f"{qe}_baked_pulse_{self._ctr}" + self._config["elements"][qe]["operations"][f"baked_Op_{self._ctr}"] = f"{qe}_baked_pulse_{self._ctr}" if "I" in qe_samples: self._config["pulses"][f"{qe}_baked_pulse_{self._ctr}"] = { "operation": "control", @@ -168,12 +162,8 @@ def _update_config(self, qe, qe_samples) -> None: "is_overridable": self.override, } if self.sampling_rate < int(1e9): - self._config["waveforms"][f"{qe}_baked_wf_I_{self._ctr}"][ - "sampling_rate" - ] = self.sampling_rate - self._config["waveforms"][f"{qe}_baked_wf_Q_{self._ctr}"][ - "sampling_rate" - ] = self.sampling_rate + self._config["waveforms"][f"{qe}_baked_wf_I_{self._ctr}"]["sampling_rate"] = self.sampling_rate + self._config["waveforms"][f"{qe}_baked_wf_Q_{self._ctr}"]["sampling_rate"] = self.sampling_rate elif "single" in qe_samples: self._config["pulses"][f"{qe}_baked_pulse_{self._ctr}"] = { "operation": "control", @@ -186,23 +176,21 @@ def _update_config(self, qe, qe_samples) -> None: "is_overridable": self.override, } if self.sampling_rate < int(1e9): - self._config["waveforms"][f"{qe}_baked_wf_{self._ctr}"][ - "sampling_rate" - ] = self.sampling_rate + self._config["waveforms"][f"{qe}_baked_wf_{self._ctr}"]["sampling_rate"] = self.sampling_rate if len(self._digital_samples_dict[qe]) != 0: self._config["pulses"][f"{qe}_baked_pulse_{self._ctr}"][ "digital_marker" ] = f"{qe}_baked_digital_wf_{self._ctr}" if "digital_waveforms" in self._config: - self._config["digital_waveforms"][ - f"{qe}_baked_digital_wf_{self._ctr}" - ] = {"samples": self._digital_samples_dict[qe]} + self._config["digital_waveforms"][f"{qe}_baked_digital_wf_{self._ctr}"] = { + "samples": self._digital_samples_dict[qe] + } else: self._config["digital_waveforms"] = {} - self._config["digital_waveforms"][ - f"{qe}_baked_digital_wf_{self._ctr}" - ] = {"samples": self._digital_samples_dict[qe]} + self._config["digital_waveforms"][f"{qe}_baked_digital_wf_{self._ctr}"] = { + "samples": self._digital_samples_dict[qe] + } def __exit__(self, exc_type, exc_value, exc_traceback): """ @@ -216,9 +204,7 @@ def __exit__(self, exc_type, exc_value, exc_traceback): wait_duration = 0 # Stores the duration that has to be padded with 0s to make a valid sample for QUA # in original config file - if ( - self._qe_dict[qe]["time"] > 0 - ): # Check if sample was added to the quantum element + if self._qe_dict[qe]["time"] > 0: # Check if sample was added to the quantum element # otherwise we do not add any Op self._qe_set.add(qe) qe_samples = self._samples_dict[qe] @@ -252,14 +238,10 @@ def __exit__(self, exc_type, exc_value, exc_traceback): ) wait_duration += self.length_constraint - self._qe_dict[qe]["time"] self.wait(self.length_constraint - self._qe_dict[qe]["time"], qe) - if ( - self._qe_dict[qe]["time"] < 16 - ): # Sample length must be at least 16 ns long + if self._qe_dict[qe]["time"] < 16: # Sample length must be at least 16 ns long wait_duration += 16 - self._qe_dict[qe]["time"] self.wait(16 - self._qe_dict[qe]["time"], qe) - if ( - not self._qe_dict[qe]["time"] % 4 == 0 - ): # Sample length must be a multiple of 4 + if not self._qe_dict[qe]["time"] % 4 == 0: # Sample length must be a multiple of 4 wait_duration += 4 - self._qe_dict[qe]["time"] % 4 self.wait(4 - self._qe_dict[qe]["time"] % 4, qe) @@ -284,19 +266,10 @@ def __exit__(self, exc_type, exc_value, exc_traceback): elif self._padding_method == "left": if "mixInputs" in elements[qe] or "RF_inputs" in elements[qe]: - qe_samples["I"] = ( - qe_samples["I"][end_samples:] - + qe_samples["I"][0:end_samples] - ) - qe_samples["Q"] = ( - qe_samples["Q"][end_samples:] - + qe_samples["Q"][0:end_samples] - ) + qe_samples["I"] = qe_samples["I"][end_samples:] + qe_samples["I"][0:end_samples] + qe_samples["Q"] = qe_samples["Q"][end_samples:] + qe_samples["Q"][0:end_samples] elif "singleInput" in elements[qe]: - qe_samples["single"] = ( - qe_samples["single"][end_samples:] - + qe_samples["single"][0:end_samples] - ) + qe_samples["single"] = qe_samples["single"][end_samples:] + qe_samples["single"][0:end_samples] elif self._padding_method == "symmetric_l" or ( self._padding_method == "symmetric_r" and wait_duration % 2 == 0 @@ -331,26 +304,18 @@ def __exit__(self, exc_type, exc_value, exc_traceback): elif "singleInput" in elements[qe]: qe_samples["single"] = ( qe_samples["single"][end_samples + wait_duration // 2 + 1 :] - + qe_samples["single"][ - 0 : end_samples + wait_duration // 2 + 1 - ] + + qe_samples["single"][0 : end_samples + wait_duration // 2 + 1] ) if self.update_config: self._update_config(qe, qe_samples) if "mixInputs" in elements[qe] or "RF_inputs" in elements[qe]: - self.override_waveforms_dict["waveforms"][ - f"{qe}_baked_wf_I_{self._ctr}" - ] = qe_samples["I"] - self.override_waveforms_dict["waveforms"][ - f"{qe}_baked_wf_Q_{self._ctr}" - ] = qe_samples["Q"] + self.override_waveforms_dict["waveforms"][f"{qe}_baked_wf_I_{self._ctr}"] = qe_samples["I"] + self.override_waveforms_dict["waveforms"][f"{qe}_baked_wf_Q_{self._ctr}"] = qe_samples["Q"] elif "singleInput" in elements[qe]: - self.override_waveforms_dict["waveforms"][ - f"{qe}_baked_wf_{self._ctr}" - ] = qe_samples["single"] + self.override_waveforms_dict["waveforms"][f"{qe}_baked_wf_{self._ctr}"] = qe_samples["single"] def is_out(self): return self._out @@ -414,15 +379,11 @@ def _get_samples(self, pulse: str) -> Union[List[float], List[List[float]]]: wf_I = pulses[pulse]["waveforms"]["I"] wf_Q = pulses[pulse]["waveforms"]["Q"] if waveforms[wf_I]["type"] == "constant": - samples_I = [waveforms[wf_I]["sample"]] * pulses[pulse][ - "length" - ] + samples_I = [waveforms[wf_I]["sample"]] * pulses[pulse]["length"] else: samples_I = list(waveforms[wf_I]["samples"]) if waveforms[wf_Q]["type"] == "constant": - samples_Q = [waveforms[wf_Q]["sample"]] * pulses[pulse][ - "length" - ] + samples_Q = [waveforms[wf_Q]["sample"]] * pulses[pulse]["length"] else: samples_Q = list(waveforms[wf_Q]["samples"]) return [samples_I, samples_Q] @@ -451,17 +412,12 @@ def get_current_length(self, qe: Optional[str] = None) -> int: max_length = length return max_length else: - if ( - "mixInputs" in self._local_config["elements"][qe] - or "RF_inputs" in self._local_config["elements"][qe] - ): + if "mixInputs" in self._local_config["elements"][qe] or "RF_inputs" in self._local_config["elements"][qe]: return len(self._samples_dict[qe]["I"]) elif "singleInput" in self._local_config["elements"][qe]: return len(self._samples_dict[qe]["single"]) else: - raise KeyError( - "Element not in the config or does not have any analog input." - ) + raise KeyError("Element not in the config or does not have any analog input.") def _get_pulse_index(self, qe) -> int: index = 0 @@ -527,30 +483,20 @@ def delete_for_el(qe_internal, t_start_internal, t_stop_internal): for i in input_type: del self._samples_dict[qe_internal][i][t_start_internal:] else: - raise ValueError( - "Desired deletion exceeds current waveform length" - ) + raise ValueError("Desired deletion exceeds current waveform length") else: if t_stop_internal is None: t_stop_internal = ref_length if t_stop_internal > ref_length: - raise ValueError( - "Desired deletion exceeds current waveform length" - ) + raise ValueError("Desired deletion exceeds current waveform length") if t_start_internal > ref_length: - raise ValueError( - "t_start is higher than current waveform length" - ) + raise ValueError("t_start is higher than current waveform length") if t_start_internal > t_stop_internal: raise ValueError("t_stop is smaller than t_start") - self._update_qe_time( - qe_internal, t_start_internal - t_stop_internal - ) + self._update_qe_time(qe_internal, t_start_internal - t_stop_internal) for i in input_type: - del self._samples_dict[qe_internal][i][ - t_start_internal:t_stop_internal - ] + del self._samples_dict[qe_internal][i][t_start_internal:t_stop_internal] if not self._out: if qe is not None: @@ -564,8 +510,7 @@ def delete_for_el(qe_internal, t_start_internal, t_stop_internal): delete_for_el(q, t_start, t_stop) else: raise Warning( - "Cannot delete samples whe outside of the baking context manager, use delete_baked_Op " - "instead" + "Cannot delete samples whe outside of the baking context manager, use delete_baked_Op " "instead" ) def delete_baked_op(self, *qe_set: str) -> None: @@ -581,30 +526,17 @@ def delete_baked_op(self, *qe_set: str) -> None: def remove_op(q): if self.length_constraint is None: if self._out: - if ( - f"baked_Op_{self._ctr}" - in self.config["elements"][q]["operations"] - ): - del self.config["elements"][q]["operations"][ - f"baked_Op_{self._ctr}" - ] + if f"baked_Op_{self._ctr}" in self.config["elements"][q]["operations"]: + del self.config["elements"][q]["operations"][f"baked_Op_{self._ctr}"] del self.config["pulses"][f"{q}_baked_pulse_{self._ctr}"] - if ( - "mixInputs" in self.config["elements"][q] - or "RF_inputs" in self.config["elements"][q] - ): + if "mixInputs" in self.config["elements"][q] or "RF_inputs" in self.config["elements"][q]: del self.config["waveforms"][f"{q}_baked_wf_I_{self._ctr}"] del self.config["waveforms"][f"{q}_baked_wf_Q_{self._ctr}"] elif "singleInput" in self.config["elements"][q]: del self.config["waveforms"][f"{q}_baked_wf_{self._ctr}"] if "digital_waveforms" in self._config: - if ( - f"{q}_baked_digital_wf_{self._ctr}" - in self._config["digital_waveforms"] - ): - del self.config["digital_waveforms"][ - f"{q}_baked_digital_wf_{self._ctr}" - ] + if f"{q}_baked_digital_wf_{self._ctr}" in self._config["digital_waveforms"]: + del self.config["digital_waveforms"][f"{q}_baked_digital_wf_{self._ctr}"] else: raise KeyError( @@ -612,9 +544,7 @@ def remove_op(q): "(config is updated at the exit)" ) else: - raise Warning( - "Operation could not be deleted because baking object does not update the config" - ) + raise Warning("Operation could not be deleted because baking object does not update the config") if len(qe_set) != 0: for qe in qe_set: @@ -631,9 +561,7 @@ def get_op_name(self, qe: str) -> str: :returns: Name of baked operation associated to element qe """ if not (qe in self._qe_set): - raise KeyError( - f"{qe} is not in the set of quantum elements of the baking object " - ) + raise KeyError(f"{qe} is not in the set of quantum elements of the baking object ") else: return f"baked_Op_{self._ctr}" @@ -649,25 +577,12 @@ def get_op_length(self, qe: Optional[str] = None) -> int: if qe is not None: if self.update_config and self._out: if not (qe in self._qe_set): - raise KeyError( - f"{qe} is not in the set of quantum elements of the baking object " - ) + raise KeyError(f"{qe} is not in the set of quantum elements of the baking object ") else: - if ( - "mixInputs" in self._config["elements"][qe] - or "RF_inputs" in self._config["elements"][qe] - ): - return len( - self._config["waveforms"][f"{qe}_baked_wf_I_{self._ctr}"][ - "samples" - ] - ) + if "mixInputs" in self._config["elements"][qe] or "RF_inputs" in self._config["elements"][qe]: + return len(self._config["waveforms"][f"{qe}_baked_wf_I_{self._ctr}"]["samples"]) else: - return len( - self._config["waveforms"][f"{qe}_baked_wf_{self._ctr}"][ - "samples" - ] - ) + return len(self._config["waveforms"][f"{qe}_baked_wf_{self._ctr}"]["samples"]) else: return self.get_current_length(qe) @@ -726,13 +641,8 @@ def add_op( index = self._get_pulse_index(qe) Op = {name: f"{qe}_baked_pulse_b{self._ctr}_{index}"} - if ( - "mixInputs" in self._local_config["elements"][qe] - or "RF_inputs" in self._local_config["elements"][qe] - ): - assert ( - len(samples) == 2 - ), f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" + if "mixInputs" in self._local_config["elements"][qe] or "RF_inputs" in self._local_config["elements"][qe]: + assert len(samples) == 2, f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" assert len(samples[0]) == len( samples[1] ), "Error : samples provided for I and Q do not have the same length" @@ -748,9 +658,7 @@ def add_op( } } if digital_marker is not None: - pulse[f"{qe}_baked_pulse_b{self._ctr}_{index}"][ - "digital_marker" - ] = digital_marker + pulse[f"{qe}_baked_pulse_b{self._ctr}_{index}"]["digital_marker"] = digital_marker waveform = { f"{qe}_baked_b{self._ctr}_{index}_wf_I": { @@ -778,9 +686,7 @@ def add_op( } if digital_marker is not None: - pulse[f"{qe}_baked_pulse_b{self._ctr}_{index}"][ - "digital_marker" - ] = digital_marker + pulse[f"{qe}_baked_pulse_b{self._ctr}_{index}"]["digital_marker"] = digital_marker waveform = { f"{qe}_baked_b{self._ctr}_{index}_wf": { "type": "arbitrary", @@ -817,9 +723,7 @@ def play(self, Op: str, qe: str, amp: Union[float, Tuple[float]] = 1.0) -> None: assert isinstance( samples, list ), f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" - assert ( - len(samples) == 2 - ), f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" + assert len(samples) == 2, f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" assert type(samples[0] == list) and type( samples[1] == list ), f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" @@ -841,20 +745,12 @@ def play(self, Op: str, qe: str, amp: Union[float, Tuple[float]] = 1.0) -> None: I2[i] = amp * I[i] Q2[i] = amp * Q[i] elif len(amp) != 4 or type(amp) != tuple: - raise IndexError( - "Amplitudes provided must be stored in a tuple (v00, v01, v10, v11)" - ) + raise IndexError("Amplitudes provided must be stored in a tuple (v00, v01, v10, v11)") else: I2[i] = amp[0] * I[i] + amp[1] * Q[i] Q2[i] = amp[2] * I[i] + amp[3] * Q[i] - I3[i] = ( - np.cos(freq * i * 1e-9 + phi) * I2[i] - - np.sin(freq * i * 1e-9 + phi) * Q2[i] - ) - Q3[i] = ( - np.sin(freq * i * 1e-9 + phi) * I2[i] - + np.cos(freq * i * 1e-9 + phi) * Q2[i] - ) + I3[i] = np.cos(freq * i * 1e-9 + phi) * I2[i] - np.sin(freq * i * 1e-9 + phi) * Q2[i] + Q3[i] = np.sin(freq * i * 1e-9 + phi) * I2[i] + np.cos(freq * i * 1e-9 + phi) * Q2[i] self._samples_dict[qe]["I"].append(I3[i]) self._samples_dict[qe]["Q"].append(Q3[i]) self._update_qe_time(qe, len(I)) @@ -864,21 +760,15 @@ def play(self, Op: str, qe: str, amp: Union[float, Tuple[float]] = 1.0) -> None: assert ( type(samples[i]) == float or type(samples[i]) == int ), f"{qe} is a singleInput element, list of numbers (int or float) should be provided " - self._samples_dict[qe]["single"].append( - amp * np.cos(freq * i * 1e-9 + phi) * samples[i] - ) + self._samples_dict[qe]["single"].append(amp * np.cos(freq * i * 1e-9 + phi) * samples[i]) self._update_qe_time(qe, len(samples)) else: raise ValueError("Element provided does not have any analog input") # Update of digital waveform if "digital_marker" in self._local_config["pulses"][pulse]: - digital_marker = self._local_config["pulses"][pulse][ - "digital_marker" - ] - digital_waveform = self._local_config["digital_waveforms"][ - digital_marker - ]["samples"] + digital_marker = self._local_config["pulses"][pulse]["digital_marker"] + digital_waveform = self._local_config["digital_waveforms"][digital_marker]["samples"] self._digital_samples_dict[qe] += digital_waveform else: @@ -886,13 +776,9 @@ def play(self, Op: str, qe: str, amp: Union[float, Tuple[float]] = 1.0) -> None: self._qe_dict[qe]["time_track"] = 0 except KeyError: - raise KeyError( - f'Op:"{Op}" does not exist in configuration and not manually added (use add_pulse)' - ) + raise KeyError(f'Op:"{Op}" does not exist in configuration and not manually added (use add_pulse)') - def play_at( - self, Op: str, qe: str, t: int, amp: Union[float, Tuple[float]] = 1.0 - ) -> None: + def play_at(self, Op: str, qe: str, t: int, amp: Union[float, Tuple[float]] = 1.0) -> None: """ Add a waveform to the sequence at the specified time index. If t is higher than pulse duration for the specified quantum element, @@ -931,12 +817,9 @@ def play_at( assert isinstance( samples, list ), f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" - assert ( - len(samples) == 2 - ), f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" + assert len(samples) == 2, f"{qe} is a mixInputs/RF_inputs element, two lists should be provided" assert type(samples[0] == list) and type(samples[1] == list), ( - f"{qe} is a mixInputs/RF_inputs element, " - f"two lists should be provided" + f"{qe} is a mixInputs/RF_inputs element, " f"two lists should be provided" ) assert len(samples[0]) == len( @@ -956,9 +839,7 @@ def play_at( Q2[i] = amp * Q[i] else: if len(amp) != 4 or type(amp) != tuple: - raise IndexError( - "Amplitudes provided must be stored in a tuple (v00, v01, v10, v11)" - ) + raise IndexError("Amplitudes provided must be stored in a tuple (v00, v01, v10, v11)") else: I2[i] = amp[0] * I[i] + amp[1] * Q[i] Q2[i] = amp[2] * I[i] + amp[3] * Q[i] @@ -975,14 +856,8 @@ def play_at( self._samples_dict[qe]["I"][t + i] += I3[i] self._samples_dict[qe]["Q"][t + i] += Q3[i] else: - I3[i] = ( - np.cos(freq * i * 1e-9 + phi) * I2[i] - - np.sin(freq * i * 1e-9 + phi) * Q2[i] - ) - Q3[i] = ( - np.sin(freq * i * 1e-9 + phi) * I2[i] - + np.cos(freq * i * 1e-9 + phi) * Q2[i] - ) + I3[i] = np.cos(freq * i * 1e-9 + phi) * I2[i] - np.sin(freq * i * 1e-9 + phi) * Q2[i] + Q3[i] = np.sin(freq * i * 1e-9 + phi) * I2[i] + np.cos(freq * i * 1e-9 + phi) * Q2[i] self._samples_dict[qe]["I"].append(I3[i]) self._samples_dict[qe]["Q"].append(Q3[i]) @@ -1009,9 +884,7 @@ def play_at( self._update_qe_time(qe, new_samples) except KeyError: - raise KeyError( - f'Op:"{Op}" does not exist in configuration and not manually added (use add_pulse)' - ) + raise KeyError(f'Op:"{Op}" does not exist in configuration and not manually added (use add_pulse)') def frame_rotation(self, angle: float, qe: str) -> None: """ @@ -1072,10 +945,7 @@ def ramp(self, amp: float, duration: int, qe: str) -> None: ramp_sample = [amp * t for t in range(duration)] if "singleInput" in self._local_config["elements"][qe]: self._samples_dict[qe]["single"] += ramp_sample - elif ( - "mixInputs" in self._local_config["elements"][qe] - or "RF_inputs" in self._local_config["elements"][qe] - ): + elif "mixInputs" in self._local_config["elements"][qe] or "RF_inputs" in self._local_config["elements"][qe]: self._samples_dict[qe]["Q"] += ramp_sample self._samples_dict[qe]["I"] += [0] * duration self._update_qe_time(qe, duration) @@ -1186,9 +1056,7 @@ def run( index2 = list(zip(*amp_array))[0].index(qe) amp = list(zip(*amp_array))[1][index2] if type(amp) == list: - raise TypeError( - "Amplitude can only be a number (either Python or QUA variable)" - ) + raise TypeError("Amplitude can only be a number (either Python or QUA variable)") qua.play(f"baked_Op_{self._ctr}" * qua.amp(amp), qe) else: @@ -1208,12 +1076,8 @@ def run( index2 = list(zip(*amp_array))[0].index(qe) amp = list(zip(*amp_array))[1][index2] if type(amp) == list: - raise TypeError( - "Amplitude can only be a number (either Python or QUA variable)" - ) - qua.play( - f"baked_Op_{self._ctr}" * qua.amp(amp), qe, truncate=trunc - ) + raise TypeError("Amplitude can only be a number (either Python or QUA variable)") + qua.play(f"baked_Op_{self._ctr}" * qua.amp(amp), qe, truncate=trunc) for qe in qe_set: if self._qe_dict[qe]["phase"] != 0: diff --git a/qualang_tools/bakery/randomized_benchmark.py b/qualang_tools/bakery/randomized_benchmark.py index 2b53c73f..c56478e9 100644 --- a/qualang_tools/bakery/randomized_benchmark.py +++ b/qualang_tools/bakery/randomized_benchmark.py @@ -55,13 +55,9 @@ def __init__(self, config: dict, d_max: int, qubit: str): self.d_max = d_max self.config = config self.qubit = qubit - self.state_tracker = [ - 0 - ] * d_max # Keeps track of all transformations done on qubit state + self.state_tracker = [0] * d_max # Keeps track of all transformations done on qubit state self.state_init = 0 - self.revert_ops = [ - 0 - ] * d_max # Keeps track of inverse op index associated to each sequence + self.revert_ops = [0] * d_max # Keeps track of inverse op index associated to each sequence self.duration_tracker = [0] * d_max # Keeps track of each Clifford's duration # self.baked_cliffords = self.generate_cliffords() # List of baking objects for running Cliffords self.operations_list = [None] * d_max @@ -180,9 +176,7 @@ def generate_RB_sequence(self): self.operations_list[d] = random_clifford for op in random_clifford: b.play(op, self.qubit) - self.duration_tracker[ - d - ] += 1 # Add additional duration for each pulse played to build Clifford + self.duration_tracker[d] += 1 # Add additional duration for each pulse played to build Clifford if d == 0: # Handle the case for qubit set to original/ground state self.state_tracker[d] = c1_table[self.state_init][i] diff --git a/qualang_tools/bakery/xeb.py b/qualang_tools/bakery/xeb.py index c88e86dc..906d1676 100644 --- a/qualang_tools/bakery/xeb.py +++ b/qualang_tools/bakery/xeb.py @@ -49,9 +49,7 @@ def __init__( self.m_max = m_max self.duration_tracker = [0] * m_max self.operations_list = {qe: [] for qe in ["q1", "q2"]} - self.baked_sequence = self._generate_xeb_sequence( - q1_ops, q2_ops, two_qubit_op, align_op - ) + self.baked_sequence = self._generate_xeb_sequence(q1_ops, q2_ops, two_qubit_op, align_op) def _generate_xeb_sequence(self, q1_ops, q2_ops, two_qubit_op, align_op): rand_seq1 = np.random.randint(3, size=self.m_max) @@ -103,6 +101,4 @@ def play_all_ops(current_bake, sub_bake): def get_total_len(baking_sequence): - return max( - baking_sequence.get_op_length(element) for element in baking_sequence.elements - ) + return max(baking_sequence.get_op_length(element) for element in baking_sequence.elements) diff --git a/qualang_tools/config/README.md b/qualang_tools/config/README.md index 740dffb7..69289176 100644 --- a/qualang_tools/config/README.md +++ b/qualang_tools/config/README.md @@ -6,5 +6,5 @@ It currently has the following packages: * [Helper Tools](README_helper_tools.md) - This package includes tools for writing and updating the configuration. * [Integration Weights Tools](README_integration_weights_tools.md) - This package includes tools for the creation and manipulation of integration weights. * [Waveform Tools](README_waveform_tools.md) - This package includes tools for creating waveforms useful for experiments with the QOP. -* [Config GUI](README_config_GUI.md) - This package contains a GUI for creating and visualizing the configuration file. -* [Config Builder](README_config_builder.md) - This package contains an API for creating and manipulation configuration files. +* [Config GUI](README_config_GUI.md) - This package contains a GUI for creating and visualizing the configuration file - No longer being actively developed. +* [Config Builder](README_config_builder.md) - This package contains an API for creating and manipulation configuration files - No longer being actively developed. diff --git a/qualang_tools/config/README_config_GUI.md b/qualang_tools/config/README_config_GUI.md index c84e8d65..ef83625b 100644 --- a/qualang_tools/config/README_config_GUI.md +++ b/qualang_tools/config/README_config_GUI.md @@ -1,3 +1,8 @@ +# Deprecation Warning + +ConfigGUI is no longer being actively developed and may not support all config functionality. +To use, you need to install the package using `pip instal qualang_tools[configbuilder]` + # Feature GUI for creating configuration. It allows: diff --git a/qualang_tools/config/README_config_builder.md b/qualang_tools/config/README_config_builder.md index 1d1fe7fe..1bf59f6d 100644 --- a/qualang_tools/config/README_config_builder.md +++ b/qualang_tools/config/README_config_builder.md @@ -1,3 +1,8 @@ +# Deprecation Warning + +ConfigBuilder is no longer being actively developed and may not support all config functionality. +To use, you need to install the package using `pip instal qualang_tools[configbuilder]` + # Config module ## Introduction diff --git a/qualang_tools/config/builder.py b/qualang_tools/config/builder.py index a3c77777..a8e72929 100644 --- a/qualang_tools/config/builder.py +++ b/qualang_tools/config/builder.py @@ -1,4 +1,5 @@ import copy +import warnings from typing import Union, List from qualang_tools.config.components import ( @@ -28,6 +29,11 @@ class ConfigBuilder: def __init__(self) -> None: """A class used to build the configuration of an experiment with QUA""" + warnings.warn( + "ConfigBuilder is no longer being actively developed and may not support all config functionality", + DeprecationWarning, + stacklevel=2, + ) self.objects = [] self.configuration = QMConfiguration([]) self.controllers = [] @@ -136,9 +142,7 @@ def build(self, config=None): elif isinstance(obj, Oscillator): self.configuration.add_oscillator(obj) else: - raise NotImplementedError( - "Can not add objects of type {0}".format(type(obj)) - ) + raise NotImplementedError("Can not add objects of type {0}".format(type(obj))) return self.configuration.config def find_instances(self, obj_type): @@ -188,9 +192,7 @@ def find_users_of( elif isinstance(elm, Mixer): return self._find_users_of_mixer(elm) else: - raise NotImplementedError( - "can not find objects of type {}".format(type(elm)) - ) + raise NotImplementedError("can not find objects of type {}".format(type(elm))) def _find_users_of_port(self, port: Port): objects = [] diff --git a/qualang_tools/config/components.py b/qualang_tools/config/components.py index 41ec1a57..d0533960 100644 --- a/qualang_tools/config/components.py +++ b/qualang_tools/config/components.py @@ -127,9 +127,7 @@ def _use_analog_input_port(self, port_num: int, offset: float = 0.0): """ if port_num not in self.dict["analog_inputs"]: self.dict["analog_inputs"][port_num] = {"offset": offset} - self.analog_input_ports += [ - AnalogInputPort(self.name, port_num, offset=offset) - ] + self.analog_input_ports += [AnalogInputPort(self.name, port_num, offset=offset)] def _use_analog_output_port(self, port_num: int, offset: float = 0.0): """Adds an instance of AnalogOutputPort to configuration if it is not used @@ -141,9 +139,7 @@ def _use_analog_output_port(self, port_num: int, offset: float = 0.0): """ if port_num not in self.dict["analog_outputs"]: self.dict["analog_outputs"][port_num] = {"offset": offset} - self.analog_output_ports += [ - AnalogOutputPort(self.name, port_num, offset=offset) - ] + self.analog_output_ports += [AnalogOutputPort(self.name, port_num, offset=offset)] def _use_digital_output_port(self, port_num: int): """Adds an instance of DigitalOutputPort to configuration if it is not used @@ -172,12 +168,7 @@ def ports(self): :return: :rtype: Set """ - return ( - self.digital_input_ports - + self.digital_output_ports - + self.analog_input_ports - + self.analog_output_ports - ) + return self.digital_input_ports + self.digital_output_ports + self.analog_input_ports + self.analog_output_ports class ArbitraryWaveform(Waveform): @@ -233,9 +224,7 @@ def __init__(self, name: str, samples: List[DigitalSample]): if isinstance(samples[0], DigitalSample): self._samples = samples else: - self._samples = [ - DigitalSample(state, duration) for (state, duration) in samples - ] + self._samples = [DigitalSample(state, duration) for (state, duration) in samples] dic = dict() dic["samples"] = [(ds.state, ds.duration) for ds in self._samples] super(DigitalWaveform, self).__init__(name, dic) @@ -249,9 +238,7 @@ def samples(self, samples: Union[List[Tuple[int, int]], List[DigitalSample]]): if isinstance(samples[0], DigitalSample): self._samples = samples else: - self._samples = [ - DigitalSample(state, duration) for (state, duration) in samples - ] + self._samples = [DigitalSample(state, duration) for (state, duration) in samples] self.dict["samples"] = [(ds.state, ds.duration) for ds in self._samples] @@ -338,9 +325,7 @@ def add(self, data: MixerData): class Oscillator(ConfigBuilderElement): - def __init__( - self, name: str, intermediate_frequency: int, lo_frequency: int, mixer: str - ): + def __init__(self, name: str, intermediate_frequency: int, lo_frequency: int, mixer: str): """An internal oscillator. :param name: name of the oscillator :type name: str @@ -435,23 +420,13 @@ def __init__( self.pulses = [] if pulses is not None: self.pulses = pulses - self.element_analog_inputs = ( - [] if element_analog_inputs is None else element_analog_inputs - ) - self.element_analog_outputs = ( - [] if element_analog_outputs is None else element_analog_outputs - ) - self.element_digital_outputs = ( - [] if element_digital_outputs is None else element_digital_outputs - ) - self.element_digital_inputs = ( - [] if element_digital_inputs is None else element_digital_inputs - ) + self.element_analog_inputs = [] if element_analog_inputs is None else element_analog_inputs + self.element_analog_outputs = [] if element_analog_outputs is None else element_analog_outputs + self.element_digital_outputs = [] if element_digital_outputs is None else element_digital_outputs + self.element_digital_inputs = [] if element_digital_inputs is None else element_digital_inputs assert len(self.element_analog_inputs) <= 2 - self.type = ( - "singleInput" if len(self.element_analog_inputs) == 1 else "mixInputs" - ) + self.type = "singleInput" if len(self.element_analog_inputs) == 1 else "mixInputs" self.mixer: Mixer = mixer if len(self.element_analog_inputs) > 0: @@ -543,9 +518,7 @@ def _add_operation(self, op: Operation): self.dict["operations"][op.name] = op.pulse.name self.pulses.append(op.pulse) - def _add( - self, obj: Union[Operation, Mixer, ControlPulse, MeasurePulse, Oscillator] - ): + def _add(self, obj: Union[Operation, Mixer, ControlPulse, MeasurePulse, Oscillator]): """A method to add components to an element :param obj: The component to be added @@ -589,19 +562,11 @@ def waveform_names(self): @property def ports(self): - return ( - self.analog_input_ports - + self.analog_output_ports - + self.digital_output_ports - + self.digital_input_ports - ) + return self.analog_input_ports + self.analog_output_ports + self.digital_output_ports + self.digital_input_ports @property def has_signal_threshold(self): - return ( - "outputPulseParameters" in self.dict - and "signalThreshold" in self.dict["outputPulseParameters"].keys() - ) + return "outputPulseParameters" in self.dict and "signalThreshold" in self.dict["outputPulseParameters"].keys() @property def signal_threshold(self): @@ -618,10 +583,7 @@ def signal_threshold(self, val: int): @property def has_signal_polarity(self): - return ( - "outputPulseParameters" in self.dict - and "signalPolarity" in self.dict["outputPulseParameters"].keys() - ) + return "outputPulseParameters" in self.dict and "signalPolarity" in self.dict["outputPulseParameters"].keys() @property def signal_polarity(self): @@ -639,8 +601,7 @@ def signal_polarity(self, val: str): @property def has_derivative_threshold(self): return ( - "outputPulseParameters" in self.dict - and "derivativeThreshold" in self.dict["outputPulseParameters"].keys() + "outputPulseParameters" in self.dict and "derivativeThreshold" in self.dict["outputPulseParameters"].keys() ) @property @@ -659,8 +620,7 @@ def derivative_threshold(self, val: int): @property def has_derivative_polarity(self): return ( - "outputPulseParameters" in self.dict - and "derivativePolarity" in self.dict["outputPulseParameters"].keys() + "outputPulseParameters" in self.dict and "derivativePolarity" in self.dict["outputPulseParameters"].keys() ) @property @@ -790,9 +750,7 @@ def __init__( tot_duration_sin = 0 for e in sines: tot_duration_sin += e[1] - assert ( - tot_duration_sin == tot_duration_cos - ), "Total duration of the sine and cosine weights must be same" + assert tot_duration_sin == tot_duration_cos, "Total duration of the sine and cosine weights must be same" super(PiecewiseConstantIntegrationWeights, self).__init__( name, @@ -816,9 +774,7 @@ def __init__(self, name: str, cosine: float, sine: float, duration: int): self._duration = duration self._cosine = cosine self._sine = sine - super(ConstantIntegrationWeights, self).__init__( - name, [(cosine, duration)], [(sine, duration)] - ) + super(ConstantIntegrationWeights, self).__init__(name, [(cosine, duration)], [(sine, duration)]) @property def cosine(self): @@ -1078,14 +1034,7 @@ def mixer(self, mixer: Mixer): class Transmon(ElementCollection): - def __init__( - self, - name: str, - I: AnalogOutputPort, - Q: AnalogOutputPort, - intermediate_frequency: int, - **kwargs - ): + def __init__(self, name: str, I: AnalogOutputPort, Q: AnalogOutputPort, intermediate_frequency: int, **kwargs): """A superconducting transmon qubit :param name: A name for this transmon @@ -1266,23 +1215,17 @@ def _add(self, op: Union[Operation, ControlPulse]): elif len(op.pulse.wfs) == 1: self.flux_operations.append(op) else: - raise ConfigurationError( - "Can not add a pulse with {0} waveforms".format(len(op.pulse.wfs)) - ) + raise ConfigurationError("Can not add a pulse with {0} waveforms".format(len(op.pulse.wfs))) elif isinstance(op, ControlPulse): if len(op.wfs) == 2: super(FluxTunableTransmon, self)._add(op) elif len(op.wfs) == 1: self.flux_operations.append(op) else: - raise ConfigurationError( - "Can not add a pulse with {0} waveforms".format(len(op.wfs)) - ) + raise ConfigurationError("Can not add a pulse with {0} waveforms".format(len(op.wfs))) else: - raise ConfigurationError( - "adding unsupported object of type {}".format(type(op)) - ) + raise ConfigurationError("adding unsupported object of type {}".format(type(op))) class Coupler(ElementCollection): @@ -1310,9 +1253,7 @@ def _add(self, op: Operation): if len(op.pulse.wfs) == 1: self.operations.append(op) else: - raise ConfigurationError( - "Can not add a pulse with {0} waveforms".format(len(op.pulse.wfs)) - ) + raise ConfigurationError("Can not add a pulse with {0} waveforms".format(len(op.pulse.wfs))) def add(self, op: Union[List[Operation], Operation]): if isinstance(op, list): diff --git a/qualang_tools/config/configuration.py b/qualang_tools/config/configuration.py index 5e1126d5..a42658af 100644 --- a/qualang_tools/config/configuration.py +++ b/qualang_tools/config/configuration.py @@ -31,9 +31,7 @@ def __init__(self, controllers: List[Controller] = None, version: int = 1): self.config["version"] = 1 self.config["controllers"] = dict() for cont in controllers: - self.config["controllers"][cont.name] = self._call_dict_parameters( - cont.dict - ) + self.config["controllers"][cont.name] = self._call_dict_parameters(cont.dict) self.config["elements"] = dict() self.config["pulses"] = dict() self.config["waveforms"] = dict() @@ -115,16 +113,14 @@ def add_pulse(self, pulse: Pulse): self.add_waveforms(pulse.wfs) if pulse.digital_marker is not None: _dict["digital_marker"] = pulse.digital_marker.name - self.config["digital_waveforms"][ - pulse.digital_marker.name - ] = self._call_dict_parameters(pulse.digital_marker.dict) + self.config["digital_waveforms"][pulse.digital_marker.name] = self._call_dict_parameters( + pulse.digital_marker.dict + ) if isinstance(pulse, MeasurePulse): _dict["integration_weights"] = dict() for w in pulse.integration_weights: _dict["integration_weights"][w.name] = w.weights.name - self.config["integration_weights"][ - w.weights.name - ] = self._call_weights_dict(w.weights.dict) + self.config["integration_weights"][w.weights.name] = self._call_weights_dict(w.weights.dict) self.config["pulses"][pulse.name] = self._call_dict_parameters(_dict) def add_pulses(self, pulses: List[Pulse]): @@ -175,9 +171,7 @@ def update_integration_weights(self, pulse_name: str, iw: IntegrationWeights): assert self.config["pulses"][pulse_name]["operation"] == "measure" assert len(self.config["pulses"][pulse_name]["waveforms"].keys()) == 2 weight_name = pulse_name + "_weight" - self.config["integration_weights"][weight_name] = self._call_dict_parameters( - iw.dict - ) + self.config["integration_weights"][weight_name] = self._call_dict_parameters(iw.dict) def update_constant_waveform(self, wf_name: str, amp: float): """Update the amplitude of an existing constant waveform @@ -208,9 +202,7 @@ def reset(self, controllers=None): controllers = [] self.__init__(controllers) - def update_intermediate_frequency( - self, elm_name: str, freq: float, update_mixer: bool = True - ): + def update_intermediate_frequency(self, elm_name: str, freq: float, update_mixer: bool = True): self.config["elements"][elm_name]["intermediate_frequency"] = freq if update_mixer: m_name = self.config["elements"][elm_name]["mixer"] @@ -261,9 +253,7 @@ def add_integration_weights(self, weight: IntegrationWeights): :param weight: an IntegrationWeights object :type weight: IntegrationWeights """ - self.config["integration_weights"][weight.name] = self._call_dict_parameters( - weight.dict - ) + self.config["integration_weights"][weight.name] = self._call_dict_parameters(weight.dict) def add_mixer(self, mixer: Mixer): """Add a mixer to this configuration @@ -271,9 +261,7 @@ def add_mixer(self, mixer: Mixer): :param mixer: A Mixer object :type mixer: Mixer """ - self.config["mixers"][mixer.name] = [ - self._call_dict_parameters(data) for data in mixer.dict - ] + self.config["mixers"][mixer.name] = [self._call_dict_parameters(data) for data in mixer.dict] def add_oscillator(self, oscillator: Oscillator): """Add an oscillator to this configuration @@ -281,6 +269,4 @@ def add_oscillator(self, oscillator: Oscillator): :param oscillator: an Oscillator object :type oscillator: Oscillator """ - self.config["oscillators"][oscillator.name] = self._call_dict_parameters( - oscillator.dict - ) + self.config["oscillators"][oscillator.name] = self._call_dict_parameters(oscillator.dict) diff --git a/qualang_tools/config/gui.py b/qualang_tools/config/gui.py index d6ca1d0e..f1108681 100644 --- a/qualang_tools/config/gui.py +++ b/qualang_tools/config/gui.py @@ -1,5 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import warnings from dash import dcc import dash_bootstrap_components as dbc @@ -89,12 +90,15 @@ def open_browser(): if __name__ == "__main__": + warnings.warn( + "ConfigGUI is no longer being actively developed and may not support all config functionality", + DeprecationWarning, + stacklevel=2, + ) global port_number parser = argparse.ArgumentParser() - parser.add_argument( - "-p", "--port", help="port number to use for GUI server", type=int - ) + parser.add_argument("-p", "--port", help="port number to use for GUI server", type=int) args = parser.parse_args() if args.port is not None: port_number = args.port @@ -106,9 +110,7 @@ def open_browser(): timer.start() try: print(f"\tConfig GUI is running on http://{host}:{port_number}") - print( - "\tIf web browser does not open, please enter the address stated above manually." - ) + print("\tIf web browser does not open, please enter the address stated above manually.") print("\tStop GUI by pressing Ctrl+C") print( "\t%s: %s" diff --git a/qualang_tools/config/helper_tools.py b/qualang_tools/config/helper_tools.py index 48df2584..07b4a6e0 100644 --- a/qualang_tools/config/helper_tools.py +++ b/qualang_tools/config/helper_tools.py @@ -55,9 +55,7 @@ def dump(self, filename): with open(filename, "w") as fp: _json.dump(self.data, fp) - def add_control_operation_iq( - self, element: str, operation_name: str, wf_i: List[float], wf_q: List[float] - ): + def add_control_operation_iq(self, element: str, operation_name: str, wf_i: List[float], wf_q: List[float]): """ Add or update a control operation to a mixed input element. @@ -88,9 +86,7 @@ def add_control_operation_iq( # Add waveform self.update_waveforms(element, operation_name, (wf_i, wf_q)) - def add_control_operation_single( - self, element: str, operation_name: str, wf: List[float] - ): + def add_control_operation_single(self, element: str, operation_name: str, wf: List[float]): """ Add or update a control operation to a single input element. @@ -118,9 +114,7 @@ def add_control_operation_single( # Add waveform self.update_waveforms(element, operation_name, (wf,)) - def get_waveforms_from_op( - self, element: str, operation_name: str - ) -> List or List[List]: + def get_waveforms_from_op(self, element: str, operation_name: str) -> List or List[List]: """ Get the waveforms corresponding to the given element and operation. @@ -177,13 +171,9 @@ def get_pulse_from_op(self, element: str, operation_name: str) -> dict: f"The operation '{operation_name}' in not defined in the config for the element '{element}'." ) - return self.data["pulses"][ - self.data["elements"][element]["operations"][operation_name] - ] + return self.data["pulses"][self.data["elements"][element]["operations"][operation_name]] - def update_op_amp( - self, element: str, operation_name: str, amp: float, force_update: bool = False - ): + def update_op_amp(self, element: str, operation_name: str, amp: float, force_update: bool = False): """ Update the operation amplitude. Can only access amplitude for a constant pulse of a single element. @@ -204,14 +194,10 @@ def update_op_amp( f"The operation '{operation_name}' in not defined in the config for the element '{element}'." ) if not -0.5 <= amp < 0.5: - raise ValueError( - "The amplitude must be within the range [-0.5, 0.5) Volts." - ) + raise ValueError("The amplitude must be within the range [-0.5, 0.5) Volts.") pulse = self.get_pulse_from_op(element, operation_name) if "single" not in pulse["waveforms"].keys(): - raise KeyError( - "Can only access amplitude for a constant pulse of a single element" - ) + raise KeyError("Can only access amplitude for a constant pulse of a single element") wf = pulse["waveforms"]["single"] # Check if the waveform is used in another pulse count = 0 @@ -230,9 +216,7 @@ def update_op_amp( "The updated waveform is used in other operations. To force the update, please set the force_update flag to True." ) elif count == 0: - raise Exception( - f"The operation {operation_name} doesn't have a valid waveform." - ) + raise Exception(f"The operation {operation_name} doesn't have a valid waveform.") # Update the waveform self.data["waveforms"][wf]["sample"] = amp @@ -257,9 +241,7 @@ def get_op_amp(self, element: str, operation_name: str) -> float: try: return self.data["waveforms"][pulse["waveforms"]["single"]]["sample"] except KeyError: - raise KeyError( - "Can only access amplitude for a constant pulse of a single element" - ) + raise KeyError("Can only access amplitude for a constant pulse of a single element") def update_integration_weight( self, @@ -289,9 +271,9 @@ def update_integration_weight( ) if ( iw_op_name - not in self.data["pulses"][ - self.data["elements"][element]["operations"][operation_name] - ]["integration_weights"].keys() + not in self.data["pulses"][self.data["elements"][element]["operations"][operation_name]][ + "integration_weights" + ].keys() ): raise KeyError( f"The integration weight '{iw_op_name}' in not associated to the pulse corresponding to the operation '{operation_name}'." @@ -309,9 +291,7 @@ def update_integration_weight( "The updated integration weights are used in other operations. To force the update, please set the force_update flag to True." ) elif count == 0: - raise Exception( - f"The integration weights {iw_op_name} are not listed in the config integration weights." - ) + raise Exception(f"The integration weights {iw_op_name} are not listed in the config integration weights.") self.data["integration_weights"][iw_name] = {"cosine": iw_cos, "sine": iw_sin} @@ -333,13 +313,9 @@ def copy_operation(self, element: str, operation_name: str, new_name: str): ) # Copy operation pulse_name = self.data["elements"][element]["operations"][operation_name] - self.data["pulses"][element + "_" + new_name + self.pulse_suffix] = _deepcopy( - self.data["pulses"][pulse_name] - ) + self.data["pulses"][element + "_" + new_name + self.pulse_suffix] = _deepcopy(self.data["pulses"][pulse_name]) # Rename the copied operation - self.data["elements"][element]["operations"][new_name] = ( - element + "_" + new_name + self.pulse_suffix - ) + self.data["elements"][element]["operations"][new_name] = element + "_" + new_name + self.pulse_suffix def update_waveforms( self, diff --git a/qualang_tools/config/integration_weights_tools.py b/qualang_tools/config/integration_weights_tools.py index 3f239818..9587396b 100644 --- a/qualang_tools/config/integration_weights_tools.py +++ b/qualang_tools/config/integration_weights_tools.py @@ -6,9 +6,7 @@ def _round_to_fixed_point_accuracy(x, accuracy=2**-15): return np.round(x / accuracy) * accuracy -def convert_integration_weights( - integration_weights, N=100, accuracy=2**-15, plot=False -): +def convert_integration_weights(integration_weights, N=100, accuracy=2**-15, plot=False): """ Converts a list of integration weights, in which each sample corresponds to a clock cycle (4ns), to a list of tuples with the format (weight, time_to_integrate_in_ns). @@ -39,9 +37,7 @@ def convert_integration_weights( new_integration_weights.append(constant_part) prev_index = curr_index - new_integration_weights = compress_integration_weights( - new_integration_weights, N=N, plot=plot - ) + new_integration_weights = compress_integration_weights(new_integration_weights, N=N, plot=plot) return new_integration_weights @@ -66,9 +62,7 @@ def compress_integration_weights(integration_weights, N=100, plot=False): times2 = integration_weights[min_diff_indices + 1, 1] weights1 = integration_weights[min_diff_indices, 0] weights2 = integration_weights[min_diff_indices + 1, 0] - integration_weights[min_diff_indices, 0] = ( - weights1 * times1 + weights2 * times2 - ) / (times1 + times2) + integration_weights[min_diff_indices, 0] = (weights1 * times1 + weights2 * times2) / (times1 + times2) integration_weights[min_diff_indices, 1] = times1 + times2 integration_weights = np.delete(integration_weights, min_diff_indices + 1, 0) integration_weights = list( diff --git a/qualang_tools/config/parameters.py b/qualang_tools/config/parameters.py index 56c50d29..6d833416 100644 --- a/qualang_tools/config/parameters.py +++ b/qualang_tools/config/parameters.py @@ -219,9 +219,7 @@ def parameter(self, name: str, setter=None): :type setter: Callable """ if name.find(" ") != -1: - raise ValueError( - "Parameter name cannot contain spaces. " "Use underscore of camelCase." - ) + raise ValueError("Parameter name cannot contain spaces. " "Use underscore of camelCase.") if name not in self.params.keys(): self.params[name] = Parameter(name) if setter is not None: diff --git a/qualang_tools/config/server/component_editor.py b/qualang_tools/config/server/component_editor.py index 6b0cd018..08f8c6e2 100644 --- a/qualang_tools/config/server/component_editor.py +++ b/qualang_tools/config/server/component_editor.py @@ -91,12 +91,9 @@ def component_editor(selected_component, inputs=None): # objects that we can add through add method additional_add_docstring = "" - if ( - hasattr(component_class, "add") - and callable(component_class.add) - and inputs[0] is None - and inputs[1] is None - ): + + if hasattr(component_class, "add") and callable(component_class.add) and inputs[0] is None and inputs[1] is None: + arugments = inspect.getfullargspec(component_class.add) argument_names = arugments[0][1:] argument_types = arugments[6] @@ -186,9 +183,7 @@ def component_editor(selected_component, inputs=None): }, ) ) - possible_add_on_objects_gui.append( - dbc.AccordionItem(gui2, title=option_name) - ) + possible_add_on_objects_gui.append(dbc.AccordionItem(gui2, title=option_name)) component_gui.append( dbc.InputGroup( @@ -294,9 +289,7 @@ def class_editor_and_gui( elif argument_types[name] == float: if inputs[0] is not None: value = float(inputs[0][input_index[0]]) - python_command += ( - ",\n " if (input_index[1] > 0 or input_index[0] > 0) else "" - ) + f"{value}" + python_command += (",\n " if (input_index[1] > 0 or input_index[0] > 0) else "") + f"{value}" else: component_gui.append( dbc.InputGroup( @@ -318,9 +311,7 @@ def class_editor_and_gui( elif argument_types[name] == int: if inputs[0] is not None: value = int(inputs[0][input_index[0]]) - python_command += ( - ",\n " if (input_index[1] > 0 or input_index[0] > 0) else "" - ) + f"{value}" + python_command += (",\n " if (input_index[1] > 0 or input_index[0] > 0) else "") + f"{value}" else: component_gui.append( dbc.InputGroup( @@ -405,9 +396,7 @@ def class_editor_and_gui( command += f".digital_output({port_id})" elif argument_types[name] == primitive_components.DigitalInputPort: command += f".digital_input({port_id})" - python_command += ( - ",\n" if (input_index[0] > 0 or input_index[1] > 0) else "" - ) + command + python_command += (",\n" if (input_index[0] > 0 or input_index[1] > 0) else "") + command else: for index, c in enumerate(controllers): controllerList.append({"label": c.name, "value": index}) @@ -415,9 +404,7 @@ def class_editor_and_gui( component_gui.append( dbc.InputGroup( [ - dbc.InputGroupText( - [html.I(className="bi bi-diagram-3-fill me-2"), name] - ), + dbc.InputGroupText([html.I(className="bi bi-diagram-3-fill me-2"), name]), dcc.Dropdown( options=controllerList, placeholder="choose controller", @@ -460,34 +447,21 @@ def class_editor_and_gui( port = port.split(",") controller_id = int(port[0]) port_id = int(port[1]) - if ( - argument_types[name] - == typing.List[primitive_components.AnalogOutputPort] - ): + if argument_types[name] == typing.List[primitive_components.AnalogOutputPort]: list += f"setup.find_instances(Controller)[{controller_id}].analog_output({port_id})" - elif ( - argument_types[name] - == typing.List[primitive_components.AnalogInputPort] - ): + elif argument_types[name] == typing.List[primitive_components.AnalogInputPort]: list += f"setup.find_instances(Controller)[{controller_id}].analog_input({port_id})" - elif ( - argument_types[name] - == typing.List[primitive_components.DigitalOutputPort] - ): + elif argument_types[name] == typing.List[primitive_components.DigitalOutputPort]: list += f"setup.find_instances(Controller)[{controller_id}].digital_output({port_id})" else: # it is (argument_types[name] == typing.List[quantum_machine.primitive_components.DigitalInputPort]) list += f"setup.find_instances(Controller)[{controller_id}].digital_input({port_id})" list += "]" - python_command += ( - ",\n " if (input_index[1] > 0 or input_index[0] > 0) else "" - ) + list + python_command += (",\n " if (input_index[1] > 0 or input_index[0] > 0) else "") + list else: for index, c in enumerate(controllers): - controllerList.append( - {"label": c.name, "value": "%s, %d" % (c.name, index)} - ) + controllerList.append({"label": c.name, "value": "%s, %d" % (c.name, index)}) component_gui.append( dbc.InputGroup( @@ -560,9 +534,7 @@ def class_editor_and_gui( list += f"setup.find_instances(Waveform)[{component_index}]" list += "]" - python_command += ( - ",\n " if (input_index[1] > 0 or input_index[0] > 0) else "" - ) + list + python_command += (",\n " if (input_index[1] > 0 or input_index[0] > 0) else "") + list else: for index, c in enumerate(waveforms): waveformList.append({"label": c.name, "value": index}) @@ -630,9 +602,7 @@ def class_editor_and_gui( list += f"setup.find_instances(Element)[{component_index}]" list += "]" - python_command += ( - ",\n " if (input_index[1] > 0 or input_index[0] > 0) else "" - ) + list + python_command += (",\n " if (input_index[1] > 0 or input_index[0] > 0) else "") + list else: for index, c in enumerate(elements): elementList.append({"label": c.name, "value": index}) @@ -669,9 +639,8 @@ def class_editor_and_gui( else: # selection == 2 python_command += ( - (",\n " if (input_index[1] > 0 or input_index[0] > 0) else "") - + f"setup.find_instances(ArbitraryIntegrationWeights)[{index}]" - ) + ",\n " if (input_index[1] > 0 or input_index[0] > 0) else "" + ) + f"setup.find_instances(ArbitraryIntegrationWeights)[{index}]" else: options1 = setup.find_instances(components.ConstantIntegrationWeights) options2 = setup.find_instances(components.ArbitraryIntegrationWeights) @@ -774,10 +743,7 @@ def class_editor_and_gui( def get_docstring(selected_class): - if ( - selected_class.__init__ is not None - and selected_class.__init__.__doc__ is not None - ): + if selected_class.__init__ is not None and selected_class.__init__.__doc__ is not None: docstring = publish_doctree(selected_class.__init__.__doc__) docstring = publish_from_doctree(docstring, writer_name="html").decode() else: @@ -789,9 +755,7 @@ def get_component(selected_component): component_class = None if isinstance(selected_component, str): component = selected_component.split(".")[-1] - library = inspect.getmembers( - importlib.import_module(selected_component[0 : -len(component) - 1]) - ) + library = inspect.getmembers(importlib.import_module(selected_component[0 : -len(component) - 1])) for name, obj in library: if name == component: diff --git a/qualang_tools/config/server/config_editor.py b/qualang_tools/config/server/config_editor.py index 32104c64..e858384e 100644 --- a/qualang_tools/config/server/config_editor.py +++ b/qualang_tools/config/server/config_editor.py @@ -23,16 +23,12 @@ try: # try updating config schema print("\tDownloading latest config schema...") - with urllib.request.urlopen( - "https://qm-docs.qualang.io/qm_config_spec.json" - ) as url: + with urllib.request.urlopen("https://qm-docs.qualang.io/qm_config_spec.json") as url: config_structure = json.loads(url.read().decode()) print("\tDONE") except Exception: print("Cannot download. Using the local copy of the schema.") - with open( - os.path.join(os.path.dirname(os.path.realpath(__file__)), "qua1_openapi.json") - ) as file: + with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), "qua1_openapi.json")) as file: config_structure = json.load(file) @@ -80,41 +76,27 @@ def config_editor(pathname, updated_value=None, configuration=None): # print(l) # print(a) - if isinstance(a[l], dict) or ( - isinstance(a[l], list) and len(a[l]) > 0 and isinstance(a[l][0], dict) - ): + if isinstance(a[l], dict) or (isinstance(a[l], list) and len(a[l]) > 0 and isinstance(a[l][0], dict)): a = a[l] if l in documentation: documentation = documentation[l] else: - if ( - "properties" in documentation - and l in documentation["properties"] - ): + if "properties" in documentation and l in documentation["properties"]: documentation = documentation["properties"][l] if "$ref" in documentation: documentation = getDefinition(documentation["$ref"]) elif "additionalProperties" in documentation: if "$ref" in documentation["additionalProperties"]: - documentation = getDefinition( - documentation["additionalProperties"]["$ref"] - ) + documentation = getDefinition(documentation["additionalProperties"]["$ref"]) # print(documentation) elif "oneOf" in documentation["additionalProperties"]: - for option in documentation["additionalProperties"][ - "oneOf" - ]: + for option in documentation["additionalProperties"]["oneOf"]: # print("\n") option = getDefinition(option["$ref"]) try: # print(option) # print(a["type"]) - if ( - option["properties"]["type"][ - "description" - ].find(a["type"]) - != -1 - ): + if option["properties"]["type"]["description"].find(a["type"]) != -1: documentation = option except KeyError: pass @@ -217,9 +199,7 @@ def config_editor(pathname, updated_value=None, configuration=None): # show selected values if selected != "": - if isinstance(input_dict[selected], list) or isinstance( - input_dict[selected], np.ndarray - ): + if isinstance(input_dict[selected], list) or isinstance(input_dict[selected], np.ndarray): if isinstance(input_dict[selected], np.ndarray): input_dict[selected] = input_dict[selected].tolist() @@ -230,9 +210,9 @@ def config_editor(pathname, updated_value=None, configuration=None): input_dict[selected] = np.fromstring(updated_value, sep=",") return "OK" if controlArguments.find("view=list") != -1: - details.append( - dcc.Link("view as plot", href=url + f"/{selected}/[view=plot]") - ) + + details.append(dcc.Link("view as plot", href=url + f"/{selected}/[view=plot]")) + # show list details.append( dbc.InputGroup( @@ -241,9 +221,7 @@ def config_editor(pathname, updated_value=None, configuration=None): id="input-field", className="mb-3", placeholder="array", - value=htmlpy.escape( - pprint.pformat(input_dict[selected]) - ), + value=htmlpy.escape(pprint.pformat(input_dict[selected])), ), dbc.Button("Update", id="update-button", n_clicks=0), ] @@ -251,16 +229,12 @@ def config_editor(pathname, updated_value=None, configuration=None): ) details.append(html.Div(id="update-success")) else: - details.append( - dcc.Link("view as list", href=url + f"/{selected}/[view=list]") - ) + details.append(dcc.Link("view as list", href=url + f"/{selected}/[view=list]")) # show plot data = pandas.DataFrame(input_dict[selected]) fig = px.line(data, markers=True) fig.update_layout(showlegend=False) - details.append( - dcc.Graph(id="graph", config={"displayModeBar": False}, figure=fig) - ) + details.append(dcc.Graph(id="graph", config={"displayModeBar": False}, figure=fig)) else: if isinstance(input_dict[selected], float): if updated_value is not None: @@ -296,9 +270,7 @@ def config_editor(pathname, updated_value=None, configuration=None): clearable=False, ) ) - details.append( - html.Span(input_dict[selected], id="wf-initial", hidden=True) - ) + details.append(html.Span(input_dict[selected], id="wf-initial", hidden=True)) if updated_value is not None: input_dict[selected] = updated_value return "OK" @@ -309,11 +281,7 @@ def config_editor(pathname, updated_value=None, configuration=None): data = pandas.DataFrame([wf["sample"]]) fig = px.line(data, markers=True) fig.update_layout(showlegend=False) - details.append( - dcc.Graph( - id="wf-view", config={"displayModeBar": False}, figure=fig - ) - ) + details.append(dcc.Graph(id="wf-view", config={"displayModeBar": False}, figure=fig)) details.append( dcc.Link( @@ -324,9 +292,7 @@ def config_editor(pathname, updated_value=None, configuration=None): ) else: if isinstance(input_dict[selected], tuple): - if updated_value is not None and isinstance( - updated_value, tuple - ): + if updated_value is not None and isinstance(updated_value, tuple): input_dict[selected] = updated_value return "OK" details.append( @@ -347,16 +313,12 @@ def config_editor(pathname, updated_value=None, configuration=None): value=("%s" % input_dict[selected][1]), ), dbc.InputGroupText(")"), - dbc.Button( - "Update", id="update-tuple-button", n_clicks=0 - ), + dbc.Button("Update", id="update-tuple-button", n_clicks=0), ], className="mb-3", ) ) - details.append( - details.append(html.Div(id="update-success-tuple")) - ) + details.append(details.append(html.Div(id="update-success-tuple"))) else: if updated_value is not None: # do checks @@ -371,9 +333,7 @@ def config_editor(pathname, updated_value=None, configuration=None): type="text", value=("%s" % input_dict[selected]), ), - dbc.Button( - "Update", id="update-button", n_clicks=0 - ), + dbc.Button("Update", id="update-button", n_clicks=0), ] ) ) diff --git a/qualang_tools/config/server/download.py b/qualang_tools/config/server/download.py index 4bdb0e1b..f79f541e 100644 --- a/qualang_tools/config/server/download.py +++ b/qualang_tools/config/server/download.py @@ -21,9 +21,7 @@ def generate_download_page(): [ dbc.Button("config_initial.py", id="download-config-inital"), dcc.Download(id="config-initial-data"), - html.Span( - " + ", style={"fontSize": "3rem", "verticalAlign": "middle"} - ), + html.Span(" + ", style={"fontSize": "3rem", "verticalAlign": "middle"}), dbc.Button("config_edits.py", id="download-config-edits"), dcc.Download(id="config-edits-data"), ] diff --git a/qualang_tools/config/server/editors.py b/qualang_tools/config/server/editors.py index bc4aa30d..21be84d0 100644 --- a/qualang_tools/config/server/editors.py +++ b/qualang_tools/config/server/editors.py @@ -32,13 +32,9 @@ def update_field(click_number, value, pathname): if success == "OK": with open(os.path.join(UPLOAD_DIRECTORY, "config_edits.py"), "a") as myfile: if isinstance(value, str): - myfile.write( - f"config_editor('{pathname}', updated_value='{value}', configuration=configuration)\n" - ) + myfile.write(f"config_editor('{pathname}', updated_value='{value}', configuration=configuration)\n") else: - myfile.write( - f"config_editor('{pathname}', updated_value={value}, configuration=configuration)\n" - ) + myfile.write(f"config_editor('{pathname}', updated_value={value}, configuration=configuration)\n") return [dbc.Alert(f"Updated {pathname} = {value}", color="success")] else: return [dbc.Alert(f"{success}", color="danger")] @@ -60,9 +56,7 @@ def update_tuple(click_number, value0, value1, pathname): f"config_editor('{pathname}', updated_value=('{value0}',{value1}), configuration=configuration)\n" ) - return [ - dbc.Alert(f"Updated {pathname} = ('{value0}', {value1})", color="success") - ] + return [dbc.Alert(f"Updated {pathname} = ('{value0}', {value1})", color="success")] else: return [dbc.Alert(f"{success}", color="danger")] @@ -81,13 +75,9 @@ def update_wf(value, pathname, initial_waveform): if success == "OK": with open(os.path.join(UPLOAD_DIRECTORY, "config_edits.py"), "a") as myfile: if isinstance(value, str): - myfile.write( - f"config_editor('{pathname}', updated_value='{value}', config=configuration)\n" - ) + myfile.write(f"config_editor('{pathname}', updated_value='{value}', config=configuration)\n") else: - myfile.write( - f"config_editor('{pathname}', updated_value={value}, config=configuration)\n" - ) + myfile.write(f"config_editor('{pathname}', updated_value={value}, config=configuration)\n") import config_edits import config_final @@ -156,9 +146,7 @@ def add_port_to_list(bclick, options, values, controller, port): ) def add_component_click(bclick, inputs, ports, added_objects, selected_component): try: - python_edit_command = component_editor( - selected_component, inputs=[inputs, ports] - ) + python_edit_command = component_editor(selected_component, inputs=[inputs, ports]) if added_objects is not None: for index, item in enumerate(added_objects): if index == 0: @@ -170,9 +158,7 @@ def add_component_click(bclick, inputs, ports, added_objects, selected_component with open(os.path.join(UPLOAD_DIRECTORY, "config_edits.py"), "a") as myfile: myfile.write(f"setup.add({python_edit_command})\n") - return dbc.Alert( - f"Component added successfuly!\n {python_edit_command}", color="success" - ) + return dbc.Alert(f"Component added successfuly!\n {python_edit_command}", color="success") except Exception: return dbc.Alert(traceback.format_exc(), color="danger") @@ -226,9 +212,7 @@ def add_optional_input( return ( current_added_items, current_options, - dbc.Alert( - f"Component added successfuly!\n {python_command}", color="success" - ), + dbc.Alert(f"Component added successfuly!\n {python_command}", color="success"), ) except Exception: raise PreventUpdate diff --git a/qualang_tools/config/waveform_tools.py b/qualang_tools/config/waveform_tools.py index 205e0e2b..340d6381 100644 --- a/qualang_tools/config/waveform_tools.py +++ b/qualang_tools/config/waveform_tools.py @@ -3,14 +3,7 @@ def drag_gaussian_pulse_waveforms( - amplitude, - length, - sigma, - alpha, - anharmonicity, - detuning=0.0, - subtracted=True, - **kwargs + amplitude, length, sigma, alpha, anharmonicity, detuning=0.0, subtracted=True, sampling_rate=1e9, **kwargs ): """ Creates Gaussian based DRAG waveforms that compensate for the leakage and for the AC stark shift. @@ -29,25 +22,20 @@ def drag_gaussian_pulse_waveforms( :param float detuning: The frequency shift to correct for AC stark shift, in Hz. :param bool subtracted: If true, returns a subtracted Gaussian, such that the first and last points will be at 0 volts. This reduces high-frequency components due to the initial and final points offset. Default is true. - :return: Returns a tuple of two lists. The first list is the I waveform (real part) and the second is the - Q waveform (imaginary part) + :param float sampling_rate: The sampling rate used to describe the waveform, in samples/s. Default is 1G samples/s. + :return: Returns a tuple of two lists. The first list is the 'I' waveform (real part) and the second is the + 'Q' waveform (imaginary part) """ delta = kwargs.get("delta", None) if delta is not None: - print( - "'delta' has been replaced by 'anharmonicity' and will be deprecated in the future. " - ) + print("'delta' has been replaced by 'anharmonicity' and will be deprecated in the future. ") if alpha != 0 and delta == 0: raise Exception("Cannot create a DRAG pulse with `anharmonicity=0`") - t = np.arange(length, dtype=int) # An array of size pulse length in ns - center = (length - 1) / 2 - gauss_wave = amplitude * np.exp( - -((t - center) ** 2) / (2 * sigma**2) - ) # The gaussian function + t = np.arange(length, step=1e9 / sampling_rate) # An array of size pulse length in ns + center = (length - 1e9 / sampling_rate) / 2 + gauss_wave = amplitude * np.exp(-((t - center) ** 2) / (2 * sigma**2)) # The gaussian function gauss_der_wave = ( - amplitude - * (-2 * 1e9 * (t - center) / (2 * sigma**2)) - * np.exp(-((t - center) ** 2) / (2 * sigma**2)) + amplitude * (-2 * 1e9 * (t - center) / (2 * sigma**2)) * np.exp(-((t - center) ** 2) / (2 * sigma**2)) ) # The derivative of gaussian if subtracted: gauss_wave = gauss_wave - gauss_wave[-1] # subtracted gaussian @@ -58,44 +46,30 @@ def drag_gaussian_pulse_waveforms( # The complex detuned DRAG envelope: z *= np.exp(1j * 2 * np.pi * detuning * t * 1e-9) I_wf = z.real.tolist() # The `I` component is the real part of the waveform - Q_wf = ( - z.imag.tolist() - ) # The `Q` component is the imaginary part of the waveform + Q_wf = z.imag.tolist() # The `Q` component is the imaginary part of the waveform else: if alpha != 0 and anharmonicity == 0: raise Exception("Cannot create a DRAG pulse with `anharmonicity=0`") - t = np.arange(length, dtype=int) # An array of size pulse length in ns - center = (length - 1) / 2 - gauss_wave = amplitude * np.exp( - -((t - center) ** 2) / (2 * sigma**2) - ) # The gaussian function + t = np.arange(length, step=1e9 / sampling_rate) # An array of size pulse length in ns + center = (length - 1e9 / sampling_rate) / 2 + gauss_wave = amplitude * np.exp(-((t - center) ** 2) / (2 * sigma**2)) # The gaussian function gauss_der_wave = ( - amplitude - * (-2 * 1e9 * (t - center) / (2 * sigma**2)) - * np.exp(-((t - center) ** 2) / (2 * sigma**2)) + amplitude * (-2 * 1e9 * (t - center) / (2 * sigma**2)) * np.exp(-((t - center) ** 2) / (2 * sigma**2)) ) # The derivative of gaussian if subtracted: gauss_wave = gauss_wave - gauss_wave[-1] # subtracted gaussian z = gauss_wave + 1j * 0 if alpha != 0: # The complex DRAG envelope: - z += ( - 1j - * gauss_der_wave - * (alpha / (2 * np.pi * anharmonicity - 2 * np.pi * detuning)) - ) + z += 1j * gauss_der_wave * (alpha / (2 * np.pi * anharmonicity - 2 * np.pi * detuning)) # The complex detuned DRAG envelope: z *= np.exp(1j * 2 * np.pi * detuning * t * 1e-9) I_wf = z.real.tolist() # The `I` component is the real part of the waveform - Q_wf = ( - z.imag.tolist() - ) # The `Q` component is the imaginary part of the waveform + Q_wf = z.imag.tolist() # The `Q` component is the imaginary part of the waveform return I_wf, Q_wf -def drag_cosine_pulse_waveforms( - amplitude, length, alpha, anharmonicity, detuning=0.0, **kwargs -): +def drag_cosine_pulse_waveforms(amplitude, length, alpha, anharmonicity, detuning=0.0, sampling_rate=1e9, **kwargs): """ Creates Cosine based DRAG waveforms that compensate for the leakage and for the AC stark shift. @@ -110,26 +84,20 @@ def drag_cosine_pulse_waveforms( :param float alpha: The DRAG coefficient. :param float anharmonicity: f_21 - f_10 - The differences in energy between the 2-1 and the 1-0 energy levels, in Hz. :param float detuning: The frequency shift to correct for AC stark shift, in Hz. - :return: Returns a tuple of two lists. The first list is the I waveform (real part) and the second is the - Q waveform (imaginary part) + :param float sampling_rate: The sampling rate used to describe the waveform, in samples/s. Default is 1G samples/s. + :return: Returns a tuple of two lists. The first list is the 'I' waveform (real part) and the second is the + 'Q' waveform (imaginary part) """ delta = kwargs.get("delta", None) if delta is not None: - print( - "'delta' has been replaced by 'anharmonicity' and will be deprecated in the future." - ) + print("'delta' has been replaced by 'anharmonicity' and will be deprecated in the future.") if alpha != 0 and anharmonicity == 0: raise Exception("Cannot create a DRAG pulse with `anharmonicity=0`") - t = np.arange(length, dtype=int) # An array of size pulse length in ns - end_point = length - 1 - cos_wave = ( - 0.5 * amplitude * (1 - np.cos(t * 2 * np.pi / end_point)) - ) # The cosine function + t = np.arange(length, step=1e9 / sampling_rate) # An array of size pulse length in ns + end_point = length - 1e9 / sampling_rate + cos_wave = 0.5 * amplitude * (1 - np.cos(t * 2 * np.pi / end_point)) # The cosine function sin_wave = ( - 0.5 - * amplitude - * (2 * np.pi / end_point * 1e9) - * np.sin(t * 2 * np.pi / end_point) + 0.5 * amplitude * (2 * np.pi / end_point * 1e9) * np.sin(t * 2 * np.pi / end_point) ) # The derivative of cosine function z = cos_wave + 1j * 0 if alpha != 0: @@ -138,43 +106,28 @@ def drag_cosine_pulse_waveforms( # The complex detuned DRAG envelope: z *= np.exp(1j * 2 * np.pi * detuning * t * 1e-9) I_wf = z.real.tolist() # The `I` component is the real part of the waveform - Q_wf = ( - z.imag.tolist() - ) # The `Q` component is the imaginary part of the waveform + Q_wf = z.imag.tolist() # The `Q` component is the imaginary part of the waveform else: if alpha != 0 and anharmonicity == 0: raise Exception("Cannot create a DRAG pulse with `anharmonicity=0`") - t = np.arange(length, dtype=int) # An array of size pulse length in ns - end_point = length - 1 - cos_wave = ( - 0.5 * amplitude * (1 - np.cos(t * 2 * np.pi / end_point)) - ) # The cosine function + t = np.arange(length, step=1e9 / sampling_rate) # An array of size pulse length in ns + end_point = length - 1e9 / sampling_rate + cos_wave = 0.5 * amplitude * (1 - np.cos(t * 2 * np.pi / end_point)) # The cosine function sin_wave = ( - 0.5 - * amplitude - * (2 * np.pi / end_point * 1e9) - * np.sin(t * 2 * np.pi / end_point) + 0.5 * amplitude * (2 * np.pi / end_point * 1e9) * np.sin(t * 2 * np.pi / end_point) ) # The derivative of cosine function z = cos_wave + 1j * 0 if alpha != 0: # The complex DRAG envelope: - z += ( - 1j - * sin_wave - * (alpha / (2 * np.pi * anharmonicity - 2 * np.pi * detuning)) - ) + z += 1j * sin_wave * (alpha / (2 * np.pi * anharmonicity - 2 * np.pi * detuning)) # The complex detuned DRAG envelope: z *= np.exp(1j * 2 * np.pi * detuning * t * 1e-9) I_wf = z.real.tolist() # The `I` component is the real part of the waveform - Q_wf = ( - z.imag.tolist() - ) # The `Q` component is the imaginary part of the waveform + Q_wf = z.imag.tolist() # The `Q` component is the imaginary part of the waveform return I_wf, Q_wf -def flattop_gaussian_waveform( - amplitude, flat_length, rise_fall_length, return_part="all" -): +def flattop_gaussian_waveform(amplitude, flat_length, rise_fall_length, return_part="all", sampling_rate=1e9): """ Returns a flat top Gaussian waveform. This is a square pulse with a rise and fall of a Gaussian with the given sigma. It is possible to only get the rising or falling parts, which allows scanning the flat part length from QUA. @@ -187,14 +140,19 @@ def flattop_gaussian_waveform( :param str return_part: When set to 'all', returns the complete waveform. Default is 'all'. When set to 'rise', returns only the rising part. When set to 'fall', returns only the falling part. This is useful for separating the three parts which allows scanning the duration of the flat part is to scanned from QUA + :param float sampling_rate: The sampling rate used to describe the waveform, in samples/s. Must be an integer multiple of 1e9 samples per seconds. Default is 1G samples/s. :return: Returns the waveform as a list of values with 1ns spacing """ - gauss_wave = amplitude * gaussian(2 * rise_fall_length, rise_fall_length / 5) - rise_part = gauss_wave[:rise_fall_length] + assert sampling_rate % 1e9 == 0, "The sampling rate must be an integer multiple of 1e9 samples per second." + + gauss_wave = amplitude * gaussian( + int(np.round(2 * rise_fall_length * sampling_rate / 1e9)), rise_fall_length / 5 * sampling_rate / 1e9 + ) + rise_part = gauss_wave[: int(rise_fall_length * sampling_rate / 1e9)] rise_part = rise_part.tolist() if return_part == "all": - return rise_part + [amplitude] * flat_length + rise_part[::-1] + return rise_part + [amplitude] * int(flat_length * sampling_rate / 1e9) + rise_part[::-1] elif return_part == "rise": return rise_part elif return_part == "fall": @@ -203,9 +161,7 @@ def flattop_gaussian_waveform( raise Exception("'return_part' must be either 'all', 'rise' or 'fall'") -def flattop_cosine_waveform( - amplitude, flat_length, rise_fall_length, return_part="all" -): +def flattop_cosine_waveform(amplitude, flat_length, rise_fall_length, return_part="all", sampling_rate=1e9): """ Returns a flat top cosine waveform. This is a square pulse with a rise and fall with cosine shape with the given sigma. It is possible to only get the rising or falling parts, which allows scanning the flat part length from QUA. @@ -218,12 +174,14 @@ def flattop_cosine_waveform( :param str return_part: When set to 'all', returns the complete waveform. Default is 'all'. When set to 'rise', returns only the rising part. When set to 'fall', returns only the falling part. This is useful for separating the three parts which allows scanning the duration of the flat part is to scanned from QUA + :param float sampling_rate: The sampling rate used to describe the waveform, in samples/s. Must be an integer multiple of 1e9 samples per seconds. Default is 1G samples/s. :return: Returns the waveform as a list of values with 1ns spacing """ - rise_part = amplitude * 0.5 * (1 - np.cos(np.linspace(0, np.pi, rise_fall_length))) + assert sampling_rate % 1e9 == 0, "The sampling rate must be an integer multiple of 1e9 samples per second." + rise_part = amplitude * 0.5 * (1 - np.cos(np.linspace(0, np.pi, int(rise_fall_length * sampling_rate / 1e9)))) rise_part = rise_part.tolist() if return_part == "all": - return rise_part + [amplitude] * flat_length + rise_part[::-1] + return rise_part + [amplitude] * int(flat_length * sampling_rate / 1e9) + rise_part[::-1] elif return_part == "rise": return rise_part elif return_part == "fall": @@ -232,7 +190,7 @@ def flattop_cosine_waveform( raise Exception("'return_part' must be either 'all', 'rise' or 'fall'") -def flattop_tanh_waveform(amplitude, flat_length, rise_fall_length, return_part="all"): +def flattop_tanh_waveform(amplitude, flat_length, rise_fall_length, return_part="all", sampling_rate=1e9): """ Returns a flat top tanh waveform. This is a square pulse with a rise and fall with tanh shape with the given sigma. It is possible to only get the rising or falling parts, which allows scanning the flat part length from QUA. @@ -245,12 +203,14 @@ def flattop_tanh_waveform(amplitude, flat_length, rise_fall_length, return_part= :param str return_part: When set to 'all', returns the complete waveform. Default is 'all'. When set to 'rise', returns only the rising part. When set to 'fall', returns only the falling part. This is useful for separating the three parts which allows scanning the duration of the flat part is to scanned from QUA + :param float sampling_rate: The sampling rate used to describe the waveform, in samples/s. Must be an integer multiple of 1e9 samples per seconds. Default is 1G samples/s. :return: Returns the waveform as a list of values with 1ns spacing """ - rise_part = amplitude * 0.5 * (1 + np.tanh(np.linspace(-4, 4, rise_fall_length))) + assert sampling_rate % 1e9 == 0, "The sampling rate must be an integer multiple of 1e9 samples per second." + rise_part = amplitude * 0.5 * (1 + np.tanh(np.linspace(-4, 4, int(rise_fall_length * sampling_rate / 1e9)))) rise_part = rise_part.tolist() if return_part == "all": - return rise_part + [amplitude] * flat_length + rise_part[::-1] + return rise_part + [amplitude] * int(flat_length * sampling_rate / 1e9) + rise_part[::-1] elif return_part == "rise": return rise_part elif return_part == "fall": @@ -259,9 +219,7 @@ def flattop_tanh_waveform(amplitude, flat_length, rise_fall_length, return_part= raise Exception("'return_part' must be either 'all', 'rise' or 'fall'") -def flattop_blackman_waveform( - amplitude, flat_length, rise_fall_length, return_part="all" -): +def flattop_blackman_waveform(amplitude, flat_length, rise_fall_length, return_part="all", sampling_rate=1e9): """ Returns a flat top Blackman waveform. This is a square pulse with a rise and fall with Blackman shape with the given length. It is possible to only get the rising or falling parts, which allows scanning the flat part length from QUA. @@ -273,13 +231,15 @@ def flattop_blackman_waveform( :param str return_part: When set to 'all', returns the complete waveform. Default is 'all'. When set to 'rise', returns only the rising part. When set to 'fall', returns only the falling part. This is useful for separating the three parts which allows scanning the duration of the flat part is to scanned from QUA + :param float sampling_rate: The sampling rate used to describe the waveform, in samples/s. Must be an integer multiple of 1e9 samples per seconds. Default is 1G samples/s. :return: Returns the waveform as a list """ - backman_wave = amplitude * blackman(2 * rise_fall_length) - rise_part = backman_wave[:rise_fall_length] + assert sampling_rate % 1e9 == 0, "The sampling rate must be an integer multiple of 1e9 samples per second." + backman_wave = amplitude * blackman(2 * int(rise_fall_length * sampling_rate / 1e9)) + rise_part = backman_wave[: int(rise_fall_length * sampling_rate / 1e9)] rise_part = rise_part.tolist() if return_part == "all": - return rise_part + [amplitude] * flat_length + rise_part[::-1] + return rise_part + [amplitude] * int(flat_length * sampling_rate / 1e9) + rise_part[::-1] elif return_part == "rise": return rise_part elif return_part == "fall": @@ -288,7 +248,7 @@ def flattop_blackman_waveform( raise Exception("'return_part' must be either 'all', 'rise' or 'fall'") -def blackman_integral_waveform(pulse_length, v_start, v_end): +def blackman_integral_waveform(pulse_length, v_start, v_end, sampling_rate=1e9): """ Returns a Blackman integral waveform. This is the integral of a Blackman waveform, adiabatically going from 'v_start' to 'v_end' in 'pulse_length' ns. @@ -296,9 +256,11 @@ def blackman_integral_waveform(pulse_length, v_start, v_end): :param int pulse_length: The pulse length in ns. :param float v_start: The starting amplitude in volts. :param float v_end: The ending amplitude in volts. + :param float sampling_rate: The sampling rate used to describe the waveform, in samples/s. Must be an integer multiple of 1e9 samples per seconds. Default is 1G samples/s. :return: Returns the waveform as a list """ - time = np.asarray([x * 1.0 for x in range(int(pulse_length))]) + assert sampling_rate % 1e9 == 0, "The sampling rate must be an integer multiple of 1e9 samples per second." + time = np.linspace(0, pulse_length - 1, int(pulse_length * sampling_rate / 1e9)) black_wave = v_start + ( time / (pulse_length - 1) - (25 / (42 * np.pi)) * np.sin(2 * np.pi * time / (pulse_length - 1)) diff --git a/qualang_tools/control_panel/manual_output_control.py b/qualang_tools/control_panel/manual_output_control.py index 48570b9d..73e64b83 100644 --- a/qualang_tools/control_panel/manual_output_control.py +++ b/qualang_tools/control_panel/manual_output_control.py @@ -94,13 +94,9 @@ def ports( if len(port_int) == 2: con_number = (port_int[0] - 1) // 10 + 1 if con_number is not (port_int[1] - 1) // 10 + 1: - raise Exception( - f"Ports {port_int[0]} and {port_int[1]} are not from the same controller" - ) + raise Exception(f"Ports {port_int[0]} and {port_int[1]} are not from the same controller") else: - raise Exception( - f"Port {port_int} should be either an integer or a tuple of two integers" - ) + raise Exception(f"Port {port_int} should be either an integer or a tuple of two integers") else: con_number = (port_int - 1) // 10 + 1 con = f"con{con_number}" @@ -116,13 +112,9 @@ def ports( port1 = (port_int[0] - 1) % 10 + 1 port2 = (port_int[1] - 1) % 10 + 1 if port1 not in config["controllers"][con]["analog_outputs"]: - config["controllers"][con]["analog_outputs"][port1] = { - "offset": 0.0 - } + config["controllers"][con]["analog_outputs"][port1] = {"offset": 0.0} if port2 not in config["controllers"][con]["analog_outputs"]: - config["controllers"][con]["analog_outputs"][port2] = { - "offset": 0.0 - } + config["controllers"][con]["analog_outputs"][port2] = {"offset": 0.0} if port_str not in config["elements"]: config["elements"][port_str] = { "mixInputs": { @@ -135,9 +127,7 @@ def ports( port_str = str(port_int) port_int = (port_int - 1) % 10 + 1 if port_int not in config["controllers"][con]["analog_outputs"]: - config["controllers"][con]["analog_outputs"][port_int] = { - "offset": 0.0 - } + config["controllers"][con]["analog_outputs"][port_int] = {"offset": 0.0} if port_str not in config["elements"]: config["elements"][port_str] = { "singleInput": { @@ -200,9 +190,7 @@ def turn_on_element(self, element, amplitude=None, frequency=None): if not isinstance(element, str): element = str(element) if element not in self.digital_elements and element not in self.analog_elements: - raise Exception( - f"Element {element} is not part of the elements in the configuration files" - ) + raise Exception(f"Element {element} is not part of the elements in the configuration files") if amplitude is None: amplitude = self.ANALOG_WAVEFORM_AMPLITUDE if frequency is not None: @@ -221,13 +209,8 @@ def turn_off_elements(self, *elements): for element in elements: if not isinstance(element, str): element = str(element) - if ( - element not in self.digital_elements - and element not in self.analog_elements - ): - raise Exception( - f"Element {element} is not part of the elements in the configuration files" - ) + if element not in self.digital_elements and element not in self.analog_elements: + raise Exception(f"Element {element} is not part of the elements in the configuration files") self.digital_off(*elements, ignore_missing_elements=True) if len(elements) == 0: elements = self.analog_elements @@ -249,18 +232,14 @@ def set_amplitude(self, element, value, ignore_missing_elements=False): if ignore_missing_elements: return else: - raise Exception( - f"Element {element} is not part of the elements in the analog configuration file" - ) + raise Exception(f"Element {element} is not part of the elements in the analog configuration file") if abs(value) > self.ANALOG_WAVEFORM_AMPLITUDE: if value == 0.5: value = 0.5 - 2**-16 elif value == -0.5: value = -0.5 + 2**-16 else: - raise Exception( - f"The absolute value of the amplitude must smaller than 0.5, {value} was given" - ) + raise Exception(f"The absolute value of the amplitude must smaller than 0.5, {value} was given") prev_value = self.analog_data[element]["amplitude"] self.analog_data[element]["amplitude"] = value @@ -294,19 +273,13 @@ def set_frequency(self, element, value, ignore_missing_elements=False): if ignore_missing_elements: return else: - raise Exception( - f"Element {element} is not part of the elements in the analog configuration file" - ) + raise Exception(f"Element {element} is not part of the elements in the analog configuration file") if int(value) > int(500e6): - raise Exception( - f"The frequency should be lower than 500e6, {value} was given" - ) + raise Exception(f"The frequency should be lower than 500e6, {value} was given") self.analog_data[element]["frequency"] = value while not self.analog_job.is_paused(): sleep(0.01) - self.analog_qm.set_io_values( - int(self.analog_elements.index(element)), int(value) - ) + self.analog_qm.set_io_values(int(self.analog_elements.index(element)), int(value)) self.analog_job.resume() def digital_on(self, *digital_elements, ignore_missing_elements=False): @@ -327,9 +300,7 @@ def digital_on(self, *digital_elements, ignore_missing_elements=False): if ignore_missing_elements: return else: - raise Exception( - f"Element {element} is not part of the elements in the digital configuration file" - ) + raise Exception(f"Element {element} is not part of the elements in the digital configuration file") self.digital_data[element] = True self._start_digital() @@ -351,9 +322,7 @@ def digital_off(self, *digital_elements, ignore_missing_elements=False): if ignore_missing_elements: return else: - raise Exception( - f"Element {element} is not part of the elements in the digital configuration file" - ) + raise Exception(f"Element {element} is not part of the elements in the digital configuration file") self.digital_data[element] = False self._start_digital() @@ -369,9 +338,7 @@ def digital_switch(self, *digital_element): if not isinstance(element, str): element = str(element) if element not in self.digital_elements: - raise Exception( - f"Element {element} is not part of the elements in the digital configuration file" - ) + raise Exception(f"Element {element} is not part of the elements in the digital configuration file") self.digital_data[element] = not self.digital_data[element] self._start_digital() @@ -452,9 +419,9 @@ def _process_config(self, config_original, elements_to_control=None): "type": "opx1", "analog_outputs": {}, } - self.analog_config["controllers"][controller]["analog_outputs"] = config[ - "controllers" - ][controller]["analog_outputs"] + self.analog_config["controllers"][controller]["analog_outputs"] = config["controllers"][controller][ + "analog_outputs" + ] pulser_count[controller] = 0 self.analog_config["elements"] = {} self.analog_config["waveforms"] = { @@ -500,29 +467,21 @@ def _process_config(self, config_original, elements_to_control=None): self.digital_data[element] = False self.digital_elements.append(element) for digital_input in config["elements"][element]["digitalInputs"]: - con, port = config["elements"][element]["digitalInputs"][ - digital_input - ]["port"] + con, port = config["elements"][element]["digitalInputs"][digital_input]["port"] con_int_index = int(con[-1]) - 1 port_index = port - 1 self.digital_index[element].append((con_int_index, port_index)) if self.digital_configs[con_int_index][port_index] is None: pulser_count[con] += 1 - self.digital_configs[con_int_index][port_index] = copy.deepcopy( - digital_config - ) - self.digital_configs[con_int_index][port_index]["controllers"][ - con - ] = { + self.digital_configs[con_int_index][port_index] = copy.deepcopy(digital_config) + self.digital_configs[con_int_index][port_index]["controllers"][con] = { "type": "opx1", "digital_outputs": {port: {}}, } - self.digital_configs[con_int_index][port_index]["elements"][ - "digital" - ] = {"operations": {"ON": "digital_ON"}} - self.digital_configs[con_int_index][port_index]["elements"][ - "digital" - ]["digitalInputs"] = { + self.digital_configs[con_int_index][port_index]["elements"]["digital"] = { + "operations": {"ON": "digital_ON"} + } + self.digital_configs[con_int_index][port_index]["elements"]["digital"]["digitalInputs"] = { "digital": { "port": (con, port), "delay": 0, @@ -535,54 +494,36 @@ def _process_config(self, config_original, elements_to_control=None): con = config["elements"][element]["mixInputs"]["I"][0] pulser_count[con] += 2 self.analog_config["elements"][element] = config["elements"][element] - if ( - self.analog_config["elements"][element].get("digitalInputs") - is not None - ): + if self.analog_config["elements"][element].get("digitalInputs") is not None: self.analog_config["elements"][element].pop("digitalInputs") if self.analog_config["elements"][element].get("outputs") is not None: self.analog_config["elements"][element].pop("outputs") self.analog_config["elements"][element].pop("time_of_flight") self.analog_config["elements"][element].pop("smearing") - if ( - self.analog_config["elements"][element].get("operations") - is not None - ): + if self.analog_config["elements"][element].get("operations") is not None: self.analog_config["elements"][element].pop("operations") - self.analog_config["elements"][element]["operations"] = { - "play": "IQ_Ion" - } + self.analog_config["elements"][element]["operations"] = {"play": "IQ_Ion"} self.analog_elements.append(element) elif config["elements"][element].get("singleInput") is not None: con = config["elements"][element]["singleInput"]["port"][0] pulser_count[con] += 1 self.analog_config["elements"][element] = config["elements"][element] - if ( - self.analog_config["elements"][element].get("digitalInputs") - is not None - ): + if self.analog_config["elements"][element].get("digitalInputs") is not None: self.analog_config["elements"][element].pop("digitalInputs") if self.analog_config["elements"][element].get("outputs") is not None: self.analog_config["elements"][element].pop("outputs") self.analog_config["elements"][element].pop("time_of_flight") self.analog_config["elements"][element].pop("smearing") - if ( - self.analog_config["elements"][element].get("operations") - is not None - ): + if self.analog_config["elements"][element].get("operations") is not None: self.analog_config["elements"][element].pop("operations") - self.analog_config["elements"][element]["operations"] = { - "play": "single_on" - } + self.analog_config["elements"][element]["operations"] = {"play": "single_on"} self.analog_elements.append(element) for element in self.analog_elements: self.analog_config["elements"][element]["hold_offset"] = {"duration": 16} self.analog_data[element] = { "amplitude": 0, - "frequency": self.analog_config["elements"][element].get( - "intermediate_frequency" - ), + "frequency": self.analog_config["elements"][element].get("intermediate_frequency"), } opx_plus = True if self.qmm.version()["server"][0] == "2" else False @@ -620,9 +561,7 @@ def _start_digital_qms(self): for con_port_list in self.digital_index.values(): for con, port in con_port_list: if self.digital_qms[con][port] is None: - self.digital_qms[con][port] = self.qmm.open_qm( - self.digital_configs[con][port], False - ) + self.digital_qms[con][port] = self.qmm.open_qm(self.digital_configs[con][port], False) def _start_digital(self): """ @@ -645,13 +584,9 @@ def _start_digital(self): if (con, port) in digital_on: # Needs to be on if ( # Is not on self.digital_jobs[con][port] is None - or not self.digital_jobs[con][ - port - ].result_handles.is_processing() + or not self.digital_jobs[con][port].result_handles.is_processing() ): - self.digital_jobs[con][port] = self.digital_qms[con][ - port - ].execute(prog) + self.digital_jobs[con][port] = self.digital_qms[con][port].execute(prog) else: # Is already on pass else: # Needs to be off @@ -685,9 +620,7 @@ def _QUA_update_freq_or_amp(self, input1, input2): for i in range(len(self.analog_elements)): with case_(i): if ( - self.analog_config["elements"][self.analog_elements[i]].get( - "intermediate_frequency" - ) + self.analog_config["elements"][self.analog_elements[i]].get("intermediate_frequency") is not None ): update_frequency(self.analog_elements[i], freq) diff --git a/qualang_tools/control_panel/vna.py b/qualang_tools/control_panel/vna.py index 3c16a8d0..ae364db0 100644 --- a/qualang_tools/control_panel/vna.py +++ b/qualang_tools/control_panel/vna.py @@ -32,21 +32,11 @@ def __init__(self, config: dict, element: str, operation: str, Q: int = None): self.element = element self.operation = operation self.inputs = [ - config["elements"][element]["outputs"][out][1] - for out in config["elements"][element]["outputs"].keys() + config["elements"][element]["outputs"][out][1] for out in config["elements"][element]["outputs"].keys() ] if Q is not None: - self.relax_time = int( - Q - / ( - 2 - * np.pi - * config["elements"][element]["mixInputs"]["lo_frequency"] - * 1e-9 - ) - / 4 - ) + self.relax_time = int(Q / (2 * np.pi * config["elements"][element]["mixInputs"]["lo_frequency"] * 1e-9) / 4) else: self.relax_time = 4 self.measurements = [] @@ -95,15 +85,13 @@ def add_envelope_detector(self, measurement: str, outputs: str, int_weights: str raise KeyError(f"Output '{outputs}' is not in the config") elif not ( int_weights - in self.config["pulses"][ - self.config["elements"][self.element]["operations"][self.operation] - ]["integration_weights"] + in self.config["pulses"][self.config["elements"][self.element]["operations"][self.operation]][ + "integration_weights" + ] ): raise KeyError(f"Integration weights '{int_weights}' is not in the config") elif not (measurement in ["S11", "S21"]): - raise KeyError( - f"Measurement '{measurement}' not implemented yet, must be in ['S11', 'S21']" - ) + raise KeyError(f"Measurement '{measurement}' not implemented yet, must be in ['S11', 'S21']") self._add_S_measurement(measurement, outputs, int_weights) self.measurements[-1]["down_converter"] = "ED" @@ -124,20 +112,16 @@ def add_IR_mixer(self, measurement: str, outputs: str, int_weights: list): all( [ iw - in self.config["pulses"][ - self.config["elements"][self.element]["operations"][ - self.operation - ] - ]["integration_weights"] + in self.config["pulses"][self.config["elements"][self.element]["operations"][self.operation]][ + "integration_weights" + ] for iw in int_weights ] ) ): raise KeyError(f"Integration weights '{int_weights}' are not in the config") elif not (measurement in ["S11", "S21"]): - raise KeyError( - f"Measurement '{measurement}' not implemented yet, must be in ['S11', 'S21']" - ) + raise KeyError(f"Measurement '{measurement}' not implemented yet, must be in ['S11', 'S21']") self._add_S_measurement(measurement, outputs, int_weights) self.measurements[-1]["down_converter"] = "IR" @@ -156,33 +140,22 @@ def add_IQ_mixer(self, measurement: str, outputs: list, int_weights: list): raise TypeError(f"Output '{outputs}' must be a list of two outputs.") if np.array(int_weights).shape != (2, 2): raise TypeError(f"Output '{int_weights}' must be a 2x2 list.") - if not ( - all( - [ - out in self.config["elements"][self.element]["outputs"] - for out in outputs - ] - ) - ): + if not (all([out in self.config["elements"][self.element]["outputs"] for out in outputs])): raise KeyError(f"Integration weights '{outputs}' are not in the config") elif not ( all( [ iw - in self.config["pulses"][ - self.config["elements"][self.element]["operations"][ - self.operation - ] - ]["integration_weights"] + in self.config["pulses"][self.config["elements"][self.element]["operations"][self.operation]][ + "integration_weights" + ] for iw in np.array(int_weights).reshape(1, 4)[0] ] ) ): raise KeyError(f"Integration weights '{int_weights}' are not in the config") elif not (measurement in ["S11", "S21"]): - raise KeyError( - f"Measurement '{measurement}' not implemented yet, must be in ['S11', 'S21']" - ) + raise KeyError(f"Measurement '{measurement}' not implemented yet, must be in ['S11', 'S21']") self._add_S_measurement(measurement, outputs, int_weights) self.measurements[-1]["down_converter"] = "IQ" @@ -255,12 +228,8 @@ def _run_spectrum_analyzer(self, qm, n_avg: int): raw = np.array(raw) # Store data in self.results self.results["SA"]["raw"] = raw / 4096 - self.results["SA"]["fft"] = ( - fft / 4096 * (2 / self.calibration["SA"]["pulse_length"]) - ) - self.results["SA"]["f"] = np.arange( - 0, 0.5 * 1e9, 1e9 / self.calibration["SA"]["pulse_length"] - ) + self.results["SA"]["fft"] = fft / 4096 * (2 / self.calibration["SA"]["pulse_length"]) + self.results["SA"]["f"] = np.arange(0, 0.5 * 1e9, 1e9 / self.calibration["SA"]["pulse_length"]) def _define_single_measurement(self, sequence: dict, freq_sweep: dict, n_avg: int): """ @@ -301,9 +270,7 @@ def _define_single_measurement(self, sequence: dict, freq_sweep: dict, n_avg: in self.operation, self.element, None, - integration.full( - sequence["integration_weights"], I, sequence["outputs"] - ), + integration.full(sequence["integration_weights"], I, sequence["outputs"]), ) elif sequence["down_converter"] == "IR": @@ -380,13 +347,7 @@ def _run_single_measurement(self, qm, sequence: dict, freq_sweep: dict, n_avg: i self.results[sequence["measurement"]]["S"] = ( np.abs(I) * 4096 - / ( - self.config["pulses"][ - self.config["elements"][self.element]["operations"][ - self.operation - ] - ]["length"] - ) + / (self.config["pulses"][self.config["elements"][self.element]["operations"][self.operation]]["length"]) ) self.results[sequence["measurement"]]["phase"] = 0 * np.abs(I) else: @@ -569,16 +530,10 @@ def _run_dual_measurement(self, qm, freq_sweep: dict, n_avg: int): self.results[self.measurements[i]["measurement"]]["f"] = f if self.measurements[i]["down_converter"] == "ED": self.results[self.measurements[i]["measurement"]]["S"] = np.abs(I) - self.results[self.measurements[i]["measurement"]]["phase"] = 0 * np.abs( - I - ) + self.results[self.measurements[i]["measurement"]]["phase"] = 0 * np.abs(I) else: - self.results[self.measurements[i]["measurement"]]["S"] = np.sqrt( - I**2 + Q**2 - ) - self.results[self.measurements[i]["measurement"]]["phase"] = np.unwrap( - np.arctan2(I, Q) - ) + self.results[self.measurements[i]["measurement"]]["S"] = np.sqrt(I**2 + Q**2) + self.results[self.measurements[i]["measurement"]]["phase"] = np.unwrap(np.arctan2(I, Q)) def run_all(self, freq_sweep: dict = None, n_avg: int = 1, dual: bool = False): """ @@ -598,9 +553,7 @@ def run_all(self, freq_sweep: dict = None, n_avg: int = 1, dual: bool = False): print("Spectrum analyzer...") # update measurement pulse duration to match bandwidth pulse = self.config["elements"][self.element]["operations"][self.operation] - self.config["pulses"][pulse]["length"] = self.calibration["SA"][ - "pulse_length" - ] + self.config["pulses"][pulse]["length"] = self.calibration["SA"]["pulse_length"] qm = self.qmm.open_qm(self.config) self._run_spectrum_analyzer(qm, n_avg) @@ -611,9 +564,7 @@ def run_all(self, freq_sweep: dict = None, n_avg: int = 1, dual: bool = False): self._run_single_measurement(qm, seq, freq_sweep, n_avg) else: if len(self.measurements) != 2: - raise KeyError( - "Dual run only works for two previously defined measurements" - ) + raise KeyError("Dual run only works for two previously defined measurements") self._run_dual_measurement(qm, freq_sweep, n_avg) def plot_all(self): @@ -637,9 +588,7 @@ def plot_all(self): plt.subplot(212) plt.plot( self.results["SA"]["f"], - self.results["SA"]["fft"][i][ - : int(np.ceil(len(self.results["SA"]["fft"][i]) / 2)) - ], + self.results["SA"]["fft"][i][: int(np.ceil(len(self.results["SA"]["fft"][i]) / 2))], label=f"OPX input {self.inputs[i]}", ) plt.subplot(211) @@ -660,9 +609,7 @@ def plot_all(self): plt.ylabel(r"$\sqrt{I^2+Q^2}$ [V]") plt.legend() plt.subplot(212) - plt.plot( - self.results[ss]["f"] / 1e6, self.results[ss]["phase"], label=ss - ) + plt.plot(self.results[ss]["f"] / 1e6, self.results[ss]["phase"], label=ss) plt.ylabel("phase [rad]") plt.xlabel("Frequency [Hz]") plt.legend() diff --git a/qualang_tools/external_frameworks/qcodes/opx_driver.py b/qualang_tools/external_frameworks/qcodes/opx_driver.py index 2cd8d2d6..4cedbb93 100644 --- a/qualang_tools/external_frameworks/qcodes/opx_driver.py +++ b/qualang_tools/external_frameworks/qcodes/opx_driver.py @@ -164,17 +164,13 @@ def __init__( vals=Arrays(shape=(self.axis1_npoints.get_latest,)), ) # Open QMM - self.connect_to_qmm( - host=host, port=port, cluster_name=cluster_name, octave=octave - ) + self.connect_to_qmm(host=host, port=port, cluster_name=cluster_name, octave=octave) # Set config self.set_config(config=config) # Open QM self.open_qm(close_other_machines) - def connect_to_qmm( - self, host: str = None, port: int = None, cluster_name: str = None, octave=None - ): + def connect_to_qmm(self, host: str = None, port: int = None, cluster_name: str = None, octave=None): """ Enable the connection with the OPX by creating the QuantumMachineManager. Displays the connection message with idn when the connection is established. @@ -184,14 +180,10 @@ def connect_to_qmm( :param cluster_name: Name of the cluster as defined in the OPX admin panel (from version QOP220) :param octave: Octave configuration if an Octave is to be used in this experiment. """ - self.qmm = QuantumMachinesManager( - host=host, port=port, cluster_name=cluster_name, octave=octave - ) + self.qmm = QuantumMachinesManager(host=host, port=port, cluster_name=cluster_name, octave=octave) self.connect_message() - def connect_message( - self, idn_param: str = "IDN", begin_time: Optional[float] = None - ) -> None: + def connect_message(self, idn_param: str = "IDN", begin_time: Optional[float] = None) -> None: """ Print a standard message on initial connection to an instrument. @@ -239,9 +231,7 @@ def open_qm(self, close_other_machines: bool): Open a quantum machine with a given configuration ready to execute a program. Beware that each call will close the existing quantum machines and interrupt the running jobs. """ - self.qm = self.qmm.open_qm( - self.config, close_other_machines=close_other_machines - ) + self.qm = self.qmm.open_qm(self.config, close_other_machines=close_other_machines) self.qm_id = self.qm.id def update_qm(self): @@ -286,16 +276,10 @@ def get_res(self): # Get data and convert to Volt out = None # demodulated or integrated data - self.result_handles.get(self.results["names"][i]).wait_for_values( - self.counter - ) + self.result_handles.get(self.results["names"][i]).wait_for_values(self.counter) if self.results["types"][i] == "IQ": out = ( - -( - self.result_handles.get(self.results["names"][i]).fetch( - self.counter - 1 - )["value"] - ) + -(self.result_handles.get(self.results["names"][i]).fetch(self.counter - 1)["value"]) * 4096 / self.readout_pulse_length() * self.demod_factor @@ -304,11 +288,7 @@ def get_res(self): # raw adc traces elif self.results["types"][i] == "adc": out = ( - -( - self.result_handles.get(self.results["names"][i]).fetch( - self.counter - 1 - )["value"] - ) + -(self.result_handles.get(self.results["names"][i]).fetch(self.counter - 1)["value"]) / 4096 * self.results["scale_factor"][i] ) @@ -318,18 +298,14 @@ def get_res(self): self.results["buffers"][i][0], self.results["buffers"][i][1] ) elif len(self.results["buffers"][i]) == 1: - output[self.results["names"][i]] = out.reshape( - self.results["buffers"][i][0] - ) + output[self.results["names"][i]] = out.reshape(self.results["buffers"][i][0]) else: output[self.results["names"][i]] = out # Add amplitude and phase if I and Q are in the SP if "I" in output.keys() and "Q" in output.keys(): output["R"] = np.sqrt(output["I"] ** 2 + output["Q"] ** 2) - output["Phi"] = ( - np.unwrap(np.angle(output["I"] + 1j * output["Q"])) * 180 / np.pi - ) + output["Phi"] = np.unwrap(np.angle(output["I"] + 1j * output["Q"])) * 180 / np.pi return output def _extend_result(self, gene, count, averaging_buffer): @@ -350,28 +326,14 @@ def _extend_result(self, gene, count, averaging_buffer): self.results["scale_factor"].append(1) # Check if next buffer is for averaging if len(gene.values[2].list_value.values[1].list_value.values) > 0: - if ( - gene.values[2] - .list_value.values[1] - .list_value.values[0] - .string_value - == "average" - ): + if gene.values[2].list_value.values[1].list_value.values[0].string_value == "average": averaging_buffer = True elif gene.values[0].string_value == "buffer": if not averaging_buffer: - self.results["buffers"][count].append( - int(gene.values[1].string_value) - ) + self.results["buffers"][count].append(int(gene.values[1].string_value)) # Check if next buffer is for averaging if len(gene.values[2].list_value.values[1].list_value.values) > 0: - if ( - gene.values[2] - .list_value.values[1] - .list_value.values[0] - .string_value - == "average" - ): + if gene.values[2].list_value.values[1].list_value.values[0].string_value == "average": averaging_buffer = True else: averaging_buffer = False @@ -459,9 +421,7 @@ def get_measurement_parameter(self, scale_factor=((),)): self.axis1_stop(int(self.readout_pulse_length())) self.axis1_step(1) self.axis1_npoints(int(self.readout_pulse_length())) - self.axis1_full_list( - np.arange(self.axis1_start(), self.axis1_stop(), self.axis1_step()) - ) + self.axis1_full_list(np.arange(self.axis1_start(), self.axis1_stop(), self.axis1_step())) self.axis1_axis.unit = "ns" self.axis1_axis.label = "Readout time" # Rescale the results if a scale factor is provided @@ -470,12 +430,8 @@ def get_measurement_parameter(self, scale_factor=((),)): if len(scale_factor[0]) == 3: for param in scale_factor: if param[0] in self.results["names"]: - self.results["units"][ - self.results["names"].index(param[0]) - ] = param[2] - self.results["scale_factor"][ - self.results["names"].index(param[0]) - ] = param[1] + self.results["units"][self.results["names"].index(param[0])] = param[2] + self.results["scale_factor"][self.results["names"].index(param[0])] = param[1] else: raise ValueError( "scale_factor must be a list of tuples with 3 elements (the result name, the scale factor and the new unit), as in [('I', 0.152, 'pA'), ]." @@ -488,16 +444,11 @@ def get_measurement_parameter(self, scale_factor=((),)): "OPX_results", names=self.results["names"], units=self.results["units"], - shapes=( - (self.results["buffers"][0][0], self.results["buffers"][0][1]), - ) - * len(self.results["names"]), - setpoints=((self.axis2_axis(), self.axis1_axis()),) - * len(self.results["names"]), - setpoint_units=((self.axis2_axis.unit, self.axis1_axis.unit),) - * len(self.results["names"]), - setpoint_labels=((self.axis2_axis.label, self.axis1_axis.label),) + shapes=((self.results["buffers"][0][0], self.results["buffers"][0][1]),) * len(self.results["names"]), + setpoints=((self.axis2_axis(), self.axis1_axis()),) * len(self.results["names"]), + setpoint_units=((self.axis2_axis.unit, self.axis1_axis.unit),) * len(self.results["names"]), + setpoint_labels=((self.axis2_axis.label, self.axis1_axis.label),) * len(self.results["names"]), setpoint_names=( ( self.axis2_axis.label.replace(" ", "").lower(), @@ -513,15 +464,11 @@ def get_measurement_parameter(self, scale_factor=((),)): "OPX_results", names=self.results["names"], units=self.results["units"], - shapes=((self.results["buffers"][0][0],),) - * len(self.results["names"]), + shapes=((self.results["buffers"][0][0],),) * len(self.results["names"]), setpoints=((self.axis1_axis(),),) * len(self.results["names"]), - setpoint_units=((self.axis1_axis.unit,),) - * len(self.results["names"]), - setpoint_labels=((self.axis1_axis.label,),) - * len(self.results["names"]), - setpoint_names=((self.axis1_axis.label.replace(" ", "").lower(),),) - * len(self.results["names"]), + setpoint_units=((self.axis1_axis.unit,),) * len(self.results["names"]), + setpoint_labels=((self.axis1_axis.label,),) * len(self.results["names"]), + setpoint_names=((self.axis1_axis.label.replace(" ", "").lower(),),) * len(self.results["names"]), ) else: return ResultParameters( @@ -536,9 +483,7 @@ def get_measurement_parameter(self, scale_factor=((),)): setpoint_labels=((),) * len(self.results["names"]), ) - def update_readout_length( - self, readout_element: str, readout_operation: str, new_length: int - ): + def update_readout_length(self, readout_element: str, readout_operation: str, new_length: int): """ Update the readout length of a given readout operation and readout element. This only works if the corresponding integration weights are constant. @@ -617,12 +562,7 @@ def live_plotting(self, results_to_plot: list = (), number_of_runs: int = 0): else: # Convert the results into Volts - data = ( - -data[-1] - * 4096 - / int(self.readout_pulse_length()) - * self.demod_factor - ) + data = -data[-1] * 4096 / int(self.readout_pulse_length()) * self.demod_factor # Plot results if len(data.shape) == 1: if len(results_to_plot) > 1: @@ -641,9 +581,7 @@ def live_plotting(self, results_to_plot: list = (), number_of_runs: int = 0): plt.title(results_to_plot[i] + " [V]") i += 1 - plt.suptitle( - f"Iteration: {progress}/{number_of_runs} = {progress / number_of_runs * 100:.1f} %" - ) + plt.suptitle(f"Iteration: {progress}/{number_of_runs} = {progress / number_of_runs * 100:.1f} %") plt.pause(1) plt.tight_layout() @@ -668,9 +606,7 @@ def resume(self, timeout: int = 30): """ wait_until_job_is_paused(self.job, timeout) if not self.job.is_paused(): - raise RuntimeError( - f"The program has not reached the pause statement before {timeout} s." - ) + raise RuntimeError(f"The program has not reached the pause statement before {timeout} s.") else: self.job.resume() self.counter += 1 @@ -697,19 +633,13 @@ def simulate(self): Simulate a given QUA program and store the simulated waveform into the simulated_wf attribute. """ prog = self.get_prog() - self.job = self.qmm.simulate( - self.config, prog, SimulationConfig(self.sim_time() // 4) - ) + self.job = self.qmm.simulate(self.config, prog, SimulationConfig(self.sim_time() // 4)) simulated_samples = self.job.get_simulated_samples() for con in [f"con{i}" for i in range(1, 10)]: if hasattr(simulated_samples, con): self.simulated_wf[con] = {} - self.simulated_wf[con]["analog"] = ( - self.job.get_simulated_samples().__dict__[con].analog - ) - self.simulated_wf[con]["digital"] = ( - self.job.get_simulated_samples().__dict__[con].digital - ) + self.simulated_wf[con]["analog"] = self.job.get_simulated_samples().__dict__[con].analog + self.simulated_wf[con]["digital"] = self.job.get_simulated_samples().__dict__[con].digital self.result_handles = self.job.result_handles def plot_simulated_wf(self): @@ -722,9 +652,7 @@ def plot_simulated_wf(self): for port in self.simulated_wf[con][t].keys(): if not np.all(self.simulated_wf[con][t][port] == 0): if len(self.simulated_wf.keys()) == 1: - plt.plot( - self.simulated_wf[con][t][port], label=f"{t} {port}" - ) + plt.plot(self.simulated_wf[con][t][port], label=f"{t} {port}") else: plt.plot( self.simulated_wf[con][t][port], @@ -806,9 +734,7 @@ def __init__(self, startparam, stopparam, numpointsparam, *args, **kwargs): self._numpointsparam = numpointsparam def get_raw(self): - return np.linspace( - self._startparam(), self._stopparam(), self._numpointsparam() - ) + return np.linspace(self._startparam(), self._stopparam(), self._numpointsparam()) # noinspection PyAbstractClass diff --git a/qualang_tools/loops/loops.py b/qualang_tools/loops/loops.py index 15b506f7..df8e555f 100644 --- a/qualang_tools/loops/loops.py +++ b/qualang_tools/loops/loops.py @@ -28,9 +28,7 @@ def from_array(var, array): # Check QUA vs python variables if not isinstance(var, _Variable): raise Exception("The first argument must be a QUA variable.") - if (not isinstance(array[0], (np.generic, int, float))) or ( - isinstance(array[0], bool) - ): + if (not isinstance(array[0], (np.generic, int, float))) or (isinstance(array[0], bool)): raise Exception("The array must be an array of python variables.") # Check array increment if np.isclose(np.std(np.diff(array)), 0): @@ -51,14 +49,8 @@ def from_array(var, array): if var.is_int(): # Check that the array is an array of int with integer increments - if ( - not float(step).is_integer() - or not float(start).is_integer() - or not float(stop).is_integer() - ): - raise Exception( - "When looping over a QUA int variable, the step and array elements must be integers." - ) + if not float(step).is_integer() or not float(start).is_integer() or not float(stop).is_integer(): + raise Exception("When looping over a QUA int variable, the step and array elements must be integers.") # Generate the loop parameters for positive and negative steps if step > 0: return var, int(start), var <= int(stop), var + int(step) @@ -170,9 +162,7 @@ def qua_arange(var, start, stop, step): stop_condition = stop if np.abs((stop - start) / step * 2**-28) >= np.abs(step): - raise Exception( - "The required accuracy is to large:N * (2 ** -28) > step/2, please contact a QM member." - ) + raise Exception("The required accuracy is to large:N * (2 ** -28) > step/2, please contact a QM member.") if step > 0: return var, start, var < stop_condition, var + step diff --git a/qualang_tools/multi_user/multi_user_tools.py b/qualang_tools/multi_user/multi_user_tools.py index cfe38e7d..a701e83f 100644 --- a/qualang_tools/multi_user/multi_user_tools.py +++ b/qualang_tools/multi_user/multi_user_tools.py @@ -17,9 +17,7 @@ def filter(self, record): @contextmanager -def qm_session( - qmm: QuantumMachinesManager, config: dict, timeout: int = 100 -) -> QuantumMachine: +def qm_session(qmm: QuantumMachinesManager, config: dict, timeout: int = 100) -> QuantumMachine: """ This context manager allows a user to _try_ to open a quantum machine, and if it is not possible since its resources are currently in use, @@ -56,9 +54,7 @@ def qm_session( and msg in e.errors[1][2] ): if not printed: - qm_log.warning( - f"QOP is busy. Waiting for it to free up for {timeout}s..." - ) + qm_log.warning(f"QOP is busy. Waiting for it to free up for {timeout}s...") printed = True sleep(0.2) time += 0.2 @@ -71,9 +67,7 @@ def qm_session( qm_log.removeFilter(filt) if is_busy and time >= timeout: qm_log.warning(f"While waiting for QOP to free, reached timeout: {timeout}s") - raise TimeoutError( - f"While waiting for QOP to free, reached timeout: {timeout}s" - ) + raise TimeoutError(f"While waiting for QOP to free, reached timeout: {timeout}s") try: yield qm while qm.get_running_job() is not None: diff --git a/qualang_tools/plot/fitting.py b/qualang_tools/plot/fitting.py index e032fd03..f894f2fa 100644 --- a/qualang_tools/plot/fitting.py +++ b/qualang_tools/plot/fitting.py @@ -84,11 +84,7 @@ def linear( ) # Print the initial guess if verbose=True if verbose: - print( - f"Initial guess:\n" - f" a = {a0 * y_normal / x_normal:.3f}, \n" - f" b = {b0 * y_normal:.3f}" - ) + print(f"Initial guess:\n" f" a = {a0 * y_normal / x_normal:.3f}, \n" f" b = {b0 * y_normal:.3f}") # Fitting function def func(x_var, c0, c1): @@ -181,9 +177,7 @@ def T1( # Finding a guess for the offsets final_offset = np.mean(y[np.min((int(len(y) * 0.9), len(y) - 3)) :]) # Finding a guess for the decay - guess_T1 = ( - 1 / (np.abs(np.polyfit(x, np.log(np.abs(y - final_offset)), 1)[0])) / 2 - ) + guess_T1 = 1 / (np.abs(np.polyfit(x, np.log(np.abs(y - final_offset)), 1)[0])) / 2 # Check user guess if guess is not None: @@ -322,9 +316,7 @@ def ramsey( f = f[1 : len(f) // 2] # Remove the DC peak if there is one if (np.abs(fft)[1:] - np.abs(fft)[:-1] > 0).any(): - first_read_data_ind = np.where(np.abs(fft)[1:] - np.abs(fft)[:-1] > 0)[0][ - 0 - ] # away from the DC peak + first_read_data_ind = np.where(np.abs(fft)[1:] - np.abs(fft)[:-1] > 0)[0][0] # away from the DC peak fft = fft[first_read_data_ind:] f = f[first_read_data_ind:] @@ -335,23 +327,12 @@ def ramsey( # The period is 1 / guess_freq --> number of oscillations --> peaks decay to get guess_T2 period = int(np.ceil(1 / out_freq)) peaks = ( - np.array( - [ - np.std(y[i * period : (i + 1) * period]) - for i in range(round(len(y) / period)) - ] - ) - * np.sqrt(2) - * 2 + np.array([np.std(y[i * period : (i + 1) * period]) for i in range(round(len(y) / period))]) * np.sqrt(2) * 2 ) # Finding a guess for the decay (slope of log(peaks)) if len(peaks) > 1: - guess_T2 = ( - -1 - / ((np.log(peaks)[-1] - np.log(peaks)[0]) / (period * (len(peaks) - 1))) - * (x[1] - x[0]) - ) + guess_T2 = -1 / ((np.log(peaks)[-1] - np.log(peaks)[0]) / (period * (len(peaks) - 1))) * (x[1] - x[0]) else: guess_T2 = 100 / x_normal @@ -360,9 +341,7 @@ def ramsey( final_offset = np.mean(y[-period:]) # Finding a guess for the phase - guess_phase = ( - np.angle(fft[np.argmax(np.abs(fft))]) - guess_freq * 2 * np.pi * x[0] - ) + guess_phase = np.angle(fft[np.argmax(np.abs(fft))]) - guess_freq * 2 * np.pi * x[0] # Check user guess if guess is not None: @@ -398,14 +377,9 @@ def ramsey( # Fitting function def func(x_var, a0, a1, a2, a3, a4, a5): - return final_offset * a4 * (1 - np.exp(-x_var / (guess_T2 * a1))) + peaks[ - 0 - ] / 2 * a2 * ( + return final_offset * a4 * (1 - np.exp(-x_var / (guess_T2 * a1))) + peaks[0] / 2 * a2 * ( np.exp(-x_var / (guess_T2 * a1)) - * ( - a5 * initial_offset / peaks[0] * 2 - + np.cos(2 * np.pi * a0 * guess_freq * x + a3) - ) + * (a5 * initial_offset / peaks[0] * 2 + np.cos(2 * np.pi * a0 * guess_freq * x + a3)) ) def fit_type(x_var, a): @@ -557,10 +531,7 @@ def transmission_resonator_spectroscopy( # Fitting function def func(x_var, a0, a1, a2, a3): - return ( - ((peak - v0) * a0) - / (1 + (4 * ((x_var - (f0 * a2)) ** 2) / ((width0 * a1) ** 2))) - ) + (v0 * a3) + return (((peak - v0) * a0) / (1 + (4 * ((x_var - (f0 * a2)) ** 2) / ((width0 * a1) ** 2)))) + (v0 * a3) def fit_type(x_var, a): return func(x_var, a[0], a[1], a[2], a[3]) @@ -577,10 +548,8 @@ def fit_type(x_var, a): (peak - v0) * perr[0] * (width0 * perr[1] * x_normal) * y_normal, ], "ki": [ - (popt[1] * width0 * x_normal) - - ((peak - v0) * popt[0] * (width0 * popt[1] * x_normal) * y_normal), - (perr[1] * width0 * x_normal) - - ((peak - v0) * perr[0] * (width0 * perr[1] * x_normal) * y_normal), + (popt[1] * width0 * x_normal) - ((peak - v0) * popt[0] * (width0 * popt[1] * x_normal) * y_normal), + (perr[1] * width0 * x_normal) - ((peak - v0) * perr[0] * (width0 * perr[1] * x_normal) * y_normal), ], "k": [popt[1] * width0 * x_normal, perr[1] * width0 * x_normal], "offset": [v0 * popt[3] * y_normal, v0 * perr[3] * y_normal], @@ -691,12 +660,8 @@ def reflection_resonator_spectroscopy( v0 = (np.mean(y[-10:-1]) + np.mean(y[0:10])) / 2 # Finding a guess to the slope - m = ( - np.mean(y[int(width0_arg_right + width0) : -1]) - - np.mean(y[0 : int(width0_arg_left - width0)]) - ) / ( - np.mean(x[int(width0_arg_right + width0) : -1]) - - np.mean(x[0 : int(width0_arg_left - width0)]) + m = (np.mean(y[int(width0_arg_right + width0) : -1]) - np.mean(y[0 : int(width0_arg_left - width0)])) / ( + np.mean(x[int(width0_arg_right + width0) : -1]) - np.mean(x[0 : int(width0_arg_left - width0)]) ) # Check user guess @@ -729,10 +694,7 @@ def reflection_resonator_spectroscopy( def func(x_var, a0, a1, a2, a3, a4): return ( ((v0 - peak) * a3) - - ( - ((v0 - peak) * a0) - / (1 + (4 * ((x_var - (f0 * a2)) ** 2) / ((width0 * a1) ** 2))) - ) + - (((v0 - peak) * a0) / (1 + (4 * ((x_var - (f0 * a2)) ** 2) / ((width0 * a1) ** 2)))) + m * a4 * x_var ) @@ -751,10 +713,8 @@ def fit_type(x_var, a): (v0 - peak) * perr[0] * (width0 * perr[1] * x_normal) * y_normal, ], "ki": [ - (popt[1] * width0 * x_normal) - - ((v0 - peak) * popt[0] * (width0 * popt[1] * x_normal) * y_normal), - (perr[1] * width0 * x_normal) - - ((v0 - peak) * perr[0] * (width0 * perr[1] * x_normal) * y_normal), + (popt[1] * width0 * x_normal) - ((v0 - peak) * popt[0] * (width0 * popt[1] * x_normal) * y_normal), + (perr[1] * width0 * x_normal) - ((v0 - peak) * perr[0] * (width0 * perr[1] * x_normal) * y_normal), ], "k": [popt[1] * width0 * x_normal, perr[1] * width0 * x_normal], "offset": [ @@ -862,46 +822,22 @@ def rabi( # If not enough oscillations if np.argmax(np.abs(fft)) < 1: # If at least 1 oscillation - if ( - np.max(np.diff(np.where(y < min(y) + 0.1 * np.abs(max(y) - min(y))))) - > 1 - ): - guess_freq = 1 / ( - np.max( - np.diff(np.where(y < min(y) + 0.1 * np.abs(max(y) - min(y)))) - ) - * (x[1] - x[0]) - ) + if np.max(np.diff(np.where(y < min(y) + 0.1 * np.abs(max(y) - min(y))))) > 1: + guess_freq = 1 / (np.max(np.diff(np.where(y < min(y) + 0.1 * np.abs(max(y) - min(y))))) * (x[1] - x[0])) # If less than 1 oscillation else: guess_freq = 1 / ( - ( - np.argmin(y[len(y) // 2 :]) - + len(y) // 2 - - np.argmin(y[: len(y) // 2]) - ) - * (x[1] - x[0]) + (np.argmin(y[len(y) // 2 :]) + len(y) // 2 - np.argmin(y[: len(y) // 2])) * (x[1] - x[0]) ) # The period is 1 / guess_freq --> number of oscillations --> peaks decay to get guess_T period = int(np.ceil(1 / out_freq)) peaks = ( - np.array( - [ - np.std(y[i * period : (i + 1) * period]) - for i in range(round(len(y) / period)) - ] - ) - * np.sqrt(2) - * 2 + np.array([np.std(y[i * period : (i + 1) * period]) for i in range(round(len(y) / period))]) * np.sqrt(2) * 2 ) # Finding a guess for the decay (slope of log(peaks)) if len(peaks) > 1: - guess_T = ( - -1 - / ((np.log(peaks)[-1] - np.log(peaks)[0]) / (period * (len(peaks) - 1))) - * (x[1] - x[0]) - ) + guess_T = -1 / ((np.log(peaks)[-1] - np.log(peaks)[0]) / (period * (len(peaks) - 1))) * (x[1] - x[0]) else: guess_T = 100 / x_normal @@ -912,9 +848,7 @@ def rabi( guess_amp = np.abs(np.max(y) - np.min(y)) # Finding a guess for the phase - guess_phase = ( - np.angle(fft[np.argmax(np.abs(fft))]) - guess_freq * 2 * np.pi * x[0] - ) + guess_phase = np.angle(fft[np.argmax(np.abs(fft))]) - guess_freq * 2 * np.pi * x[0] # Check user guess if guess is not None: @@ -947,9 +881,9 @@ def rabi( # Fitting function def func(x_var, a0, a1, a2, a3, a4): - return (guess_amp * a0) * ( - np.sin(0.5 * (2 * np.pi * guess_freq * a1) * x_var + a3) - ) ** 2 * np.exp(-x_var / np.abs(guess_T * a2)) + offset * a4 + return (guess_amp * a0) * (np.sin(0.5 * (2 * np.pi * guess_freq * a1) * x_var + a3)) ** 2 * np.exp( + -x_var / np.abs(guess_T * a2) + ) + offset * a4 def fit_type(x_var, a): return func(x_var, a[0], a[1], a[2], a[3], a[4]) @@ -1088,9 +1022,7 @@ def resonator_frequency_vs_flux( offset = np.mean(y) # Finding a guess for the phase - guess_phase = ( - np.angle(fft[np.argmax(np.abs(fft))]) - guess_freq * 2 * np.pi * x[0] - ) + guess_phase = np.angle(fft[np.argmax(np.abs(fft))]) - guess_freq * 2 * np.pi * x[0] guess_amp = np.max(y) - np.min(y) # Check user guess @@ -1121,9 +1053,7 @@ def resonator_frequency_vs_flux( # Fitting function def func(x_var, a0, a1, a2, a3): - return (guess_amp * a0) * np.sin( - (2 * np.pi * guess_freq * a1) * x_var + a2 - ) + offset * a3 + return (guess_amp * a0) * np.sin((2 * np.pi * guess_freq * a1) * x_var + a2) + offset * a3 def fit_type(x_var, a): return func(x_var, a[0], a[1], a[2], a[3]) diff --git a/qualang_tools/plot/plot.py b/qualang_tools/plot/plot.py index 9fca8b83..3391ad97 100644 --- a/qualang_tools/plot/plot.py +++ b/qualang_tools/plot/plot.py @@ -201,9 +201,7 @@ def plot_demodulated_data_1d( return fig, fit -def get_simulated_samples_by_element( - element_name: str, job: QmJob, config: dict -) -> Tuple: +def get_simulated_samples_by_element(element_name: str, job: QmJob, config: dict) -> Tuple: """ Extract the simulated samples (analog and digital) corresponding to a given element. @@ -233,9 +231,7 @@ def get_simulated_samples_by_element( if "digitalInputs" in element: for key in element["digitalInputs"].keys(): port = element["digitalInputs"][key]["port"] - digital_samples.append( - sample_struct.__dict__[port[0]].digital[str(port[1])].astype(int) - ) + digital_samples.append(sample_struct.__dict__[port[0]].digital[str(port[1])].astype(int)) else: digital_samples.append(None) @@ -267,10 +263,7 @@ def plot_simulator_output( # Find the elements used in the program el_list = [] for statement in qua_program.__dict__["_program"].script.body.statements: - if ( - statement.play.qe.name not in el_list - and statement.play.qe.name != "" - ): + if statement.play.qe.name not in el_list and statement.play.qe.name != "": el_list.append(statement.play.qe.name) else: raise Exception( @@ -278,12 +271,8 @@ def plot_simulator_output( ) plot_axes = [[element] for element in el_list] for plot_axis in plot_axes: - samples_struct.append( - [get_simulated_samples_by_element(pa, job, config)[0] for pa in plot_axis] - ) - digital_samples_struct.append( - [get_simulated_samples_by_element(pa, job, config)[1] for pa in plot_axis] - ) + samples_struct.append([get_simulated_samples_by_element(pa, job, config)[0] for pa in plot_axis]) + digital_samples_struct.append([get_simulated_samples_by_element(pa, job, config)[1] for pa in plot_axis]) fig = go.Figure().set_subplots(rows=len(plot_axes), cols=1, shared_xaxes=True) @@ -293,9 +282,7 @@ def plot_simulator_output( if samples_struct[i][j] is not None: if isinstance(samples_struct[i][j][0], float): fig.add_trace( - go.Scatter( - x=time_vec, y=samples_struct[i][j], name=plot_item + " [V]" - ), + go.Scatter(x=time_vec, y=samples_struct[i][j], name=plot_item + " [V]"), row=i + 1, col=1, ) @@ -327,9 +314,7 @@ def plot_simulator_output( y=digital_samples_struct[i][j][k], name=plot_item + " - " - + list( - config["elements"][plot_item]["digitalInputs"].keys() - )[k] + + list(config["elements"][plot_item]["digitalInputs"].keys())[k] + " [3.3V]", ), row=i + 1, diff --git a/qualang_tools/results/README.md b/qualang_tools/results/README.md index c9f2b9d5..4c9c4cb2 100644 --- a/qualang_tools/results/README.md +++ b/qualang_tools/results/README.md @@ -17,10 +17,10 @@ Then the results can be fetched with the `.fetch_all()` method while the program from qualang_tools.results import fetching_tool n_avg = 1000 -with program as prog: +with program() as prog: # QUA program with n_avg averaging iterations -qmm = QuantumMachinesManager(host="127.0.0.1", port="80") +qmm = QuantumMachinesManager(host=qop_ip, port=qop_port, cluster_name=cluster_name) qm = qmm.open_qm(config) job = qm.execute(prog) diff --git a/qualang_tools/results/results.py b/qualang_tools/results/results.py index 7c261290..be895e2d 100644 --- a/qualang_tools/results/results.py +++ b/qualang_tools/results/results.py @@ -22,9 +22,7 @@ def __init__(self, job, data_list, mode="wait_for_all"): if not data_list: raise Exception("The provided data list is empty.") if mode not in ["live", "wait_for_all"]: - raise Exception( - f"Mode '{mode}' is not supported. Supported modes are ['live', 'wait_for_all']" - ) + raise Exception(f"Mode '{mode}' is not supported. Supported modes are ['live', 'wait_for_all']") self.data_list = data_list self.mode = mode self.results = [] @@ -86,9 +84,7 @@ def fetch_all(self): self.res_handles.wait_for_all_values() for data in self.data_list: if hasattr(self.res_handles, data): - self.results.append( - self._format(self.res_handles.get(data).fetch_all()) - ) + self.results.append(self._format(self.res_handles.get(data).fetch_all())) elif self.mode == "live": self.results = [] @@ -97,9 +93,7 @@ def fetch_all(self): return self.results -def progress_counter( - iteration, total, progress_bar=True, percent=True, start_time=None -): +def progress_counter(iteration, total, progress_bar=True, percent=True, start_time=None): """Displays progress bar and prints remaining computation time. :param iteration: current iteration. Must be a python integer. diff --git a/qualang_tools/simulator/README.md b/qualang_tools/simulator/README.md new file mode 100644 index 00000000..54f33891 --- /dev/null +++ b/qualang_tools/simulator/README.md @@ -0,0 +1,43 @@ +# Simulator tools +This library includes tools to help simulate programs + +## create_simulator_controller_connections +Creates a list of :class:`~qm.simulate.interface.ControllerConnection` objects with the Inter-controllers connections between controllers in a way which maximizes the optical links connectivity. +For use inside the :class:`~qm.simulate.interface.SimulationConfig` for simulating the controllers' behavior. +It can be used to also simulate part of a small cluster: For example, the following command would create all the connections +needed to run a simulation on 'con1', 'con4', 'con5' which are part of a 9 OPX cluster: `create_simulator_controller_connections(9, [1,4,5])` + +### Usage example +A simple example for a 3 OPX cluster: +```python +from qualang_tools.simulator import create_simulator_controller_connections + +with program() as prog: + # QUA program + +qmm = QuantumMachinesManager(host=qop_ip, port=qop_port, cluster_name=cluster_name) +job = qmm.simulate(config, + prog, + SimulationConfig(simulation_duration, + controller_connections=create_simulator_controller_connections(3))) +``` + +A simulation running on 'con1', 'con4', 'con5' which are part of a 9 OPX cluster, which also has loopback connected between the controllers: +```python +from qualang_tools.simulator import create_simulator_controller_connections + +with program() as prog: + # QUA program + +qmm = QuantumMachinesManager(host=qop_ip, port=qop_port, cluster_name=cluster_name) +job = qmm.simulate(config, + prog, + SimulationConfig(simulation_duration, + simulation_interface=LoopbackInterface([('con1', 1, 'con4', 1), + ('con1', 2, 'con4', 2), + ('con4', 1, 'con1', 1), + ('con4', 2, 'con1', 2), + ], + latency=168), + controller_connections=create_simulator_controller_connections(9, [1,4,5]))) +``` \ No newline at end of file diff --git a/qualang_tools/simulator/__init__.py b/qualang_tools/simulator/__init__.py new file mode 100644 index 00000000..2f658b92 --- /dev/null +++ b/qualang_tools/simulator/__init__.py @@ -0,0 +1,5 @@ +from qualang_tools.simulator.simulator import create_simulator_controller_connections + +__all__ = [ + "create_simulator_controller_connections", +] diff --git a/qualang_tools/simulator/simulator.py b/qualang_tools/simulator/simulator.py new file mode 100644 index 00000000..e29d9069 --- /dev/null +++ b/qualang_tools/simulator/simulator.py @@ -0,0 +1,54 @@ +import numpy as np +from qm import ControllerConnection, InterOpxChannel + + +def create_simulator_controller_connections( + n_controllers, actual_controllers=None, n_connections=12, print_debug=False +): + """ + Creates a list of :class:`~qm.simulate.interface.ControllerConnection` objects with the Inter-controllers + connections between controllers in a way which maximizes the optical links connectivity. + For use inside the :class:`~qm.simulate.interface.SimulationConfig` for simulating the controllers` behavior. + + :param n_controllers: The number of controllers + :type n_controllers: int + :param actual_controllers: A list of the controllers actually being used in the simulation. For `con1` & `con2` use [1,2]. + :type actual_controllers: List[int] + :param n_connections: The number of optical connectors each controller has, default is 12 + :type n_connections: int + :param print_debug: If true, prints the connections to the terminal + :type print_debug: bool + :returns: The ControllerConnection object + + """ + if n_controllers == 1: + return [] + if not actual_controllers: + actual_controllers = [i + 1 for i in range(n_controllers)] + controller_connections = [] + unused_connection = np.ones((n_controllers, n_connections), dtype=bool) + while unused_connection.any(): + for i in range(n_controllers): + for j in range(i + 1, n_controllers): + first_con_port = np.nonzero(unused_connection[i, :])[0] + if first_con_port.size == 0: + break + first_con_port = first_con_port[0] + second_con_port = np.nonzero(unused_connection[j, :])[0] + if second_con_port.size == 0: + break + second_con_port = second_con_port[0] + if i + 1 in actual_controllers and j + 1 in actual_controllers: + controller_connections.append( + ControllerConnection( + InterOpxChannel(f"con{i+1}", first_con_port), InterOpxChannel(f"con{j+1}", second_con_port) + ) + ) + if print_debug: + print(f"con{i + 1}:{first_con_port} <-> con{j + 1}, {second_con_port}") + elif print_debug: + print(f"con{i + 1}:{first_con_port} <-> con{j + 1}, {second_con_port} - Skipped") + unused_connection[i, first_con_port] = False + unused_connection[j, second_con_port] = False + + return controller_connections diff --git a/qualang_tools/simulator_tools.py b/qualang_tools/simulator_tools.py index 3f585f95..77fa2288 100644 --- a/qualang_tools/simulator_tools.py +++ b/qualang_tools/simulator_tools.py @@ -1,57 +1,14 @@ -from qm import ControllerConnection, InterOpxChannel - - -def create_simulator_controller_connections(n_controllers, n_connections=12): - """ - Creates a list of :class:`~qm.simulate.interface.ControllerConnection` objects with all of the Inter-controllers - connections according to the `recommended schema - `__. - For use inside the :class:`~qm.simulate.interface.SimulationConfig` for simulating the controllers` behavior. - - :param n_controllers: The number of controllers - :type n_controllers: int - :param n_connections: The number of optical connectors each controller has, default is 12 - :type n_connections: int - :returns: The ControllerConnection object - - """ - if n_controllers == 1: - return None - - ncbc = n_connections // ( - n_controllers - 1 - ) # ncbc = number_of_connections_between_controllers - n_connections = ncbc * (n_controllers - 1) - first_controller_list = [] - first_port_list = [] - second_controller_list = [] - second_port_list = [] - for i in range(n_controllers): - first_controller_list = first_controller_list + [i + 1] * ( - n_connections - i * ncbc - ) - - first_port_list = first_port_list + [j for j in range(i * ncbc, n_connections)] - - for j in range(i + 1, n_controllers): - second_controller_list = second_controller_list + [j + 1] * ncbc - - second_port_list = second_port_list + [ - j for j in range(i * ncbc, (i + 1) * ncbc) - ] * (n_controllers - i - 1) - - controller_connections = [ - ControllerConnection( - InterOpxChannel(f"con{i}", j), InterOpxChannel(f"con{k}", l) - ) - for i, j, k, l in list( - zip( - first_controller_list, - first_port_list, - second_controller_list, - second_port_list, - ) - ) - ] - - return controller_connections +from qualang_tools.simulator import create_simulator_controller_connections +import warnings + +__all__ = [ + "create_simulator_controller_connections", +] + +warnings.warn( + "The 'create_simulator_controller_connections' function has been moved to 'qualang_tools.simulator'.", FutureWarning +) +warnings.warn( + "The 'create_simulator_controller_connections' function has been moved to 'qualang_tools.simulator'.", + DeprecationWarning, +) diff --git a/qualang_tools/units/units.py b/qualang_tools/units/units.py index 7195d68d..d579ecbc 100644 --- a/qualang_tools/units/units.py +++ b/qualang_tools/units/units.py @@ -21,12 +21,8 @@ def __init__(self): def _get_value(self) -> float: for frameinfo in stack(): for var in frameinfo.frame.f_locals.values(): - if isinstance( - var, Program - ): # we have a qua program being declared somewhere - if ( - var._is_in_scope # this is set by __enter__ and unset by __exit__ of Program - ): + if isinstance(var, Program): # we have a qua program being declared somewhere + if var._is_in_scope: # this is set by __enter__ and unset by __exit__ of Program return 0.25 # now it is in clock cycles else: return 1.0 # this is in nanoseconds @@ -215,9 +211,7 @@ def raw2volts(self, data: Union[float, ndarray]) -> Union[float, ndarray]: return data * self.V / 4096 @staticmethod - def volts2dBm( - Vp: Union[float, ndarray], Z: Union[float, int] = 50 - ) -> Union[float, ndarray]: + def volts2dBm(Vp: Union[float, ndarray], Z: Union[float, int] = 50) -> Union[float, ndarray]: """Converts the peak voltage (amplitude) from volts to dBm. :param Vp: the peak voltage (amplitude) in volts. Must be a python variable or array. @@ -227,9 +221,7 @@ def volts2dBm( return 10 * log10(((Vp / sqrt(2)) ** 2 * 1000) / Z) @staticmethod - def dBm2volts( - P_dBm: Union[float, ndarray], Z: Union[float, int] = 50 - ) -> Union[float, ndarray]: + def dBm2volts(P_dBm: Union[float, ndarray], Z: Union[float, int] = 50) -> Union[float, ndarray]: """Converts the power from dBm to volts (peak voltage or amplitude). :param P_dBm: the power in dBm. Must be a python variable or array. diff --git a/tests/test_config_builder.py b/tests/test_config_builder.py index 3c4d0bb6..740e7f5e 100644 --- a/tests/test_config_builder.py +++ b/tests/test_config_builder.py @@ -376,7 +376,7 @@ def test_deprecated_warning(): cb.add(elm) cb.build() - assert len(record.list) == 1 + assert len(record.list) == 2 with pytest.warns(None) as record: cb = ConfigBuilder() @@ -385,7 +385,7 @@ def test_deprecated_warning(): elm = Element("elm", element_analog_inputs=[cont.analog_output(1)]) cb.add(elm) cb.build() - assert len(record.list) == 0 + assert len(record.list) == 1 def test_digital_input(): diff --git a/tests/test_simulator_tools.py b/tests/test_simulator_tools.py index 6796d9bc..3712ad21 100644 --- a/tests/test_simulator_tools.py +++ b/tests/test_simulator_tools.py @@ -1,7 +1,6 @@ -import pytest from qm import ControllerConnection, InterOpxChannel -from qualang_tools.simulator_tools import create_simulator_controller_connections +from qualang_tools.simulator import create_simulator_controller_connections def test_two_controllers_connection_schema(): @@ -22,17 +21,17 @@ def test_two_controllers_connection_schema(): ) ) ] - generated_controller_connections = create_simulator_controller_connections(2, 12) + generated_controller_connections = create_simulator_controller_connections(2) assert len(controller_connections) == len(generated_controller_connections) for a, b in zip(controller_connections, generated_controller_connections): assert (a.source == b.source) & (a.target == b.target) def test_three_controllers_connection_schema(): - first_controller_list = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2] - first_port_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 6, 7, 8, 9, 10, 11] - second_controller_list = [2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] - second_port_list = [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + first_controller_list = [1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2] + first_port_list = [0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11] + second_controller_list = [2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3] + second_port_list = [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11] controller_connections = [ ControllerConnection( InterOpxChannel(f"con{i}", j), InterOpxChannel(f"con{k}", l) @@ -46,265 +45,19 @@ def test_three_controllers_connection_schema(): ) ) ] - generated_controller_connections = create_simulator_controller_connections(3, 12) + generated_controller_connections = create_simulator_controller_connections(3) assert len(controller_connections) == len(generated_controller_connections) for a, b in zip(controller_connections, generated_controller_connections): assert (a.source == b.source) & (a.target == b.target) -def test_four_controllers_connection_schema(): - first_controller_list = [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - ] - first_port_list = [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 8, - 9, - 10, - 11, - ] - second_controller_list = [ - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - 4, - ] - second_port_list = [ - 0, - 1, - 2, - 3, - 0, - 1, - 2, - 3, - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - ] - controller_connections = [ - ControllerConnection( - InterOpxChannel(f"con{i}", j), InterOpxChannel(f"con{k}", l) - ) - for i, j, k, l in list( - zip( - first_controller_list, - first_port_list, - second_controller_list, - second_port_list, - ) - ) - ] - generated_controller_connections = create_simulator_controller_connections(4, 12) - assert len(controller_connections) == len(generated_controller_connections) - for a, b in zip(controller_connections, generated_controller_connections): - assert (a.source == b.source) & (a.target == b.target) - - -def test_five_controllers_connection_schema(): - first_controller_list = [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - ] - first_port_list = [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 6, - 7, - 8, - 9, - 10, - 11, - 9, - 10, - 11, - ] - second_controller_list = [ - 2, - 2, - 2, - 3, - 3, - 3, - 4, - 4, - 4, - 5, - 5, - 5, - 3, - 3, - 3, - 4, - 4, - 4, - 5, - 5, - 5, - 4, - 4, - 4, - 5, - 5, - 5, - 5, - 5, - 5, - ] - second_port_list = [ - 0, - 1, - 2, - 0, - 1, - 2, - 0, - 1, - 2, - 0, - 1, - 2, - 3, - 4, - 5, - 3, - 4, - 5, - 3, - 4, - 5, - 6, - 7, - 8, - 6, - 7, - 8, - 9, - 10, - 11, - ] +def test_last_two_in_a_three_controllers_connection_schema(): + first_controller_list = [1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2] + first_port_list = [0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11] + second_controller_list = [2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3] + second_port_list = [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11] + filtered_lists = [(item1, item2, item3, item4) for item1, item2, item3, item4 in zip(first_controller_list, first_port_list, second_controller_list, second_port_list) if item1 != 1 and item3 != 1] + first_controller_list, first_port_list, second_controller_list, second_port_list = zip(*filtered_lists) controller_connections = [ ControllerConnection( InterOpxChannel(f"con{i}", j), InterOpxChannel(f"con{k}", l) @@ -318,349 +71,19 @@ def test_five_controllers_connection_schema(): ) ) ] - generated_controller_connections = create_simulator_controller_connections(5, 12) + generated_controller_connections = create_simulator_controller_connections(3, [2, 3]) assert len(controller_connections) == len(generated_controller_connections) for a, b in zip(controller_connections, generated_controller_connections): assert (a.source == b.source) & (a.target == b.target) -def test_six_controllers_connection_schema(): - first_controller_list = [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 5, - 5, - ] - first_port_list = [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 4, - 5, - 6, - 7, - 8, - 9, - 6, - 7, - 8, - 9, - 8, - 9, - ] - second_controller_list = [ - 2, - 2, - 3, - 3, - 4, - 4, - 5, - 5, - 6, - 6, - 3, - 3, - 4, - 4, - 5, - 5, - 6, - 6, - 4, - 4, - 5, - 5, - 6, - 6, - 5, - 5, - 6, - 6, - 6, - 6, - ] - second_port_list = [ - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 0, - 1, - 2, - 3, - 2, - 3, - 2, - 3, - 2, - 3, - 4, - 5, - 4, - 5, - 4, - 5, - 6, - 7, - 6, - 7, - 8, - 9, - ] - controller_connections = [ - ControllerConnection( - InterOpxChannel(f"con{i}", j), InterOpxChannel(f"con{k}", l) - ) - for i, j, k, l in list( - zip( - first_controller_list, - first_port_list, - second_controller_list, - second_port_list, - ) - ) - ] - generated_controller_connections = create_simulator_controller_connections(6, 12) - assert len(controller_connections) == len(generated_controller_connections) - for a, b in zip(controller_connections, generated_controller_connections): - assert (a.source == b.source) & (a.target == b.target) - - -def test_ten_controllers_connection_schema(): - first_controller_list = [ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 4, - 4, - 5, - 5, - 5, - 5, - 5, - 6, - 6, - 6, - 6, - 7, - 7, - 7, - 8, - 8, - 9, - ] - first_port_list = [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 3, - 4, - 5, - 6, - 7, - 8, - 4, - 5, - 6, - 7, - 8, - 5, - 6, - 7, - 8, - 6, - 7, - 8, - 7, - 8, - 8, - ] - second_controller_list = [ - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 5, - 6, - 7, - 8, - 9, - 10, - 6, - 7, - 8, - 9, - 10, - 7, - 8, - 9, - 10, - 8, - 9, - 10, - 9, - 10, - 10, - ] - second_port_list = [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 3, - 3, - 3, - 3, - 4, - 4, - 4, - 4, - 4, - 5, - 5, - 5, - 5, - 6, - 6, - 6, - 7, - 7, - 8, - ] +def test_two_in_a_three_controllers_connection_schema(): + first_controller_list = [1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2] + first_port_list = [0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11] + second_controller_list = [2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3] + second_port_list = [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11] + filtered_lists = [(item1, item2, item3, item4) for item1, item2, item3, item4 in zip(first_controller_list, first_port_list, second_controller_list, second_port_list) if item1 != 2 and item3 != 2] + first_controller_list, first_port_list, second_controller_list, second_port_list = zip(*filtered_lists) controller_connections = [ ControllerConnection( InterOpxChannel(f"con{i}", j), InterOpxChannel(f"con{k}", l) @@ -674,7 +97,7 @@ def test_ten_controllers_connection_schema(): ) ) ] - generated_controller_connections = create_simulator_controller_connections(10, 12) + generated_controller_connections = create_simulator_controller_connections(3, [1, 3]) assert len(controller_connections) == len(generated_controller_connections) for a, b in zip(controller_connections, generated_controller_connections): assert (a.source == b.source) & (a.target == b.target) diff --git a/tests/test_waveform_tools.py b/tests/test_waveform_tools.py index 7f11ea27..5155ccd8 100644 --- a/tests/test_waveform_tools.py +++ b/tests/test_waveform_tools.py @@ -1,6 +1,5 @@ import numpy as np import pytest -from matplotlib import pyplot as plt from scipy.signal.windows import gaussian, blackman from qualang_tools.config import ( @@ -16,8 +15,8 @@ ) -@pytest.mark.parametrize("length", [16, 21, 60]) -def test_drag_no_drag_gaussian_to_scipy(length): +@pytest.mark.parametrize("length, sampling_rate", list(zip([16, 21, 60] * 2, [1e9, 1e9, 1e9, 2e9, 2e9, 2e9]))) +def test_drag_no_drag_gaussian_to_scipy(length, sampling_rate): amp = 0.1 sigma = length // 5 I_wf, Q_wf = drag_gaussian_pulse_waveforms( @@ -28,6 +27,7 @@ def test_drag_no_drag_gaussian_to_scipy(length): anharmonicity=0, detuning=0, subtracted=False, + sampling_rate=sampling_rate ) I_sub_wf, Q_sub_wf = drag_gaussian_pulse_waveforms( amplitude=amp, @@ -37,15 +37,16 @@ def test_drag_no_drag_gaussian_to_scipy(length): anharmonicity=0, detuning=0, subtracted=True, + sampling_rate=sampling_rate ) - gauss = amp * gaussian(length, sigma) + gauss = amp * gaussian(int(length * sampling_rate/1e9), sigma * sampling_rate / 1e9) sub_gauss = gauss - gauss[0] assert (I_wf == gauss).all() assert (I_sub_wf == sub_gauss).all() -@pytest.mark.parametrize("length", [16, 21, 60]) -def test_drag_no_detune_symmetric(length): +@pytest.mark.parametrize("length, sampling_rate", list(zip([16, 21, 60] * 2, [1e9, 1e9, 1e9, 2e9, 2e9, 2e9]))) +def test_drag_no_detune_symmetric(length, sampling_rate): amp = 0.1 sigma = length // 5 I_gauss_wf, Q_gauss_wf = drag_gaussian_pulse_waveforms( @@ -56,28 +57,29 @@ def test_drag_no_detune_symmetric(length): anharmonicity=10e6, detuning=0, subtracted=False, + sampling_rate=sampling_rate ) I_cos_wf, Q_cos_wf = drag_cosine_pulse_waveforms( - amplitude=amp, length=length, alpha=0.1, anharmonicity=10e6, detuning=0 + amplitude=amp, length=length, alpha=0.1, anharmonicity=10e6, detuning=0, sampling_rate=sampling_rate ) - I_gauss_first_half = I_gauss_wf[: length // 2] - Q_gauss_first_half = Q_gauss_wf[: length // 2] - if length % 2 == 0: - I_gauss_second_half = I_gauss_wf[length // 2 :] - Q_gauss_second_half = Q_gauss_wf[length // 2 :] + I_gauss_first_half = I_gauss_wf[: int(length * sampling_rate / 1e9) // 2] + Q_gauss_first_half = Q_gauss_wf[: int(length * sampling_rate / 1e9) // 2] + if int(length * sampling_rate / 1e9) % 2 == 0: + I_gauss_second_half = I_gauss_wf[int(length * sampling_rate / 1e9) // 2 :] + Q_gauss_second_half = Q_gauss_wf[int(length * sampling_rate / 1e9) // 2 :] else: - I_gauss_second_half = I_gauss_wf[length // 2 + 1 :] - Q_gauss_second_half = Q_gauss_wf[length // 2 + 1 :] - - I_cos_first_half = I_cos_wf[: length // 2] - Q_cos_first_half = Q_cos_wf[: length // 2] - if length % 2 == 0: - I_cos_second_half = I_cos_wf[length // 2 :] - Q_cos_second_half = Q_cos_wf[length // 2 :] + I_gauss_second_half = I_gauss_wf[int(length * sampling_rate / 1e9) // 2 + 1 :] + Q_gauss_second_half = Q_gauss_wf[int(length * sampling_rate / 1e9) // 2 + 1 :] + + I_cos_first_half = I_cos_wf[: int(length * sampling_rate / 1e9) // 2] + Q_cos_first_half = Q_cos_wf[: int(length * sampling_rate / 1e9) // 2] + if int(length * sampling_rate / 1e9) % 2 == 0: + I_cos_second_half = I_cos_wf[int(length * sampling_rate / 1e9) // 2 :] + Q_cos_second_half = Q_cos_wf[int(length * sampling_rate / 1e9) // 2 :] else: - I_cos_second_half = I_cos_wf[length // 2 + 1 :] - Q_cos_second_half = Q_cos_wf[length // 2 + 1 :] + I_cos_second_half = I_cos_wf[int(length * sampling_rate / 1e9) // 2 + 1 :] + Q_cos_second_half = Q_cos_wf[int(length * sampling_rate / 1e9) // 2 + 1 :] assert (np.array(I_gauss_first_half) == np.flip(I_gauss_second_half)).all() assert (np.array(Q_gauss_first_half) == -np.flip(Q_gauss_second_half)).all() @@ -145,69 +147,69 @@ def test_drag_zero_delta(): @pytest.mark.parametrize( - "flat_length, rise_fall_length", - list(zip([0, 16, 16, 21, 21, 60, 60], [8, 5, 10, 5, 10, 0, 10])), + "flat_length, rise_fall_length, sampling_rate", + list(zip([0, 16, 16, 21, 21, 60, 60, 0, 16, 16, 21, 21, 60, 60], [8, 5, 10, 5, 10, 0, 10, 8, 5, 10, 5, 10, 0, 10], [1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9, 2e9, 2e9, 2e9, 2e9, 2e9, 2e9, 2e9])), ) -def test_flattop_flat_length(flat_length, rise_fall_length): +def test_flattop_flat_length(flat_length, rise_fall_length, sampling_rate): amp = 0.1 - flattop_gaussian = flattop_gaussian_waveform(amp, flat_length, rise_fall_length) - flattop_cosine = flattop_cosine_waveform(amp, flat_length, rise_fall_length) - flattop_tanh = flattop_tanh_waveform(amp, flat_length, rise_fall_length) - flattop_blackman = flattop_blackman_waveform(amp, flat_length, rise_fall_length) + flattop_gaussian = flattop_gaussian_waveform(amp, flat_length, rise_fall_length, sampling_rate=sampling_rate) + flattop_cosine = flattop_cosine_waveform(amp, flat_length, rise_fall_length, sampling_rate=sampling_rate) + flattop_tanh = flattop_tanh_waveform(amp, flat_length, rise_fall_length, sampling_rate=sampling_rate) + flattop_blackman = flattop_blackman_waveform(amp, flat_length, rise_fall_length, sampling_rate=sampling_rate) flattop_gaussian_rise = flattop_gaussian_waveform( - amp, flat_length, rise_fall_length, return_part="rise" + amp, flat_length, rise_fall_length, return_part="rise", sampling_rate=sampling_rate ) flattop_cosine_rise = flattop_cosine_waveform( - amp, flat_length, rise_fall_length, return_part="rise" + amp, flat_length, rise_fall_length, return_part="rise", sampling_rate=sampling_rate ) flattop_tanh_rise = flattop_tanh_waveform( - amp, flat_length, rise_fall_length, return_part="rise" + amp, flat_length, rise_fall_length, return_part="rise", sampling_rate=sampling_rate ) flattop_blackman_rise = flattop_blackman_waveform( - amp, flat_length, rise_fall_length, return_part="rise" + amp, flat_length, rise_fall_length, return_part="rise", sampling_rate=sampling_rate ) flattop_gaussian_fall = flattop_gaussian_waveform( - amp, flat_length, rise_fall_length, return_part="fall" + amp, flat_length, rise_fall_length, return_part="fall", sampling_rate=sampling_rate ) flattop_cosine_fall = flattop_cosine_waveform( - amp, flat_length, rise_fall_length, return_part="fall" + amp, flat_length, rise_fall_length, return_part="fall", sampling_rate=sampling_rate ) flattop_tanh_fall = flattop_tanh_waveform( - amp, flat_length, rise_fall_length, return_part="fall" + amp, flat_length, rise_fall_length, return_part="fall", sampling_rate=sampling_rate ) flattop_blackman_fall = flattop_blackman_waveform( - amp, flat_length, rise_fall_length, return_part="fall" + amp, flat_length, rise_fall_length, return_part="fall", sampling_rate=sampling_rate ) assert np.allclose( flattop_gaussian, - flattop_gaussian_rise + [amp] * flat_length + flattop_gaussian_fall, + flattop_gaussian_rise + [amp] * int(flat_length * sampling_rate / 1e9) + flattop_gaussian_fall, rtol=1e-10, ) assert np.allclose( flattop_cosine, - flattop_cosine_rise + [amp] * flat_length + flattop_cosine_fall, + flattop_cosine_rise + [amp] * int(flat_length * sampling_rate / 1e9) + flattop_cosine_fall, rtol=1e-10, ) assert np.allclose( flattop_tanh, - flattop_tanh_rise + [amp] * flat_length + flattop_tanh_fall, + flattop_tanh_rise + [amp] * int(flat_length * sampling_rate / 1e9) + flattop_tanh_fall, rtol=1e-10, ) assert np.allclose( flattop_blackman, - flattop_blackman_rise + [amp] * flat_length + flattop_blackman_fall, + flattop_blackman_rise + [amp] * int(flat_length * sampling_rate / 1e9) + flattop_blackman_fall, rtol=1e-10, ) assert np.allclose( flattop_gaussian_rise + flattop_gaussian_fall, - (amp * gaussian(2 * rise_fall_length, rise_fall_length / 5)).tolist(), + (amp * gaussian(int(np.round(2 * rise_fall_length * sampling_rate / 1e9)), rise_fall_length / 5 * sampling_rate / 1e9)).tolist(), rtol=1e-10, ) cosine_rise_part = ( - amp * 0.5 * (1 - np.cos(np.linspace(0, np.pi, rise_fall_length))) + amp * 0.5 * (1 - np.cos(np.linspace(0, np.pi, int(rise_fall_length * sampling_rate / 1e9)))) ).tolist() assert np.allclose( flattop_cosine_rise + flattop_cosine_fall, @@ -215,7 +217,7 @@ def test_flattop_flat_length(flat_length, rise_fall_length): rtol=1e-10, ) tanh_rise_part = ( - amp * 0.5 * (1 + np.tanh(np.linspace(-4, 4, rise_fall_length))) + amp * 0.5 * (1 + np.tanh(np.linspace(-4, 4, int(rise_fall_length * sampling_rate / 1e9)))) ).tolist() assert np.allclose( flattop_tanh_rise + flattop_tanh_fall, @@ -224,23 +226,24 @@ def test_flattop_flat_length(flat_length, rise_fall_length): ) assert np.allclose( flattop_blackman_rise + flattop_blackman_fall, - (amp * blackman(2 * rise_fall_length)).tolist(), + (amp * blackman(2 * int(rise_fall_length * sampling_rate / 1e9))).tolist(), rtol=1e-10, ) @pytest.mark.parametrize( - "pulse_length, v_start, v_end", + "pulse_length, v_start, v_end, sampling_rate", list( zip( - np.linspace(2, 31, 30).astype(int).tolist() + [10], - np.linspace(0, 0.5, 30).tolist() + [-0.2], - np.linspace(0.5, 0, 30).tolist() + [-0.2], + np.linspace(2, 31, 30).astype(int).tolist(), + np.linspace(-0.5, 0.5, 30).tolist(), + np.linspace(0.5, -0.5, 30).tolist(), + [1e9]*15 + [2e9]*15, ) ), ) -def test_blackman_integral_waveform(pulse_length, v_start, v_end): - waveform = blackman_integral_waveform(pulse_length, v_start, v_end) - assert len(waveform) == pulse_length +def test_blackman_integral_waveform(pulse_length, v_start, v_end, sampling_rate): + waveform = blackman_integral_waveform(pulse_length, v_start, v_end, sampling_rate) + assert len(waveform) == int(pulse_length * sampling_rate / 1e9) assert np.isclose(waveform[0], v_start, rtol=1e-10) assert np.isclose(waveform[-1], v_end, rtol=1e-10)