mxcubecore 1.403.0__py3-none-any.whl → 1.404.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.

Potentially problematic release.


This version of mxcubecore might be problematic. Click here for more details.

@@ -1,507 +0,0 @@
1
- """
2
- Class for cameras connected by EPICS Area Detector
3
- """
4
-
5
- import logging
6
- import os
7
- from io import BytesIO
8
- from threading import Thread
9
-
10
- import gevent
11
- import numpy as np
12
- from PIL import Image
13
-
14
- from mxcubecore import BaseHardwareObjects
15
-
16
- CAMERA_DATA = "epicsCameraSample_data"
17
- CAMERA_BACK = "epicsCameraSample_back"
18
- CAMERA_EN_BACK = "epicsCameraSample_en_back"
19
- CAMERA_ACQ_START = "epicsCameraSample_acq_start"
20
- CAMERA_ACQ_STOP = "epicsCameraSample_acq_stop"
21
- CAMERA_GAIN = "epicsCameraSample_gain"
22
- CAMERA_GAIN_RBV = "epicsCameraSample_gain_rbv"
23
- CAMERA_AUTO_GAIN = "epicsCameraSample_auto_gain"
24
- CAMERA_AUTO_GAIN_RBV = "epicsCameraSample_auto_gain_rbv"
25
- CAMERA_FPS_RBV = "epicsCameraSample_frames_per_second_rbv"
26
- CAMERA_ACQ_TIME = "epicsCameraSample_acq_time"
27
- CAMERA_ACQ_TIME_RBV = "epicsCameraSample_acq_time_rbv"
28
- CAMERA_IMG_PIXEL_SIZE = "epicsCameraSample_img_pixel_size"
29
- CAMERA_IMG_WIDTH = "epicsCameraSample_img_width"
30
- CAMERA_IMG_HEIGHT = "epicsCameraSample_img_height"
31
-
32
-
33
- class LNLSCamera(BaseHardwareObjects.HardwareObject):
34
- def __init__(self, name):
35
- BaseHardwareObjects.Device.__init__(self, name)
36
- self.liveState = False
37
- self.refreshing = False
38
- self.imagegen = None
39
- self.refreshgen = None
40
- self.imgArray = None
41
- self.qImage = None
42
- self.qImageHalf = None
43
- self.delay = None
44
- self.array_size = None
45
- # Status (cam is getting images)
46
- # This flag makes errors to be printed only when needed in the log,
47
- # which prevents the log file to get gigantic.
48
- self._print_cam_sucess = True
49
- self._print_cam_error_null = True
50
- self._print_cam_error_size = True
51
- self._print_cam_error_format = True
52
-
53
- def _init(self):
54
- self.stream_hash = "#"
55
- self.setIsReady(True)
56
-
57
- def init(self):
58
- self.read_sizes()
59
- # Start camera image acquisition
60
- self.setLive(True)
61
- # Snapshot
62
- self.centring_status = {"valid": False}
63
- self.snapshots_procedure = None
64
-
65
- def read_sizes(self):
66
- self.pixel_size = self.read_pixel_size()
67
- self.width = self.read_width()
68
- self.height = self.read_height()
69
- self.array_size = self.read_array_size()
70
-
71
- def poll(self):
72
- self.log.debug("LNLS Camera image acquiring has started.")
73
- self.imageGenerator(self.delay)
74
-
75
- def imageGenerator(self, delay):
76
- while self.liveState:
77
- self.getCameraImage()
78
- gevent.sleep(delay)
79
- self.log.debug("LNLS Camera image acquiring has stopped.")
80
-
81
- def getCameraImage(self):
82
- # Get the image from uEye camera IOC
83
- self.imgArray = self.get_channel_value(CAMERA_DATA)
84
- if self.imgArray is None:
85
- if self._print_cam_error_null:
86
- self.log.error(
87
- "%s - Error: null camera image!" % (self.__class__.__name__)
88
- )
89
- self._print_cam_sucess = True
90
- self._print_cam_error_null = False
91
- self._print_cam_error_size = True
92
- self._print_cam_error_format = True
93
- # Return error for this frame, but cam remains live for new frames
94
- return -1
95
-
96
- if len(self.imgArray) != self.array_size:
97
- # PS: This check possibly can be removed and the treatment can be
98
- # moved into the except scope.
99
- if self._print_cam_error_size:
100
- self.log.error(
101
- "%s - Error in array lenght! Expected %d, but got %d."
102
- % (self.__class__.__name__, self.array_size, len(self.imgArray))
103
- )
104
- self._print_cam_sucess = True
105
- self._print_cam_error_null = True
106
- self._print_cam_error_size = False
107
- self._print_cam_error_format = True
108
- # Try to read sizes again
109
- self.read_sizes()
110
- # Return error for this frame, but cam remains live for new frames
111
- return -1
112
-
113
- if self.refreshing:
114
- logging.getLogger("user_level_log").info("Camera was refreshed!")
115
- self.refreshing = False
116
-
117
- try:
118
- # Get data
119
- data = self.imgArray
120
- arr = np.array(data).reshape(self.height, self.width, self.pixel_size)
121
- # Convert data to rgb image
122
- img = Image.fromarray(arr)
123
- # img_rot = img.rotate(angle=0, expand=True)
124
- img_rgb = img.convert("RGB")
125
- # Get binary image
126
- with BytesIO() as f:
127
- img_rgb.save(f, format="JPEG")
128
- f.seek(0)
129
- img_bin_str = f.getvalue()
130
- # Sent image to gui
131
- self.emit("imageReceived", img_bin_str, self.height, self.width)
132
- # self.log.debug('Got camera image: ' + \
133
- # str(img_bin_str[0:10]))
134
- if self._print_cam_sucess:
135
- self.log.info("LNLSCamera is emitting images! Cam routine is ok.")
136
- self._print_cam_sucess = False
137
- self._print_cam_error_null = True
138
- self._print_cam_error_size = True
139
- self._print_cam_error_format = True
140
- return 0
141
- except:
142
- if self._print_cam_error_format:
143
- self.log.error("Error while formatting camera image")
144
- self._print_cam_sucess = True
145
- self._print_cam_error_null = True
146
- self._print_cam_error_size = True
147
- self._print_cam_error_format = False
148
- return -1
149
-
150
- def read_pixel_size(self):
151
- pixel_size = 1
152
- try:
153
- pixel_size = self.get_channel_value(CAMERA_IMG_PIXEL_SIZE)
154
- if pixel_size is None or pixel_size <= 0:
155
- pixel_size = 1
156
- except:
157
- print("Error on getting camera pixel size.")
158
- finally:
159
- self.log.info("LNLSCamera pixel size is %d." % (pixel_size))
160
- return pixel_size
161
-
162
- def read_width(self):
163
- width = 0
164
- try:
165
- width = self.get_channel_value(CAMERA_IMG_WIDTH)
166
- if width is None:
167
- width = 0
168
- except:
169
- print("Error on getting camera width.")
170
- finally:
171
- self.log.info("LNLSCamera width is %d." % (width))
172
- return width
173
-
174
- def read_height(self):
175
- height = 0
176
- try:
177
- height = self.get_channel_value(CAMERA_IMG_HEIGHT)
178
- if height is None:
179
- height = 0
180
- except:
181
- print("Error on getting camera height.")
182
- finally:
183
- self.log.info("LNLSCamera height is %d." % (height))
184
- return height
185
-
186
- def read_array_size(self):
187
- array_size = -1
188
- try:
189
- pixel_size = self.read_pixel_size()
190
- width = self.read_width()
191
- height = self.read_height()
192
- array_size = pixel_size * width * height
193
- except:
194
- print("Error on getting camera array size.")
195
- return array_size
196
-
197
- def get_pixel_size(self):
198
- return self.pixel_size
199
-
200
- def get_width(self):
201
- return self.width
202
-
203
- def get_height(self):
204
- return self.height
205
-
206
- def get_array_size(self):
207
- return self.array_size
208
-
209
- def getStaticImage(self):
210
- pass
211
- # qtPixMap = QtGui.QPixmap(self.source, "1")
212
- # self.emit("imageReceived", qtPixMap)
213
-
214
- def get_image_dimensions(self):
215
- return self.get_array_size()
216
-
217
- def getWidth(self):
218
- # X
219
- return self.get_width()
220
-
221
- def getHeight(self):
222
- # Z
223
- return self.get_height()
224
-
225
- def contrastExists(self):
226
- return False
227
-
228
- def brightnessExists(self):
229
- return False
230
-
231
- def gainExists(self):
232
- return True
233
-
234
- def get_gain(self):
235
- gain = None
236
-
237
- try:
238
- gain = self.get_channel_value(CAMERA_GAIN_RBV)
239
- except:
240
- print("Error getting gain of camera...")
241
-
242
- return gain
243
-
244
- def set_gain(self, gain):
245
- try:
246
- self.setValue(CAMERA_GAIN, gain)
247
- except:
248
- print("Error setting gain of camera...")
249
-
250
- def get_gain_auto(self):
251
- auto = None
252
-
253
- try:
254
- auto = self.get_channel_value(CAMERA_AUTO_GAIN_RBV)
255
- except:
256
- print("Error getting auto-gain of camera...")
257
-
258
- return auto
259
-
260
- def set_gain_auto(self, auto):
261
- try:
262
- self.setValue(CAMERA_AUTO_GAIN, auto)
263
- except:
264
- print("Error setting auto-gain of camera...")
265
-
266
- def get_exposure_time(self):
267
- exp = None
268
-
269
- try:
270
- exp = self.get_channel_value(CAMERA_ACQ_TIME_RBV)
271
- except:
272
- print("Error getting exposure time of camera...")
273
-
274
- return exp
275
-
276
- def set_exposure_time(self, exp):
277
- try:
278
- self.setValue(CAMERA_ACQ_TIME, exp)
279
- except:
280
- print("Error setting exposure time of camera...")
281
-
282
- def start_camera(self):
283
- try:
284
- self.setValue(CAMERA_BACK, 1)
285
- self.setValue(CAMERA_EN_BACK, 1)
286
- self.setValue(CAMERA_ACQ_STOP, 0)
287
- self.setValue(CAMERA_ACQ_START, 1)
288
- except:
289
- pass
290
-
291
- def stop_camera(self):
292
- try:
293
- self.setValue(CAMERA_ACQ_START, 0)
294
- self.setValue(CAMERA_ACQ_STOP, 1)
295
- except:
296
- pass
297
-
298
- def refresh_camera_procedure(self):
299
- self.refreshing = True
300
-
301
- # Try to reconnect to PVs
302
- self.reconnect(CAMERA_DATA)
303
- self.reconnect(CAMERA_IMG_PIXEL_SIZE)
304
- self.reconnect(CAMERA_IMG_WIDTH)
305
- self.reconnect(CAMERA_IMG_HEIGHT)
306
- self.reconnect(CAMERA_BACK)
307
- self.reconnect(CAMERA_EN_BACK)
308
- self.reconnect(CAMERA_ACQ_START)
309
- self.reconnect(CAMERA_ACQ_STOP)
310
- self.reconnect(CAMERA_GAIN)
311
- self.reconnect(CAMERA_GAIN_RBV)
312
- self.reconnect(CAMERA_AUTO_GAIN)
313
- self.reconnect(CAMERA_AUTO_GAIN_RBV)
314
- self.reconnect(CAMERA_FPS_RBV)
315
- self.reconnect(CAMERA_ACQ_TIME)
316
- self.reconnect(CAMERA_ACQ_TIME_RBV)
317
-
318
- # Try to stop camera image acquisition
319
- self.setLive(False)
320
- # Wait a while
321
- gevent.sleep(0.2)
322
- # Set PVs to start
323
- self.start_camera()
324
- # (Re)start camera image acquisition
325
- self.setLive(True)
326
-
327
- def refresh_camera(self):
328
- logging.getLogger("user_level_log").error(
329
- "Resetting camera, please, wait a while..."
330
- )
331
- print("refresh_camera")
332
-
333
- # Start a new thread to don't freeze UI
334
- self.refreshgen = gevent.spawn(self.refresh_camera_procedure)
335
-
336
- def setLive(self, live):
337
- try:
338
- if live and self.liveState == live:
339
- return
340
-
341
- self.liveState = live
342
-
343
- if live:
344
- self.log.info("LNLSCamera is going to poll images")
345
- self.delay = float(int(self.getProperty("interval")) / 1000.0)
346
- thread = Thread(target=self.poll)
347
- thread.daemon = True
348
- thread.start()
349
- else:
350
- self.stop_camera()
351
-
352
- return True
353
- except:
354
- return False
355
-
356
- def takeSnapshot(self, *args):
357
- pass
358
- # imgFile = QtCore.QFile(args[0])
359
- # imgFile.open(QtCore.QIODevice.WriteOnly)
360
- # self.qtPixMap.save(imgFile,"PNG")
361
- # imgFile.close()
362
-
363
- def take_snapshots_procedure(
364
- self,
365
- image_count,
366
- snapshotFilePath,
367
- snapshotFilePrefix,
368
- logFilePath,
369
- runNumber,
370
- collectStart,
371
- collectEnd,
372
- motorHwobj,
373
- detectorHwobj,
374
- ):
375
- """
376
- Descript. : It takes snapshots of sample camera and camserver execution.
377
- """
378
- # Avoiding a processing of AbstractMultiCollect class for saving snapshots
379
- # centred_images = []
380
- centred_images = None
381
- positions = []
382
-
383
- try:
384
- # Calculate goniometer positions where to take snapshots
385
- if collectEnd is not None and collectStart is not None:
386
- interval = collectEnd - collectStart
387
- else:
388
- interval = 0
389
-
390
- # To increment in angle increment
391
- increment = (
392
- 0 if ((image_count - 1) == 0) else (interval / (image_count - 1))
393
- )
394
-
395
- for incrementPos in range(image_count):
396
- if collectStart is not None:
397
- positions.append(collectStart + (incrementPos * increment))
398
- else:
399
- positions.append(motorHwobj.getPosition())
400
-
401
- # Create folders if not found
402
- if not os.path.exists(snapshotFilePath):
403
- try:
404
- os.makedirs(snapshotFilePath, mode=0o700)
405
- except OSError as diag:
406
- logging.getLogger().error(
407
- "Snapshot: error trying to create the directory %s (%s)"
408
- % (snapshotFilePath, str(diag))
409
- )
410
-
411
- for index in range(image_count):
412
- while motorHwobj.getPosition() < positions[index]:
413
- gevent.sleep(0.02)
414
-
415
- self.log.info(
416
- "%s - taking snapshot #%d" % (self.__class__.__name__, index + 1)
417
- )
418
-
419
- # Save snapshot image file
420
- imageFileName = os.path.join(
421
- snapshotFilePath,
422
- snapshotFilePrefix
423
- + "_"
424
- + str(round(motorHwobj.getPosition(), 2))
425
- + "_"
426
- + motorHwobj.getEgu()
427
- + "_snapshot.png",
428
- )
429
-
430
- # imageInfo = self.takeSnapshot(imageFileName)
431
-
432
- # This way all shapes will be also saved...
433
- self.emit("saveSnapshot", imageFileName)
434
-
435
- # Send a command to detector hardware-object to take snapshot of camserver execution...
436
- if logFilePath and detectorHwobj:
437
- detectorHwobj.takeScreenshotOfXpraRunningProcess(
438
- image_path=logFilePath, run_number=runNumber
439
- )
440
-
441
- # centred_images.append((0, str(imageInfo)))
442
- # centred_images.reverse()
443
- except:
444
- self.log.exception(
445
- "%s - could not take crystal snapshots" % (self.__class__.__name__)
446
- )
447
-
448
- return centred_images
449
-
450
- def take_snapshots(
451
- self,
452
- image_count,
453
- snapshotFilePath,
454
- snapshotFilePrefix,
455
- logFilePath,
456
- runNumber,
457
- collectStart,
458
- collectEnd,
459
- motorHwobj,
460
- detectorHwobj,
461
- wait=False,
462
- ):
463
- """
464
- Descript. : It takes snapshots of sample camera and camserver execution.
465
- """
466
- if image_count > 0:
467
- self.snapshots_procedure = gevent.spawn(
468
- self.take_snapshots_procedure,
469
- image_count,
470
- snapshotFilePath,
471
- snapshotFilePrefix,
472
- logFilePath,
473
- runNumber,
474
- collectStart,
475
- collectEnd,
476
- motorHwobj,
477
- detectorHwobj,
478
- )
479
-
480
- self.centring_status["images"] = []
481
-
482
- self.snapshots_procedure.link(self.snapshots_done)
483
-
484
- if wait:
485
- self.centring_status["images"] = self.snapshots_procedure.get()
486
-
487
- def snapshots_done(self, snapshots_procedure):
488
- """
489
- Descript. :
490
- """
491
- try:
492
- self.centring_status["images"] = snapshots_procedure.get()
493
- except:
494
- self.log.exception(
495
- "%s - could not take crystal snapshots" % (self.__class__.__name__)
496
- )
497
-
498
- def cancel_snapshot(self):
499
- try:
500
- self.snapshots_procedure.kill()
501
- except:
502
- pass
503
-
504
- def __del__(self):
505
- logging.getLogger().exception("%s - __del__()!" % (self.__class__.__name__))
506
- self.stop_camera()
507
- self.setLive(False)