deapi 5.2.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.
- deapi/__init__.py +33 -0
- deapi/buffer_protocols/__init__.py +29 -0
- deapi/buffer_protocols/pb_2_3_0.py +666 -0
- deapi/buffer_protocols/pb_3_11_4.py +741 -0
- deapi/buffer_protocols/pb_3_19_3.py +114 -0
- deapi/buffer_protocols/pb_3_23_3.py +41 -0
- deapi/buffer_protocols/pb_3_6_1.py +745 -0
- deapi/client.py +2159 -0
- deapi/conf.py +184 -0
- deapi/data_types.py +586 -0
- deapi/fake_data/__init__.py +7 -0
- deapi/fake_data/base_fake_data.py +113 -0
- deapi/fake_data/grains.py +87 -0
- deapi/index.rst +10 -0
- deapi/prop_dump.json +450 -0
- deapi/python_3_instruction.txt +31 -0
- deapi/release_notes.txt +34 -0
- deapi/simulated_server/__init__.py +0 -0
- deapi/simulated_server/fake_server.py +721 -0
- deapi/simulated_server/initialize_server.py +66 -0
- deapi/tests/__init__.py +0 -0
- deapi/tests/conftest.py +95 -0
- deapi/tests/original_tests/01_fps.py +102 -0
- deapi/tests/original_tests/02_hwRoisize.py +155 -0
- deapi/tests/original_tests/03_hwBinning.py +117 -0
- deapi/tests/original_tests/04_swBinning.py +141 -0
- deapi/tests/original_tests/05_swhwBinning.py +113 -0
- deapi/tests/original_tests/06_patternPixel.py +139 -0
- deapi/tests/original_tests/07_reference.py +92 -0
- deapi/tests/original_tests/08_virtmask.py +114 -0
- deapi/tests/original_tests/09_scanRoi.py +104 -0
- deapi/tests/original_tests/10_imageStatistics.py +247 -0
- deapi/tests/original_tests/__init__.py +0 -0
- deapi/tests/original_tests/func.py +76 -0
- deapi/tests/original_tests/propertyName.py +725 -0
- deapi/tests/original_tests/test_legacy.py +132 -0
- deapi/tests/speed_tests/__init__.py +0 -0
- deapi/tests/speed_tests/test_internal_file_saving.py +54 -0
- deapi/tests/speed_tests/test_movie_buffer_transfer.py +54 -0
- deapi/tests/test_client.py +270 -0
- deapi/tests/test_fake_server/__init__.py +0 -0
- deapi/tests/test_fake_server/test_server.py +35 -0
- deapi/tests/test_file_saving/__init__.py +0 -0
- deapi/tests/test_file_saving/test_file_loading_libertem.py +49 -0
- deapi/tests/test_file_saving/test_file_loading_rsciio.py +53 -0
- deapi/tests/test_file_saving/test_scan_pattern_saving.py +68 -0
- deapi/version.py +3 -0
- deapi-5.2.0.dist-info/METADATA +44 -0
- deapi-5.2.0.dist-info/RECORD +52 -0
- deapi-5.2.0.dist-info/WHEEL +5 -0
- deapi-5.2.0.dist-info/entry_points.txt +2 -0
- deapi-5.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,721 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import warnings
|
|
3
|
+
|
|
4
|
+
from deapi.buffer_protocols import pb
|
|
5
|
+
import json
|
|
6
|
+
from importlib import resources
|
|
7
|
+
import deapi
|
|
8
|
+
import numpy as np
|
|
9
|
+
from deapi.version import commandVersion
|
|
10
|
+
from deapi.fake_data.grains import TiltGrains
|
|
11
|
+
from skimage.transform import resize
|
|
12
|
+
from sympy import parse_expr
|
|
13
|
+
|
|
14
|
+
inp_file = resources.files(deapi) / "prop_dump.json"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def add_parameter(ack, value):
|
|
18
|
+
"""
|
|
19
|
+
Add a parameter to a protobuffer
|
|
20
|
+
"""
|
|
21
|
+
param = ack.parameter.add()
|
|
22
|
+
if isinstance(value, str):
|
|
23
|
+
param.type = pb.AnyParameter.P_STRING
|
|
24
|
+
param.p_string = value
|
|
25
|
+
elif isinstance(value, int):
|
|
26
|
+
param.type = pb.AnyParameter.P_INT
|
|
27
|
+
param.p_int = value
|
|
28
|
+
elif isinstance(value, bool):
|
|
29
|
+
param.type = pb.AnyParameter.P_BOOL
|
|
30
|
+
param.p_bool = value
|
|
31
|
+
elif isinstance(value, float):
|
|
32
|
+
param.type = pb.AnyParameter.P_FLOAT
|
|
33
|
+
param.p_float = value
|
|
34
|
+
else:
|
|
35
|
+
raise ValueError(f"Value {value} not recognized of type {type(value)}")
|
|
36
|
+
return ack
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class Property:
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
name,
|
|
43
|
+
value,
|
|
44
|
+
data_type,
|
|
45
|
+
category,
|
|
46
|
+
value_type,
|
|
47
|
+
options,
|
|
48
|
+
default_value=None,
|
|
49
|
+
set_expression=None,
|
|
50
|
+
get_expression=None,
|
|
51
|
+
set_also_expressions=None,
|
|
52
|
+
server=None,
|
|
53
|
+
):
|
|
54
|
+
self.name = name
|
|
55
|
+
self.data_type = data_type
|
|
56
|
+
self.category = category
|
|
57
|
+
self.value_type = value_type
|
|
58
|
+
self.options = options
|
|
59
|
+
self.server = server
|
|
60
|
+
self._value = value
|
|
61
|
+
self.default_value = default_value
|
|
62
|
+
self.set_expression = set_expression
|
|
63
|
+
self.get_expression = get_expression
|
|
64
|
+
self.set_also_expressions = set_also_expressions
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def value(self):
|
|
68
|
+
if self.get_expression is not None:
|
|
69
|
+
epr = parse_expr(self.get_expression)
|
|
70
|
+
symbols = epr.free_symbols
|
|
71
|
+
replace_dict = {}
|
|
72
|
+
for s in symbols:
|
|
73
|
+
if s == "value":
|
|
74
|
+
replace_dict[s] = self._value
|
|
75
|
+
else:
|
|
76
|
+
replace_dict[s] = self.server[s]
|
|
77
|
+
value = epr.evalf(subs=replace_dict)
|
|
78
|
+
if self.data_type == "Integer":
|
|
79
|
+
value = int(value)
|
|
80
|
+
elif self.data_type == "Float":
|
|
81
|
+
value = float(value)
|
|
82
|
+
elif self.data_type == "String":
|
|
83
|
+
value = str(value)
|
|
84
|
+
value = str(value)
|
|
85
|
+
self._value = value
|
|
86
|
+
return value
|
|
87
|
+
elif self.category == "Server":
|
|
88
|
+
return getattr(self.server, self.name.replace(" ", "_").lower())
|
|
89
|
+
else:
|
|
90
|
+
return self._value
|
|
91
|
+
|
|
92
|
+
@value.setter
|
|
93
|
+
def value(self, value):
|
|
94
|
+
if self.set_expression is not None:
|
|
95
|
+
epr = parse_expr(self.set_expression)
|
|
96
|
+
symbols = epr.free_symbols
|
|
97
|
+
replace_dict = {}
|
|
98
|
+
for s in symbols:
|
|
99
|
+
if str(s) == "value":
|
|
100
|
+
replace_dict[s] = value
|
|
101
|
+
else:
|
|
102
|
+
replace_dict[s] = self.server[s]
|
|
103
|
+
value = epr.evalf(subs=replace_dict)
|
|
104
|
+
elif self.value_type == "READ_ONLY" or self.value_type == "Server":
|
|
105
|
+
warnings.warn(f"Property {self.name} is read only")
|
|
106
|
+
value = self._value
|
|
107
|
+
elif self.value_type == "Range" and self.options is not None:
|
|
108
|
+
range = np.array(self.options.split(",")[:2]).astype(float)
|
|
109
|
+
if float(value) < range[0] or float(value) > range[1]:
|
|
110
|
+
warnings.warn(f"Value {value} not in range {range}")
|
|
111
|
+
value = self._value
|
|
112
|
+
elif self.value_type == "Set" and self.options is not None:
|
|
113
|
+
op = [
|
|
114
|
+
o.replace("*", "").replace("'", "").strip()
|
|
115
|
+
for o in self.options.split(",")
|
|
116
|
+
]
|
|
117
|
+
if str(value) not in op:
|
|
118
|
+
warnings.warn(f"Value {value} not in options {self.options}")
|
|
119
|
+
value = self._value
|
|
120
|
+
|
|
121
|
+
if self.data_type == "Integer":
|
|
122
|
+
value = int(value)
|
|
123
|
+
elif self.data_type == "Float":
|
|
124
|
+
value = float(value)
|
|
125
|
+
elif self.data_type == "String":
|
|
126
|
+
value = str(value)
|
|
127
|
+
self._value = str(value)
|
|
128
|
+
|
|
129
|
+
if self.set_also_expressions is not None:
|
|
130
|
+
for parameter, expr in self.set_also_expressions.items():
|
|
131
|
+
epr = parse_expr(expr)
|
|
132
|
+
symbols = epr.free_symbols
|
|
133
|
+
replace_dict = {}
|
|
134
|
+
for s in symbols:
|
|
135
|
+
if s == "value":
|
|
136
|
+
replace_dict[s] = value
|
|
137
|
+
else:
|
|
138
|
+
replace_dict[s] = self.server[s]
|
|
139
|
+
ans = epr.evalf(subs=replace_dict)
|
|
140
|
+
self.server[parameter] = ans
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class FakeServer:
|
|
144
|
+
def __init__(self, dataset="grains", socket=None):
|
|
145
|
+
self.start_time = time.time()
|
|
146
|
+
self.end_time = time.time()
|
|
147
|
+
self.has_movie_buffer = False
|
|
148
|
+
self.movie_buffer_index = 0
|
|
149
|
+
self.dataset = dataset
|
|
150
|
+
self.fake_data = None
|
|
151
|
+
self.socket = socket
|
|
152
|
+
self.current_movie_index = 0
|
|
153
|
+
|
|
154
|
+
with open(inp_file) as f:
|
|
155
|
+
values = json.load(f)
|
|
156
|
+
property_dict = {}
|
|
157
|
+
for v in values:
|
|
158
|
+
new_v = v.replace(" ", "_").lower().replace("(", "").replace(")", "")
|
|
159
|
+
property_dict[new_v] = Property(
|
|
160
|
+
name=v,
|
|
161
|
+
value=values[v]["value"],
|
|
162
|
+
data_type=values[v]["data_type"],
|
|
163
|
+
category=values[v]["category"],
|
|
164
|
+
value_type=values[v]["value_type"],
|
|
165
|
+
options=values[v]["options"],
|
|
166
|
+
default_value=values[v]["default_value"],
|
|
167
|
+
server=self,
|
|
168
|
+
set_expression=values[v].get("set", None),
|
|
169
|
+
get_expression=values[v].get("get", None),
|
|
170
|
+
set_also_expressions=values[v].get("set_also", None),
|
|
171
|
+
)
|
|
172
|
+
self._values = property_dict
|
|
173
|
+
self._number_of_frames_requested = 0
|
|
174
|
+
|
|
175
|
+
self.current_socket_result = None
|
|
176
|
+
self._values["acquisition_status"] = Property(
|
|
177
|
+
name="Acquisition Status",
|
|
178
|
+
value="Idle",
|
|
179
|
+
data_type="String",
|
|
180
|
+
category="Server",
|
|
181
|
+
value_type="Set",
|
|
182
|
+
options=["Idle", "Acquiring"],
|
|
183
|
+
server=self,
|
|
184
|
+
)
|
|
185
|
+
self._values["number_of_frames_requested"] = Property(
|
|
186
|
+
name="Number of Frames Requested",
|
|
187
|
+
value="Idle",
|
|
188
|
+
data_type="Integer",
|
|
189
|
+
category="Server",
|
|
190
|
+
value_type="Read Only",
|
|
191
|
+
options=None,
|
|
192
|
+
server=self,
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
self.virtual_masks = []
|
|
196
|
+
for i in range(4):
|
|
197
|
+
self.virtual_masks.append(
|
|
198
|
+
np.ones(
|
|
199
|
+
shape=(
|
|
200
|
+
int(self["Image Size X (pixels)"]),
|
|
201
|
+
int(self["Image Size Y (pixels)"]),
|
|
202
|
+
),
|
|
203
|
+
dtype=np.int8,
|
|
204
|
+
)
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
def __getitem__(self, item):
|
|
208
|
+
if not isinstance(item, str):
|
|
209
|
+
item = str(item)
|
|
210
|
+
item = item.replace(" ", "_").lower().replace("(", "").replace(")", "")
|
|
211
|
+
return self._values[item].value
|
|
212
|
+
|
|
213
|
+
def __setitem__(self, key, value):
|
|
214
|
+
key = key.replace(" ", "_").lower().replace("(", "").replace(")", "")
|
|
215
|
+
self._values[key].value = value
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def acquisition_status(self):
|
|
219
|
+
if time.time() < self.end_time:
|
|
220
|
+
return "Acquiring"
|
|
221
|
+
else:
|
|
222
|
+
return "Idle"
|
|
223
|
+
|
|
224
|
+
@property
|
|
225
|
+
def number_of_frames_requested(self):
|
|
226
|
+
if self["Scan - Enable"] == "On":
|
|
227
|
+
return self["Scan - Size X"] * self["Scan - Size Y"]
|
|
228
|
+
else:
|
|
229
|
+
return self._number_of_frames_requested
|
|
230
|
+
|
|
231
|
+
@number_of_frames_requested.setter
|
|
232
|
+
def number_of_frames_requested(self, value):
|
|
233
|
+
self._number_of_frames_requested = value
|
|
234
|
+
|
|
235
|
+
@property
|
|
236
|
+
def current_navigation_index(self):
|
|
237
|
+
if self.fake_data is None:
|
|
238
|
+
return ValueError("No fake data initialized")
|
|
239
|
+
if self.acquisition_status == "Idle":
|
|
240
|
+
return tuple(np.array(self.fake_data.navigator.shape) - 1)
|
|
241
|
+
else:
|
|
242
|
+
index = np.unravel_index(
|
|
243
|
+
int(
|
|
244
|
+
(time.time() - self.start_time) * float(self["Frames Per Second"]),
|
|
245
|
+
),
|
|
246
|
+
self.fake_data.navigator.shape,
|
|
247
|
+
) # only works for raster scans
|
|
248
|
+
return index
|
|
249
|
+
|
|
250
|
+
def _respond_to_command(self, command=None):
|
|
251
|
+
if command is None:
|
|
252
|
+
return False
|
|
253
|
+
if command.command[0].command_id == self.GET_PROPERTY + commandVersion * 100:
|
|
254
|
+
return self._fake_get_property(command)
|
|
255
|
+
elif command.command[0].command_id == self.SET_PROPERTY + commandVersion * 100:
|
|
256
|
+
return self._fake_set_property(command)
|
|
257
|
+
elif (
|
|
258
|
+
command.command[0].command_id == self.LIST_PROPERTIES + commandVersion * 100
|
|
259
|
+
):
|
|
260
|
+
return self._fake_list_properties(command)
|
|
261
|
+
elif (
|
|
262
|
+
command.command[0].command_id
|
|
263
|
+
== self.LIST_ALLOWED_VALUES + commandVersion * 100
|
|
264
|
+
):
|
|
265
|
+
return self._fake_list_allowed_values(command)
|
|
266
|
+
elif (
|
|
267
|
+
command.command[0].command_id
|
|
268
|
+
== self.GET_MOVIE_BUFFER_INFO + commandVersion * 100
|
|
269
|
+
):
|
|
270
|
+
return self._fake_get_movie_buffer_info(command)
|
|
271
|
+
elif (
|
|
272
|
+
command.command[0].command_id
|
|
273
|
+
== self.GET_MOVIE_BUFFER + commandVersion * 100
|
|
274
|
+
):
|
|
275
|
+
return self._fake_get_movie_buffer(command)
|
|
276
|
+
elif (
|
|
277
|
+
command.command[0].command_id
|
|
278
|
+
== self.START_ACQUISITION + commandVersion * 100
|
|
279
|
+
):
|
|
280
|
+
return self._fake_start_acquisition(command)
|
|
281
|
+
elif command.command[0].command_id == self.GET_RESULT + commandVersion * 100:
|
|
282
|
+
return self._fake_get_result(command)
|
|
283
|
+
elif command.command[0].command_id == self.LIST_CAMERAS + commandVersion * 100:
|
|
284
|
+
return self._fake_list_cameras(command)
|
|
285
|
+
elif (
|
|
286
|
+
command.command[0].command_id
|
|
287
|
+
== self.SET_CLIENT_READ_ONLY + commandVersion * 100
|
|
288
|
+
):
|
|
289
|
+
return self._fake_set_client_read_only(command)
|
|
290
|
+
elif (
|
|
291
|
+
command.command[0].command_id
|
|
292
|
+
== self.SET_VIRTUAL_MASK + commandVersion * 100
|
|
293
|
+
):
|
|
294
|
+
return self._fake_set_virtual_mask(command)
|
|
295
|
+
else:
|
|
296
|
+
raise NotImplementedError(
|
|
297
|
+
f"Command {command.command[0].command_id} not implemented"
|
|
298
|
+
f" in the FakeServer. Please use the real DEServer for testing."
|
|
299
|
+
f" The commandVersion is {commandVersion}"
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
def _fake_set_client_read_only(self, command):
|
|
303
|
+
|
|
304
|
+
self.is_read_only = command.command[0].parameter[0].p_bool
|
|
305
|
+
acknowledge_return = pb.DEPacket()
|
|
306
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
307
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
308
|
+
ack1.command_id = command.command[0].command_id
|
|
309
|
+
return (acknowledge_return,)
|
|
310
|
+
|
|
311
|
+
def _fake_set_virtual_mask(self, command):
|
|
312
|
+
acknowledge_return = pb.DEPacket()
|
|
313
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
314
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
315
|
+
ack1.command_id = command.command[0].command_id
|
|
316
|
+
|
|
317
|
+
mask_id = command.command[0].parameter[0].p_int
|
|
318
|
+
w = command.command[0].parameter[1].p_int
|
|
319
|
+
h = command.command[0].parameter[2].p_int
|
|
320
|
+
|
|
321
|
+
total_bytes = w * h
|
|
322
|
+
buffer = self.socket.recv(total_bytes)
|
|
323
|
+
total_len = len(buffer)
|
|
324
|
+
if total_len < total_bytes:
|
|
325
|
+
while total_len < total_bytes:
|
|
326
|
+
try:
|
|
327
|
+
buffer += self.socket.recv(total_bytes)
|
|
328
|
+
total_len = len(buffer)
|
|
329
|
+
except self.socket.timeout:
|
|
330
|
+
raise ValueError("Socket timed out")
|
|
331
|
+
buffer = buffer
|
|
332
|
+
mask = np.frombuffer(buffer, dtype=np.int8).reshape((w, h))
|
|
333
|
+
self.virtual_masks[mask_id] = mask
|
|
334
|
+
return (acknowledge_return,)
|
|
335
|
+
|
|
336
|
+
def _fake_list_cameras(self, command):
|
|
337
|
+
acknowledge_return = pb.DEPacket()
|
|
338
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
339
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
340
|
+
ack1.command_id = command.command[0].command_id
|
|
341
|
+
add_parameter(ack1, "Fake Camera")
|
|
342
|
+
return (acknowledge_return,)
|
|
343
|
+
|
|
344
|
+
def _initialize_data(self, scan_size_x, scan_size_y, kx_pixels, ky_pixels):
|
|
345
|
+
if self.dataset == "grains":
|
|
346
|
+
self.fake_data = TiltGrains(
|
|
347
|
+
x_pixels=scan_size_x,
|
|
348
|
+
y_pixels=scan_size_y,
|
|
349
|
+
kx_pixels=kx_pixels,
|
|
350
|
+
ky_pixels=ky_pixels,
|
|
351
|
+
server=self,
|
|
352
|
+
)
|
|
353
|
+
else:
|
|
354
|
+
raise ValueError(
|
|
355
|
+
f"Dataset {self.dataset} not recognized. Please use 'grains'"
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
def _fake_start_acquisition(self, command):
|
|
359
|
+
self.current_movie_index = 0
|
|
360
|
+
|
|
361
|
+
acknowledge_return = pb.DEPacket()
|
|
362
|
+
num_acq = command.command[0].parameter[0].p_int
|
|
363
|
+
if self["Scan - Enable"] == "On":
|
|
364
|
+
frames = int(self["Scan - Size X"]) * int(self["Scan - Size Y"])
|
|
365
|
+
self._initialize_data(
|
|
366
|
+
int(self["Scan - Size X"]),
|
|
367
|
+
int(self["Scan - Size Y"]),
|
|
368
|
+
int(self["Sensor Size X (pixels)"]),
|
|
369
|
+
int(self["Sensor Size X (pixels)"]),
|
|
370
|
+
)
|
|
371
|
+
else:
|
|
372
|
+
self._initialize_data(
|
|
373
|
+
int(4),
|
|
374
|
+
int(4),
|
|
375
|
+
int(self["Sensor Size X (pixels)"]),
|
|
376
|
+
int(self["Sensor Size X (pixels)"]),
|
|
377
|
+
)
|
|
378
|
+
frames = num_acq
|
|
379
|
+
self.number_of_frames_requested = frames
|
|
380
|
+
fps = float(self["Frames Per Second"])
|
|
381
|
+
total_time = frames * num_acq / fps
|
|
382
|
+
self.start_time = time.time()
|
|
383
|
+
print(f"Acquisition started for {total_time} seconds")
|
|
384
|
+
print(f"Acquisition started at {self.start_time}")
|
|
385
|
+
print(f"Acquisition will end at {self.start_time + total_time}")
|
|
386
|
+
|
|
387
|
+
self.end_time = self.start_time + total_time
|
|
388
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
389
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
390
|
+
ack1.command_id = command.command[0].command_id
|
|
391
|
+
return (acknowledge_return,)
|
|
392
|
+
|
|
393
|
+
def _fake_list_allowed_values(self, command):
|
|
394
|
+
acknowledge_return = pb.DEPacket()
|
|
395
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
396
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
397
|
+
ack1.command_id = command.command[0].command_id
|
|
398
|
+
name = command.command[0].parameter[0].p_string
|
|
399
|
+
prop_dict = self._values[
|
|
400
|
+
name.replace(" ", "_").lower().replace("(", "").replace(")", "")
|
|
401
|
+
]
|
|
402
|
+
|
|
403
|
+
list_props = [
|
|
404
|
+
"data_type",
|
|
405
|
+
"value_type",
|
|
406
|
+
"category",
|
|
407
|
+
"options",
|
|
408
|
+
"default_value",
|
|
409
|
+
"value",
|
|
410
|
+
]
|
|
411
|
+
|
|
412
|
+
for key in list_props:
|
|
413
|
+
param = ack1.parameter.add()
|
|
414
|
+
if isinstance(getattr(prop_dict, key), bool):
|
|
415
|
+
param.type = pb.AnyParameter.P_BOOL
|
|
416
|
+
param.p_bool = getattr(prop_dict, key)
|
|
417
|
+
elif isinstance(getattr(prop_dict, key), int):
|
|
418
|
+
param.type = pb.AnyParameter.P_INT
|
|
419
|
+
param.p_int = getattr(prop_dict, key)
|
|
420
|
+
elif isinstance(getattr(prop_dict, key), float):
|
|
421
|
+
param.type = pb.AnyParameter.P_FLOAT
|
|
422
|
+
param.p_float = getattr(prop_dict, key)
|
|
423
|
+
else:
|
|
424
|
+
param.type = pb.AnyParameter.P_STRING
|
|
425
|
+
param.p_string = getattr(prop_dict, key)
|
|
426
|
+
|
|
427
|
+
return (acknowledge_return,)
|
|
428
|
+
|
|
429
|
+
def _fake_list_properties(self, command):
|
|
430
|
+
acknowledge_return = pb.DEPacket()
|
|
431
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
432
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
433
|
+
ack1.command_id = command.command[0].command_id
|
|
434
|
+
for key in self._values:
|
|
435
|
+
string_param = ack1.parameter.add()
|
|
436
|
+
string_param.type = pb.AnyParameter.P_STRING
|
|
437
|
+
string_param.p_string = self._values[key].name
|
|
438
|
+
return (acknowledge_return,)
|
|
439
|
+
|
|
440
|
+
def _fake_set_property(self, command):
|
|
441
|
+
acknowledge_return = pb.DEPacket()
|
|
442
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
443
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
444
|
+
ack1.command_id = command.command[0].command_id
|
|
445
|
+
name = command.command[0].parameter[0].p_string
|
|
446
|
+
type = command.command[0].parameter[1].type
|
|
447
|
+
if type == pb.AnyParameter.P_BOOL:
|
|
448
|
+
val = command.command[0].parameter[1].p_bool
|
|
449
|
+
elif type == pb.AnyParameter.P_INT:
|
|
450
|
+
val = command.command[0].parameter[1].p_int
|
|
451
|
+
elif type == pb.AnyParameter.P_FLOAT:
|
|
452
|
+
val = command.command[0].parameter[1].p_float
|
|
453
|
+
else: # type == pb.AnyParameter.P_STRING:
|
|
454
|
+
val = command.command[0].parameter[1].p_string
|
|
455
|
+
name = name.replace(" ", "_").lower().replace("(", "").replace(")", "")
|
|
456
|
+
self._values[name].value = val
|
|
457
|
+
return (acknowledge_return,)
|
|
458
|
+
|
|
459
|
+
def _fake_get_property(self, command):
|
|
460
|
+
acknowledge_return = pb.DEPacket()
|
|
461
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
462
|
+
ack1 = acknowledge_return.acknowledge.add() # add the first acknowledge
|
|
463
|
+
ack1.command_id = command.command[0].command_id
|
|
464
|
+
name = command.command[0].parameter[0].p_string
|
|
465
|
+
name = name.replace(" ", "_").lower().replace("(", "").replace(")", "")
|
|
466
|
+
val = self._values[name]
|
|
467
|
+
|
|
468
|
+
if val.data_type == "String":
|
|
469
|
+
val = val.value
|
|
470
|
+
elif val.data_type == "Integer":
|
|
471
|
+
val = int(val.value)
|
|
472
|
+
elif val.data_type == "Float":
|
|
473
|
+
val = float(val.value)
|
|
474
|
+
elif val.data_type == "Boolean":
|
|
475
|
+
val = bool(val.value)
|
|
476
|
+
|
|
477
|
+
if isinstance(val, bool):
|
|
478
|
+
bool_param = acknowledge_return.acknowledge[0].parameter.add()
|
|
479
|
+
bool_param.type = pb.AnyParameter.P_BOOL
|
|
480
|
+
bool_param.p_bool = val
|
|
481
|
+
elif isinstance(val, int) or isinstance(val, np.int32):
|
|
482
|
+
int_param = acknowledge_return.acknowledge[0].parameter.add()
|
|
483
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
484
|
+
int_param.p_int = val
|
|
485
|
+
elif isinstance(val, float):
|
|
486
|
+
float_param = acknowledge_return.acknowledge[0].parameter.add()
|
|
487
|
+
float_param.type = pb.AnyParameter.P_FLOAT
|
|
488
|
+
float_param.p_float = val
|
|
489
|
+
else:
|
|
490
|
+
string_param = acknowledge_return.acknowledge[0].parameter.add()
|
|
491
|
+
string_param.type = pb.AnyParameter.P_STRING
|
|
492
|
+
string_param.p_string = val
|
|
493
|
+
return (acknowledge_return,)
|
|
494
|
+
|
|
495
|
+
def _fake_get_movie_buffer_info(self, command):
|
|
496
|
+
print("Getting movie buffer info")
|
|
497
|
+
acknowledge_return = pb.DEPacket()
|
|
498
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
499
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
500
|
+
|
|
501
|
+
ack1.command_id = command.command[0].command_id
|
|
502
|
+
int_param = ack1.parameter.add()
|
|
503
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
504
|
+
int_param.p_int = 1024 # Header bytes
|
|
505
|
+
int_param = ack1.parameter.add()
|
|
506
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
507
|
+
int_param.p_int = (
|
|
508
|
+
int(self["Image Size Y (pixels)"])
|
|
509
|
+
* int(self["Image Size X (pixels)"])
|
|
510
|
+
* int(self["Grabbing - Frames Per Buffer"])
|
|
511
|
+
* 2
|
|
512
|
+
) # Image buffer bytes
|
|
513
|
+
int_param = ack1.parameter.add()
|
|
514
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
515
|
+
int_param.p_int = 0 # Frame index start pos
|
|
516
|
+
int_param = ack1.parameter.add()
|
|
517
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
518
|
+
int_param.p_int = int(self["Image Size X (pixels)"]) # image width
|
|
519
|
+
int_param = ack1.parameter.add()
|
|
520
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
521
|
+
int_param.p_int = 1024 # image start
|
|
522
|
+
int_param = ack1.parameter.add()
|
|
523
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
524
|
+
int_param.p_int = int(self["Image Size Y (pixels)"]) # image height
|
|
525
|
+
int_param = ack1.parameter.add()
|
|
526
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
527
|
+
int_param.p_int = int(self["Grabbing - Frames Per Buffer"]) # frames in buffer
|
|
528
|
+
int_param = ack1.parameter.add()
|
|
529
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
530
|
+
int_param.p_int = 5 # data type (only int16 supported)
|
|
531
|
+
|
|
532
|
+
return (acknowledge_return,)
|
|
533
|
+
|
|
534
|
+
def _fake_get_result(self, command):
|
|
535
|
+
acknowledge_return = pb.DEPacket()
|
|
536
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
537
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
538
|
+
ack1.command_id = command.command[0].command_id
|
|
539
|
+
|
|
540
|
+
frame_type = command.command[0].parameter[0].p_int
|
|
541
|
+
pixel_format = command.command[0].parameter[1].p_int
|
|
542
|
+
center_x = command.command[0].parameter[2].p_int
|
|
543
|
+
center_y = command.command[0].parameter[3].p_int
|
|
544
|
+
zoom = command.command[0].parameter[4].p_float
|
|
545
|
+
windowWidth = command.command[0].parameter[5].p_int
|
|
546
|
+
windowHeight = command.command[0].parameter[6].p_int
|
|
547
|
+
fft = command.command[0].parameter[7].p_int
|
|
548
|
+
stretchType = command.command[0].parameter[8].p_int
|
|
549
|
+
stretch_min = command.command[0].parameter[9].p_float
|
|
550
|
+
stretch_max = command.command[0].parameter[10].p_float
|
|
551
|
+
stretch_gama = command.command[0].parameter[11].p_float
|
|
552
|
+
outlier = command.command[0].parameter[12].p_float
|
|
553
|
+
histo_min = command.command[0].parameter[13].p_float
|
|
554
|
+
histo_max = command.command[0].parameter[14].p_float
|
|
555
|
+
histo_bins = command.command[0].parameter[15].p_int
|
|
556
|
+
|
|
557
|
+
pixel_format_dict = {1: np.int8, 5: np.int16, 13: np.float32}
|
|
558
|
+
|
|
559
|
+
if self.fake_data is None:
|
|
560
|
+
self._initialize_data(
|
|
561
|
+
scan_size_x=1,
|
|
562
|
+
scan_size_y=1,
|
|
563
|
+
kx_pixels=int(self["Sensor Size X (pixels)"]),
|
|
564
|
+
ky_pixels=int(self["Sensor Size X (pixels)"]),
|
|
565
|
+
)
|
|
566
|
+
curr = self.current_navigation_index
|
|
567
|
+
flat_index = int(np.ravel_multi_index(curr, self.fake_data.navigator.shape))
|
|
568
|
+
|
|
569
|
+
# map to right order...
|
|
570
|
+
response_mapping = [
|
|
571
|
+
pixel_format,
|
|
572
|
+
windowWidth,
|
|
573
|
+
windowHeight,
|
|
574
|
+
"Test",
|
|
575
|
+
0,
|
|
576
|
+
self.acquisition_status == "Acquiring",
|
|
577
|
+
flat_index,
|
|
578
|
+
1,
|
|
579
|
+
0,
|
|
580
|
+
2**16,
|
|
581
|
+
100,
|
|
582
|
+
10,
|
|
583
|
+
0,
|
|
584
|
+
0,
|
|
585
|
+
0,
|
|
586
|
+
0,
|
|
587
|
+
0,
|
|
588
|
+
0,
|
|
589
|
+
0,
|
|
590
|
+
0,
|
|
591
|
+
0,
|
|
592
|
+
0,
|
|
593
|
+
1,
|
|
594
|
+
time.time(),
|
|
595
|
+
0,
|
|
596
|
+
0,
|
|
597
|
+
0,
|
|
598
|
+
]
|
|
599
|
+
for val in response_mapping:
|
|
600
|
+
ack1 = add_parameter(ack1, val)
|
|
601
|
+
ans = (acknowledge_return,)
|
|
602
|
+
# add the data header packet for how many bytes are in the data
|
|
603
|
+
pack = pb.DEPacket()
|
|
604
|
+
pack.type = pb.DEPacket.P_DATA_HEADER
|
|
605
|
+
|
|
606
|
+
if 2 < frame_type < 8:
|
|
607
|
+
image = self.fake_data[self.current_navigation_index].astype(
|
|
608
|
+
pixel_format_dict[pixel_format]
|
|
609
|
+
)
|
|
610
|
+
result = image.tobytes()
|
|
611
|
+
elif frame_type == 10:
|
|
612
|
+
image = np.sum(self.fake_data.signal, axis=1).astype(
|
|
613
|
+
pixel_format_dict[pixel_format]
|
|
614
|
+
)
|
|
615
|
+
result = image.tobytes()
|
|
616
|
+
elif 11 < frame_type < 17: # virtual image
|
|
617
|
+
mask = self.virtual_masks[frame_type - 12]
|
|
618
|
+
if mask.shape != (windowWidth, windowHeight):
|
|
619
|
+
mask = resize(
|
|
620
|
+
mask, (windowWidth, windowHeight), preserve_range=True
|
|
621
|
+
).astype(np.int8)
|
|
622
|
+
result = mask.tobytes()
|
|
623
|
+
elif 17 <= frame_type < 22:
|
|
624
|
+
mask = self.virtual_masks[frame_type - 17]
|
|
625
|
+
calculation_type = self[
|
|
626
|
+
f"Scan - Virtual Detector {frame_type-17} Calculation"
|
|
627
|
+
]
|
|
628
|
+
result = self.fake_data.get_virtual_image(mask, method=calculation_type)
|
|
629
|
+
result = result.astype(pixel_format_dict[pixel_format]).tobytes()
|
|
630
|
+
|
|
631
|
+
else:
|
|
632
|
+
raise ValueError(f"Frame type {frame_type} not Supported in PythonDEServer")
|
|
633
|
+
pack.data_header.bytesize = len(result)
|
|
634
|
+
ans += (pack,)
|
|
635
|
+
ans += (result,)
|
|
636
|
+
|
|
637
|
+
return ans
|
|
638
|
+
|
|
639
|
+
def _fake_get_movie_buffer(self, command):
|
|
640
|
+
sizey = int(self["Image Size Y (pixels)"])
|
|
641
|
+
sizex = int(self["Image Size X (pixels)"])
|
|
642
|
+
frames_per_buffer = int(self["Grabbing - Frames Per Buffer"])
|
|
643
|
+
|
|
644
|
+
acknowledge_return = pb.DEPacket()
|
|
645
|
+
acknowledge_return.type = pb.DEPacket.P_ACKNOWLEDGE
|
|
646
|
+
ack1 = acknowledge_return.acknowledge.add()
|
|
647
|
+
ack1.command_id = command.command[0].command_id
|
|
648
|
+
int_param = ack1.parameter.add()
|
|
649
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
650
|
+
|
|
651
|
+
if np.prod(self.fake_data.navigator.shape) > self.current_movie_index:
|
|
652
|
+
frame_numbers = np.arange(
|
|
653
|
+
self.current_movie_index,
|
|
654
|
+
self.current_movie_index + frames_per_buffer,
|
|
655
|
+
dtype=np.int64,
|
|
656
|
+
)
|
|
657
|
+
print(f"Getting movie buffer {frame_numbers}")
|
|
658
|
+
data = self.fake_data.flat[
|
|
659
|
+
self.current_movie_index : self.current_movie_index + frames_per_buffer
|
|
660
|
+
]
|
|
661
|
+
print(f"Data shape {data.shape}")
|
|
662
|
+
self.current_movie_index = self.current_movie_index + frames_per_buffer
|
|
663
|
+
if len(frame_numbers) < 128:
|
|
664
|
+
frame_numbers = np.pad(
|
|
665
|
+
frame_numbers,
|
|
666
|
+
(0, 128 - len(frame_numbers)),
|
|
667
|
+
mode="constant",
|
|
668
|
+
constant_values=0,
|
|
669
|
+
)
|
|
670
|
+
|
|
671
|
+
int_param.p_int = 5 # okay
|
|
672
|
+
int_param = ack1.parameter.add()
|
|
673
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
674
|
+
int_param.p_int = np.prod(data.shape) * 2 + 1024 # Image total bytes
|
|
675
|
+
# Image total bytes
|
|
676
|
+
int_param = ack1.parameter.add()
|
|
677
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
678
|
+
int_param.p_int = data.shape[0] # Number of frames
|
|
679
|
+
|
|
680
|
+
ans = (acknowledge_return,)
|
|
681
|
+
ans += (frame_numbers.tobytes(), data.astype(np.int16).tobytes())
|
|
682
|
+
else:
|
|
683
|
+
int_param.p_int = 4 # finished
|
|
684
|
+
int_param = ack1.parameter.add()
|
|
685
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
686
|
+
int_param.p_int = 0 # Image total bytes
|
|
687
|
+
# Image total bytes
|
|
688
|
+
int_param = ack1.parameter.add()
|
|
689
|
+
int_param.type = pb.AnyParameter.P_INT
|
|
690
|
+
int_param.p_int = 0
|
|
691
|
+
ans = (acknowledge_return,)
|
|
692
|
+
|
|
693
|
+
return ans
|
|
694
|
+
|
|
695
|
+
# command lists
|
|
696
|
+
LIST_CAMERAS = 0
|
|
697
|
+
LIST_PROPERTIES = 1
|
|
698
|
+
LIST_ALLOWED_VALUES = 2
|
|
699
|
+
GET_PROPERTY = 3
|
|
700
|
+
SET_PROPERTY = 4
|
|
701
|
+
GET_IMAGE_16U = 5
|
|
702
|
+
GET_IMAGE_32F = 10
|
|
703
|
+
STOP_ACQUISITION = 11
|
|
704
|
+
GET_RESULT = 14
|
|
705
|
+
START_ACQUISITION = 15
|
|
706
|
+
SET_HW_ROI = 16
|
|
707
|
+
SET_SW_ROI = 17
|
|
708
|
+
GET_MOVIE_BUFFER_INFO = 18
|
|
709
|
+
GET_MOVIE_BUFFER = 19
|
|
710
|
+
SET_PROPERTY_AND_GET_CHANGED_PROPERTIES = 20
|
|
711
|
+
SET_HW_ROI_AND_GET_CHANGED_PROPERTIES = 21
|
|
712
|
+
SET_SW_ROI_AND_GET_CHANGED_PROPERTIES = 22
|
|
713
|
+
SET_VIRTUAL_MASK = 23
|
|
714
|
+
SAVE_FINAL_AFTER_ACQ = 24
|
|
715
|
+
SET_ENG_MODE = 25
|
|
716
|
+
SET_ENG_MODE_GET_CHANGED_PROPERTIES = 26
|
|
717
|
+
SET_SCAN_SIZE = 27
|
|
718
|
+
SET_SCAN_ROI = 28
|
|
719
|
+
SET_SCAN_SIZE_AND_GET_CHANGED_PROPERTIES = 29
|
|
720
|
+
SET_SCAN_ROI__AND_GET_CHANGED_PROPERTIES = 30
|
|
721
|
+
SET_CLIENT_READ_ONLY = 31
|