qcodespp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. qcodespp-0.1.0/LICENSE +21 -0
  2. qcodespp-0.1.0/PKG-INFO +91 -0
  3. qcodespp-0.1.0/README.rst +54 -0
  4. qcodespp-0.1.0/pyproject.toml +50 -0
  5. qcodespp-0.1.0/qcodespp/__init__.py +77 -0
  6. qcodespp-0.1.0/qcodespp/actions.py +237 -0
  7. qcodespp-0.1.0/qcodespp/data/__init__.py +0 -0
  8. qcodespp-0.1.0/qcodespp/data/data_array.py +555 -0
  9. qcodespp-0.1.0/qcodespp/data/data_set.py +926 -0
  10. qcodespp-0.1.0/qcodespp/data/format.py +338 -0
  11. qcodespp-0.1.0/qcodespp/data/gnuplot_format.py +425 -0
  12. qcodespp-0.1.0/qcodespp/data/hdf5_format.py +537 -0
  13. qcodespp-0.1.0/qcodespp/data/hdf5_format_hickle.py +63 -0
  14. qcodespp-0.1.0/qcodespp/data/io.py +241 -0
  15. qcodespp-0.1.0/qcodespp/data/location.py +171 -0
  16. qcodespp-0.1.0/qcodespp/instrument_drivers/Keysight/Keysight_34450A.py +9 -0
  17. qcodespp-0.1.0/qcodespp/instrument_drivers/Keysight/__init__.py +0 -0
  18. qcodespp-0.1.0/qcodespp/instrument_drivers/Keysight/private/Keysight_344xxA.py +456 -0
  19. qcodespp-0.1.0/qcodespp/instrument_drivers/Keysight/private/__init__.py +0 -0
  20. qcodespp-0.1.0/qcodespp/instrument_drivers/Lakeshore/Model_340.py +483 -0
  21. qcodespp-0.1.0/qcodespp/instrument_drivers/Lakeshore/__init__.py +0 -0
  22. qcodespp-0.1.0/qcodespp/instrument_drivers/QDevil/159fit_params_high_latest.json +386 -0
  23. qcodespp-0.1.0/qcodespp/instrument_drivers/QDevil/159fit_params_low_latest.json +386 -0
  24. qcodespp-0.1.0/qcodespp/instrument_drivers/QDevil/QDAC2.py +3229 -0
  25. qcodespp-0.1.0/qcodespp/instrument_drivers/QDevil/QDAC2_Array.py +300 -0
  26. qcodespp-0.1.0/qcodespp/instrument_drivers/QDevil/QSwitch_elab.py +652 -0
  27. qcodespp-0.1.0/qcodespp/instrument_drivers/QDevil/__init__.py +0 -0
  28. qcodespp-0.1.0/qcodespp/instrument_drivers/ZI/ZIHF2LI.py +415 -0
  29. qcodespp-0.1.0/qcodespp/instrument_drivers/ZI/ZIMFLI.py +764 -0
  30. qcodespp-0.1.0/qcodespp/instrument_drivers/ZI/ZIMFLI_sync.py +108 -0
  31. qcodespp-0.1.0/qcodespp/instrument_drivers/ZI/ZIUHFLI.py +2179 -0
  32. qcodespp-0.1.0/qcodespp/instrument_drivers/ZI/__init__.py +1 -0
  33. qcodespp-0.1.0/qcodespp/instrument_drivers/__init__.py +0 -0
  34. qcodespp-0.1.0/qcodespp/instrument_drivers/cryogenic/CryogenicSMS120C.py +599 -0
  35. qcodespp-0.1.0/qcodespp/instrument_drivers/cryogenic/__init__.py +0 -0
  36. qcodespp-0.1.0/qcodespp/instrument_drivers/instrument_mocks.py +379 -0
  37. qcodespp-0.1.0/qcodespp/instrument_drivers/multiplexer_instrument.py +287 -0
  38. qcodespp-0.1.0/qcodespp/instrument_drivers/national_instruments/PXI_4461.py +451 -0
  39. qcodespp-0.1.0/qcodespp/instrument_drivers/national_instruments/PXI_4462.py +290 -0
  40. qcodespp-0.1.0/qcodespp/instrument_drivers/national_instruments/PXI_6259.py +436 -0
  41. qcodespp-0.1.0/qcodespp/instrument_drivers/national_instruments/PXI_6733.py +230 -0
  42. qcodespp-0.1.0/qcodespp/instrument_drivers/national_instruments/PXI_6733_e.py +243 -0
  43. qcodespp-0.1.0/qcodespp/instrument_drivers/national_instruments/__init__.py +0 -0
  44. qcodespp-0.1.0/qcodespp/instrument_drivers/oxford/__init__.py +0 -0
  45. qcodespp-0.1.0/qcodespp/instrument_drivers/oxford/mercuryiPS_serial.py +658 -0
  46. qcodespp-0.1.0/qcodespp/instrument_drivers/oxford/triton.py +434 -0
  47. qcodespp-0.1.0/qcodespp/instrument_drivers/tektronix/Keithley_2000_Scan.py +65 -0
  48. qcodespp-0.1.0/qcodespp/instrument_drivers/tektronix/Keithley_2182a.py +190 -0
  49. qcodespp-0.1.0/qcodespp/instrument_drivers/tektronix/Keithley_2400.py +158 -0
  50. qcodespp-0.1.0/qcodespp/instrument_drivers/tektronix/Keithley_2450.py +242 -0
  51. qcodespp-0.1.0/qcodespp/instrument_drivers/tektronix/Keithley_2700.py +397 -0
  52. qcodespp-0.1.0/qcodespp/instrument_drivers/tektronix/Keithley_6500.py +161 -0
  53. qcodespp-0.1.0/qcodespp/instrument_drivers/tektronix/__init__.py +0 -0
  54. qcodespp-0.1.0/qcodespp/instrument_drivers/yokogawa/GS200.py +513 -0
  55. qcodespp-0.1.0/qcodespp/instrument_drivers/yokogawa/__init__.py +0 -0
  56. qcodespp-0.1.0/qcodespp/loops.py +1342 -0
  57. qcodespp-0.1.0/qcodespp/measure.py +310 -0
  58. qcodespp-0.1.0/qcodespp/parameters.py +311 -0
  59. qcodespp-0.1.0/qcodespp/plotting/RemotePlot.py +469 -0
  60. qcodespp-0.1.0/qcodespp/plotting/RemotePlotClient.py +367 -0
  61. qcodespp-0.1.0/qcodespp/plotting/RemoteQtPlotWidgets.py +871 -0
  62. qcodespp-0.1.0/qcodespp/plotting/__init__.py +0 -0
  63. qcodespp-0.1.0/qcodespp/plotting/analysis_tools.py +195 -0
  64. qcodespp-0.1.0/qcodespp/plotting/colors.py +135 -0
  65. qcodespp-0.1.0/qcodespp/plotting/offline/__init__.py +0 -0
  66. qcodespp-0.1.0/qcodespp/plotting/offline/datatypes.py +999 -0
  67. qcodespp-0.1.0/qcodespp/plotting/offline/design.py +906 -0
  68. qcodespp-0.1.0/qcodespp/plotting/offline/design.ui +1578 -0
  69. qcodespp-0.1.0/qcodespp/plotting/offline/editor.py +2966 -0
  70. qcodespp-0.1.0/qcodespp/plotting/offline/filters.py +561 -0
  71. qcodespp-0.1.0/qcodespp/plotting/offline/fits.py +1171 -0
  72. qcodespp-0.1.0/qcodespp/plotting/offline/helpers.py +288 -0
  73. qcodespp-0.1.0/qcodespp/plotting/offline/iconGadget.png +0 -0
  74. qcodespp-0.1.0/qcodespp/plotting/offline/main.py +55 -0
  75. qcodespp-0.1.0/qcodespp/plotting/offline/popupwindows.py +1848 -0
  76. qcodespp-0.1.0/qcodespp/plotting/offline/qcodes_pp_extension.py +328 -0
  77. qcodespp-0.1.0/qcodespp/plotting/offline/sidebars.py +1108 -0
  78. qcodespp-0.1.0/qcodespp/station.py +290 -0
  79. qcodespp-0.1.0/qcodespp/utils/__init__.py +0 -0
  80. qcodespp-0.1.0/qcodespp/utils/helpers.py +618 -0
  81. qcodespp-0.1.0/qcodespp/utils/visa_helpers.py +61 -0
  82. qcodespp-0.1.0/qcodespp/version.py +12 -0
qcodespp-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 djcarrad
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,91 @@
1
+ Metadata-Version: 2.4
2
+ Name: qcodespp
3
+ Version: 0.1.0
4
+ Summary: Package providing additional functions for QCoDeS
5
+ Maintainer-email: Damon Carrad <damonc@dtu.dk>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/x-rst
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Scientific/Engineering
17
+ License-File: LICENSE
18
+ Requires-Dist: qcodes
19
+ Requires-Dist: numpy>=1.10
20
+ Requires-Dist: pyqtgraph
21
+ Requires-Dist: matplotlib
22
+ Requires-Dist: PyQt5
23
+ Requires-Dist: ipykernel
24
+ Requires-Dist: jupyter
25
+ Requires-Dist: pyvisa
26
+ Requires-Dist: h5py>=2.6
27
+ Requires-Dist: websockets>=3.2
28
+ Requires-Dist: jsonschema
29
+ Requires-Dist: pyzmq
30
+ Requires-Dist: wrapt
31
+ Requires-Dist: pyserial
32
+ Requires-Dist: pandas
33
+ Requires-Dist: tqdm
34
+ Requires-Dist: scipy
35
+ Requires-Dist: lmfit
36
+ Project-URL: Homepage, https://github.com/qcodespp/qcodespp
37
+
38
+ qcodes++
39
+ ===================================
40
+
41
+ qcodes++ (aka qcodespp, qcpp, qc++) is a python package to run scientific experiments. qcodes++ is built on top of `QCoDeS <https://qcodes.github.io/Qcodes/>`__, both extending capabilities and preserving older features.
42
+
43
+ QCoDeS is a Python-based data acquisition framework developed by the
44
+ Copenhagen / Delft / Sydney / Microsoft quantum computing consortium.
45
+ It contains a huge range of drivers for communicating with instruments,
46
+ and a flexible - but complex - database-based method for collecting data
47
+ and running measurement loops.
48
+
49
+ The qcodes++ package provides a user-friendly
50
+ frontend to the solid backend of QCoDeS. If you have always wanted to run
51
+ your measurements using python but found QCoDeS too daunting, qcodes++ is
52
+ the package for you. qcodes++ features
53
+
54
+ * Text-based data (i.e. readable by e.g. notepad, excel, origin pro, etc)
55
+ * A simple yet powerful method for taking data and running measurements and loops
56
+ * True live plotting and an integrated offline plotting/analysis tool
57
+ * Improvements to core qcodes functions (e.g. Station, Parameters) to streamline data acquisition, protect (meta)data integtrity and minimise user error
58
+ * Improved drivers for certain instruments
59
+ * and other user-friendliness improvements
60
+
61
+ `qcodes++ is installed alongside/around QCoDeS <https://qcodespp.github.io/differences_from_qcodes.html>`__, meaning all features of both packages can be used
62
+ seamlessly within the same notebook/environment. e.g. you could still use the QCoDeS
63
+ dataset and measurement process for some experiments while relying on qcodes++ in other instances.
64
+ In addition, all top level qcodes functions are available in qcodes++ with the same names.
65
+
66
+ The name: In addition to being a really stupid pun on q(c++), it reflects the fact that really we just want
67
+ to add some nice features to the main package, and also it makes me happy because totally
68
+ coincidentally we have always named our plotting windows pp, e.g. pp = qc.live_plot().
69
+
70
+ Documentation
71
+ =============
72
+ is available at https://qcodespp.github.io
73
+
74
+ Installation
75
+ ============
76
+
77
+ See https://qcodespp.github.io/installation.html
78
+
79
+ QCoDeS and qcodes++ are compatible with Python 3.9+. They are primarily intended for use
80
+ from Jupyter notebooks and Jupyter lab, but can also be used from Spyder, traditional terminal-based
81
+ shells and in stand-alone scripts.
82
+
83
+ License
84
+ =======
85
+
86
+ See `License <https://github.com/QCoDeS/Qcodes/tree/master/LICENSE.rst>`__.
87
+
88
+ Contact and contributing
89
+ ==================================================
90
+
91
+ This package is largely maintained by Damon Carrad. If you have a question, or want to contribute, please don't hesitate to contact me at damonc@dtu.dk. Note I'm mainly doing it in my spare time, but I will always try to help.
@@ -0,0 +1,54 @@
1
+ qcodes++
2
+ ===================================
3
+
4
+ qcodes++ (aka qcodespp, qcpp, qc++) is a python package to run scientific experiments. qcodes++ is built on top of `QCoDeS <https://qcodes.github.io/Qcodes/>`__, both extending capabilities and preserving older features.
5
+
6
+ QCoDeS is a Python-based data acquisition framework developed by the
7
+ Copenhagen / Delft / Sydney / Microsoft quantum computing consortium.
8
+ It contains a huge range of drivers for communicating with instruments,
9
+ and a flexible - but complex - database-based method for collecting data
10
+ and running measurement loops.
11
+
12
+ The qcodes++ package provides a user-friendly
13
+ frontend to the solid backend of QCoDeS. If you have always wanted to run
14
+ your measurements using python but found QCoDeS too daunting, qcodes++ is
15
+ the package for you. qcodes++ features
16
+
17
+ * Text-based data (i.e. readable by e.g. notepad, excel, origin pro, etc)
18
+ * A simple yet powerful method for taking data and running measurements and loops
19
+ * True live plotting and an integrated offline plotting/analysis tool
20
+ * Improvements to core qcodes functions (e.g. Station, Parameters) to streamline data acquisition, protect (meta)data integtrity and minimise user error
21
+ * Improved drivers for certain instruments
22
+ * and other user-friendliness improvements
23
+
24
+ `qcodes++ is installed alongside/around QCoDeS <https://qcodespp.github.io/differences_from_qcodes.html>`__, meaning all features of both packages can be used
25
+ seamlessly within the same notebook/environment. e.g. you could still use the QCoDeS
26
+ dataset and measurement process for some experiments while relying on qcodes++ in other instances.
27
+ In addition, all top level qcodes functions are available in qcodes++ with the same names.
28
+
29
+ The name: In addition to being a really stupid pun on q(c++), it reflects the fact that really we just want
30
+ to add some nice features to the main package, and also it makes me happy because totally
31
+ coincidentally we have always named our plotting windows pp, e.g. pp = qc.live_plot().
32
+
33
+ Documentation
34
+ =============
35
+ is available at https://qcodespp.github.io
36
+
37
+ Installation
38
+ ============
39
+
40
+ See https://qcodespp.github.io/installation.html
41
+
42
+ QCoDeS and qcodes++ are compatible with Python 3.9+. They are primarily intended for use
43
+ from Jupyter notebooks and Jupyter lab, but can also be used from Spyder, traditional terminal-based
44
+ shells and in stand-alone scripts.
45
+
46
+ License
47
+ =======
48
+
49
+ See `License <https://github.com/QCoDeS/Qcodes/tree/master/LICENSE.rst>`__.
50
+
51
+ Contact and contributing
52
+ ==================================================
53
+
54
+ This package is largely maintained by Damon Carrad. If you have a question, or want to contribute, please don't hesitate to contact me at damonc@dtu.dk. Note I'm mainly doing it in my spare time, but I will always try to help.
@@ -0,0 +1,50 @@
1
+ [build-system]
2
+ requires = ["flit_core >=3.2,<4"]
3
+
4
+ build-backend = 'flit_core.buildapi'
5
+
6
+ [project]
7
+ name = "qcodespp"
8
+ version = '0.1.0'
9
+ maintainers = [{name = "Damon Carrad", email = "damonc@dtu.dk"}]
10
+ description = "Package providing additional functions for QCoDeS"
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Intended Audience :: Science/Research",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Programming Language :: Python :: 3 :: Only",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Topic :: Scientific/Engineering",
21
+ ]
22
+ license = {text = "MIT"}
23
+ requires-python = ">=3.10"
24
+ dependencies = [
25
+ "qcodes",
26
+ 'numpy>=1.10',
27
+ 'pyqtgraph',
28
+ 'matplotlib',
29
+ 'PyQt5',
30
+ 'ipykernel',
31
+ 'jupyter',
32
+ 'pyvisa',
33
+ 'h5py>=2.6',
34
+ 'websockets>=3.2',
35
+ 'jsonschema',
36
+ 'pyzmq',
37
+ 'wrapt',
38
+ 'pyserial',
39
+ 'pandas',
40
+ 'tqdm',
41
+ 'scipy',
42
+ 'lmfit'
43
+ ]
44
+
45
+ [project.readme]
46
+ file = "README.rst"
47
+ content-type = "text/x-rst"
48
+
49
+ [project.urls]
50
+ Homepage = "https://github.com/qcodespp/qcodespp"
@@ -0,0 +1,77 @@
1
+ from qcodes.configuration import Config
2
+ config = Config() # type: Config
3
+
4
+ # Import all modules included in the qcodes namespace, except Parameter and Station
5
+ # as these need to go through qcodespp wrappers
6
+ from qcodes.dataset import (
7
+ Measurement,
8
+ ParamSpec,
9
+ SQLiteSettings,
10
+ experiments,
11
+ get_guids_by_run_spec,
12
+ initialise_database,
13
+ initialise_or_create_database_at,
14
+ initialised_database_at,
15
+ load_by_counter,
16
+ load_by_guid,
17
+ load_by_id,
18
+ load_by_run_spec,
19
+ load_experiment,
20
+ load_experiment_by_name,
21
+ load_last_experiment,
22
+ load_or_create_experiment,
23
+ new_data_set,
24
+ new_experiment,
25
+ )
26
+ from qcodes.instrument import (
27
+ ChannelList,
28
+ ChannelTuple,
29
+ Instrument,
30
+ InstrumentChannel,
31
+ IPInstrument,
32
+ VisaInstrument,
33
+ find_or_create_instrument,
34
+ )
35
+ from qcodes.monitor import Monitor
36
+ from qcodes.parameters import (
37
+ ArrayParameter,
38
+ CombinedParameter,
39
+ DelegateParameter,
40
+ Function,
41
+ ManualParameter,
42
+ MultiParameter,
43
+ #Parameter,
44
+ ParameterWithSetpoints,
45
+ ScaledParameter,
46
+ SweepFixedValues,
47
+ SweepValues,
48
+ combine,
49
+ )
50
+
51
+ from qcodes.utils import deprecate
52
+ from qcodes.parameters import ElapsedTimeParameter
53
+
54
+ # modules from qcodes that have been extended/modified
55
+ from qcodespp.parameters import Parameter
56
+
57
+ from qcodespp.station import Station
58
+
59
+ # new modules not included in qcodes
60
+ from qcodespp.version import __version__
61
+
62
+ from qcodespp.loops import Loop, loop1d,loop2d,loop2dUD
63
+ from qcodespp.measure import Measure
64
+ from qcodespp.actions import Task, Wait, BreakIf
65
+
66
+ from qcodespp.plotting.RemotePlot import Plot, live_plot
67
+ from qcodespp.plotting.offline.main import offline_plotting
68
+
69
+ from qcodespp.data.data_set import new_data, load_data, load_data_num, load_data_nums, set_data_format, set_data_folder
70
+
71
+ from qcodespp.utils.visa_helpers import listVISAinstruments
72
+
73
+ from qcodespp.parameters import MultiParameterWrapper, ArrayParameterWrapper
74
+
75
+ # ensure to close all instruments when interpreter is closed
76
+ import atexit
77
+ atexit.register(Instrument.close_all)
@@ -0,0 +1,237 @@
1
+ """Actions, mainly to be executed in measurement Loops."""
2
+ import time
3
+
4
+ from qcodes.utils.helpers import is_function
5
+ from qcodes.utils.threading import thread_map
6
+
7
+
8
+ _NO_SNAPSHOT = {'type': None, 'description': 'Action without snapshot'}
9
+
10
+
11
+ # exception when threading is attempted used to simultaneously
12
+ # query the same instrument for several values
13
+ class UnsafeThreadingException(Exception):
14
+ pass
15
+
16
+
17
+ def _actions_snapshot(actions, update):
18
+ """Make a list of snapshots from a list of actions."""
19
+ snapshot = []
20
+ for action in actions:
21
+ if hasattr(action, 'snapshot'):
22
+ snapshot.append(action.snapshot(update=update))
23
+ else:
24
+ snapshot.append(_NO_SNAPSHOT)
25
+ return snapshot
26
+
27
+
28
+ class Task:
29
+ """
30
+ Execute a function within a measurement Loop, e.g. .each(Task(func, *args, **kwargs)).
31
+
32
+ The first argument should be a callable function, to which any subsequent
33
+ args and kwargs (which are evaluated before the loop starts) are passed.
34
+
35
+ e.g.:
36
+ Define a function to wait for a temperature setpoint to be reached:
37
+
38
+ >>> def wait_for_temperature(target_T, measured_T, tolerance):
39
+ >>> while abs(measured_T - target_T) > tolerance:
40
+ >>> time.sleep(1)
41
+
42
+ Then use it in a Loop, inside each, before measuring.
43
+
44
+ >>> loop = Loop(temperature_setpoint.sweep(0,2,101),delay=0.1).each(
45
+ >>> Task(wait_for_temperature, temperature_setpoint(), temperature(), 0.1),
46
+ >>> *station.measure())
47
+
48
+ If the args and kwargs are also callable, then they are evaluated
49
+ before being passed to the func.
50
+
51
+ Args:
52
+ func (callable): Function to executed
53
+ *args: pass to func, after evaluation if callable
54
+ **kwargs: pass to func, after evaluation if callable
55
+
56
+ """
57
+ def __init__(self, func, *args, **kwargs):
58
+ self.func = func
59
+ self.args = args
60
+ self.kwargs = kwargs
61
+
62
+ def __call__(self, **ignore_kwargs):
63
+ # If any of the arguments are callable, evaluate them first
64
+ eval_args = [arg() if callable(arg) else arg for arg in self.args]
65
+ eval_kwargs = {k: (v() if callable(v) else v) for k, v in self.kwargs.items()}
66
+
67
+ self.func(*eval_args, **eval_kwargs)
68
+
69
+ return 0 #This seems to stop spurious printing of self.func. Perhaps better way to do this.
70
+
71
+ def snapshot(self, update=False):
72
+ """
73
+ Snapshots task
74
+ Args:
75
+ update (bool): TODO not in use
76
+
77
+ Returns:
78
+ dict: snapshot
79
+ """
80
+ return {'type': 'Task', 'func': repr(self.func)}
81
+
82
+
83
+ class Wait:
84
+ """
85
+ A simple class to tell a Loop to wait <delay> seconds.
86
+
87
+ This is transformed into a Task within the Loop, such that
88
+ it can do other things (monitor, check for halt) during the delay.
89
+
90
+ But for use outside of a Loop, it is also callable (then it just sleeps)
91
+
92
+ Args:
93
+ delay: seconds to delay
94
+
95
+ Raises:
96
+ ValueError: if delay is negative
97
+ """
98
+ def __init__(self, delay):
99
+ if not delay >= 0:
100
+ raise ValueError('delay must be > 0, not {}'.format(repr(delay)))
101
+ self.delay = delay
102
+
103
+ def __call__(self):
104
+ if self.delay:
105
+ time.sleep(self.delay)
106
+
107
+ def snapshot(self, update=False):
108
+ """
109
+ Snapshots delay
110
+ Args:
111
+ update (bool): TODO not in use
112
+
113
+ Returns:
114
+ dict: snapshot
115
+ """
116
+ return {'type': 'Wait', 'delay': self.delay}
117
+
118
+
119
+ class _Measure:
120
+ """
121
+ A callable collection of parameters to measure.
122
+
123
+ This should not be constructed manually, only by an ActiveLoop.
124
+ """
125
+ def __init__(self, params_indices, data_set, use_threads):
126
+ self.use_threads = use_threads and len(params_indices) > 1
127
+ # the applicable DataSetPP.store function
128
+ self.store = data_set.store
129
+
130
+ # for performance, pre-calculate which params return data for
131
+ # multiple arrays, and the name mappings
132
+ self.getters = []
133
+ self.param_ids = []
134
+ self.composite = []
135
+ paramcheck = [] # list to check if parameters are unique
136
+ for param, action_indices in params_indices:
137
+ self.getters.append(param.get)
138
+
139
+ if param._instrument:
140
+ paramcheck.append((param, param._instrument))
141
+
142
+ if hasattr(param, 'names'):
143
+ part_ids = []
144
+ for i in range(len(param.names)):
145
+ param_id = data_set.action_id_map[action_indices + (i,)]
146
+ part_ids.append(param_id)
147
+ self.param_ids.append(None)
148
+ self.composite.append(part_ids)
149
+ else:
150
+ param_id = data_set.action_id_map[action_indices]
151
+ self.param_ids.append(param_id)
152
+ self.composite.append(False)
153
+
154
+ if self.use_threads:
155
+ insts = [p[1] for p in paramcheck]
156
+ if (len(set(insts)) != len(insts)):
157
+ duplicates = [p for p in paramcheck if insts.count(p[1]) > 1]
158
+ raise UnsafeThreadingException('Can not use threading to '
159
+ 'read '
160
+ 'several things from the same '
161
+ 'instrument. Specifically, you '
162
+ 'asked for'
163
+ ' {}.'.format(duplicates))
164
+
165
+ def __call__(self, loop_indices, **ignore_kwargs):
166
+ out_dict = {}
167
+ if self.use_threads:
168
+ out = thread_map(self.getters)
169
+ else:
170
+ out = [g() for g in self.getters]
171
+
172
+ for param_out, param_id, composite in zip(out, self.param_ids,
173
+ self.composite):
174
+ if composite:
175
+ for val, part_id in zip(param_out, composite):
176
+ out_dict[part_id] = val
177
+ else:
178
+ out_dict[param_id] = param_out
179
+
180
+ self.store(loop_indices, out_dict)
181
+
182
+
183
+ class _Nest:
184
+
185
+ """
186
+ Wrapper to make a callable nested ActiveLoop.
187
+
188
+ This should not be constructed manually, only by an ActiveLoop.
189
+ """
190
+
191
+ def __init__(self, inner_loop, action_indices):
192
+ self.inner_loop = inner_loop
193
+ self.action_indices = action_indices
194
+
195
+ def __call__(self, **kwargs):
196
+ self.inner_loop._run_loop(action_indices=self.action_indices, **kwargs)
197
+
198
+
199
+ class BreakIf:
200
+
201
+ """
202
+ Loop action that breaks out of the loop if a condition is truthy.
203
+
204
+ Args:
205
+ condition (callable): a callable taking no arguments.
206
+ Can be a simple function that returns truthy when it's time to quit
207
+ Raises:
208
+ TypeError: if condition is not a callable with no aguments.
209
+
210
+ Examples:
211
+ >>> BreakIf(lambda: np.abs(chan1.curr()) >= 3e-9)
212
+ """
213
+
214
+ def __init__(self, condition):
215
+ if not is_function(condition, 0):
216
+ raise TypeError('BreakIf condition must be a callable with '
217
+ 'no arguments')
218
+ self.condition = condition
219
+
220
+ def __call__(self, **ignore_kwargs):
221
+ if self.condition():
222
+ raise _QcodesBreak
223
+
224
+ def snapshot(self, update=False):
225
+ """
226
+ Snapshots breakIf action
227
+ Args:
228
+ update (bool): TODO not in use
229
+
230
+ Returns:
231
+ dict: snapshot
232
+
233
+ """
234
+ return {'type': 'BreakIf', 'condition': repr(self.condition)}
235
+
236
+ class _QcodesBreak(Exception):
237
+ pass
File without changes