qplotter 1.6.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.
- qplot/__init__.py +46 -0
- qplot/__main__.py +232 -0
- qplot/_auxiliary_paths.py +67 -0
- qplot/_build_info.json +1 -0
- qplot/_metadata.py +75 -0
- qplot/_repair.py +14 -0
- qplot/_shutdown_supervisor.py +4049 -0
- qplot/_version.py +12 -0
- qplot/_windows_shutdown_job.py +1166 -0
- qplot/configuration/__init__.py +3 -0
- qplot/configuration/config.py +578 -0
- qplot/configuration/config_schema.json +357 -0
- qplot/configuration/fonts.py +3 -0
- qplot/configuration/scripts.py +255 -0
- qplot/configuration/themes/__init__.py +13 -0
- qplot/configuration/themes/_base.py +592 -0
- qplot/configuration/themes/blank.py +17 -0
- qplot/configuration/themes/dark.py +54 -0
- qplot/configuration/themes/light.py +54 -0
- qplot/datahandling/LoadFromDB.py +224 -0
- qplot/datahandling/__init__.py +47 -0
- qplot/datahandling/_trusted_live_helper.py +812 -0
- qplot/datahandling/_trusted_live_protocol.py +1745 -0
- qplot/datahandling/database.py +2340 -0
- qplot/datahandling/dimensions.py +43 -0
- qplot/datahandling/file_identity.py +461 -0
- qplot/datahandling/parameter_data.py +149 -0
- qplot/datahandling/plot_progress.py +17 -0
- qplot/datahandling/qcodes_cache.py +277 -0
- qplot/datahandling/qcodes_compat.py +14 -0
- qplot/datahandling/readSQL.py +2442 -0
- qplot/datahandling/readonly.py +2566 -0
- qplot/datahandling/source_activity.py +21 -0
- qplot/datahandling/trusted_array_preview.py +148 -0
- qplot/datahandling/trusted_derived_cache.py +1605 -0
- qplot/datahandling/trusted_derived_rendering.py +876 -0
- qplot/datahandling/trusted_heatmap.py +246 -0
- qplot/datahandling/trusted_live.py +2808 -0
- qplot/datahandling/trusted_live_queries.py +5907 -0
- qplot/datahandling/trusted_live_service.py +1919 -0
- qplot/datahandling/trusted_live_supervisor.py +2161 -0
- qplot/datahandling/trusted_plot.py +283 -0
- qplot/datahandling/trusted_presentation.py +1065 -0
- qplot/datahandling/trusted_snapshot.py +1132 -0
- qplot/datahandling/trusted_work_coordinator.py +2157 -0
- qplot/datahandling/trusted_work_scheduler.py +1204 -0
- qplot/diagnostics.py +241 -0
- qplot/resources/testdata/qplot_test_db_01_10mb.csv +11 -0
- qplot/resources/testdata/qplot_test_db_02_25mb.csv +14 -0
- qplot/resources/testdata/qplot_test_db_03_50mb.csv +17 -0
- qplot/resources/testdata/qplot_test_db_04_100mb.csv +20 -0
- qplot/resources/testdata/qplot_test_db_05_250mb.csv +23 -0
- qplot/resources/testdata/qplot_test_db_06_500mb.csv +26 -0
- qplot/resources/testdata/qplot_test_db_07_1gb.csv +29 -0
- qplot/resources/testdata/qplot_test_db_08_5gb.csv +32 -0
- qplot/resources/testdata/qplot_test_db_09_10gb.csv +35 -0
- qplot/resources/testdata/qplot_test_db_10_30gb.csv +38 -0
- qplot/testdata.py +1804 -0
- qplot/tools/__init__.py +13 -0
- qplot/tools/finite_means.py +123 -0
- qplot/tools/general.py +139 -0
- qplot/tools/heatmap_geometry.py +391 -0
- qplot/tools/operation_registry.py +179 -0
- qplot/tools/plot_tools.py +650 -0
- qplot/tools/sample_statistics.py +111 -0
- qplot/tools/worker.py +2838 -0
- qplot/windows/__init__.py +9 -0
- qplot/windows/_colorbar.py +422 -0
- qplot/windows/_commands.py +523 -0
- qplot/windows/_config_persistence.py +123 -0
- qplot/windows/_database_actions.py +4933 -0
- qplot/windows/_dataset_handle.py +221 -0
- qplot/windows/_display_precision.py +48 -0
- qplot/windows/_dragdrop.py +70 -0
- qplot/windows/_export_paths.py +1167 -0
- qplot/windows/_help.py +210 -0
- qplot/windows/_mixed_appearance.py +303 -0
- qplot/windows/_mixed_plots.py +461 -0
- qplot/windows/_native_averaging.py +323 -0
- qplot/windows/_native_transforms.py +551 -0
- qplot/windows/_plot1d_snap.py +612 -0
- qplot/windows/_plot1d_traces.py +2236 -0
- qplot/windows/_plot2d_colorbar.py +1127 -0
- qplot/windows/_plot2d_colorbar_dialog.py +786 -0
- qplot/windows/_plot2d_layers.py +2291 -0
- qplot/windows/_plot2d_sweeps.py +712 -0
- qplot/windows/_plotWin.py +2082 -0
- qplot/windows/_plot_actions.py +2703 -0
- qplot/windows/_plot_annotation.py +186 -0
- qplot/windows/_plot_appearance.py +283 -0
- qplot/windows/_plot_axis_scaling.py +1521 -0
- qplot/windows/_plot_data_viewbox.py +94 -0
- qplot/windows/_plot_drop_axes.py +224 -0
- qplot/windows/_plot_export.py +1445 -0
- qplot/windows/_plot_feedback.py +112 -0
- qplot/windows/_plot_marquee.py +659 -0
- qplot/windows/_plot_refresh.py +950 -0
- qplot/windows/_plot_source_promotion.py +178 -0
- qplot/windows/_plot_state.py +237 -0
- qplot/windows/_plot_status.py +115 -0
- qplot/windows/_plot_tiling.py +35 -0
- qplot/windows/_plot_transform_labels.py +60 -0
- qplot/windows/_preferences.py +724 -0
- qplot/windows/_refresh_interval.py +172 -0
- qplot/windows/_run_controls.py +789 -0
- qplot/windows/_shortcuts.py +47 -0
- qplot/windows/_subplots/__init__.py +8 -0
- qplot/windows/_subplots/subplot1d.py +532 -0
- qplot/windows/_subplots/subplot2d.py +919 -0
- qplot/windows/_svg_export.py +209 -0
- qplot/windows/_trusted_derived_qt.py +1759 -0
- qplot/windows/_widgets/__init__.py +23 -0
- qplot/windows/_widgets/_run_formatting.py +387 -0
- qplot/windows/_widgets/details_tables.py +1119 -0
- qplot/windows/_widgets/dropbox.py +290 -0
- qplot/windows/_widgets/operations.py +460 -0
- qplot/windows/_widgets/preview.py +2997 -0
- qplot/windows/_widgets/run_list_items.py +488 -0
- qplot/windows/_widgets/toolbar.py +111 -0
- qplot/windows/_widgets/treeWidgets.py +2572 -0
- qplot/windows/_window_controls.py +414 -0
- qplot/windows/main.py +1632 -0
- qplot/windows/plot1d.py +313 -0
- qplot/windows/plot2d.py +1935 -0
- qplotter-1.6.0.dist-info/METADATA +322 -0
- qplotter-1.6.0.dist-info/RECORD +130 -0
- qplotter-1.6.0.dist-info/WHEEL +5 -0
- qplotter-1.6.0.dist-info/entry_points.txt +4 -0
- qplotter-1.6.0.dist-info/licenses/LICENSE +21 -0
- qplotter-1.6.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Compatibility helpers for QCoDeS dataset cache internals.
|
|
3
|
+
|
|
4
|
+
qPlot needs per-parameter refreshes that QCoDeS does not expose as a stable
|
|
5
|
+
public API. Keep those private-attribute touches in this module so future
|
|
6
|
+
QCoDeS upgrades have one place to adapt.
|
|
7
|
+
"""
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from threading import Lock, RLock
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
_CACHE_LOCK_CREATION = Lock()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class CacheParameterPublicationState:
|
|
17
|
+
"""Rollback state for one GUI-thread cache publication."""
|
|
18
|
+
|
|
19
|
+
read_present: bool
|
|
20
|
+
read_status: Any
|
|
21
|
+
write_present: bool
|
|
22
|
+
write_status: Any
|
|
23
|
+
data_present: bool
|
|
24
|
+
data: Any
|
|
25
|
+
dataset_completed: bool
|
|
26
|
+
synchronized: bool
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def cache_lock(cache):
|
|
30
|
+
"""Return qPlot's per-cache lock, creating it safely on first use."""
|
|
31
|
+
|
|
32
|
+
with _CACHE_LOCK_CREATION:
|
|
33
|
+
lock = getattr(cache, "_qplot_lock", None)
|
|
34
|
+
if lock is None:
|
|
35
|
+
lock = RLock()
|
|
36
|
+
cache._qplot_lock = lock
|
|
37
|
+
return lock
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def cache_dataset(cache):
|
|
41
|
+
return cache._dataset
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def cache_table_name(cache):
|
|
45
|
+
return cache_dataset(cache).table_name
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def cache_database_path(cache):
|
|
49
|
+
return cache_dataset(cache).path_to_db
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def cache_rundescriber(cache):
|
|
53
|
+
return cache.rundescriber
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def cache_read_status(cache):
|
|
57
|
+
return cache._read_status
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def cache_write_status(cache):
|
|
61
|
+
return cache._write_status
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def cache_data(cache):
|
|
65
|
+
return cache._data
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def cache_parameter_data(cache, parameter_name):
|
|
69
|
+
return cache_data(cache)[parameter_name]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def cache_is_live(cache):
|
|
73
|
+
return cache.live
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def cache_dataset_connection(cache):
|
|
77
|
+
return cache_dataset(cache).conn
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def cache_dataset_run_id(cache):
|
|
81
|
+
return cache_dataset(cache).run_id
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def cache_dataset_completed(cache):
|
|
85
|
+
return cache_dataset(cache).completed
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def set_cache_dataset_completed(cache, completed):
|
|
89
|
+
"""Update qPlot's cached QCoDeS completion state without database writes.
|
|
90
|
+
|
|
91
|
+
QCoDeS 0.58's public ``DataSet.completed`` setter calls
|
|
92
|
+
``mark_run_complete`` after changing ``_completed``. Viewer datasets are
|
|
93
|
+
loaded from databases that qPlot must never write, and their connections
|
|
94
|
+
may belong to another thread, so completion observations from SQLite must
|
|
95
|
+
only update the viewer-owned in-memory flag.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
with cache_lock(cache):
|
|
99
|
+
cache_dataset(cache)._completed = bool(completed)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def cache_parameter_is_synchronized(cache, parameter_name):
|
|
103
|
+
"""Return whether qPlot has committed this parameter's final cache rows."""
|
|
104
|
+
|
|
105
|
+
with cache_lock(cache):
|
|
106
|
+
synchronized = getattr(cache, "_qplot_synchronized_parameters", ())
|
|
107
|
+
return parameter_name in synchronized
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def set_cache_parameter_synchronized(cache, parameter_name, synchronized=True):
|
|
111
|
+
"""Publish viewer-owned, cache-wide final synchronization state."""
|
|
112
|
+
|
|
113
|
+
with cache_lock(cache):
|
|
114
|
+
completed_parameters = getattr(
|
|
115
|
+
cache,
|
|
116
|
+
"_qplot_synchronized_parameters",
|
|
117
|
+
None,
|
|
118
|
+
)
|
|
119
|
+
if completed_parameters is None:
|
|
120
|
+
completed_parameters = set()
|
|
121
|
+
cache._qplot_synchronized_parameters = completed_parameters
|
|
122
|
+
|
|
123
|
+
if synchronized:
|
|
124
|
+
completed_parameters.add(parameter_name)
|
|
125
|
+
else:
|
|
126
|
+
completed_parameters.discard(parameter_name)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def parameter_is_complete(param):
|
|
130
|
+
"""Return the legacy ParamSpec-local completion mirror.
|
|
131
|
+
|
|
132
|
+
QCoDeS can reconstruct ParamSpec instances, so this is not authoritative;
|
|
133
|
+
use :func:`cache_parameter_is_synchronized` for refresh decisions.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
return param._complete is True
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def set_parameter_complete(param, complete=True):
|
|
140
|
+
param._complete = complete
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def prepare_cache_if_empty(cache):
|
|
144
|
+
with cache_lock(cache):
|
|
145
|
+
if cache_data(cache) == {}:
|
|
146
|
+
cache.prepare()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def snapshot_cache_parameter_state(cache, parameter_name):
|
|
150
|
+
"""Take a consistent shallow snapshot for one parameter-tree read."""
|
|
151
|
+
|
|
152
|
+
with cache_lock(cache):
|
|
153
|
+
parameter_data = dict(cache_parameter_data(cache, parameter_name))
|
|
154
|
+
return (
|
|
155
|
+
dict(cache_write_status(cache)),
|
|
156
|
+
dict(cache_read_status(cache)),
|
|
157
|
+
{parameter_name: parameter_data},
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def snapshot_cache_parameter_publication_state(cache, parameter_name):
|
|
162
|
+
"""Capture the exact cache slots mutated by a refresh callback."""
|
|
163
|
+
|
|
164
|
+
with cache_lock(cache):
|
|
165
|
+
read_status = cache_read_status(cache)
|
|
166
|
+
write_status = cache_write_status(cache)
|
|
167
|
+
data = cache_data(cache)
|
|
168
|
+
synchronized = getattr(cache, "_qplot_synchronized_parameters", ())
|
|
169
|
+
return CacheParameterPublicationState(
|
|
170
|
+
read_present=parameter_name in read_status,
|
|
171
|
+
read_status=read_status.get(parameter_name),
|
|
172
|
+
write_present=parameter_name in write_status,
|
|
173
|
+
write_status=write_status.get(parameter_name),
|
|
174
|
+
data_present=parameter_name in data,
|
|
175
|
+
data=data.get(parameter_name),
|
|
176
|
+
dataset_completed=bool(
|
|
177
|
+
getattr(cache_dataset(cache), "_completed", False)
|
|
178
|
+
),
|
|
179
|
+
synchronized=parameter_name in synchronized,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def restore_cache_parameter_publication_state(
|
|
184
|
+
cache,
|
|
185
|
+
parameter_name,
|
|
186
|
+
prior_state,
|
|
187
|
+
committed_state,
|
|
188
|
+
):
|
|
189
|
+
"""Rollback one stale callback unless another callback superseded it."""
|
|
190
|
+
|
|
191
|
+
with cache_lock(cache):
|
|
192
|
+
current_state = snapshot_cache_parameter_publication_state(
|
|
193
|
+
cache,
|
|
194
|
+
parameter_name,
|
|
195
|
+
)
|
|
196
|
+
if (
|
|
197
|
+
current_state.read_present != committed_state.read_present
|
|
198
|
+
or current_state.read_status != committed_state.read_status
|
|
199
|
+
or current_state.write_present != committed_state.write_present
|
|
200
|
+
or current_state.write_status != committed_state.write_status
|
|
201
|
+
or current_state.data_present != committed_state.data_present
|
|
202
|
+
or current_state.data is not committed_state.data
|
|
203
|
+
or current_state.dataset_completed
|
|
204
|
+
!= committed_state.dataset_completed
|
|
205
|
+
or current_state.synchronized != committed_state.synchronized
|
|
206
|
+
):
|
|
207
|
+
return False
|
|
208
|
+
|
|
209
|
+
for mapping, present, value in (
|
|
210
|
+
(cache_read_status(cache), prior_state.read_present, prior_state.read_status),
|
|
211
|
+
(
|
|
212
|
+
cache_write_status(cache),
|
|
213
|
+
prior_state.write_present,
|
|
214
|
+
prior_state.write_status,
|
|
215
|
+
),
|
|
216
|
+
(cache_data(cache), prior_state.data_present, prior_state.data),
|
|
217
|
+
):
|
|
218
|
+
if present:
|
|
219
|
+
mapping[parameter_name] = value
|
|
220
|
+
else:
|
|
221
|
+
mapping.pop(parameter_name, None)
|
|
222
|
+
cache_dataset(cache)._completed = prior_state.dataset_completed
|
|
223
|
+
set_cache_parameter_synchronized(
|
|
224
|
+
cache,
|
|
225
|
+
parameter_name,
|
|
226
|
+
prior_state.synchronized,
|
|
227
|
+
)
|
|
228
|
+
return True
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def update_cache_parameter_data(
|
|
232
|
+
cache,
|
|
233
|
+
parameter_name,
|
|
234
|
+
updated_read_status,
|
|
235
|
+
updated_write_status,
|
|
236
|
+
updated_data,
|
|
237
|
+
dataset_completed=None,
|
|
238
|
+
):
|
|
239
|
+
"""Commit a parameter refresh unless a newer worker already won the race.
|
|
240
|
+
|
|
241
|
+
``_read_status`` is QCoDeS' database cursor and is therefore monotonic for
|
|
242
|
+
data read from SQLite. ``_write_status`` is instead an in-memory array
|
|
243
|
+
insertion offset. In particular, QCoDeS reports ``0`` after appending to
|
|
244
|
+
an unshaped parameter tree, so it cannot safely be used to order refresh
|
|
245
|
+
workers. Parameter synchronization and database completion are monotonic
|
|
246
|
+
and are published only after the full parameter cache commit, so another
|
|
247
|
+
plot can distinguish global source completion from its own outstanding
|
|
248
|
+
final read.
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
with cache_lock(cache):
|
|
252
|
+
next_read_status = updated_read_status[parameter_name]
|
|
253
|
+
next_write_status = updated_write_status[parameter_name]
|
|
254
|
+
current_read_status = cache_read_status(cache).get(parameter_name, -1)
|
|
255
|
+
|
|
256
|
+
# QCoDeS represents an untouched shaped parameter with ``None``. Treat
|
|
257
|
+
# it as older than any concrete row count when comparing results.
|
|
258
|
+
comparable = lambda status: -1 if status is None else status
|
|
259
|
+
if comparable(current_read_status) > comparable(next_read_status):
|
|
260
|
+
return False
|
|
261
|
+
|
|
262
|
+
cache_read_status(cache)[parameter_name] = next_read_status
|
|
263
|
+
cache_write_status(cache)[parameter_name] = next_write_status
|
|
264
|
+
cache_data(cache)[parameter_name] = updated_data[parameter_name]
|
|
265
|
+
if dataset_completed is True:
|
|
266
|
+
set_cache_parameter_synchronized(cache, parameter_name, True)
|
|
267
|
+
# Source completion is global, but individual plots still track
|
|
268
|
+
# whether their final display commit succeeded.
|
|
269
|
+
set_cache_dataset_completed(cache, dataset_completed)
|
|
270
|
+
return True
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def cache_has_no_written_data(cache):
|
|
274
|
+
return all(
|
|
275
|
+
status is None or status == 0
|
|
276
|
+
for status in cache_write_status(cache).values()
|
|
277
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Compatibility helpers for QCoDeS dataset implementation details."""
|
|
2
|
+
|
|
3
|
+
from qcodes.dataset.data_set import DataSet
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def result_owns_supplied_connection(result: object) -> bool:
|
|
7
|
+
"""Return whether QCoDeS transferred a supplied connection to ``result``.
|
|
8
|
+
|
|
9
|
+
QCoDeS' database-backed ``DataSet`` owns the connection passed to its
|
|
10
|
+
loader. Other dataset protocol implementations, including ``DataSetInMem``,
|
|
11
|
+
do not. Keep this implementation-specific type knowledge in one place.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
return isinstance(result, DataSet)
|