#
# Project name: MXCuBE
# https://github.com/mxcube
#
# This file is part of MXCuBE software.
#
# MXCuBE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# MXCuBE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.
"""
[Name]
TangoLimaVideoDevice
[Note]
This class was previously called QtTangoLimaVideo. It was changed to
TangoLimaVideoDevice as it can be used now in Qt4(Qt5) environment or
without it.
The property <useqt>False</useqt> in the xml configuration file will inhibit
the use of qt.
The Hardware Object will poll for images at regular interval
(set by property <interval>value-in-msecs</interval>
For every image received a signal "imageReceived" is emitted. The content of the
information emitted varies:
- When qt is used:
a "qimage" is delivered as parameter with the signal
- When qt is not used (for web applications):
three values are sent with the signal
val1: string with jpeg encoding of the image
val2: width (pixels) of the image
val3: height (pixels) of the image
(web, non-qt encoding, has been validated for Prosilica cameras
but in principle other cameras could also adopt the same mechanism)
[Description]
HwObj used to grab images via Tango Lima device server
If you want to access the Lima Library directly you may consider using
the LimaVideoDevice module instead
[Configuration]
Example Hardware Object XML file :
==================================
<object class="QtLimaVideo">
<type>basler</type>
<encoding>yuv422p</encoding>
<tangoname>bl13/eh/lima_oav</tangoname>
<gain>0.5</gain>
<exposure>0.01</exposure>
<mirror>(False, False)</mirror>
<interval>30</interval>
</object>
"""
import struct
import numpy as np
import PyTango
from mxcubecore.HardwareObjects.abstract.AbstractVideoDevice import AbstractVideoDevice
[docs]class TangoLimaVideoDevice(AbstractVideoDevice):
"""
Descript. :
"""
def __init__(self, name):
"""
Descript. :
"""
AbstractVideoDevice.__init__(self, name)
self.device = None
[docs] def init(self):
"""
Descript. :
"""
tangoname = self.get_property("tangoname")
endian = self.get_property("endian")
if endian in ["small", "Small", "Little", "little"]:
self.header_fmt = "<IHHqiiHHHH"
else:
self.header_fmt = ">IHHqiiHHHH"
self.header_size = struct.calcsize(self.header_fmt)
self.device = PyTango.DeviceProxy(tangoname)
self.device.ping()
AbstractVideoDevice.init(self)
[docs] def set_cam_encoding(self, cam_encoding):
if cam_encoding == "yuv422p":
self.device.video_mode = "YUV422"
elif cam_encoding == "y8":
self.device.video_mode = "Y8"
AbstractVideoDevice.set_cam_encoding(self, cam_encoding)
""" Overloading of AbstractVideoDevice methods """
[docs] def get_image_dimensions(self):
return [self.device.image_width, self.device.image_height]
[docs] def get_image(self):
"""
Reads image from `video_last_image` attribute of lima device proxy,
which is type of `bytes` and converts it into np.array of int.
Returns
raw_buffer : 1d np.array of np.uint16
Image
width : int
Image width
height : int
Image height
"""
img_data = self.device.video_last_image
if img_data[0] == "VIDEO_IMAGE":
_ = img_data[1][: self.header_size]
raw_buffer = np.fromstring(img_data[1][self.header_size :], np.uint16)
_, _, _, _, width, height, _, _, _, _ = struct.unpack(
self.header_fmt, img_data[1][: self.header_size]
)
return raw_buffer, width, height
else:
return None, 0, 0
[docs] def get_gain(self):
if self.get_cam_type() == "basler":
value = self.device.video_gain
return value
[docs] def set_gain(self, gain_value):
if self.get_cam_type() == "basler":
self.device.video_gain = gain_value
return
[docs] def get_exposure_time(self):
if self.get_cam_type() == "basler":
return self.device.video_exposure
[docs] def set_exposure_time(self, exposure_time_value):
if self.get_cam_type() == "basler":
self.device.video_exposure = exposure_time_value
[docs] def get_video_live(self):
return self.device.video_live
[docs] def set_video_live(self, flag):
self.device.video_live = flag
""" END Overloading of AbstractVideoDevice methods """
def test_hwo(hwo):
print("Image dimensions: ", hwo.get_image_dimensions())
print("Live Mode: ", hwo.get_video_live())