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.
Files changed (52) hide show
  1. deapi/__init__.py +33 -0
  2. deapi/buffer_protocols/__init__.py +29 -0
  3. deapi/buffer_protocols/pb_2_3_0.py +666 -0
  4. deapi/buffer_protocols/pb_3_11_4.py +741 -0
  5. deapi/buffer_protocols/pb_3_19_3.py +114 -0
  6. deapi/buffer_protocols/pb_3_23_3.py +41 -0
  7. deapi/buffer_protocols/pb_3_6_1.py +745 -0
  8. deapi/client.py +2159 -0
  9. deapi/conf.py +184 -0
  10. deapi/data_types.py +586 -0
  11. deapi/fake_data/__init__.py +7 -0
  12. deapi/fake_data/base_fake_data.py +113 -0
  13. deapi/fake_data/grains.py +87 -0
  14. deapi/index.rst +10 -0
  15. deapi/prop_dump.json +450 -0
  16. deapi/python_3_instruction.txt +31 -0
  17. deapi/release_notes.txt +34 -0
  18. deapi/simulated_server/__init__.py +0 -0
  19. deapi/simulated_server/fake_server.py +721 -0
  20. deapi/simulated_server/initialize_server.py +66 -0
  21. deapi/tests/__init__.py +0 -0
  22. deapi/tests/conftest.py +95 -0
  23. deapi/tests/original_tests/01_fps.py +102 -0
  24. deapi/tests/original_tests/02_hwRoisize.py +155 -0
  25. deapi/tests/original_tests/03_hwBinning.py +117 -0
  26. deapi/tests/original_tests/04_swBinning.py +141 -0
  27. deapi/tests/original_tests/05_swhwBinning.py +113 -0
  28. deapi/tests/original_tests/06_patternPixel.py +139 -0
  29. deapi/tests/original_tests/07_reference.py +92 -0
  30. deapi/tests/original_tests/08_virtmask.py +114 -0
  31. deapi/tests/original_tests/09_scanRoi.py +104 -0
  32. deapi/tests/original_tests/10_imageStatistics.py +247 -0
  33. deapi/tests/original_tests/__init__.py +0 -0
  34. deapi/tests/original_tests/func.py +76 -0
  35. deapi/tests/original_tests/propertyName.py +725 -0
  36. deapi/tests/original_tests/test_legacy.py +132 -0
  37. deapi/tests/speed_tests/__init__.py +0 -0
  38. deapi/tests/speed_tests/test_internal_file_saving.py +54 -0
  39. deapi/tests/speed_tests/test_movie_buffer_transfer.py +54 -0
  40. deapi/tests/test_client.py +270 -0
  41. deapi/tests/test_fake_server/__init__.py +0 -0
  42. deapi/tests/test_fake_server/test_server.py +35 -0
  43. deapi/tests/test_file_saving/__init__.py +0 -0
  44. deapi/tests/test_file_saving/test_file_loading_libertem.py +49 -0
  45. deapi/tests/test_file_saving/test_file_loading_rsciio.py +53 -0
  46. deapi/tests/test_file_saving/test_scan_pattern_saving.py +68 -0
  47. deapi/version.py +3 -0
  48. deapi-5.2.0.dist-info/METADATA +44 -0
  49. deapi-5.2.0.dist-info/RECORD +52 -0
  50. deapi-5.2.0.dist-info/WHEEL +5 -0
  51. deapi-5.2.0.dist-info/entry_points.txt +2 -0
  52. 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