QuLab 2.4.0__cp312-cp312-macosx_10_13_universal2.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 (97) hide show
  1. QuLab-2.4.0.dist-info/LICENSE +21 -0
  2. QuLab-2.4.0.dist-info/METADATA +105 -0
  3. QuLab-2.4.0.dist-info/RECORD +97 -0
  4. QuLab-2.4.0.dist-info/WHEEL +5 -0
  5. QuLab-2.4.0.dist-info/entry_points.txt +2 -0
  6. QuLab-2.4.0.dist-info/top_level.txt +1 -0
  7. qulab/__init__.py +3 -0
  8. qulab/__main__.py +30 -0
  9. qulab/dicttree.py +511 -0
  10. qulab/executor/__init__.py +5 -0
  11. qulab/executor/__main__.py +89 -0
  12. qulab/executor/load.py +202 -0
  13. qulab/executor/schedule.py +223 -0
  14. qulab/executor/storage.py +143 -0
  15. qulab/executor/transform.py +90 -0
  16. qulab/executor/utils.py +107 -0
  17. qulab/fun.cpython-312-darwin.so +0 -0
  18. qulab/monitor/__init__.py +1 -0
  19. qulab/monitor/__main__.py +8 -0
  20. qulab/monitor/config.py +41 -0
  21. qulab/monitor/dataset.py +77 -0
  22. qulab/monitor/event_queue.py +54 -0
  23. qulab/monitor/mainwindow.py +234 -0
  24. qulab/monitor/monitor.py +93 -0
  25. qulab/monitor/ploter.py +123 -0
  26. qulab/monitor/qt_compat.py +16 -0
  27. qulab/monitor/toolbar.py +265 -0
  28. qulab/scan/__init__.py +3 -0
  29. qulab/scan/curd.py +221 -0
  30. qulab/scan/expression.py +646 -0
  31. qulab/scan/models.py +554 -0
  32. qulab/scan/optimize.py +76 -0
  33. qulab/scan/query.py +374 -0
  34. qulab/scan/record.py +603 -0
  35. qulab/scan/scan.py +1166 -0
  36. qulab/scan/server.py +533 -0
  37. qulab/scan/space.py +213 -0
  38. qulab/scan/utils.py +229 -0
  39. qulab/storage/__init__.py +0 -0
  40. qulab/storage/__main__.py +51 -0
  41. qulab/storage/backend/__init__.py +0 -0
  42. qulab/storage/backend/redis.py +204 -0
  43. qulab/storage/base_dataset.py +352 -0
  44. qulab/storage/chunk.py +60 -0
  45. qulab/storage/dataset.py +127 -0
  46. qulab/storage/file.py +273 -0
  47. qulab/storage/models/__init__.py +22 -0
  48. qulab/storage/models/base.py +4 -0
  49. qulab/storage/models/config.py +28 -0
  50. qulab/storage/models/file.py +89 -0
  51. qulab/storage/models/ipy.py +58 -0
  52. qulab/storage/models/models.py +88 -0
  53. qulab/storage/models/record.py +161 -0
  54. qulab/storage/models/report.py +22 -0
  55. qulab/storage/models/tag.py +93 -0
  56. qulab/storage/storage.py +95 -0
  57. qulab/sys/__init__.py +0 -0
  58. qulab/sys/chat.py +688 -0
  59. qulab/sys/device/__init__.py +3 -0
  60. qulab/sys/device/basedevice.py +229 -0
  61. qulab/sys/device/loader.py +86 -0
  62. qulab/sys/device/utils.py +79 -0
  63. qulab/sys/drivers/FakeInstrument.py +52 -0
  64. qulab/sys/drivers/__init__.py +0 -0
  65. qulab/sys/ipy_events.py +125 -0
  66. qulab/sys/net/__init__.py +0 -0
  67. qulab/sys/net/bencoder.py +205 -0
  68. qulab/sys/net/cli.py +169 -0
  69. qulab/sys/net/dhcp.py +543 -0
  70. qulab/sys/net/dhcpd.py +176 -0
  71. qulab/sys/net/kad.py +1142 -0
  72. qulab/sys/net/kcp.py +192 -0
  73. qulab/sys/net/nginx.py +192 -0
  74. qulab/sys/progress.py +190 -0
  75. qulab/sys/rpc/__init__.py +0 -0
  76. qulab/sys/rpc/client.py +0 -0
  77. qulab/sys/rpc/exceptions.py +96 -0
  78. qulab/sys/rpc/msgpack.py +1052 -0
  79. qulab/sys/rpc/msgpack.pyi +41 -0
  80. qulab/sys/rpc/router.py +35 -0
  81. qulab/sys/rpc/rpc.py +412 -0
  82. qulab/sys/rpc/serialize.py +139 -0
  83. qulab/sys/rpc/server.py +29 -0
  84. qulab/sys/rpc/socket.py +29 -0
  85. qulab/sys/rpc/utils.py +25 -0
  86. qulab/sys/rpc/worker.py +0 -0
  87. qulab/sys/rpc/zmq_socket.py +220 -0
  88. qulab/version.py +1 -0
  89. qulab/visualization/__init__.py +188 -0
  90. qulab/visualization/__main__.py +71 -0
  91. qulab/visualization/_autoplot.py +464 -0
  92. qulab/visualization/plot_circ.py +319 -0
  93. qulab/visualization/plot_layout.py +408 -0
  94. qulab/visualization/plot_seq.py +242 -0
  95. qulab/visualization/qdat.py +152 -0
  96. qulab/visualization/rot3d.py +23 -0
  97. qulab/visualization/widgets.py +86 -0
@@ -0,0 +1,152 @@
1
+ """
2
+ This module provides the visualization of the qdat file.
3
+ """
4
+ import logging
5
+ import math
6
+ import re
7
+ from functools import reduce
8
+
9
+ import matplotlib.pyplot as plt
10
+ import numpy as np
11
+ from matplotlib import cm
12
+
13
+ log = logging.getLogger(__name__)
14
+
15
+
16
+ def draw(record_dict, fig=None, transpose=True, remove=True):
17
+ """Draw a 2D or 3D plot from a record dict.
18
+
19
+ Args:
20
+ record_dict (dict): The record dict.
21
+ fig (matplotlib.figure.Figure): The figure to draw on.
22
+ transpose (bool): Whether to transpose the data.
23
+ """
24
+ dim = record_dict['info']['dim']
25
+ zshape = record_dict['info']['zshape']
26
+ zsize = reduce(lambda a, b: a * b, zshape, 1)
27
+
28
+ axis_label = np.asarray(record_dict['info'].get('axis_label',
29
+ [])).flatten()
30
+ z_label = np.asarray(record_dict['info'].get('z_label', [])).flatten()
31
+ axis_unit = np.asarray(record_dict['info'].get('axis_unit', [])).flatten()
32
+ z_unit = np.asarray(record_dict['info'].get('z_unit', [])).flatten()
33
+
34
+ fig = plt.figure() if fig is None else fig
35
+ if zsize < 4:
36
+ plot_shape = (1, zsize)
37
+ else:
38
+ n = int(np.sqrt(zsize))
39
+ plot_shape = (math.ceil(zsize / n), n)
40
+ if dim < 3 and zsize < 100:
41
+ figsize = plot_shape[1] * 8, plot_shape[0] * 6
42
+ fig.set_size_inches(*figsize)
43
+ axes = fig.subplots(*plot_shape)
44
+ axes = np.array(axes).flatten()
45
+ else:
46
+ axes = []
47
+
48
+ cb_list = []
49
+ if dim == 1 and zsize < 101:
50
+ for i in range(zsize):
51
+ title = record_dict[
52
+ 'name'] + f' {i}' if zsize > 1 else record_dict['name']
53
+ try:
54
+ xlabel = axis_label[0]
55
+ ylabel = z_label[0] if len(z_label) == 1 else z_label[i]
56
+ except:
57
+ xlabel, ylabel = 'X', 'Y'
58
+ try:
59
+ x_unit = axis_unit[0]
60
+ y_unit = z_unit[0] if len(z_unit) == 1 else z_unit[i]
61
+ except:
62
+ x_unit, y_unit = 'a.u.', 'a.u.'
63
+ axes[i].set_title(title)
64
+ axes[i].set_xlabel(f'{xlabel} ({x_unit})')
65
+ axes[i].set_ylabel(f'{ylabel} ({y_unit})')
66
+ elif dim == 2 and zsize < 101:
67
+ for i in range(zsize):
68
+ smp = cm.ScalarMappable(norm=None, cmap=None)
69
+ cb = fig.colorbar(smp, ax=axes[i]) # 默认色谱的colorbar
70
+ cb_list.append(cb)
71
+ try:
72
+ title = record_dict['name'] + \
73
+ f': {z_label[i]}' if zsize > 1 else record_dict['name']
74
+ except:
75
+ title = record_dict[
76
+ 'name'] + f' {i}' if zsize > 1 else record_dict['name']
77
+ try:
78
+ xlabel, ylabel = axis_label[1], axis_label[0]
79
+ if transpose:
80
+ xlabel, ylabel = ylabel, xlabel
81
+ except:
82
+ xlabel, ylabel = 'X', 'Y'
83
+ try:
84
+ x_unit, y_unit = axis_unit[1], axis_unit[0]
85
+ if transpose:
86
+ x_unit, y_unit = y_unit, x_unit
87
+ except:
88
+ x_unit, y_unit = 'a.u.', 'a.u.'
89
+ axes[i].set_title(title)
90
+ axes[i].set_xlabel(f'{xlabel} ({x_unit})')
91
+ axes[i].set_ylabel(f'{ylabel} ({y_unit})')
92
+ else:
93
+ message1 = f'dim {dim} is too large (>2)! ' if dim > 2 else f'dim={dim}; '
94
+ message2 = f'zsize {zsize} is too large (>101)!' if zsize > 101 else f'zsize={zsize}'
95
+ log.warning('PASS: ' + message1 + message2)
96
+ #########################################################################################
97
+ try:
98
+ tags = [
99
+ tag.strip(r'\*')
100
+ for tag in record_dict['ParaSpace'].get('tags', [])
101
+ if re.match(r'\*', tag)
102
+ ]
103
+ tag_text = ','.join(tags)
104
+ if tag_text:
105
+ axes[0].text(-0.1,
106
+ 1.1,
107
+ 'TAG: ' + tag_text,
108
+ horizontalalignment='left',
109
+ verticalalignment='bottom',
110
+ transform=axes[0].transAxes) # fig.transFigure)#
111
+ except:
112
+ pass
113
+ #########################################################################################
114
+ fig.tight_layout()
115
+
116
+ dim = record_dict['info']['dim']
117
+ zshape = record_dict['info']['zshape']
118
+ datashape = record_dict['info']['datashape']
119
+ zsize = reduce(lambda a, b: a * b, zshape, 1)
120
+ datashape_r = (*datashape[:dim], zsize)
121
+
122
+ if dim == 1 and zsize < 101:
123
+ x, z = record_dict['data']
124
+ z = z.reshape(datashape_r)
125
+ z = np.abs(z) if np.any(np.iscomplex(z)) else z.real
126
+ for i in range(zsize):
127
+ _ = [a.remove() for a in axes[i].get_lines()] if remove else []
128
+ axes[i].plot(x, z[:, i], 'C0')
129
+ axes[i].plot(x, z[:, i], 'C0.')
130
+ elif dim == 2 and zsize < 101:
131
+ x, y, z = record_dict['data']
132
+ x_step, y_step = x[1] - x[0], y[1] - y[0]
133
+ if transpose:
134
+ x, y = y, x
135
+ x_step, y_step = y_step, x_step
136
+ z = z.reshape(datashape_r)
137
+ z = np.abs(z) if np.any(np.iscomplex(z)) else z.real
138
+ for i in range(zsize):
139
+ _z = z[:, :, i]
140
+ _ = [a.remove() for a in axes[i].get_images()] if remove else []
141
+ if transpose:
142
+ _z = _z.T
143
+ im = axes[i].imshow(_z,
144
+ extent=(y[0] - y_step / 2, y[-1] + y_step / 2,
145
+ x[0] - x_step / 2, x[-1] + x_step / 2),
146
+ origin='lower',
147
+ aspect='auto')
148
+ cb_list[i].update_normal(im) # 更新对应的colorbar
149
+ else:
150
+ pass
151
+
152
+ return fig, axes
@@ -0,0 +1,23 @@
1
+ import numpy as np
2
+ from scipy.linalg import expm
3
+
4
+
5
+ def _rot(theta, v):
6
+ x, y, z = np.asarray(v) / np.sqrt(np.sum(np.asarray(v)**2))
7
+ c, s = np.cos(theta), np.sin(theta)
8
+
9
+ return np.array([[
10
+ c + (1 - c) * x**2, (1 - c) * x * y - s * z, (1 - c) * x * z + s * y
11
+ ], [(1 - c) * x * y + s * z, c + (1 - c) * y**2, (1 - c) * y * z - s * x],
12
+ [(1 - c) * x * z - s * y, (1 - c) * y * z + s * x,
13
+ c + (1 - c) * z**2]])
14
+
15
+
16
+ def rot_round(x, y, z, v=[0, 0, 1], theta=0, c=[0, 0, 0]):
17
+ ret = (np.array([x, y, z]).T - np.array(c)) @ _rot(theta, v) + np.array(c)
18
+ return ret.T
19
+
20
+
21
+ def projection(x, y, z, y0=1):
22
+ d = np.sqrt(x**2 + y**2 + z**2)
23
+ return x * y0 / y, z * y0 / y, d
@@ -0,0 +1,86 @@
1
+ import matplotlib.pyplot as plt
2
+ import numpy as np
3
+
4
+
5
+ class DataPicker():
6
+
7
+ def __init__(self, ax=None):
8
+ self.points_and_text = {}
9
+ self.points = None
10
+ self.hline = None
11
+ self.vline = None
12
+ self.text = None
13
+ if ax is None:
14
+ ax = plt.gca()
15
+ self.ax = ax
16
+ self.ax.figure.canvas.mpl_connect('button_press_event', self.on_click)
17
+ # self.ax.figure.canvas.mpl_connect('motion_notify_event', self.on_move)
18
+ self.ax.figure.canvas.mpl_connect('key_press_event', self.on_key_press)
19
+ self.mode = 'pick'
20
+
21
+ def on_key_press(self, event):
22
+ if event.key == 'a':
23
+ if self.mode != 'pick':
24
+ self.mode = 'pick'
25
+ else:
26
+ self.mode = 'default'
27
+
28
+ def on_move(self, event):
29
+ if event.inaxes is self.ax:
30
+ # self.hline = self.ax.axhline(y=np.nan, color='r', lw=1)
31
+ # self.vline = self.ax.axvline(x=np.nan, color='r', lw=1)
32
+ # self.text = self.ax.text(0, 0, '', verticalalignment='center')
33
+ self.hline.set_ydata(event.ydata)
34
+ self.vline.set_xdata(event.xdata)
35
+ self.text.set_position((event.xdata, event.ydata))
36
+ self.text.set_text(f'({event.xdata:.2f}, {event.ydata:.2f})')
37
+ self.ax.draw()
38
+
39
+ def on_click(self, event):
40
+ if self.mode != 'pick':
41
+ return
42
+ # 鼠标左键的button值为1
43
+ if event.button == 1 and event.inaxes is self.ax:
44
+ point = (event.xdata, event.ydata)
45
+ text = self.ax.text(point[0],
46
+ point[1],
47
+ f'({point[0]:.2f}, {point[1]:.2f})',
48
+ verticalalignment='center')
49
+ self.points_and_text[point] = text
50
+ x, y = self.get_xy()
51
+ if self.points is None:
52
+ self.points, = self.ax.plot(x, y, 'ro')
53
+ else:
54
+ self.points.set_data(x, y)
55
+ self.ax.draw()
56
+
57
+ elif event.button == 3 and event.inaxes is self.ax:
58
+ for point, text in list(self.points_and_text.items()):
59
+ point_xdisplay, point_ydisplay = self.ax.transData.transform_point(
60
+ point)
61
+
62
+ distance = np.sqrt((point_xdisplay - event.x)**2 +
63
+ (point_ydisplay - event.y)**2)
64
+ if distance < 10:
65
+ text.remove()
66
+ self.points_and_text.pop(point)
67
+ if self.points_and_text:
68
+ x, y = self.get_xy()
69
+ self.points.set_data(x, y)
70
+ else:
71
+ self.points.remove()
72
+ self.points = None
73
+ self.ax.draw()
74
+ break
75
+
76
+ def get_xy(self):
77
+ if self.points_and_text:
78
+ data = np.asarray(list(self.points_and_text.keys()))
79
+ x, y = data[:, 0], data[:, 1]
80
+
81
+ index = np.argsort(x)
82
+ x = np.asarray(x)[index]
83
+ y = np.asarray(y)[index]
84
+ return x, y
85
+ else:
86
+ return np.array([]), np.array([])