From 0b00deddcadc5fa2dc099d3e963c32d8c92f9905 Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Fri, 21 Jul 2023 13:33:51 +0200 Subject: [PATCH 01/16] add pylint workflow --- .github/workflows/static.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/static.yml diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml new file mode 100644 index 00000000..4aee6e00 --- /dev/null +++ b/.github/workflows/static.yml @@ -0,0 +1,31 @@ +name: Static Code Analysis + +on: + pull_request: + push: + branches: ["main"] + +permissions: {} + +jobs: + pylint: + strategy: + matrix: + python-version: ["3.11"] + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint + - name: Analysing the code with pylint + run: | + pylint src From 36de6f919fa70de16ef0061f89df9aba37a8a48d Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Fri, 21 Jul 2023 13:45:50 +0200 Subject: [PATCH 02/16] add mypy workflow --- .github/workflows/static.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 4aee6e00..6c49932e 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -29,3 +29,25 @@ jobs: - name: Analysing the code with pylint run: | pylint src + + mypy: + strategy: + matrix: + python-version: ["3.11"] + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install mypy + - name: Analysing the code with mypy + run: | + mypy src From 6d01df6b63d8a42e9126b1e57cf32e0327452046 Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Fri, 21 Jul 2023 14:01:25 +0200 Subject: [PATCH 03/16] Install qumada before analysis --- .github/workflows/static.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 6c49932e..15389d77 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -26,6 +26,8 @@ jobs: run: | python -m pip install --upgrade pip pip install pylint + - name: Install package + run: python -m pip install -e . - name: Analysing the code with pylint run: | pylint src @@ -48,6 +50,8 @@ jobs: run: | python -m pip install --upgrade pip pip install mypy + - name: Install package + run: python -m pip install -e . - name: Analysing the code with mypy run: | mypy src From 842c3c1e38c2ebbfd67d02d17005113b2b544d8f Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 13:57:07 +0200 Subject: [PATCH 04/16] use flake8 instead of pylint add mypy to tox --- .github/workflows/static.yml | 14 ++++++++++---- .pre-commit-config.yaml | 4 ++++ dev_requirements.txt | 2 +- setup.cfg | 4 +--- tox.ini | 16 +++++++++++----- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 15389d77..0be56edd 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -8,7 +8,7 @@ on: permissions: {} jobs: - pylint: + flake8: strategy: matrix: python-version: ["3.11"] @@ -25,12 +25,18 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pylint + pip install flake8 - name: Install package run: python -m pip install -e . - - name: Analysing the code with pylint + - name: Analysing the code with flake8 run: | - pylint src + flake8 --color=never --tee --output-file=flake8-output src + - name: Upload flake8 output + uses: actions/upload-artifact@v3 + with: + name: flake8-output + path: flake8-output + if: always() mypy: strategy: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cfcdc784..2c010100 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,3 +29,7 @@ repos: hooks: - id: black args: ["--line-length", "120"] +- repo: https://github.com/pycqa/flake8 + rev: 6.1.0 + hooks: + - id: flake8 \ No newline at end of file diff --git a/dev_requirements.txt b/dev_requirements.txt index 1e215d82..2c70a103 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -9,7 +9,7 @@ pre-commit pyupgrade black -pylint +flake8 mypy pytest diff --git a/setup.cfg b/setup.cfg index eb32ba54..88d61f3c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,10 +3,8 @@ package_dir = = src packages = find: -[pylint.master] +[flake8] max-line-length = 120 -ignore = FZJ_Decadac.py,Example_measurements.py,SET_testing.py -extension-pkg-whitelist = PyQt5 [mypy] show_error_codes = True diff --git a/tox.ini b/tox.ini index 5ac19c1d..d83f44d1 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,8 @@ [tox] envlist = py{39,310,311} - lint + flake8 + mypy [testenv:py{39,310,311}] deps = @@ -13,9 +14,14 @@ deps = commands = pytest --cov=src/qumada --cov-report term src/tests {posargs} -[testenv:lint] +[testenv:flake8] deps = - pylint - pylint-gitlab + flake8 commands = - pylint src {posargs} + flake8 src {posargs} + +[testenv:mypy] +deps = + mypy +commands = + mypy src {posargs} From 4db93c930b7749056d2b47abe8ff4c359ebcfaa8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:59:15 +0000 Subject: [PATCH 05/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2c010100..898d8a76 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,4 +32,4 @@ repos: - repo: https://github.com/pycqa/flake8 rev: 6.1.0 hooks: - - id: flake8 \ No newline at end of file + - id: flake8 From 35a47da104c29d5222e0a374c2968bb27d117714 Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 14:06:53 +0200 Subject: [PATCH 06/16] don't upload flake8 output --- .github/workflows/static.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 0be56edd..cc17602a 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -30,13 +30,7 @@ jobs: run: python -m pip install -e . - name: Analysing the code with flake8 run: | - flake8 --color=never --tee --output-file=flake8-output src - - name: Upload flake8 output - uses: actions/upload-artifact@v3 - with: - name: flake8-output - path: flake8-output - if: always() + flake8 src mypy: strategy: From af34d47c4b3f9fee4311bcfdddac942e1450b6c7 Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 14:30:31 +0200 Subject: [PATCH 07/16] use mypy and flake8 only in pre-commit and not in separate actions --- .github/workflows/static.yml | 57 ------------------------------------ .pre-commit-config.yaml | 4 +++ 2 files changed, 4 insertions(+), 57 deletions(-) delete mode 100644 .github/workflows/static.yml diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml deleted file mode 100644 index cc17602a..00000000 --- a/.github/workflows/static.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Static Code Analysis - -on: - pull_request: - push: - branches: ["main"] - -permissions: {} - -jobs: - flake8: - strategy: - matrix: - python-version: ["3.11"] - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - cache: "pip" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install flake8 - - name: Install package - run: python -m pip install -e . - - name: Analysing the code with flake8 - run: | - flake8 src - - mypy: - strategy: - matrix: - python-version: ["3.11"] - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - cache: "pip" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install mypy - - name: Install package - run: python -m pip install -e . - - name: Analysing the code with mypy - run: | - mypy src diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 898d8a76..e1829fa1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,3 +33,7 @@ repos: rev: 6.1.0 hooks: - id: flake8 +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.5.0 + hooks: + - id: mypy \ No newline at end of file From 78155fa33336ab0bd8cdec1867b5575a2a51dccc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 12:37:47 +0000 Subject: [PATCH 08/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e1829fa1..7b47aad0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,4 +36,4 @@ repos: - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.5.0 hooks: - - id: mypy \ No newline at end of file + - id: mypy From 66c03ab2dfa82bca8a104d3391365064ad1e4b28 Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 17:07:01 +0200 Subject: [PATCH 09/16] fix flake8 errors on most files --- src/qumada/instrument/buffers/buffer.py | 10 ++++--- .../instrument/buffers/dummy_dmm_buffer.py | 9 ++++--- src/qumada/instrument/buffers/sr830_buffer.py | 3 ++- .../custom_drivers/Dummies/dummy_dac.py | 2 +- .../custom_drivers/Dummies/dummy_dmm.py | 6 ++--- .../instrument/custom_drivers/ZI/MFLI.py | 2 +- src/qumada/instrument/mapping/base.py | 13 +++++---- src/qumada/measurement/measurement.py | 11 +++++--- src/qumada/measurement/scripts/__init__.py | 2 +- src/qumada/metadata.py | 5 +++- src/tests/mapping_test.py | 27 +++++++++++-------- src/tests/metadata_test.py | 2 -- src/tests/plotting_2D.py | 11 ++++---- 13 files changed, 60 insertions(+), 43 deletions(-) diff --git a/src/qumada/instrument/buffers/buffer.py b/src/qumada/instrument/buffers/buffer.py index 135570e8..3c8ecd54 100644 --- a/src/qumada/instrument/buffers/buffer.py +++ b/src/qumada/instrument/buffers/buffer.py @@ -63,7 +63,8 @@ def map_buffers( Args: components (Mapping[Any, Metadatable]): Instruments/Components in QCoDeS - gate_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]]): Gates, as defined in the measurement script + gate_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]]): + Gates, as defined in the measurement script """ # subscribe to gettable parameters with buffer for gate, parameters in gate_parameters.items(): @@ -87,7 +88,7 @@ def map_buffers( if overwrite_trigger is not None: try: chosen = int(overwrite_trigger) - except: + except Exception: chosen = int(input(f"Choose the trigger input for {instrument.name}: ")) else: chosen = int(input(f"Choose the trigger input for {instrument.name}: ")) @@ -111,7 +112,8 @@ def _map_triggers( Args: components (Mapping[Any, Metadatable]): Instruments/Components in QCoDeS - gate_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]]): Gates, as defined in the measurement script + gate_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]]): + Gates, as defined in the measurement script """ triggered_instruments = filter(is_triggerable, components.values()) for instrument in triggered_instruments: @@ -126,7 +128,7 @@ def _map_triggers( if overwrite_trigger is not None: try: chosen = int(overwrite_trigger) - except: + except Exception: chosen = int(input(f"Choose the trigger input for {instrument.name}: ")) else: chosen = int(input(f"Choose the trigger input for {instrument.name}: ")) diff --git a/src/qumada/instrument/buffers/dummy_dmm_buffer.py b/src/qumada/instrument/buffers/dummy_dmm_buffer.py index 06f07099..54904428 100644 --- a/src/qumada/instrument/buffers/dummy_dmm_buffer.py +++ b/src/qumada/instrument/buffers/dummy_dmm_buffer.py @@ -29,7 +29,7 @@ from jsonschema import validate from qcodes.parameters import Parameter -from qumada.instrument.buffers.buffer import Buffer +from qumada.instrument.buffers.buffer import Buffer, BufferException from qumada.instrument.custom_drivers.Dummies.dummy_dmm import DummyDmm @@ -72,7 +72,8 @@ def num_points(self) -> int | None: def num_points(self, num_points) -> None: if num_points > 16383: raise BufferException( - "Dummy Dacs Buffer is to small for this measurement. Please reduce the number of data points or the delay" + "Dummy Dacs Buffer is to small for this measurement. " + "Please reduce the number of data points or the delay" ) self._num_points = int(num_points) @@ -123,13 +124,13 @@ def read(self) -> dict: return self.read_raw() def subscribe(self, parameters: list[Parameter]) -> None: - assert type(parameters) == list + assert isinstance(parameters, list) for parameter in parameters: self._device.buffer.subscribe(parameter) self._subscribed_parameters.add(parameter) def unsubscribe(self, parameters: list[Parameter]) -> None: - assert type(parameters) == list + assert isinstance(parameters, list) for parameter in parameters: if parameter in self._device.buffer.subscribed_params: self._device.buffer.subscribed_params.remove(parameter) diff --git a/src/qumada/instrument/buffers/sr830_buffer.py b/src/qumada/instrument/buffers/sr830_buffer.py index 196dab79..987ed2cf 100644 --- a/src/qumada/instrument/buffers/sr830_buffer.py +++ b/src/qumada/instrument/buffers/sr830_buffer.py @@ -114,7 +114,8 @@ def trigger(self, trigger: str | None) -> None: self._device.buffer_trig_mode("ON") else: raise BufferException( - "SR830 does not support setting custom trigger inputs. Use 'external' and the input on the back of the unit." + "SR830 does not support setting custom trigger inputs. " + "Use 'external' and the input on the back of the unit." ) self._trigger = trigger diff --git a/src/qumada/instrument/custom_drivers/Dummies/dummy_dac.py b/src/qumada/instrument/custom_drivers/Dummies/dummy_dac.py index e788cdeb..6dfbf1b1 100644 --- a/src/qumada/instrument/custom_drivers/Dummies/dummy_dac.py +++ b/src/qumada/instrument/custom_drivers/Dummies/dummy_dac.py @@ -58,7 +58,7 @@ def ramp(self, start, stop, duration, stepsize=0.01): self.thread.start() def _run_triggered_ramp(self, start, stop, duration, stepsize=0.01): - _is_triggered = self._is_triggered.wait() + _ = self._is_triggered.wait() num_points = int((stop - start) / stepsize) for setpoint in np.linspace(start, stop, num_points): self.voltage(setpoint) diff --git a/src/qumada/instrument/custom_drivers/Dummies/dummy_dmm.py b/src/qumada/instrument/custom_drivers/Dummies/dummy_dmm.py index 013074ee..7e105498 100644 --- a/src/qumada/instrument/custom_drivers/Dummies/dummy_dmm.py +++ b/src/qumada/instrument/custom_drivers/Dummies/dummy_dmm.py @@ -78,13 +78,13 @@ def start(self): self.thread.start() def _run(self): - _is_triggered = self._is_triggered.wait() + _ = self._is_triggered.wait() for i in range(0, self.buffer_length): for j in range(len(self.subscribed_params)): datapoint = self.subscribed_params[j]() - if type(datapoint) == float: + if isinstance(datapoint, float): self.buffer_data[j].append(self.subscribed_params[j]()) - elif type(datapoint) == list: + elif isinstance(datapoint, list): self.buffer_data[j].append(self.subscribed_params[j]()[i]) sleep(1 / self.SR) self.is_finished = True diff --git a/src/qumada/instrument/custom_drivers/ZI/MFLI.py b/src/qumada/instrument/custom_drivers/ZI/MFLI.py index 627c3dea..5374bf5a 100644 --- a/src/qumada/instrument/custom_drivers/ZI/MFLI.py +++ b/src/qumada/instrument/custom_drivers/ZI/MFLI.py @@ -45,7 +45,7 @@ def __init__( self, name: str, device: str, serverhost: str = "localhost", existing_session: Session = None, **kwargs ): super().__init__(name, **kwargs) - if type(existing_session) == Session: + if isinstance(existing_session, Session): session = existing_session else: self.session = session = Session(serverhost) diff --git a/src/qumada/instrument/mapping/base.py b/src/qumada/instrument/mapping/base.py index acdd4bc1..ea9367ca 100644 --- a/src/qumada/instrument/mapping/base.py +++ b/src/qumada/instrument/mapping/base.py @@ -166,7 +166,7 @@ def add_mapping_to_instrument( instrument._qumada_mapping = mapping try: instrument._qumada_trigger = mapping.trigger - except: + except Exception: pass # TODO: Better name?? elif path is not None and mapping is None: @@ -187,7 +187,8 @@ def add_mapping_to_instrument( def _generate_mapping_stub(instrument: Instrument, path: str) -> None: """ - Generates JSON stub of instrument parametes and saves it under the provided path. Overwrites existing files by default. + Generates JSON stub of instrument parametes and saves it under the provided path. + Overwrites existing files by default. The saved JSON-structure is as follows: @@ -231,9 +232,11 @@ def map_gates_to_instruments( Args: components (Mapping[Any, Metadatable]): Instruments/Components in QCoDeS - gate_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]]): Gates, as defined in the measurement script - existing_gate_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]] | None): Already existing mapping - that is used to automatically create the mapping for already known gates without user input. + gate_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]]): + Gates, as defined in the measurement script + existing_gate_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]] | None): + Already existing mapping that is used to automatically create the mapping for already known gates + without user input. metadata (Metadata | None): If provided, add mapping to the metadata object. map_manually (bool): If set to True, don't try to automatically map parameters to gates. Defaults to False. """ diff --git a/src/qumada/measurement/measurement.py b/src/qumada/measurement/measurement.py index 4ecf8e9f..f092ca37 100644 --- a/src/qumada/measurement/measurement.py +++ b/src/qumada/measurement/measurement.py @@ -44,6 +44,8 @@ from qumada.utils.ramp_parameter import ramp_or_set_parameter from qumada.utils.utils import flatten_array +logger = logging.getLogger(__name__) + def is_measurement_script(o): return inspect.isclass(o) and issubclass(o, MeasurementScript) @@ -205,13 +207,13 @@ def setup( cls = type(self) try: self.buffer_settings.update(buffer_settings) - except: + except Exception: self.buffer_settings = buffer_settings self._set_buffered_num_points() try: self.settings.update(settings) - except: + except Exception: self.settings = settings # Add script and parameters to metadata @@ -242,7 +244,8 @@ def generate_lists(self) -> None: The .channels list always contain the QCoDes parameters that can for example directly be called to get the corresponding values. - E.g. ``[param() for param in self.gettable_channels]`` will return a list of the current values of all gettable parameters. + E.g.: ``[param() for param in self.gettable_channels]`` will return a list + of the current values of all gettable parameters. The .parameters lists contain dictionaries with the keywords "gate" for the corresponding terminal name and "parameter" for the parameter name. @@ -352,7 +355,7 @@ def generate_lists(self) -> None: if prio not in self.priorities.keys(): self.groups[group]["priority"] = prio self.priorities[prio] = self.groups[group] - except: + except Exception: pass if self.buffered: diff --git a/src/qumada/measurement/scripts/__init__.py b/src/qumada/measurement/scripts/__init__.py index 7d0bc49a..c5e867a3 100644 --- a/src/qumada/measurement/scripts/__init__.py +++ b/src/qumada/measurement/scripts/__init__.py @@ -34,7 +34,7 @@ try: from .spectrometer import Measure_Spectrum -except ModuleNotFoundError as ex: +except ModuleNotFoundError: # Only relevant if you want to use spectrometer. # Requires access to Bluhm Group GitLab pass diff --git a/src/qumada/metadata.py b/src/qumada/metadata.py index fa7454b3..549558bb 100644 --- a/src/qumada/metadata.py +++ b/src/qumada/metadata.py @@ -25,7 +25,10 @@ class Metadata(Protocol): - """Protocol for a Metadata object. Defines the methods to handle specific metadata portions collected with QuMADA.""" + """ + Protocol for a Metadata object. + Defines the methods to handle specific metadata portions collected with QuMADA. + """ def add_terminal_mapping(self, mapping: str, name: str): """Adds metadata of the mapping between terminals and instrument parameters as a (JSON) string.""" diff --git a/src/tests/mapping_test.py b/src/tests/mapping_test.py index 1e1a12a6..a36004a8 100644 --- a/src/tests/mapping_test.py +++ b/src/tests/mapping_test.py @@ -23,7 +23,6 @@ from contextlib import nullcontext as does_not_raise from datetime import datetime from random import random -from time import sleep import pytest from jsonschema import ValidationError @@ -97,9 +96,11 @@ def fixture_script(): return script -# # TODO: valid_terminal_parameters_mapping, fixture_script, fixture_station_with_instruments is only valid TOGETHER. They must exist within some kind of group +# # TODO: valid_terminal_parameters_mapping, fixture_script, fixture_station_with_instruments is only valid TOGETHER. +# # They must exist within some kind of group +# # valid for given fixture_script and fixture_station_with_instruments # @pytest.fixture -# def valid_terminal_parameters_mapping(station_with_instruments): # valid for given fixture_script and fixture_station_with_instruments +# def valid_terminal_parameters_mapping(station_with_instruments): # terminal_params = { # "dmm" : {"voltage" : station_with_instruments.dmm.voltage, # "current" : station_with_instruments.dmm.current}, @@ -221,7 +222,8 @@ def test_mapping_gui_monitoring(monitoring: bool, qtbot, station_with_instrument assert w.toggle_monitoring_action.text() == "Disable" # test monitoring in action (switch back to enabling monitoring first) - # This block is a bit convoluted because I am actually measuring the value of the monitored param over time in order to test the monitoring + # This block is a bit convoluted because I am actually measuring the value of the monitored param over time + # in order to test the monitoring # > this is much nicer if I mock the get command (this somehow didnt work for me...) if monitoring: w.toggle_monitoring_action.trigger() @@ -241,11 +243,12 @@ def test_mapping_gui_monitoring(monitoring: bool, qtbot, station_with_instrument w.monitoring_refresh_delay.trigger() # sample the last get value, wait, sample, wait, sample (catching the change due to get command in monitoring) - # careful with setting delay_seconds and the actual waiting times. There might be additional delay in process_events function call - # and cache.get() making this not completely exact. So dont make the window (time margin) to tight + # careful with setting delay_seconds and the actual waiting times. + # There might be additional delay in process_events function call and cache.get() making this not + # completely exact. So dont make the window (time margin) too tight. before = station_with_instruments.dmm.current.cache.get() # wait 0.5*delay_seconds - n = 5 # num_steps + # n = 5 # num_steps time_now = datetime.now() while (datetime.now() - time_now).microseconds < 1e6 * delay_seconds * 0.5: pass @@ -264,9 +267,9 @@ def test_mapping_gui_monitoring(monitoring: bool, qtbot, station_with_instrument assert before == tmp # this makes sure (with high probability) that monitoring called the get function within the second time window - assert ( - after != before - ) # TODO: maybe test this differently. this can fail with some probability... (new random value is equal to old value) + assert after != before + # TODO: maybe test this differently. this can fail with some probability... + # (new random value is equal to old value) # This somehow doesnt work with the CI/CD pipeline (inside docker container) @@ -286,7 +289,9 @@ def test_mapping_gui_monitoring(monitoring: bool, qtbot, station_with_instrument # qtbot.keyPress(w, Qt.Key_Return) # QApplication.processEvents() -# # wanted mapping (TODO: better as fixture? Problem is that this has to be manually set and fit to the specific station fixture (ORDER) and script fixture) +# # wanted mapping +# # (TODO: better as fixture? Problem is that this has to be manually set and fit to the specific station fixture +# # (ORDER) and script fixture) # terminal_params = { # "dmm": {"voltage": station_with_instruments.dmm.voltage, "current": station_with_instruments.dmm.current}, # "dac": {"voltage": station_with_instruments.dac.voltage}, diff --git a/src/tests/metadata_test.py b/src/tests/metadata_test.py index 45f7b183..948630ff 100644 --- a/src/tests/metadata_test.py +++ b/src/tests/metadata_test.py @@ -20,8 +20,6 @@ from typing import runtime_checkable -import pytest - from qumada.metadata import BasicMetadata, Metadata, Savable diff --git a/src/tests/plotting_2D.py b/src/tests/plotting_2D.py index e720f112..fc4f20e0 100644 --- a/src/tests/plotting_2D.py +++ b/src/tests/plotting_2D.py @@ -23,14 +23,14 @@ # from qumada.instrument.mapping.base import flatten_list import numpy as np -import qcodes as qc from matplotlib import pyplot as plt from qcodes.dataset.data_export import reshape_2D_data -from qcodes.dataset.plotting import plot_dataset -import qumada as qt -from qumada.utils.browsefiles import browsefiles -from qumada.utils.load_from_sqlite_db import * +from qumada.utils.load_from_sqlite_db import ( + get_parameter_data, + pick_measurements, + separate_up_down, +) # %% @@ -258,6 +258,7 @@ def plot_multiple_datasets( fig, ax = plt.subplots(figsize=(30, 30)) x_labels = [] y_labels = [] + p = [] for i in range(len(datasets)): label = datasets[i].name x, y = _handle_overload( From 0e15afa4560b97bb54d9e4c9468567064b8c8820 Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 17:08:36 +0200 Subject: [PATCH 10/16] fix flake8 errors for Decadac files --- .../custom_drivers/Harvard/Decadac.py | 48 ++++++++-------- .../instrument/mapping/Harvard/Decadac.py | 57 +++++++++---------- 2 files changed, 50 insertions(+), 55 deletions(-) diff --git a/src/qumada/instrument/custom_drivers/Harvard/Decadac.py b/src/qumada/instrument/custom_drivers/Harvard/Decadac.py index 089e6ee7..c8b1a453 100644 --- a/src/qumada/instrument/custom_drivers/Harvard/Decadac.py +++ b/src/qumada/instrument/custom_drivers/Harvard/Decadac.py @@ -20,7 +20,6 @@ from functools import partial -from math import ceil from time import sleep, time from typing import Union, cast @@ -54,7 +53,8 @@ def _dac_v_to_code(self, volt): """ if volt < self.min_val or volt >= self.max_val: raise ValueError( - f"Cannot convert voltage {volt} V to a voltage code, value out of range ({self.min_val} V - {self.max_val} V)" + f"Cannot convert voltage {volt} V to a voltage code, " + f"value out of range ({self.min_val} V - {self.max_val} V)" ) frac = (volt - self.min_val) / (self.max_val - self.min_val) @@ -82,9 +82,7 @@ def _set_slot(self): """ resp = self.ask_raw(f"B{self._slot};") if int(self._dac_parse(resp)) != self._slot: - raise DACException( - "Unexpected return from DAC when setting slot: " f"{resp}. DAC slot may not have been set." - ) + raise DACException(f"Unexpected return from DAC when setting slot: {resp}. DAC slot may not have been set.") def _script_set_slot(self): """ @@ -370,27 +368,27 @@ def _script_ramp(self, start, end, duration, trigger=0): timestep (bool): Should the call block until the ramp is complete? """ _control_str = "" - trigger_mapping = { - "continous": 0, - "edge": 12, - } + # trigger_mapping = { + # "continous": 0, + # "edge": 12, + # } # trigger = 'after_trig1_rising' - trigger_dict = { - "always": 0, - "trig1_low": 2, - "trig2_low": 3, - "until_trig1_rising": 4, - "until_trig2_rising": 5, - "until_trig1_falling": 6, - "until_trig2_falling": 7, - "never": 8, - "trig1_high": 10, - "trig2_high": 11, - "after_trig1_rising": 12, - "after_trig2_rising": 13, - "after_trig1_falling": 14, - "after_trig2_falling": 15, - } + # trigger_dict = { + # "always": 0, + # "trig1_low": 2, + # "trig2_low": 3, + # "until_trig1_rising": 4, + # "until_trig2_rising": 5, + # "until_trig1_falling": 6, + # "until_trig2_falling": 7, + # "never": 8, + # "trig1_high": 10, + # "trig2_high": 11, + # "after_trig1_rising": 12, + # "after_trig2_rising": 13, + # "after_trig1_falling": 14, + # "after_trig2_falling": 15, + # } # _control_str = f'G{trigger_mapping[trigger]};' _control_str = f"G{trigger};" diff --git a/src/qumada/instrument/mapping/Harvard/Decadac.py b/src/qumada/instrument/mapping/Harvard/Decadac.py index 2266a543..d43a6be8 100644 --- a/src/qumada/instrument/mapping/Harvard/Decadac.py +++ b/src/qumada/instrument/mapping/Harvard/Decadac.py @@ -20,9 +20,6 @@ # - Till Huckeman -import time - -import numpy as np from qcodes.instrument.parameter import Parameter from qumada.instrument.custom_drivers.Harvard.Decadac import Decadac @@ -65,7 +62,7 @@ def ramp( if not start_values: start_values = [param.get() for param in parameters] - ramp_rates = np.abs((np.array(end_values) - np.array(start_values)) / np.array(ramp_time)) + # ramp_rates = np.abs((np.array(end_values) - np.array(start_values)) / np.array(ramp_time)) # if sync_trigger: # if sync_trigger in parameters: # raise Exception("Synchronized trigger cannot be part of parameters") @@ -86,33 +83,33 @@ def trigger(self, parameter, level=1) -> None: parameter.volt.set(level) def setup_trigger_in(self, trigger_settings: dict): - trigger_dict = { - "always": 0, - "trig1_low": 2, - "trig2_low": 3, - "until_trig1_rising": 4, - "until_trig2_rising": 5, - "until_trig1_falling": 6, - "until_trig2_falling": 7, - "never": 8, - "trig1_high": 10, - "trig2_high": 11, - "after_trig1_rising": 12, - "after_trig2_rising": 13, - "after_trig1_falling": 14, - "after_trig2_falling": 15, - } - TRIGGER_MODE_MAPPING: dict = { - "continuous": 0, - "edge": 1, - "pulse": 3, - "tracking_edge": 4, - "tracking_pulse": 7, - "digital": 6, - } + # trigger_dict = { + # "always": 0, + # "trig1_low": 2, + # "trig2_low": 3, + # "until_trig1_rising": 4, + # "until_trig2_rising": 5, + # "until_trig1_falling": 6, + # "until_trig2_falling": 7, + # "never": 8, + # "trig1_high": 10, + # "trig2_high": 11, + # "after_trig1_rising": 12, + # "after_trig2_rising": 13, + # "after_trig1_falling": 14, + # "after_trig2_falling": 15, + # } + # TRIGGER_MODE_MAPPING: dict = { + # "continuous": 0, + # "edge": 1, + # "pulse": 3, + # "tracking_edge": 4, + # "tracking_pulse": 7, + # "digital": 6, + # } print( - "Warning: The Decadacs trigger level is fixed at roughly 1.69 V and cannot be changed. \ - Please make sure that your triggers are setup accordingly" + "Warning: The Decadacs trigger level is fixed at roughly 1.69 V and cannot be changed. " + "Please make sure that your triggers are setup accordingly" ) trigger_mode = trigger_settings.get("trigger_mode", "continuous") polarity = trigger_settings.get("trigger_mode_polarity", "positive") From 8601066206b8f8788137ccd3d3a2784e2ca06806 Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 14:53:36 +0200 Subject: [PATCH 11/16] ignore E203, as it currently has false positives for some slicings --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index 88d61f3c..f8cb9465 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,6 +5,7 @@ packages = find: [flake8] max-line-length = 120 +extend-ignore = E203 [mypy] show_error_codes = True From 2f147cdfb9fdf38f2595fab0a4fb93b93ffeeb4b Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 17:17:49 +0200 Subject: [PATCH 12/16] fix flake8 errors for mapping_gui.py --- src/qumada/instrument/mapping/mapping_gui.py | 121 +++++++++++-------- 1 file changed, 71 insertions(+), 50 deletions(-) diff --git a/src/qumada/instrument/mapping/mapping_gui.py b/src/qumada/instrument/mapping/mapping_gui.py index b2d7753c..c4411092 100644 --- a/src/qumada/instrument/mapping/mapping_gui.py +++ b/src/qumada/instrument/mapping/mapping_gui.py @@ -57,10 +57,7 @@ from qcodes.instrument.parameter import Parameter from qcodes.utils.metadata import Metadatable -from qumada.instrument.mapping.base import ( - add_mapping_to_instrument, - filter_flatten_parameters, -) +from qumada.instrument.mapping.base import filter_flatten_parameters from qumada.metadata import Metadata TerminalParameters = Mapping[Any, Union[Mapping[Any, Parameter], Parameter]] @@ -76,7 +73,8 @@ # TODO: terminal_parameter attributes class TerminalTreeView(QTreeView): """ - QTreeView, that displays QuMADA `TerminalParameters` (`Mapping[Any, Mapping[Any, Parameter] | Parameter]`) datastructure. + QTreeView, that displays QuMADA `TerminalParameters` datastructure + (`Mapping[Any, Mapping[Any, Parameter] | Parameter]`). Items are draggable to map them to instruments. """ @@ -120,19 +118,19 @@ def update_monitoring(self): for terminal in get_children(root): for terminal_param in get_children(terminal): param = self.terminal_parameters[terminal_param.source[0]][terminal_param.source[1]] - if not param is None: + if param is not None: if self.monitoring_get_type == "get" and param.gettable: # Use get command try: val = param.get() - except: + except Exception: val = param.cache.get(get_if_invalid=False) else: # Use cached value (also applicable to non-gettable parameters (last set value)) val = param.cache.get(get_if_invalid=False) - if not val is None and (type(val) is int or type(val) is float): - if not param.unit is None: + if val is not None and (type(val) is int or type(val) is float): + if param.unit is not None: self.model().setData(terminal_param.index().siblingAtColumn(2), f"{val:.2f} {param.unit}") else: self.model().setData(terminal_param.index().siblingAtColumn(2), f"{val:.2f}") @@ -162,7 +160,7 @@ def update_tree(self): tree.setData(terminal_param.index().siblingAtColumn(1), QBrush(RED), Qt.BackgroundRole) tree.setData(terminal_param.index().siblingAtColumn(1), "") param = self.terminal_parameters[terminal_param.source[0]][terminal_param.source[1]] - if not param is None: + if param is not None: if isinstance(param, Parameter): param_hash = hash(param) if param_hash in parameter_duplicates: @@ -199,7 +197,7 @@ def update_tree(self): # tree.setData(duplicate.parent().index(), QBrush(PINK), Qt.BackgroundRole) # any item selected? - if not self.selected_terminal_tree_elem is None: + if self.selected_terminal_tree_elem is not None: self.selected_terminal_tree_elem.setData(QBrush(BLUE), Qt.BackgroundRole) # tree.setData(self.selected_terminal_tree_elem, QBrush(BLUE), Qt.BackgroundRole) @@ -263,7 +261,7 @@ def focusOutEvent(self, a0: QFocusEvent) -> None: terminal_tree = child break - if not terminal_tree.selected_terminal_tree_elem is None: + if terminal_tree.selected_terminal_tree_elem is not None: terminal_tree.selected_terminal_tree_elem = None terminal_tree.update_tree() @@ -278,11 +276,11 @@ def keyPressEvent(self, event: QKeyEvent) -> None: def get_perfect_mappings(self, terminal_params: list[str], parent_elem=None) -> list[QStandardItem]: """ - Given a list of terminal_parameters (names) return a list of QStandardItems in InstrumentTree (perfect mapping candidate) - that could be mapped perfectly i.e. every terminal_parameter can be mapped uniquely to the list of all children parameters of - the perfect mapping candidate. + Given a list of terminal_parameters (names) return a list of QStandardItems in InstrumentTree + (perfect mapping candidate) that could be mapped perfectly i.e. every terminal_parameter can be + mapped uniquely to the list of all children parameters of the perfect mapping candidate. """ - if parent_elem == None: + if parent_elem is None: parent_elem = self.model().invisibleRootItem() perfect_elems = [] @@ -327,15 +325,17 @@ def map_given_terminal_instrument_elem_selection( instr_elem: Metadatable | Parameter, ) -> bool: """ - For a selected item in terminal_tree (given via terminal_tree_traversal) and selected item in instrument_tree (instr_elem) - do the mapping process. Behaviour based on combinations like: direct mapping between parameters, automap to all children etc. + For a selected item in terminal_tree (given via terminal_tree_traversal) and selected item in instrument_tree + (instr_elem) do the mapping process. Behaviour based on combinations like: direct mapping between parameters, + automap to all children etc. """ mapped = False if isinstance(terminal_tree_traversal[1], str) and isinstance(instr_elem, Parameter): # map directly - should mapping be forbidden if _mapping attribute of Parameter does not fit? tree.map_parameter(instr_elem, terminal_tree_traversal) mapped = True - # self.add_terminal_to_view(parent, row, f"{terminal[0]}.{terminal[1]}") # maybe later - if used this should be done somewhere else (map_parameter) + # maybe later - if used this should be done somewhere else (map_parameter) + # self.add_terminal_to_view(parent, row, f"{terminal[0]}.{terminal[1]}") elif isinstance(terminal_tree_traversal[1], tuple) and isinstance(instr_elem, (InstrumentModule, Instrument)): # map automatically as much as possible all_params = filter_flatten_parameters(instr_elem) @@ -386,8 +386,11 @@ def map_given_terminal_instrument_elem_selection( def dropEvent(self, event: QDropEvent) -> None: """ - Start mapping based on selected element in terminal tree (dragged from) and selected element in instrument tree (dropped to) - Different mapping behaviour depending on the combination of "types" of elements (see map_given_terminal_instrument_elem_selection) + Start mapping based on selected element in terminal tree (dragged from) + and selected element in instrument tree (dropped to). + + Different mapping behaviour depending on the combination of "types" of elements + (see map_given_terminal_instrument_elem_selection). """ dest_index = self.indexAt(event.pos()) if not dest_index.isValid(): @@ -403,7 +406,8 @@ def dropEvent(self, event: QDropEvent) -> None: terminal_tree_idx = tree.currentIndex().siblingAtColumn(0) terminal_elem = tree.model().itemFromIndex(terminal_tree_idx) - # communicate selected instrument/terminal to main window. drag_terminal_drop_instr_slot catches this signal and does mapping + # communicate selected instrument/terminal to main window. + # drag_terminal_drop_instr_slot catches this signal and does mapping self.drag_terminal_drop_instr.emit(instr_elem, terminal_elem) def add_terminal_to_view(self, parent, row, terminal_name): @@ -441,14 +445,15 @@ def recurse(node, parent) -> None: # Object of some Metadatable type, try to get __dict__ and _filter_flatten_parameters try: value_hash = hash(value) - if not parent is self.model().invisibleRootItem(): + if parent is not self.model().invisibleRootItem(): try: if value in parent.source.ancestors: continue if len(value.ancestors) >= 2: if not value.ancestors[1] == parent.source: - # print(f"{value.full_name} is not a direct decendant of {parent.source.full_name}") + # print(f"{value.full_name} is not a direct decendant of + # {parent.source.full_name}") continue except AttributeError: continue @@ -626,7 +631,9 @@ def closeEvent(self, ev) -> None: if len(items_with_param) != 1: dialog = MessageBox_duplicates(self) answer = dialog.exec() - # answer = dialog.question(self, "", "Do you really want to stop the mapping process? Multiple terminal parameters are mapped to the same parameter!", QMessageBox.Yes | QMessageBox.No) + # question = ("Do you really want to stop the mapping process? " + # "Multiple terminal parameters are mapped to the same parameter!") + # answer = dialog.question(self, "", question, QMessageBox.Yes | QMessageBox.No) if not answer == QMessageBox.Yes: ev.ignore() return @@ -693,15 +700,17 @@ def set_refresh_rate(self): def map_parameter(self, parameter: Parameter, traverse: tuple[str, str]): """ Maps a instrument parameter to a specific terminal parameter accessed by the given traversal info. - Doesn't do much anymore, but I kept this around for slightly better readability (and easier refactoring if necessary) + Doesn't do much anymore, but I kept this around for slightly better readability + (and easier refactoring if necessary). """ self.terminal_parameters[traverse[0]][traverse[1]] = parameter def keyPressEvent(self, event: QKeyEvent) -> None: """ - Handles keyboard shortcuts and mapping using enter key. Selecting an instrument in the terminal_tree and pressing enter will switch focus to the - instrument_tree and select a suitable mapping candidate. The user can change the selection and press enter again to do the mapping. The focus switches - back to the terminal_tree and a new terminal is selected. + Handles keyboard shortcuts and mapping using enter key. Selecting an instrument in the terminal_tree and + pressing enter will switch focus to the instrument_tree and select a suitable mapping candidate. + The user can change the selection and press enter again to do the mapping. The focus switches back to the + terminal_tree and a new terminal is selected. """ if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return: sel_idx = [] @@ -748,7 +757,7 @@ def keyPressEvent(self, event: QKeyEvent) -> None: self.instrument_tree.setCurrentIndex(idx) elif ( self.instrument_tree.hasFocus() - and not self.terminal_tree.selected_terminal_tree_elem is None + and self.terminal_tree.selected_terminal_tree_elem is not None and len(self.instrument_tree.selectedIndexes()) == 1 ): # Element in instrument tree selected. Start mapping @@ -824,8 +833,9 @@ def map_given_terminal_instrument_elem_selection( instr_elem: Metadatable | Parameter, ) -> bool: """ - For a selected item in terminal_tree (given via terminal_tree_traversal) and selected item in instrument_tree (instr_elem) - do the mapping process. Behaviour based on combinations like: direct mapping between parameters, automap to all children etc. + For a selected item in terminal_tree (given via terminal_tree_traversal) and selected item + in instrument_tree (instr_elem) do the mapping process. + Behaviour based on combinations like: direct mapping between parameters, automap to all children etc. """ tree = self.terminal_tree mapped = False @@ -900,17 +910,19 @@ def unfold_terminals(self): def map_automatically(self): """ - Map all terminals automatically. The algorithm used is (almost) equivalent to selecting the first terminal and repeatedly - pressing the enter key until the last terminal (in the tree) is mapped. This works best if the terminals are in - the same order as the instruments that they should be mapped to. Additionally the terminals mapping to channels of - an instrument should be ordered the same as the channels (up to the driver but usually something like 0,1,2,...) + Map all terminals automatically. The algorithm used is (almost) equivalent to selecting the first terminal and + repeatedly pressing the enter key until the last terminal (in the tree) is mapped. This works best if the + terminals are in the same order as the instruments that they should be mapped to. Additionally the terminals + mapping to channels of an instrument should be ordered the same as the channels + (up to the driver but usually something like 0,1,2,...). """ self.reset_mapping() for terminal_name, terminal in self.terminal_parameters.items(): _perfect_mappings = self.instrument_tree.get_perfect_mappings(terminal.keys()) # filtering out parent channels (instrument) that would also lead to unique mapping - # This is an edge case for instruments that have a single channel of some type (then both the channel and the instrument are uniquely mappable) + # This is an edge case for instruments that have a single channel of some type + # (then both the channel and the instrument are uniquely mappable) perfect_mappings = [] for _perfect_mapping1 in _perfect_mappings: # check if there is a mapping which has _perfect_mapping1 as parent @@ -931,7 +943,7 @@ def map_automatically(self): for _terminal_name, _terminal in self.terminal_parameters.items(): all_mapped_to_same_channel = True for terminal_param_name, param in _terminal.items(): - if not param is None: + if param is not None: if param.instrument.full_name != perfect_mapping_channel_name: all_mapped_to_same_channel = False break @@ -946,7 +958,7 @@ def map_automatically(self): if not instr_mapped: # map to channel terminal_element = (terminal_name, tuple(terminal.keys())) - mapped = self.map_given_terminal_instrument_elem_selection(terminal_element, perfect_mapping.source) + self.map_given_terminal_instrument_elem_selection(terminal_element, perfect_mapping.source) break self.terminal_tree.update_tree() @@ -954,8 +966,8 @@ def map_automatically(self): # Not used anymore. Unique, but algorithm to weak to be useful in practise def map_automatically_unique(self): """ - Automatically map all unique terminal_parameter instrument_parameter pairs. If there are multiple terminal_parameters - with the same name their unique mapping is impossible. + Automatically map all unique terminal_parameter instrument_parameter pairs. If there are multiple + terminal_parameters with the same name their unique mapping is impossible. """ # call get_possible_mapping_candidates for each terminal terminal_mapping_candidates = {} @@ -971,7 +983,8 @@ def map_automatically_unique(self): else: terminal_parameters_occurances[terminal_param] = 1 - # a terminal parameter can be mapped uniquely if its mapped parameter only appears once in the candidate dictionaries of all terminals + # a terminal parameter can be mapped uniquely if its mapped parameter only appears once in the candidate + # dictionaries of all terminals # For a unique mapping between terminal parameter and instrument parameter: # 1. a terminal parameter (name) must only occur a single time for all terminals # 2. unique mapping from terminal parameter to instrument_parameter (true if list of candidates has length 1) @@ -1012,7 +1025,8 @@ def get_possible_mapping_candidates( terminal_params: tuple[str], instrument_parameters: Mapping[Any, Parameter] ) -> Mapping[Any, list[Parameter]]: """ - For input terminal and collection of instrument_parameters: get dictionary with key: terminal parameter name, value: list(parameters that can be mapped to that terminal parameter) + For input terminal and collection of instrument_parameters: get dictionary with key: + terminal parameter name, value: list(parameters that can be mapped to that terminal parameter) Similar to base.py _map_gate_to_instrument """ mapped_parameters = { @@ -1058,7 +1072,7 @@ def traverse(parent, names): return parent child = get_child(parent, names.pop(0)) - if child == None: + if child is None: print("problem") else: return traverse(child, names) @@ -1105,7 +1119,8 @@ def __init__(self, parent): self.setWindowTitle("Warning! Duplicate mapping!") self.setIcon(QMessageBox.Warning) self.setText( - "Do you really want to stop the mapping process? Multiple terminal parameters are mapped to the same parameter!" + "Do you really want to stop the mapping process? " + "Multiple terminal parameters are mapped to the same parameter!" ) self.setStandardButtons(QMessageBox.Yes | QMessageBox.No) @@ -1133,12 +1148,18 @@ def map_terminals_gui( Args: components (Mapping[Any, Metadatable]): Instruments/Components in QCoDeS - terminal_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]]): Terminals, as defined in the measurement script - existing_terminal_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]] | None): Already existing mapping - that is used to automatically create the mapping for already known terminals without user input. + terminal_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]]): + Terminals, as defined in the measurement script + existing_terminal_parameters (Mapping[Any, Union[Mapping[Any, Parameter], Parameter]] | None): + Already existing mapping, that is used to automatically create the mapping + for already known terminals without user input. metadata (Metadata | None): If provided, add mapping to the metadata object. - monitoring: if True the mapped parameters are periodically read out (either by get command (default) or cached value) - skip_gui_if_mapped: if True and existing_terminal_parameters completely covers all terminal_parameters, dont open gui and continue + monitoring (bool): + If True the mapped parameters are periodically read out + (either by get command (default) or cached value) + skip_gui_if_mapped (bool): + If True and existing_terminal_parameters completely covers all terminal_parameters, + dont open gui and continue """ if existing_terminal_parameters is None: # reset in case there is already some mapping From 1a39ec738500de292dc9f4408e822d15f520ccf4 Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 17:21:04 +0200 Subject: [PATCH 13/16] fix flake8 errors for util/*.py --- src/qumada/utils/GUI.py | 2 +- src/qumada/utils/generate_sweeps.py | 5 ++--- src/qumada/utils/load_from_sqlite_db.py | 9 +++------ src/qumada/utils/load_save_config.py | 2 +- src/qumada/utils/ramp_parameter.py | 2 +- src/qumada/utils/resources.py | 1 - src/qumada/utils/utils.py | 4 ++-- 7 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/qumada/utils/GUI.py b/src/qumada/utils/GUI.py index 318e7ace..07683261 100644 --- a/src/qumada/utils/GUI.py +++ b/src/qumada/utils/GUI.py @@ -41,7 +41,7 @@ def open_web_gui(parameters): params = [] try: channels = [val for val in parameters.gate_parameters.values()] - except: + except Exception: print("Error not yet implemented. Maybe you forgot to do the mapping first?") return False for gate in channels: diff --git a/src/qumada/utils/generate_sweeps.py b/src/qumada/utils/generate_sweeps.py index 5616598e..db4583cd 100644 --- a/src/qumada/utils/generate_sweeps.py +++ b/src/qumada/utils/generate_sweeps.py @@ -19,6 +19,8 @@ # - Sionludi Lab +import copy + import numpy as np @@ -49,9 +51,6 @@ def replace_parameter_settings(parameters: dict, old_val: str, new_value): return parameters -import copy - - def update_parameter_settings(parameters: dict, old_val: str, new_value): """ Replaces parameters based on their values with other value. Can be used to diff --git a/src/qumada/utils/load_from_sqlite_db.py b/src/qumada/utils/load_from_sqlite_db.py index a95d0e22..c387b5d7 100644 --- a/src/qumada/utils/load_from_sqlite_db.py +++ b/src/qumada/utils/load_from_sqlite_db.py @@ -29,16 +29,14 @@ import numpy as np import qcodes as qc -from qcodes.dataset.data_export import reshape_2D_data from qcodes.dataset.data_set import DataSet from qcodes.dataset.plotting import plot_dataset -import qumada as qt from qumada.utils.browsefiles import browsefiles # %% -def flatten_list(l: list) -> list: +def flatten_list(lst: list) -> list: """ Flattens nested lists """ @@ -51,7 +49,7 @@ def rec(sublist, results): else: results.append(entry) - rec(l, results) + rec(lst, results) return results @@ -107,7 +105,7 @@ def _pick_sample_name() -> str: try: chosen = samples[int(input("Enter sample number: "))] return chosen - except: + except Exception: print("Please chose a valid entry") @@ -220,7 +218,6 @@ def plot_data(sample_name: str = None): for idx, parameter in enumerate(dependend_parameters): print(f"{idx} : {parameter.label}") plot_param_numbers = input("Please enter the numbers of the parameters you want to plot, separated by blank") - param_list = plot_param_numbers.split() plot_params = list() for param in plot_param_numbers: plot_params.append(dependend_parameters[int(param)].name) diff --git a/src/qumada/utils/load_save_config.py b/src/qumada/utils/load_save_config.py index 4454f181..bf1b6632 100644 --- a/src/qumada/utils/load_save_config.py +++ b/src/qumada/utils/load_save_config.py @@ -41,7 +41,7 @@ def save_to_config(section, key, value, config_file="../config.cfg"): """ config = configparser.ConfigParser() config.read(config_file) - if not section in config: + if section not in config: config[section] = {} config[section][key] = value with open(config_file, "w") as configfile: diff --git a/src/qumada/utils/ramp_parameter.py b/src/qumada/utils/ramp_parameter.py index b1857a9c..eb89dc57 100644 --- a/src/qumada/utils/ramp_parameter.py +++ b/src/qumada/utils/ramp_parameter.py @@ -87,7 +87,7 @@ def ramp_parameter( current_value = parameter.get() LOG.debug(f"current value: {current_value}") - if type(current_value) == float: + if isinstance(current_value, float): LOG.debug(f"target: {target}") if not ramp_rate: if not ramp_time: diff --git a/src/qumada/utils/resources.py b/src/qumada/utils/resources.py index 1b95cf02..3fa4159f 100644 --- a/src/qumada/utils/resources.py +++ b/src/qumada/utils/resources.py @@ -22,7 +22,6 @@ import importlib.resources as res from pathlib import Path -from types import ModuleType def import_resources(package: res.Package, ext: str = "*", recursive: bool = True) -> list[res.Resource]: diff --git a/src/qumada/utils/utils.py b/src/qumada/utils/utils.py index 823203d2..84cfc002 100644 --- a/src/qumada/utils/utils.py +++ b/src/qumada/utils/utils.py @@ -24,7 +24,7 @@ # %% -def flatten_array(l) -> list: +def flatten_array(lst) -> list: """ Flattens nested lists and arrays, returns flattened list """ @@ -37,7 +37,7 @@ def rec(sublist, results): else: results.append(entry) - rec(l, results) + rec(lst, results) return results From 9820e967486af2cb113b7019f359ca7c546da91d Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 17:26:23 +0200 Subject: [PATCH 14/16] fix flake8 errors for all files. There are some changes here, which might change the behavior of the functions, so the code review should be extra careful. --- .../doNd_enhanced/doNd_enhanced.py | 34 +++++++++---------- .../scripts/generic_measurement.py | 14 ++++---- .../measurement/scripts/spectrometer.py | 9 +++-- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/qumada/measurement/doNd_enhanced/doNd_enhanced.py b/src/qumada/measurement/doNd_enhanced/doNd_enhanced.py index 7fd85018..d2856e1c 100644 --- a/src/qumada/measurement/doNd_enhanced/doNd_enhanced.py +++ b/src/qumada/measurement/doNd_enhanced/doNd_enhanced.py @@ -29,20 +29,18 @@ import sys import time import warnings -from collections.abc import Iterator, Sequence +from collections.abc import Sequence from functools import partial -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union import matplotlib.axes import matplotlib.colorbar import numpy as np from qcodes import config -from qcodes.dataset.data_set import DataSet -from qcodes.dataset.data_set_protocol import DataSetProtocol, res_type +from qcodes.dataset.data_set_protocol import DataSetProtocol from qcodes.dataset.descriptions.detect_shapes import detect_shape_of_measurement from qcodes.dataset.descriptions.versioning.rundescribertypes import Shapes from qcodes.dataset.dond.do_nd_utils import ( - BreakConditionInterrupt, _catch_interrupts, _handle_plotting, _register_actions, @@ -51,7 +49,6 @@ ) from qcodes.dataset.experiment_container import Experiment from qcodes.dataset.measurements import Measurement -from qcodes.dataset.plotting import plot_dataset from qcodes.dataset.threading import ( SequentialParamsCaller, ThreadPoolParamsCaller, @@ -97,8 +94,8 @@ def do1d_parallel( show_progress: None | None = None, log_info: str | None = None, break_condition: BreakConditionT | None = None, - backsweep_after_break: Optional = False, - wait_after_break: Optional = 0, + backsweep_after_break: bool = False, + wait_after_break: float = 0, ) -> AxesTupleListWithDataSet: """ Performs a 1D scan of all ``param_set`` according to "setpoints" in parallel, @@ -184,7 +181,7 @@ def do1d_parallel( # do1D enforces a simple relationship between measured parameters # and set parameters. For anything more complicated this should be # reimplemented from scratch - with _catch_interrupts() as interrupted, meas.run() as datasaver, param_meas_caller as call_param_meas: + with _catch_interrupts() as interrupted, meas.run() as datasaver, param_meas_caller: dataset = datasaver.dataset additional_setpoints_data = process_params_meas(additional_setpoints) @@ -249,8 +246,8 @@ def do1d_parallel_asym( show_progress: None | None = None, log_info: str | None = None, break_condition: BreakConditionT | None = None, - backsweep_after_break: Optional = False, - wait_after_break: Optional = 0, + backsweep_after_break: bool = False, + wait_after_break: float = 0, ) -> AxesTupleListWithDataSet: """ Performs a 1D scan of all ``param_set`` according to "setpoints" in parallel, @@ -348,7 +345,7 @@ def do1d_parallel_asym( # do1D enforces a simple relationship between measured parameters # and set parameters. For anything more complicated this should be # reimplemented from scratch - with _catch_interrupts() as interrupted, meas.run() as datasaver, param_meas_caller as call_param_meas: + with _catch_interrupts() as interrupted, meas.run() as datasaver, param_meas_caller: dataset = datasaver.dataset additional_setpoints_data = process_params_meas(additional_setpoints) @@ -449,7 +446,7 @@ def check_conditions(conditions: list[Callable[[], bool]]): raise NotImplementedError( 'Only parameter values can be used for breaks in this version. Use "val" for the break condition.' ) - f = lambda: eval_binary_expr(cond["channel"].get(), ops[1], float(ops[2])) + f = partial(eval_binary_expr, cond["channel"].get(), ops[1], float(ops[2])) conditions.append(f) return partial(check_conditions, conditions) if conditions else None @@ -479,6 +476,9 @@ def _dev_interpret_breaks(break_conditions: list, sweep_values: dict, **kwargs) """ + def return_false(): + return False + def eval_binary_expr(op1: Any, oper: str, op2: Any) -> bool: # evaluates the string "op1 [operator] op2 # supports <, > and == as operators @@ -503,16 +503,16 @@ def check_conditions(conditions: list[Callable[[], bool]]): ops = cond["break_condition"].split(" ") data = sweep_values[cond["channel"]] if ops[0] == "val": - f = lambda: eval_binary_expr(data[-1], ops[1], float(ops[2])) + f = partial(eval_binary_expr, data[-1], ops[1], float(ops[2])) elif ops[0] == "grad": if int(ops[1]) >= len(data): - f = lambda: False + f = return_false elif float(ops[1]) < len(data): if data[len(data) - 1] != 0: dx = (data[len(data) - 1] - data[len(data) - 1 - int(ops[1])]) / data[len(data) - 1] - f = lambda: eval_binary_expr(dx, ops[2], float(ops[3])) + f = partial(eval_binary_expr, dx, ops[2], float(ops[3])) else: - f = lambda: False + f = return_false else: raise NotImplementedError("NOT IMPLEMENTED") conditions.append(f) diff --git a/src/qumada/measurement/scripts/generic_measurement.py b/src/qumada/measurement/scripts/generic_measurement.py index d64fb533..cfe6632c 100644 --- a/src/qumada/measurement/scripts/generic_measurement.py +++ b/src/qumada/measurement/scripts/generic_measurement.py @@ -139,7 +139,7 @@ def run(self, **dond_kwargs): else: try: measurement_name = self.metadata.measurement.name or "measurement" - except: + except Exception: measurement_name = "measurement" for sweep in self.dynamic_sweeps: @@ -243,7 +243,7 @@ def run(self): ], ) with meas.run() as datasaver: - start = timer.reset_clock() + timer.reset_clock() while timer() < duration: now = timer() results = [(channel, channel.get()) for channel in [*self.gettable_channels, *self.dynamic_channels]] @@ -334,7 +334,7 @@ def run(self): # Set trigger to high here try: trigger_start() - except: + except Exception: print("Please set a trigger or define a trigger_start method") pass @@ -346,7 +346,7 @@ def run(self): sleep(0.1) try: trigger_reset() - except: + except Exception: print("No method to reset the trigger defined.") results = self.readout_buffers(timestamps=True) @@ -374,7 +374,7 @@ def run(self): self.initialize() duration = self.settings.get("duration", 300) timestep = self.settings.get("timestep", 1) - backsweeps = self.settings.get("backsweeps", False) + # backsweeps = self.settings.get("backsweeps", False) timer = ElapsedTimeParameter("time") meas = Measurement(name=self.metadata.measurement.name or "timetrace") meas.register_parameter(timer) @@ -385,7 +385,7 @@ def run(self): for parameter in self.gettable_channels: meas.register_parameter(parameter, setpoints=setpoints) with meas.run() as datasaver: - start = timer.reset_clock() + timer.reset_clock() while timer() < duration: for sweep in self.dynamic_sweeps: ramp_or_set_parameter(sweep._param, sweep.get_setpoints()[0], ramp_time=timestep) @@ -510,7 +510,7 @@ def run(self): # (timer, [ti+t for ti in results.pop(-1)]), # *results, # *static_gettables,) - ti = results.pop(-1) + results.pop(-1) datasaver.add_result( (timer, t), (dyn_channel, self.dynamic_sweeps[0].get_setpoints()), diff --git a/src/qumada/measurement/scripts/spectrometer.py b/src/qumada/measurement/scripts/spectrometer.py index 1a21cb83..d47ac942 100644 --- a/src/qumada/measurement/scripts/spectrometer.py +++ b/src/qumada/measurement/scripts/spectrometer.py @@ -18,7 +18,6 @@ # - Till Huckeman import logging -from time import sleep import numpy as np from qcodes.dataset.measurements import Measurement @@ -26,10 +25,10 @@ from qcodes.parameters.specialized_parameters import ElapsedTimeParameter from qutil.measurement.spectrometer import Spectrometer, daq -from qumada.instrument.buffers.buffer import is_bufferable from qumada.measurement.measurement import MeasurementScript -from qumada.utils.ramp_parameter import ramp_or_set_parameter -from qumada.utils.utils import _validate_mapping, naming_helper +from qumada.utils.utils import naming_helper + +logger = logging.getLogger(__name__) class Measure_Spectrum(MeasurementScript): @@ -45,7 +44,7 @@ def run(self) -> list: settings = self.settings store_timetrace = settings.get("store_timetrace", True) store_spectrum = settings.get("store_spectrum", True) - module = settings.get("module", "scope") + # module = settings.get("module", "scope") # TODO: Check if instrument is supported # TODO: Cases for different instruments/modes From 23459c7984720b0899df1be34166b27ec743f69a Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Mon, 14 Aug 2023 17:38:32 +0200 Subject: [PATCH 15/16] Ignore example files for flake8 and mypy. This should be reverted, when working on these files. Related issue #18 --- src/examples/buffered_dummy_example.py | 5 +++++ src/examples/buffered_example1.py | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/examples/buffered_dummy_example.py b/src/examples/buffered_dummy_example.py index 13279d38..a67d25e5 100644 --- a/src/examples/buffered_dummy_example.py +++ b/src/examples/buffered_dummy_example.py @@ -18,6 +18,11 @@ # - Daniel Grothe # - Till Huckeman +# Ignore flake8 and mypy, as these file is going to be redone either way. +# TODO: Remove these comments then +# flake8: noqa +# type: ignore + # %% Experiment Setup # As we have only dummy instruments that are not connected, we have to use a global # trigger event for triggering. diff --git a/src/examples/buffered_example1.py b/src/examples/buffered_example1.py index 7657a8da..af4e9b2e 100644 --- a/src/examples/buffered_example1.py +++ b/src/examples/buffered_example1.py @@ -18,6 +18,10 @@ # - Till Huckemann # - Daniel Grothe +# Ignore flake8 and mypy, as these file is going to be redone either way. +# TODO: Remove these comments then +# flake8: noqa +# type: ignore import qtools_metadata.db as db import yaml From 4e8b52b2beb6522b3de2b8e5aa91d6f0f3331d2d Mon Sep 17 00:00:00 2001 From: Daniel Grothe Date: Fri, 13 Oct 2023 08:49:41 +0200 Subject: [PATCH 16/16] temporarily remove mypy from pre-commit --- .pre-commit-config.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7b47aad0..898d8a76 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,7 +33,3 @@ repos: rev: 6.1.0 hooks: - id: flake8 -- repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.5.0 - hooks: - - id: mypy