qcodespp 0.1.0__py3-none-any.whl

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/__init__.py +77 -0
  2. qcodespp/actions.py +237 -0
  3. qcodespp/data/__init__.py +0 -0
  4. qcodespp/data/data_array.py +555 -0
  5. qcodespp/data/data_set.py +926 -0
  6. qcodespp/data/format.py +338 -0
  7. qcodespp/data/gnuplot_format.py +425 -0
  8. qcodespp/data/hdf5_format.py +537 -0
  9. qcodespp/data/hdf5_format_hickle.py +63 -0
  10. qcodespp/data/io.py +241 -0
  11. qcodespp/data/location.py +171 -0
  12. qcodespp/instrument_drivers/Keysight/Keysight_34450A.py +9 -0
  13. qcodespp/instrument_drivers/Keysight/__init__.py +0 -0
  14. qcodespp/instrument_drivers/Keysight/private/Keysight_344xxA.py +456 -0
  15. qcodespp/instrument_drivers/Keysight/private/__init__.py +0 -0
  16. qcodespp/instrument_drivers/Lakeshore/Model_340.py +483 -0
  17. qcodespp/instrument_drivers/Lakeshore/__init__.py +0 -0
  18. qcodespp/instrument_drivers/QDevil/159fit_params_high_latest.json +386 -0
  19. qcodespp/instrument_drivers/QDevil/159fit_params_low_latest.json +386 -0
  20. qcodespp/instrument_drivers/QDevil/QDAC2.py +3229 -0
  21. qcodespp/instrument_drivers/QDevil/QDAC2_Array.py +300 -0
  22. qcodespp/instrument_drivers/QDevil/QSwitch_elab.py +652 -0
  23. qcodespp/instrument_drivers/QDevil/__init__.py +0 -0
  24. qcodespp/instrument_drivers/ZI/ZIHF2LI.py +415 -0
  25. qcodespp/instrument_drivers/ZI/ZIMFLI.py +764 -0
  26. qcodespp/instrument_drivers/ZI/ZIMFLI_sync.py +108 -0
  27. qcodespp/instrument_drivers/ZI/ZIUHFLI.py +2179 -0
  28. qcodespp/instrument_drivers/ZI/__init__.py +1 -0
  29. qcodespp/instrument_drivers/__init__.py +0 -0
  30. qcodespp/instrument_drivers/cryogenic/CryogenicSMS120C.py +599 -0
  31. qcodespp/instrument_drivers/cryogenic/__init__.py +0 -0
  32. qcodespp/instrument_drivers/instrument_mocks.py +379 -0
  33. qcodespp/instrument_drivers/multiplexer_instrument.py +287 -0
  34. qcodespp/instrument_drivers/national_instruments/PXI_4461.py +451 -0
  35. qcodespp/instrument_drivers/national_instruments/PXI_4462.py +290 -0
  36. qcodespp/instrument_drivers/national_instruments/PXI_6259.py +436 -0
  37. qcodespp/instrument_drivers/national_instruments/PXI_6733.py +230 -0
  38. qcodespp/instrument_drivers/national_instruments/PXI_6733_e.py +243 -0
  39. qcodespp/instrument_drivers/national_instruments/__init__.py +0 -0
  40. qcodespp/instrument_drivers/oxford/__init__.py +0 -0
  41. qcodespp/instrument_drivers/oxford/mercuryiPS_serial.py +658 -0
  42. qcodespp/instrument_drivers/oxford/triton.py +434 -0
  43. qcodespp/instrument_drivers/tektronix/Keithley_2000_Scan.py +65 -0
  44. qcodespp/instrument_drivers/tektronix/Keithley_2182a.py +190 -0
  45. qcodespp/instrument_drivers/tektronix/Keithley_2400.py +158 -0
  46. qcodespp/instrument_drivers/tektronix/Keithley_2450.py +242 -0
  47. qcodespp/instrument_drivers/tektronix/Keithley_2700.py +397 -0
  48. qcodespp/instrument_drivers/tektronix/Keithley_6500.py +161 -0
  49. qcodespp/instrument_drivers/tektronix/__init__.py +0 -0
  50. qcodespp/instrument_drivers/yokogawa/GS200.py +513 -0
  51. qcodespp/instrument_drivers/yokogawa/__init__.py +0 -0
  52. qcodespp/loops.py +1342 -0
  53. qcodespp/measure.py +310 -0
  54. qcodespp/parameters.py +311 -0
  55. qcodespp/plotting/RemotePlot.py +469 -0
  56. qcodespp/plotting/RemotePlotClient.py +367 -0
  57. qcodespp/plotting/RemoteQtPlotWidgets.py +871 -0
  58. qcodespp/plotting/__init__.py +0 -0
  59. qcodespp/plotting/analysis_tools.py +195 -0
  60. qcodespp/plotting/colors.py +135 -0
  61. qcodespp/plotting/offline/__init__.py +0 -0
  62. qcodespp/plotting/offline/datatypes.py +999 -0
  63. qcodespp/plotting/offline/design.py +906 -0
  64. qcodespp/plotting/offline/design.ui +1578 -0
  65. qcodespp/plotting/offline/editor.py +2966 -0
  66. qcodespp/plotting/offline/filters.py +561 -0
  67. qcodespp/plotting/offline/fits.py +1171 -0
  68. qcodespp/plotting/offline/helpers.py +288 -0
  69. qcodespp/plotting/offline/iconGadget.png +0 -0
  70. qcodespp/plotting/offline/main.py +55 -0
  71. qcodespp/plotting/offline/popupwindows.py +1848 -0
  72. qcodespp/plotting/offline/qcodes_pp_extension.py +328 -0
  73. qcodespp/plotting/offline/sidebars.py +1108 -0
  74. qcodespp/station.py +290 -0
  75. qcodespp/utils/__init__.py +0 -0
  76. qcodespp/utils/helpers.py +618 -0
  77. qcodespp/utils/visa_helpers.py +61 -0
  78. qcodespp/version.py +12 -0
  79. qcodespp-0.1.0.dist-info/METADATA +91 -0
  80. qcodespp-0.1.0.dist-info/RECORD +82 -0
  81. qcodespp-0.1.0.dist-info/WHEEL +4 -0
  82. qcodespp-0.1.0.dist-info/licenses/LICENSE +21 -0
qcodespp/data/io.py ADDED
@@ -0,0 +1,241 @@
1
+ """
2
+ IO managers for QCodespp.
3
+
4
+ IO managers wrap whatever physical storage layer the user wants to use
5
+ in an interface mimicking the built-in <open> context manager, with
6
+ some restrictions to minimize the overhead in creating new IO managers.
7
+
8
+ The main thing these managers need to implement is the open context manager:
9
+
10
+ - Only the context manager needs to be implemented, not separate
11
+ open function and close methods.
12
+
13
+ - open takes the standard parameters:
14
+
15
+ - filename: (string)
16
+ - mode: (string) only 'r' (read), 'w' (write), and 'a' (append) are
17
+ expected to be implemented. As with normal file objects, the only
18
+ difference between write and append is that write empties the file
19
+ before adding new data, and append leaves the existing contents in
20
+ place but starts writing at the end.
21
+ - encoding: If a special output encoding is desired. i.e. 'utf8
22
+
23
+ - the file-like object returned should implement a minimal set of operations.
24
+
25
+ In read mode:
26
+ - read([size]): read to the end or at most size bytes into a string
27
+ - readline([size]): read until a newline or up to size bytes, into a string
28
+ - iter(): usually return self, but can be any iterator over lines
29
+ - next(): assuming iter() returns self, this yields the next line.
30
+
31
+ In write or append mode:
32
+ - write(s): add string s to the end of the file.
33
+ - writelines(seq): add a sequence of strings
34
+
35
+ IO managers should also implement:
36
+
37
+ - a join method, ala ``os.path.join(*args)``.
38
+ - a list method, that returns all objects matching location
39
+ - a remove method, ala os.remove(path) except that it will remove directories
40
+ as well as files, since we're allowing "locations" to be directories
41
+ or files.
42
+ """
43
+
44
+ from contextlib import contextmanager
45
+ import os
46
+ import re
47
+ import shutil
48
+ from fnmatch import fnmatch
49
+
50
+ ALLOWED_OPEN_MODES = ('r', 'w', 'a')
51
+
52
+
53
+ class DiskIO:
54
+
55
+ """
56
+ Simple IO object to wrap disk operations with a custom base location.
57
+
58
+ Also accepts both forward and backward slashes at any point, and
59
+ normalizes both to the OS we are currently on.
60
+
61
+ Args:
62
+ base_location (str): a path to the root data folder.
63
+ Converted to an absolute path immediately, so even if you supply a
64
+ relative path, later changes to the OS working directory will not
65
+ affect data paths.
66
+ """
67
+
68
+ def __init__(self, base_location):
69
+ if base_location is None:
70
+ self.base_location = None
71
+ else:
72
+ base_location = self._normalize_slashes(base_location)
73
+ self.base_location = os.path.abspath(base_location)
74
+
75
+ @contextmanager
76
+ def open(self, filename, mode, encoding=None):
77
+ """
78
+ Mimic the interface of the built in open context manager.
79
+
80
+ Args:
81
+ filename (str): path relative to base_location.
82
+
83
+ mode (str): 'r' (read), 'w' (write), or 'a' (append).
84
+ Other open modes are not supported because we don't want
85
+ to force all IO managers to support others.
86
+
87
+ Returns:
88
+ context manager yielding the open file
89
+ """
90
+ if mode not in ALLOWED_OPEN_MODES:
91
+ raise ValueError('mode {} not allowed in IO managers'.format(mode))
92
+
93
+ filepath = self.to_path(filename)
94
+
95
+ # make directories if needed
96
+ dirpath = os.path.dirname(filepath)
97
+ if not os.path.exists(dirpath):
98
+ os.makedirs(dirpath)
99
+
100
+ # normally we'd construct this context manager with try/finally, but
101
+ # here we already have a context manager for open so we just wrap it
102
+ with open(filepath, mode, encoding=encoding) as f:
103
+ yield f
104
+
105
+ def _normalize_slashes(self, location):
106
+ # note that this is NOT os.path.join - the difference is os.path.join
107
+ # discards empty strings, so if you use it on a re.split absolute
108
+ # path you will get a relative path!
109
+ return os.sep.join(re.split('[\\\\/]', location)).rstrip(r'\\')
110
+
111
+ def to_path(self, location):
112
+ """
113
+ Convert a location string into a path on the local file system.
114
+
115
+ For DiskIO this just fixes slashes and prepends the base location,
116
+ doing nothing active with the file. But for other io managers that
117
+ refer to remote storage, this method may actually fetch the file and
118
+ put it at a temporary local path.
119
+
120
+ Args:
121
+ location (str): A location string for a complete dataset or
122
+ a file within it.
123
+
124
+ Returns:
125
+ path (str): The path on disk to which this location maps.
126
+ """
127
+ location = self._normalize_slashes(location)
128
+ if self.base_location:
129
+ return os.path.join(self.base_location, location)
130
+ else:
131
+ return location
132
+
133
+ def to_location(self, path):
134
+ """
135
+ Convert a local filesystem path into a location string.
136
+
137
+ Args:
138
+ path (str): a path on the local file system.
139
+
140
+ Returns:
141
+ location (str): the location string corresponding to this path.
142
+ """
143
+ if self.base_location:
144
+ return os.path.join(self.base_location, path)
145
+ else:
146
+ return path
147
+
148
+ def __repr__(self):
149
+ """Show the base location in the repr."""
150
+ return '<DiskIO, base_location={}>'.format(repr(self.base_location))
151
+
152
+ def join(self, *args):
153
+ """Context-dependent os.path.join for this io manager."""
154
+ return os.path.join(*list(map(self._normalize_slashes, args)))
155
+
156
+ def isfile(self, location):
157
+ """Check whether this location matches a file."""
158
+ path = self.to_path(location)
159
+ return os.path.isfile(path)
160
+
161
+ def list(self, location, maxdepth=1, include_dirs=False):
162
+ """
163
+ Return all files that match location.
164
+
165
+ This is either files whose names match up to an arbitrary extension,
166
+ or any files within an exactly matching directory name.
167
+
168
+ Args:
169
+ location (str): the location to match.
170
+ May contain the usual path wildcards * and ?
171
+
172
+ maxdepth (int, optional): maximum levels of directory nesting to
173
+ recurse into looking for files. Default 1.
174
+
175
+ include_dirs (bool, optional): whether to allow directories in
176
+ the results or just files. Default False.
177
+
178
+ Returns:
179
+ A list of matching files and/or directories, as locations
180
+ relative to our base_location.
181
+ """
182
+ location = self._normalize_slashes(location)
183
+ search_dir, pattern = os.path.split(location)
184
+ path = self.to_path(search_dir)
185
+
186
+ if not os.path.isdir(path):
187
+ return []
188
+
189
+ matches = [fn for fn in os.listdir(path) if fnmatch(fn, pattern + '*')]
190
+ out = []
191
+
192
+ for match in matches:
193
+ matchpath = self.join(path, match)
194
+ if os.path.isdir(matchpath) and fnmatch(match, pattern):
195
+ if maxdepth > 0:
196
+ # exact directory match - walk down to maxdepth
197
+ for root, dirs, files in os.walk(matchpath, topdown=True):
198
+ depth = root[len(path):].count(os.path.sep)
199
+ if depth == maxdepth:
200
+ dirs[:] = [] # don't recurse any further
201
+
202
+ for fn in files + (dirs if include_dirs else []):
203
+ out.append(self.to_location(self.join(root, fn)))
204
+
205
+ elif include_dirs:
206
+ out.append(self.join(search_dir, match))
207
+
208
+ elif (os.path.isfile(matchpath) and
209
+ (fnmatch(match, pattern) or
210
+ fnmatch(os.path.splitext(match)[0], pattern))):
211
+ # exact filename match, or match up to an extension
212
+ # note that we need fnmatch(match, pattern) in addition to the
213
+ # splitext test to cover the case of the base filename itself
214
+ # containing a dot.
215
+ out.append(self.join(search_dir, match))
216
+
217
+ return out
218
+
219
+ def remove(self, filename):
220
+ """Delete a file or folder and prune the directory tree."""
221
+ path = self.to_path(filename)
222
+ if os.path.isdir(path):
223
+ shutil.rmtree(path)
224
+ else:
225
+ os.remove(path)
226
+
227
+ filepath = os.path.split(path)[0]
228
+ try:
229
+ os.removedirs(filepath)
230
+ except OSError:
231
+ # directory was not empty - good that we're not removing it!
232
+ pass
233
+
234
+ def remove_all(self, location):
235
+ """
236
+ Delete all files/directories in the dataset at this location.
237
+
238
+ Afterward prunes the directory tree.
239
+ """
240
+ for fn in self.list(location):
241
+ self.remove(fn)
@@ -0,0 +1,171 @@
1
+ """Standard location_provider class(es) for creating DataSetPP locations."""
2
+ from datetime import datetime
3
+ import re
4
+ import string
5
+
6
+ from qcodes import config
7
+
8
+ class SafeFormatter(string.Formatter):
9
+
10
+ """Modified string formatter that doesn't complain about missing keys."""
11
+
12
+ def get_value(self, key, args, kwargs):
13
+ """Missing keys just get left as they were: '{key}'."""
14
+ try:
15
+ return super().get_value(key, args, kwargs)
16
+ except:
17
+ return '{{{}}}'.format(key)
18
+
19
+
20
+ class FormatLocation:
21
+
22
+ """
23
+ This is the default DataSetPP Location provider.
24
+
25
+ It provides a callable that returns a new (not used by another DataSetPP)
26
+ location string, based on a format string ``fmt`` and a dict ``record`` of
27
+ information to pass to ``fmt``.
28
+
29
+ Default record items are ``date``, ``time``, and ``counter``
30
+ Record item priority from lowest to highest (double items will be
31
+ overwritten):
32
+
33
+ - current ``date``, and ``time``
34
+ - record dict from ``__init__``
35
+ - record dict from ``__call__``
36
+ - automatic ``counter``
37
+
38
+ For example if any record dict contains a `date` keyword, it will no longer
39
+ be auto-generated.
40
+
41
+ Uses ``io.list`` to search for existing data at a matching location.
42
+
43
+ ``counter`` must NOT be provided in the record. If ``fmt`` contains
44
+ '{counter}', we look for existing files matching everything BEFORE this,
45
+ then find the highest counter (integer) among those files and use the next
46
+ value.
47
+
48
+ If the format string does not contain ``{counter}`` but the location we
49
+ would return is occupied, we add ``'_{counter}'`` to the end.
50
+
51
+ Usage::
52
+
53
+ loc_provider = FormatLocation(
54
+ fmt='{date}/#{counter}_{time}_{name}_{label}')
55
+ loc = loc_provider(DiskIO('.'),
56
+ record={'name': 'Rainbow', 'label': 'test'})
57
+ loc
58
+ > '2016-04-30/#001_13-28-15_Rainbow_test'
59
+
60
+ Args:
61
+ fmt (str, optional): a format string that all the other info will be
62
+ inserted into. Default '{date}/{time}', or '{date}/{time}_{name}'
63
+ if there is a ``name`` in the record.
64
+
65
+ fmt_date (str, optional): a ``datetime.strftime`` format string,
66
+ should only use the date part. The result will be inserted in
67
+ '{date}' in ``fmt``. Default '%Y-%m-%d'.
68
+
69
+ fmt_time (str, optional): a ``datetime.strftime`` format string,
70
+ should only use the time part. The result will be inserted in
71
+ '{time}' in ``fmt``. Default '%H-%M-%S'.
72
+
73
+ fmt_counter (str, optional): a format string for the counter (integer)
74
+ which is automatically generated from existing DataSetPPs that the
75
+ io manager can see. Default '{03}'.
76
+
77
+ record (dict, optional): A dict of default values to provide when
78
+ calling the location_provider. Values provided later will
79
+ override these values.
80
+
81
+ Note:
82
+ Do not include date/time or number formatting in ``fmt`` itself, such
83
+ as '{date:%Y-%m-%d}' or '{counter:03}'
84
+ """
85
+
86
+ default_fmt = config['core']['default_fmt']
87
+
88
+ def __init__(self, fmt=None, fmt_date=None, fmt_time=None,
89
+ fmt_counter=None, record=None):
90
+ # TODO(giulioungaretti) this should be
91
+ # FormatLocation.default_fmt
92
+ self.fmt = fmt or self.default_fmt
93
+ self.fmt_date = fmt_date or '%Y-%m-%d'
94
+ self.fmt_time = fmt_time or '%H-%M-%S'
95
+ self.fmt_counter = fmt_counter or '{:03}'
96
+ self.base_record = record
97
+ self.formatter = SafeFormatter()
98
+
99
+ self.counter = 0
100
+ for testval in (1, 23, 456, 7890):
101
+ if self._findint(self.fmt_counter.format(testval)) != testval:
102
+ raise ValueError('fmt_counter must produce a correct integer '
103
+ 'representation of its argument (eg "{:03}")',
104
+ fmt_counter)
105
+
106
+ def _findint(self, s):
107
+ try:
108
+ return int(re.findall(r'\d+', s)[0])
109
+ except:
110
+ return 0
111
+
112
+ def __call__(self, io, record=None):
113
+ """
114
+ Call the location provider to get a new location.
115
+
116
+ Args:
117
+ io (io manager): where we intend to put the new DataSetPP.
118
+
119
+ record (dict, optional): information to insert in the format string
120
+ Any key provided here will override the default record
121
+ """
122
+ loc_fmt = self.fmt
123
+
124
+ time_now = datetime.now()
125
+ date = time_now.strftime(self.fmt_date)
126
+ time = time_now.strftime(self.fmt_time)
127
+ format_record = {'date': date, 'time': time}
128
+
129
+ if self.base_record:
130
+ format_record.update(self.base_record)
131
+ if record:
132
+ format_record.update(record)
133
+
134
+ if 'counter' in format_record:
135
+ raise KeyError('you must not provide a counter in your record.',
136
+ format_record)
137
+
138
+ if ('name' in format_record) and ('{name}' not in loc_fmt):
139
+ loc_fmt += '_{name}'
140
+
141
+ if '{counter}' not in loc_fmt:
142
+ location = self.formatter.format(loc_fmt, **format_record)
143
+ if io.list(location):
144
+ loc_fmt += '_{counter}'
145
+ # redirect to the counter block below, but starting from 2
146
+ # because the already existing file counts like 1
147
+ existing_count = 1
148
+ else:
149
+ return location
150
+ else:
151
+ # if counter is already in loc_fmt, start from 1
152
+ existing_count = 0
153
+
154
+ # now search existing files for the next allowed counter
155
+
156
+ head_fmt = loc_fmt.split('{counter}', 1)[0]
157
+ # io.join will normalize slashes in head to match the locations
158
+ # returned by io.list
159
+ head = io.join(self.formatter.format(head_fmt, **format_record))
160
+
161
+ file_list = io.list(head + '*', maxdepth=0, include_dirs=True)
162
+
163
+ for f in file_list:
164
+ cnt = self._findint(f[len(head):])
165
+ existing_count = max(existing_count, cnt)
166
+
167
+ self.counter = existing_count + 1
168
+ format_record['counter'] = self.fmt_counter.format(self.counter)
169
+ location = self.formatter.format(loc_fmt, **format_record)
170
+
171
+ return location
@@ -0,0 +1,9 @@
1
+ from .private.Keysight_344xxA import _Keysight_344xxA
2
+
3
+ class Keysight_34450A(_Keysight_344xxA):
4
+ """
5
+ This is the qcodes driver for the Keysight 34450A Multimeter
6
+ """
7
+ def __init__(self, name, address, silent=False,
8
+ **kwargs):
9
+ super().__init__(name, address, silent, **kwargs)
File without changes