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.
Files changed (130) hide show
  1. qplot/__init__.py +46 -0
  2. qplot/__main__.py +232 -0
  3. qplot/_auxiliary_paths.py +67 -0
  4. qplot/_build_info.json +1 -0
  5. qplot/_metadata.py +75 -0
  6. qplot/_repair.py +14 -0
  7. qplot/_shutdown_supervisor.py +4049 -0
  8. qplot/_version.py +12 -0
  9. qplot/_windows_shutdown_job.py +1166 -0
  10. qplot/configuration/__init__.py +3 -0
  11. qplot/configuration/config.py +578 -0
  12. qplot/configuration/config_schema.json +357 -0
  13. qplot/configuration/fonts.py +3 -0
  14. qplot/configuration/scripts.py +255 -0
  15. qplot/configuration/themes/__init__.py +13 -0
  16. qplot/configuration/themes/_base.py +592 -0
  17. qplot/configuration/themes/blank.py +17 -0
  18. qplot/configuration/themes/dark.py +54 -0
  19. qplot/configuration/themes/light.py +54 -0
  20. qplot/datahandling/LoadFromDB.py +224 -0
  21. qplot/datahandling/__init__.py +47 -0
  22. qplot/datahandling/_trusted_live_helper.py +812 -0
  23. qplot/datahandling/_trusted_live_protocol.py +1745 -0
  24. qplot/datahandling/database.py +2340 -0
  25. qplot/datahandling/dimensions.py +43 -0
  26. qplot/datahandling/file_identity.py +461 -0
  27. qplot/datahandling/parameter_data.py +149 -0
  28. qplot/datahandling/plot_progress.py +17 -0
  29. qplot/datahandling/qcodes_cache.py +277 -0
  30. qplot/datahandling/qcodes_compat.py +14 -0
  31. qplot/datahandling/readSQL.py +2442 -0
  32. qplot/datahandling/readonly.py +2566 -0
  33. qplot/datahandling/source_activity.py +21 -0
  34. qplot/datahandling/trusted_array_preview.py +148 -0
  35. qplot/datahandling/trusted_derived_cache.py +1605 -0
  36. qplot/datahandling/trusted_derived_rendering.py +876 -0
  37. qplot/datahandling/trusted_heatmap.py +246 -0
  38. qplot/datahandling/trusted_live.py +2808 -0
  39. qplot/datahandling/trusted_live_queries.py +5907 -0
  40. qplot/datahandling/trusted_live_service.py +1919 -0
  41. qplot/datahandling/trusted_live_supervisor.py +2161 -0
  42. qplot/datahandling/trusted_plot.py +283 -0
  43. qplot/datahandling/trusted_presentation.py +1065 -0
  44. qplot/datahandling/trusted_snapshot.py +1132 -0
  45. qplot/datahandling/trusted_work_coordinator.py +2157 -0
  46. qplot/datahandling/trusted_work_scheduler.py +1204 -0
  47. qplot/diagnostics.py +241 -0
  48. qplot/resources/testdata/qplot_test_db_01_10mb.csv +11 -0
  49. qplot/resources/testdata/qplot_test_db_02_25mb.csv +14 -0
  50. qplot/resources/testdata/qplot_test_db_03_50mb.csv +17 -0
  51. qplot/resources/testdata/qplot_test_db_04_100mb.csv +20 -0
  52. qplot/resources/testdata/qplot_test_db_05_250mb.csv +23 -0
  53. qplot/resources/testdata/qplot_test_db_06_500mb.csv +26 -0
  54. qplot/resources/testdata/qplot_test_db_07_1gb.csv +29 -0
  55. qplot/resources/testdata/qplot_test_db_08_5gb.csv +32 -0
  56. qplot/resources/testdata/qplot_test_db_09_10gb.csv +35 -0
  57. qplot/resources/testdata/qplot_test_db_10_30gb.csv +38 -0
  58. qplot/testdata.py +1804 -0
  59. qplot/tools/__init__.py +13 -0
  60. qplot/tools/finite_means.py +123 -0
  61. qplot/tools/general.py +139 -0
  62. qplot/tools/heatmap_geometry.py +391 -0
  63. qplot/tools/operation_registry.py +179 -0
  64. qplot/tools/plot_tools.py +650 -0
  65. qplot/tools/sample_statistics.py +111 -0
  66. qplot/tools/worker.py +2838 -0
  67. qplot/windows/__init__.py +9 -0
  68. qplot/windows/_colorbar.py +422 -0
  69. qplot/windows/_commands.py +523 -0
  70. qplot/windows/_config_persistence.py +123 -0
  71. qplot/windows/_database_actions.py +4933 -0
  72. qplot/windows/_dataset_handle.py +221 -0
  73. qplot/windows/_display_precision.py +48 -0
  74. qplot/windows/_dragdrop.py +70 -0
  75. qplot/windows/_export_paths.py +1167 -0
  76. qplot/windows/_help.py +210 -0
  77. qplot/windows/_mixed_appearance.py +303 -0
  78. qplot/windows/_mixed_plots.py +461 -0
  79. qplot/windows/_native_averaging.py +323 -0
  80. qplot/windows/_native_transforms.py +551 -0
  81. qplot/windows/_plot1d_snap.py +612 -0
  82. qplot/windows/_plot1d_traces.py +2236 -0
  83. qplot/windows/_plot2d_colorbar.py +1127 -0
  84. qplot/windows/_plot2d_colorbar_dialog.py +786 -0
  85. qplot/windows/_plot2d_layers.py +2291 -0
  86. qplot/windows/_plot2d_sweeps.py +712 -0
  87. qplot/windows/_plotWin.py +2082 -0
  88. qplot/windows/_plot_actions.py +2703 -0
  89. qplot/windows/_plot_annotation.py +186 -0
  90. qplot/windows/_plot_appearance.py +283 -0
  91. qplot/windows/_plot_axis_scaling.py +1521 -0
  92. qplot/windows/_plot_data_viewbox.py +94 -0
  93. qplot/windows/_plot_drop_axes.py +224 -0
  94. qplot/windows/_plot_export.py +1445 -0
  95. qplot/windows/_plot_feedback.py +112 -0
  96. qplot/windows/_plot_marquee.py +659 -0
  97. qplot/windows/_plot_refresh.py +950 -0
  98. qplot/windows/_plot_source_promotion.py +178 -0
  99. qplot/windows/_plot_state.py +237 -0
  100. qplot/windows/_plot_status.py +115 -0
  101. qplot/windows/_plot_tiling.py +35 -0
  102. qplot/windows/_plot_transform_labels.py +60 -0
  103. qplot/windows/_preferences.py +724 -0
  104. qplot/windows/_refresh_interval.py +172 -0
  105. qplot/windows/_run_controls.py +789 -0
  106. qplot/windows/_shortcuts.py +47 -0
  107. qplot/windows/_subplots/__init__.py +8 -0
  108. qplot/windows/_subplots/subplot1d.py +532 -0
  109. qplot/windows/_subplots/subplot2d.py +919 -0
  110. qplot/windows/_svg_export.py +209 -0
  111. qplot/windows/_trusted_derived_qt.py +1759 -0
  112. qplot/windows/_widgets/__init__.py +23 -0
  113. qplot/windows/_widgets/_run_formatting.py +387 -0
  114. qplot/windows/_widgets/details_tables.py +1119 -0
  115. qplot/windows/_widgets/dropbox.py +290 -0
  116. qplot/windows/_widgets/operations.py +460 -0
  117. qplot/windows/_widgets/preview.py +2997 -0
  118. qplot/windows/_widgets/run_list_items.py +488 -0
  119. qplot/windows/_widgets/toolbar.py +111 -0
  120. qplot/windows/_widgets/treeWidgets.py +2572 -0
  121. qplot/windows/_window_controls.py +414 -0
  122. qplot/windows/main.py +1632 -0
  123. qplot/windows/plot1d.py +313 -0
  124. qplot/windows/plot2d.py +1935 -0
  125. qplotter-1.6.0.dist-info/METADATA +322 -0
  126. qplotter-1.6.0.dist-info/RECORD +130 -0
  127. qplotter-1.6.0.dist-info/WHEEL +5 -0
  128. qplotter-1.6.0.dist-info/entry_points.txt +4 -0
  129. qplotter-1.6.0.dist-info/licenses/LICENSE +21 -0
  130. 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)