qplotter 1.6.0b3__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 +63 -0
- qplot/_metadata.py +12 -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 +573 -0
- qplot/configuration/config_schema.json +319 -0
- qplot/configuration/scripts.py +255 -0
- qplot/configuration/themes/__init__.py +13 -0
- qplot/configuration/themes/_base.py +579 -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 +2330 -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 +2561 -0
- qplot/datahandling/source_activity.py +21 -0
- qplot/datahandling/trusted_array_preview.py +127 -0
- qplot/datahandling/trusted_derived_cache.py +1605 -0
- qplot/datahandling/trusted_derived_rendering.py +868 -0
- qplot/datahandling/trusted_heatmap.py +241 -0
- qplot/datahandling/trusted_live.py +2808 -0
- qplot/datahandling/trusted_live_queries.py +5907 -0
- qplot/datahandling/trusted_live_service.py +1894 -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 +1733 -0
- qplot/tools/__init__.py +13 -0
- qplot/tools/finite_means.py +114 -0
- qplot/tools/general.py +134 -0
- qplot/tools/heatmap_geometry.py +381 -0
- qplot/tools/operation_registry.py +179 -0
- qplot/tools/plot_tools.py +625 -0
- qplot/tools/sample_statistics.py +56 -0
- qplot/tools/worker.py +2787 -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 +4904 -0
- qplot/windows/_dataset_handle.py +221 -0
- qplot/windows/_dragdrop.py +71 -0
- qplot/windows/_export_paths.py +1167 -0
- qplot/windows/_help.py +169 -0
- qplot/windows/_native_averaging.py +173 -0
- qplot/windows/_native_transforms.py +389 -0
- qplot/windows/_plot1d_snap.py +608 -0
- qplot/windows/_plot1d_traces.py +2183 -0
- qplot/windows/_plot2d_colorbar.py +1126 -0
- qplot/windows/_plot2d_colorbar_dialog.py +786 -0
- qplot/windows/_plot2d_layers.py +2197 -0
- qplot/windows/_plot2d_sweeps.py +712 -0
- qplot/windows/_plotWin.py +1993 -0
- qplot/windows/_plot_actions.py +2695 -0
- qplot/windows/_plot_appearance.py +276 -0
- qplot/windows/_plot_axis_scaling.py +1485 -0
- qplot/windows/_plot_export.py +1445 -0
- qplot/windows/_plot_feedback.py +110 -0
- qplot/windows/_plot_marquee.py +656 -0
- qplot/windows/_plot_refresh.py +942 -0
- qplot/windows/_plot_state.py +239 -0
- qplot/windows/_plot_transform_labels.py +60 -0
- qplot/windows/_preferences.py +635 -0
- qplot/windows/_refresh_interval.py +70 -0
- qplot/windows/_run_controls.py +828 -0
- qplot/windows/_shortcuts.py +47 -0
- qplot/windows/_subplots/__init__.py +8 -0
- qplot/windows/_subplots/subplot1d.py +531 -0
- qplot/windows/_subplots/subplot2d.py +918 -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 +413 -0
- qplot/windows/main.py +1635 -0
- qplot/windows/plot1d.py +311 -0
- qplot/windows/plot2d.py +1901 -0
- qplotter-1.6.0b3.dist-info/METADATA +318 -0
- qplotter-1.6.0b3.dist-info/RECORD +119 -0
- qplotter-1.6.0b3.dist-info/WHEEL +5 -0
- qplotter-1.6.0b3.dist-info/entry_points.txt +4 -0
- qplotter-1.6.0b3.dist-info/licenses/LICENSE +21 -0
- qplotter-1.6.0b3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"properties": {
|
|
5
|
+
|
|
6
|
+
"GUI": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"plot_frame_fraction": {
|
|
10
|
+
"type": "number",
|
|
11
|
+
"exclusiveMinimum": 0,
|
|
12
|
+
"exclusiveMaximum": 1,
|
|
13
|
+
"default": 0.47
|
|
14
|
+
},
|
|
15
|
+
"main_frame_size": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"items": {
|
|
18
|
+
"type": "integer",
|
|
19
|
+
"minimum": 1,
|
|
20
|
+
"maximum": 16777215
|
|
21
|
+
},
|
|
22
|
+
"minItems": 2,
|
|
23
|
+
"maxItems": 2,
|
|
24
|
+
"default": [780, 700]
|
|
25
|
+
},
|
|
26
|
+
"preview_size": {
|
|
27
|
+
"type": "integer",
|
|
28
|
+
"minimum": 50,
|
|
29
|
+
"maximum": 1000,
|
|
30
|
+
"default": 200
|
|
31
|
+
},
|
|
32
|
+
"run_table_column_widths": {
|
|
33
|
+
"type": "array",
|
|
34
|
+
"items": {
|
|
35
|
+
"type": "integer",
|
|
36
|
+
"minimum": 32,
|
|
37
|
+
"maximum": 16777215
|
|
38
|
+
},
|
|
39
|
+
"oneOf": [
|
|
40
|
+
{ "maxItems": 0 },
|
|
41
|
+
{ "minItems": 12, "maxItems": 12 }
|
|
42
|
+
],
|
|
43
|
+
"default": []
|
|
44
|
+
},
|
|
45
|
+
"run_table_visible_columns": {
|
|
46
|
+
"type": "array",
|
|
47
|
+
"items": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"enum": [
|
|
50
|
+
"run_id",
|
|
51
|
+
"experiment",
|
|
52
|
+
"sample",
|
|
53
|
+
"measurements",
|
|
54
|
+
"setpoints",
|
|
55
|
+
"name",
|
|
56
|
+
"started",
|
|
57
|
+
"completed",
|
|
58
|
+
"status",
|
|
59
|
+
"duration",
|
|
60
|
+
"size",
|
|
61
|
+
"guid"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"uniqueItems": true,
|
|
65
|
+
"maxItems": 12,
|
|
66
|
+
"default": [
|
|
67
|
+
"run_id",
|
|
68
|
+
"measurements",
|
|
69
|
+
"setpoints",
|
|
70
|
+
"started",
|
|
71
|
+
"status",
|
|
72
|
+
"duration",
|
|
73
|
+
"size"
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"required": [
|
|
78
|
+
"plot_frame_fraction",
|
|
79
|
+
"main_frame_size",
|
|
80
|
+
"preview_size",
|
|
81
|
+
"run_table_column_widths",
|
|
82
|
+
"run_table_visible_columns"
|
|
83
|
+
],
|
|
84
|
+
"additionalProperties": false
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
"file": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"properties": {
|
|
90
|
+
"default_load_path": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"default": ""
|
|
93
|
+
},
|
|
94
|
+
"recent_file_paths": {
|
|
95
|
+
"type": "array",
|
|
96
|
+
"items": { "type": "string" },
|
|
97
|
+
"uniqueItems": true,
|
|
98
|
+
"maxItems": 10,
|
|
99
|
+
"default": []
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"required": ["default_load_path", "recent_file_paths"],
|
|
103
|
+
"additionalProperties": false
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
"user_preference": {
|
|
107
|
+
"type": "object",
|
|
108
|
+
"properties": {
|
|
109
|
+
"theme":{
|
|
110
|
+
"type": "string",
|
|
111
|
+
"enum": ["light", "dark", "pyqt"],
|
|
112
|
+
"default": "light"
|
|
113
|
+
},
|
|
114
|
+
"bar_colour" : {
|
|
115
|
+
"type": "string",
|
|
116
|
+
"default": "viridis"
|
|
117
|
+
},
|
|
118
|
+
"colorbar_width": {
|
|
119
|
+
"type": "integer",
|
|
120
|
+
"minimum": 1,
|
|
121
|
+
"maximum": 500,
|
|
122
|
+
"default": 15
|
|
123
|
+
},
|
|
124
|
+
"axis_tick_width": {
|
|
125
|
+
"type": "number",
|
|
126
|
+
"minimum": 0.5,
|
|
127
|
+
"maximum": 10,
|
|
128
|
+
"default": 2
|
|
129
|
+
},
|
|
130
|
+
"axis_major_tick_count": {
|
|
131
|
+
"type": "integer",
|
|
132
|
+
"minimum": 2,
|
|
133
|
+
"maximum": 10,
|
|
134
|
+
"default": 3
|
|
135
|
+
},
|
|
136
|
+
"bar_colour_include_cet": {
|
|
137
|
+
"type": "boolean",
|
|
138
|
+
"default": true
|
|
139
|
+
},
|
|
140
|
+
"bar_colour_include_matplotlib": {
|
|
141
|
+
"type": "boolean",
|
|
142
|
+
"default": true
|
|
143
|
+
},
|
|
144
|
+
"bar_colour_include_local": {
|
|
145
|
+
"type": "boolean",
|
|
146
|
+
"default": true
|
|
147
|
+
},
|
|
148
|
+
"bar_colour_include_custom": {
|
|
149
|
+
"type": "boolean",
|
|
150
|
+
"default": true
|
|
151
|
+
},
|
|
152
|
+
"bar_colour_include_cet_linear": {
|
|
153
|
+
"type": "boolean",
|
|
154
|
+
"default": true
|
|
155
|
+
},
|
|
156
|
+
"bar_colour_include_cet_divergent": {
|
|
157
|
+
"type": "boolean",
|
|
158
|
+
"default": true
|
|
159
|
+
},
|
|
160
|
+
"bar_colour_include_cet_cyclic": {
|
|
161
|
+
"type": "boolean",
|
|
162
|
+
"default": true
|
|
163
|
+
},
|
|
164
|
+
"bar_colour_include_cet_rainbow": {
|
|
165
|
+
"type": "boolean",
|
|
166
|
+
"default": true
|
|
167
|
+
},
|
|
168
|
+
"bar_colour_include_cet_isoluminant": {
|
|
169
|
+
"type": "boolean",
|
|
170
|
+
"default": true
|
|
171
|
+
},
|
|
172
|
+
"bar_colour_include_cet_other": {
|
|
173
|
+
"type": "boolean",
|
|
174
|
+
"default": true
|
|
175
|
+
},
|
|
176
|
+
"bar_colour_include_matplotlib_perceptual": {
|
|
177
|
+
"type": "boolean",
|
|
178
|
+
"default": true
|
|
179
|
+
},
|
|
180
|
+
"bar_colour_include_matplotlib_sequential": {
|
|
181
|
+
"type": "boolean",
|
|
182
|
+
"default": true
|
|
183
|
+
},
|
|
184
|
+
"bar_colour_include_matplotlib_divergent": {
|
|
185
|
+
"type": "boolean",
|
|
186
|
+
"default": true
|
|
187
|
+
},
|
|
188
|
+
"bar_colour_include_matplotlib_cyclic": {
|
|
189
|
+
"type": "boolean",
|
|
190
|
+
"default": true
|
|
191
|
+
},
|
|
192
|
+
"bar_colour_include_matplotlib_qualitative": {
|
|
193
|
+
"type": "boolean",
|
|
194
|
+
"default": true
|
|
195
|
+
},
|
|
196
|
+
"bar_colour_include_matplotlib_other": {
|
|
197
|
+
"type": "boolean",
|
|
198
|
+
"default": true
|
|
199
|
+
},
|
|
200
|
+
"bar_colour_excluded": {
|
|
201
|
+
"type": "array",
|
|
202
|
+
"items": { "type": "string" },
|
|
203
|
+
"default": []
|
|
204
|
+
},
|
|
205
|
+
"bar_colour_excluded_prefixes": {
|
|
206
|
+
"type": "array",
|
|
207
|
+
"items": { "type": "string" },
|
|
208
|
+
"default": []
|
|
209
|
+
},
|
|
210
|
+
"confirm_close": {
|
|
211
|
+
"type": "boolean",
|
|
212
|
+
"default": true
|
|
213
|
+
},
|
|
214
|
+
"confirm_close_all": {
|
|
215
|
+
"type": "boolean",
|
|
216
|
+
"default": true
|
|
217
|
+
},
|
|
218
|
+
"mouse_mode": {
|
|
219
|
+
"type": "string",
|
|
220
|
+
"enum": ["pan", "rect"],
|
|
221
|
+
"default": "pan"
|
|
222
|
+
},
|
|
223
|
+
"copy_plot_image_resolution": {
|
|
224
|
+
"type": "string",
|
|
225
|
+
"enum": ["screen", "dpi_300", "svg"],
|
|
226
|
+
"default": "screen"
|
|
227
|
+
},
|
|
228
|
+
"auto_plot": {
|
|
229
|
+
"type": "boolean",
|
|
230
|
+
"default": false
|
|
231
|
+
},
|
|
232
|
+
"default_refresh_rate": {
|
|
233
|
+
"type": "number",
|
|
234
|
+
"minimum": 0,
|
|
235
|
+
"maximum": 10000,
|
|
236
|
+
"default": 1
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
"required": [
|
|
240
|
+
"theme",
|
|
241
|
+
"bar_colour",
|
|
242
|
+
"colorbar_width",
|
|
243
|
+
"axis_tick_width",
|
|
244
|
+
"axis_major_tick_count",
|
|
245
|
+
"bar_colour_include_cet",
|
|
246
|
+
"bar_colour_include_matplotlib",
|
|
247
|
+
"bar_colour_include_local",
|
|
248
|
+
"bar_colour_include_custom",
|
|
249
|
+
"bar_colour_include_cet_linear",
|
|
250
|
+
"bar_colour_include_cet_divergent",
|
|
251
|
+
"bar_colour_include_cet_cyclic",
|
|
252
|
+
"bar_colour_include_cet_rainbow",
|
|
253
|
+
"bar_colour_include_cet_isoluminant",
|
|
254
|
+
"bar_colour_include_cet_other",
|
|
255
|
+
"bar_colour_include_matplotlib_perceptual",
|
|
256
|
+
"bar_colour_include_matplotlib_sequential",
|
|
257
|
+
"bar_colour_include_matplotlib_divergent",
|
|
258
|
+
"bar_colour_include_matplotlib_cyclic",
|
|
259
|
+
"bar_colour_include_matplotlib_qualitative",
|
|
260
|
+
"bar_colour_include_matplotlib_other",
|
|
261
|
+
"bar_colour_excluded",
|
|
262
|
+
"bar_colour_excluded_prefixes",
|
|
263
|
+
"confirm_close",
|
|
264
|
+
"confirm_close_all",
|
|
265
|
+
"mouse_mode",
|
|
266
|
+
"copy_plot_image_resolution",
|
|
267
|
+
"auto_plot",
|
|
268
|
+
"default_refresh_rate"
|
|
269
|
+
],
|
|
270
|
+
"additionalProperties": false
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
"runtime_settings": {
|
|
274
|
+
"type": "object",
|
|
275
|
+
"properties": {
|
|
276
|
+
"max_threads": {
|
|
277
|
+
"type": "integer",
|
|
278
|
+
"minimum": 1,
|
|
279
|
+
"maximum": 999,
|
|
280
|
+
"default": 4
|
|
281
|
+
},
|
|
282
|
+
"max_full_heatmap_points": {
|
|
283
|
+
"type": "integer",
|
|
284
|
+
"minimum": 1,
|
|
285
|
+
"maximum": 2000000000,
|
|
286
|
+
"default": 2000000
|
|
287
|
+
},
|
|
288
|
+
"max_heatmap_grid_cells": {
|
|
289
|
+
"type": "integer",
|
|
290
|
+
"minimum": 1,
|
|
291
|
+
"maximum": 2000000000,
|
|
292
|
+
"default": 250000
|
|
293
|
+
},
|
|
294
|
+
"max_heatmap_grid_side": {
|
|
295
|
+
"type": "integer",
|
|
296
|
+
"minimum": 1,
|
|
297
|
+
"maximum": 2000000000,
|
|
298
|
+
"default": 800
|
|
299
|
+
},
|
|
300
|
+
"del_grace_period": {
|
|
301
|
+
"type": "number",
|
|
302
|
+
"minimum": 0,
|
|
303
|
+
"maximum": 300,
|
|
304
|
+
"default": 10
|
|
305
|
+
},
|
|
306
|
+
"cloud_sync_timeout": {
|
|
307
|
+
"type": "number",
|
|
308
|
+
"minimum": 1,
|
|
309
|
+
"maximum": 3600,
|
|
310
|
+
"default": 120
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
"required": ["max_threads", "max_full_heatmap_points", "max_heatmap_grid_cells", "max_heatmap_grid_side", "del_grace_period", "cloud_sync_timeout"],
|
|
314
|
+
"additionalProperties": false
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
"required": ["GUI", "file", "user_preference", "runtime_settings"],
|
|
318
|
+
"additionalProperties": false
|
|
319
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from jsonschema import ValidationError
|
|
5
|
+
|
|
6
|
+
from qplot._metadata import package_version
|
|
7
|
+
|
|
8
|
+
from .config import config
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class sysHandle:
|
|
12
|
+
"""
|
|
13
|
+
Entry point for terminal/console based commands. Called through scripts,
|
|
14
|
+
which is set up in pyproject.toml.
|
|
15
|
+
|
|
16
|
+
This is somewhat Jerry-Rigged, fetching string following qplot-cfg and
|
|
17
|
+
converts them to command matching functions here.
|
|
18
|
+
"""
|
|
19
|
+
def __init__(self, command, *args):
|
|
20
|
+
|
|
21
|
+
# Find valid commands by checking against class attributes which are callable
|
|
22
|
+
self.valid_args = [f"-{str(method_name)}" for method_name in dir(sysHandle)
|
|
23
|
+
if callable(getattr(sysHandle, method_name))
|
|
24
|
+
and method_name[0] != "_"]
|
|
25
|
+
|
|
26
|
+
# Convert command str to callable
|
|
27
|
+
if command in self.valid_args:
|
|
28
|
+
func = getattr(self, command[1:])
|
|
29
|
+
else:
|
|
30
|
+
key = f"Command: ({command}), not found. Valid options: {self.valid_args}"
|
|
31
|
+
raise KeyError(key)
|
|
32
|
+
|
|
33
|
+
self._config = None
|
|
34
|
+
func(*args) # Pass other arguments to func
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def config(self):
|
|
38
|
+
"""Create the configuration only for commands that access it."""
|
|
39
|
+
if self._config is None:
|
|
40
|
+
self._config = config()
|
|
41
|
+
return self._config
|
|
42
|
+
|
|
43
|
+
def dump(self):
|
|
44
|
+
"""
|
|
45
|
+
-dump
|
|
46
|
+
-----
|
|
47
|
+
Prints the location of the config.json file along with its full
|
|
48
|
+
contents
|
|
49
|
+
|
|
50
|
+
"""
|
|
51
|
+
self.config.dump()
|
|
52
|
+
|
|
53
|
+
def reset(self):
|
|
54
|
+
"""
|
|
55
|
+
-reset
|
|
56
|
+
------
|
|
57
|
+
Reset all config.json values to their defaults and prints new config
|
|
58
|
+
file
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
self.config.reset_to_defaults()
|
|
63
|
+
print("Config reset:")
|
|
64
|
+
self.dump()
|
|
65
|
+
|
|
66
|
+
def find(self, key : str):
|
|
67
|
+
"""
|
|
68
|
+
-find
|
|
69
|
+
-----
|
|
70
|
+
Returns the key and the value assiated with that key.
|
|
71
|
+
key must be laid out as a dot (.) seperated path, i.e.
|
|
72
|
+
qplot-cfg -find GUI.main_frame_size
|
|
73
|
+
|
|
74
|
+
Parameters
|
|
75
|
+
----------
|
|
76
|
+
key : str
|
|
77
|
+
Location of value to fetch.
|
|
78
|
+
|
|
79
|
+
Raises
|
|
80
|
+
------
|
|
81
|
+
KeyError
|
|
82
|
+
Key not found in file
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
print(f"{key}:\t{self.config.get(key)}")
|
|
86
|
+
|
|
87
|
+
def set_value(
|
|
88
|
+
self,
|
|
89
|
+
key : str,
|
|
90
|
+
value: str,
|
|
91
|
+
):
|
|
92
|
+
"""
|
|
93
|
+
-set_value
|
|
94
|
+
----------
|
|
95
|
+
Sets the value in the config.json file, located at key.
|
|
96
|
+
|
|
97
|
+
> key must be laid out as a dot (.) seperated path, i.e.
|
|
98
|
+
qplot-cfg -set_value user_preference.theme dark
|
|
99
|
+
or
|
|
100
|
+
qplot-cfg -set_value GUI.plot_frame_fraction 0.25
|
|
101
|
+
|
|
102
|
+
> If value has spaces in it, speech marks are required around it
|
|
103
|
+
qplot-cfg -set_value file.default_load_path "./file/with space"
|
|
104
|
+
|
|
105
|
+
Parameters
|
|
106
|
+
----------
|
|
107
|
+
key : str
|
|
108
|
+
Location of the value to change.
|
|
109
|
+
value : [str, list, int, float]
|
|
110
|
+
Value to be changed to.
|
|
111
|
+
|
|
112
|
+
Raises
|
|
113
|
+
------
|
|
114
|
+
KeyError
|
|
115
|
+
Key passed is not located in config.json
|
|
116
|
+
ValidationError
|
|
117
|
+
Value type is incorrect for corresponding key.
|
|
118
|
+
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
#check if key is valid
|
|
122
|
+
self.config.get(key)
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
convrt_value = _config_value(value, self.config.schema_for(key))
|
|
126
|
+
self.config.update(key, convrt_value)
|
|
127
|
+
except (TypeError, ValueError, json.JSONDecodeError, ValidationError) as error:
|
|
128
|
+
err_key = f"Value: {value}, is invalid."
|
|
129
|
+
err_key += str(error)
|
|
130
|
+
raise ValidationError(err_key) from error
|
|
131
|
+
print(f"set '{key}' to '{value}'")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def info(self, attr: str | None = None):
|
|
135
|
+
"""
|
|
136
|
+
-info
|
|
137
|
+
-----
|
|
138
|
+
Gets infomation about callable functions.
|
|
139
|
+
|
|
140
|
+
'qplot-cfg -info' lists all callable functions
|
|
141
|
+
'qplot-cfg -info <attr>' produces the docstring of the function
|
|
142
|
+
Note: the '-' before <attr> can be ommited
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
attr : callable, optional
|
|
147
|
+
Produces the docstring of command attr. If none are given, prints
|
|
148
|
+
all commands
|
|
149
|
+
|
|
150
|
+
Raises
|
|
151
|
+
------
|
|
152
|
+
KeyError
|
|
153
|
+
Invalid command was given.
|
|
154
|
+
|
|
155
|
+
"""
|
|
156
|
+
if not attr:
|
|
157
|
+
print(f"Valid Commands:\n\t{self.valid_args}\nUse 'qplot-cfg -info <command>' for more info")
|
|
158
|
+
return
|
|
159
|
+
elif attr in self.valid_args:
|
|
160
|
+
func = getattr(self, attr[1:])
|
|
161
|
+
elif ("-"+attr) in self.valid_args:
|
|
162
|
+
func = getattr(self, attr)
|
|
163
|
+
else:
|
|
164
|
+
raise KeyError(f"Command: ({attr}), not found. Valid options: {self.valid_args}, '-' may be ommited")
|
|
165
|
+
|
|
166
|
+
print(func.__doc__)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def version(self):
|
|
170
|
+
"""
|
|
171
|
+
-version
|
|
172
|
+
--------
|
|
173
|
+
Prints the installed qPlot package version.
|
|
174
|
+
|
|
175
|
+
"""
|
|
176
|
+
print(package_version())
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def try_as_num(item):
|
|
180
|
+
"""
|
|
181
|
+
Attempts to convert str to float or int.
|
|
182
|
+
|
|
183
|
+
Parameters
|
|
184
|
+
----------
|
|
185
|
+
item : str
|
|
186
|
+
item to be converted.
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
item : int, float, str
|
|
191
|
+
The item after conversions.
|
|
192
|
+
|
|
193
|
+
"""
|
|
194
|
+
try:
|
|
195
|
+
item = item.strip()
|
|
196
|
+
if "." in item or "e" in item.lower():
|
|
197
|
+
item = float(item)
|
|
198
|
+
else:
|
|
199
|
+
item = int(item)
|
|
200
|
+
except ValueError: #if cannot conver to int or float
|
|
201
|
+
item = str(item)
|
|
202
|
+
return item
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _config_value(value, schema):
|
|
206
|
+
"""Parse a command-line value according to its target config schema."""
|
|
207
|
+
|
|
208
|
+
value_type = schema.get("type")
|
|
209
|
+
stripped = value.strip()
|
|
210
|
+
|
|
211
|
+
if value_type == "string":
|
|
212
|
+
return value
|
|
213
|
+
if value_type == "boolean":
|
|
214
|
+
if stripped.lower() == "true":
|
|
215
|
+
return True
|
|
216
|
+
if stripped.lower() == "false":
|
|
217
|
+
return False
|
|
218
|
+
raise ValueError("expected true or false")
|
|
219
|
+
if value_type == "integer":
|
|
220
|
+
return int(stripped, 10)
|
|
221
|
+
if value_type == "number":
|
|
222
|
+
return float(stripped)
|
|
223
|
+
if value_type == "array":
|
|
224
|
+
if not (
|
|
225
|
+
(stripped.startswith("[") and stripped.endswith("]"))
|
|
226
|
+
or (stripped.startswith("(") and stripped.endswith(")"))
|
|
227
|
+
):
|
|
228
|
+
raise ValueError("expected a bracketed list")
|
|
229
|
+
json_list = f"[{stripped[1:-1]}]"
|
|
230
|
+
try:
|
|
231
|
+
return json.loads(json_list)
|
|
232
|
+
except json.JSONDecodeError:
|
|
233
|
+
inner = stripped[1:-1].strip()
|
|
234
|
+
if not inner:
|
|
235
|
+
return []
|
|
236
|
+
item_schema = schema.get("items", {})
|
|
237
|
+
return [
|
|
238
|
+
_config_value(item.strip(), item_schema)
|
|
239
|
+
for item in inner.split(",")
|
|
240
|
+
]
|
|
241
|
+
|
|
242
|
+
return try_as_num(value)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def scripts():
|
|
246
|
+
"""
|
|
247
|
+
The actual entry point which call sysHandle to manage commands
|
|
248
|
+
|
|
249
|
+
"""
|
|
250
|
+
# Fetch str based command from command line
|
|
251
|
+
args=sys.argv
|
|
252
|
+
if len(args) == 1:
|
|
253
|
+
sysHandle("-info")
|
|
254
|
+
else:
|
|
255
|
+
sysHandle(*args[1:])
|