diff --git a/eco/bernina/config.py b/eco/bernina/config.py index 492cbd1..6d96ea0 100755 --- a/eco/bernina/config.py +++ b/eco/bernina/config.py @@ -457,17 +457,15 @@ components = [ }, }, { - "args": ["SLAAR21-LCAM-C532"], - "name": "samplecam_inline", + "args": ["SARES20-CAMS142-M3"], + "name": "samplecam_sideview", "z_und": 142, - "desc": "Qioptic sample viewer in Bernina hutch", - "type": "eco.devices_general.cameras_swissfel:QioptiqMicroscope", - "kwargs": { - "pvname_zoom": "SARES20-MF1:MOT_16", - }, + "desc": "", + "type": "eco.devices_general.cameras_swissfel:CameraBasler", + "kwargs": {}, }, { - "args": ["SARES20-CAMS142-C1"], + "args": ["SARES20-CAMS142-M3"], "name": "samplecam_sideview", "z_und": 142, "desc": "", diff --git a/eco/devices_general/cameras_swissfel.py b/eco/devices_general/cameras_swissfel.py index 5b0fb91..1d2523d 100644 --- a/eco/devices_general/cameras_swissfel.py +++ b/eco/devices_general/cameras_swissfel.py @@ -1,13 +1,65 @@ +from cam_server import CamClient from ..aliases import Alias, append_object_to_object from .adjustable import PvRecord, PvEnum, AdjustableGetSet, AdjustableVirtual from ..elements import Assembly from .motors import MotorRecord +class CamserverConfig: + def __init__(self, camname, name=None): + self.name = name + self.camname = camname + self.cc = CamClient() + + def get_current_value(self): + return self.cc.get_camera_config(self.camname) + + def set_config_fields(self, fields): + """fields is a dictionary containing the keys and values that should be updated, e.g. fields={'group': ['Laser', 'Bernina']}""" + config = self.get_current_value() + config.update(fields) + self.cc.set_camera_config(self.camname,config) + + ### convenience functions ### + def set_alias(self, alias=None): + """creates an alias in the camera config on the server. If no alias is provided, it defaults to the camera name""" + if not alias: + alias = self.name + self.set_config_fields({'alias':[alias]}) + + def stop(self): + self.cc.stop_instance(self.camname) + + def set_cross(self,x,y, x_um_per_px = None, y_um_per_px=None): + """set x and y position of the refetence marker on a camera px/um calibration is conserved if no new value is given""" + calib = self.get_current_value()['camera_calibration'] + if calib: + if not x_um_per_px: + x_um_per_px = calib['reference_marker_width']/abs(calib['reference_marker'][2]-calib['reference_marker'][0]) + if not y_um_per_px: + y_um_per_px = calib['reference_marker_height']/abs(calib['reference_marker'][3]-calib['reference_marker'][1]) + else: + calib = {} + x_um_per_px = 1 + y_um_per_px = 1 + + calib['reference_marker']=[x-1,y-1,x+1,y+1] + calib['reference_marker_width']=2*x_um_per_px + calib['reference_marker_height']=2*y_um_per_px + self.set_config_fields(fields={'camera_calibration':calib}) + + def __repr__(self): + s = f"**Camera Server Config {self.camname} with Alias {self.name}**\n" + for key, item in self.get_current_value().items(): + s += f"{key:20} : {item}\n" + return s + class CameraBasler(Assembly): def __init__(self, pvname, name=None): super().__init__(name=name) self.pvname = pvname + self.config_cs = CamserverConfig(self.pvname, name=name) + self.config_cs.set_alias() self._append(PvEnum, self.pvname + ":INIT", name="initialize") self._append(PvEnum, self.pvname + ":CAMERA", name="running") self._append(PvRecord, self.pvname + ":BOARD", name="board_no") diff --git a/eco/devices_general/detectors.py b/eco/devices_general/detectors.py index dd30bb2..dd22a97 100755 --- a/eco/devices_general/detectors.py +++ b/eco/devices_general/detectors.py @@ -3,7 +3,7 @@ from epics import caget from epics import PV from ..eco_epics.utilities_epics import EnumWrapper -from cam_server import PipelineClient +from cam_server import PipelineClient, CamClient from cam_server.utils import get_host_port_from_stream_address from bsread import source, SUB import subprocess @@ -108,6 +108,8 @@ class PvDataStream: _cameraArrayTypes = ["monochrome", "rgb"] + + class CameraCA: def __init__(self, pvname, cameraArrayType="monochrome", elog=None): self.Id = pvname diff --git a/eco/xdiagnostics/profile_monitors.py b/eco/xdiagnostics/profile_monitors.py index c46db4d..b9ad328 100755 --- a/eco/xdiagnostics/profile_monitors.py +++ b/eco/xdiagnostics/profile_monitors.py @@ -1,5 +1,6 @@ from ..devices_general.motors import MotorRecord from ..devices_general.detectors import CameraCA, CameraBS +from ..devices_general.cameras_swissfel import CameraBasler from ..aliases import Alias, append_object_to_object from ..devices_general.adjustable import PvEnum @@ -13,12 +14,36 @@ def addMotorRecordToSelf(self, Id=None, name=None): self.alias.append(self.__dict__[name].alias) -class Pprm: +class Pprm(CameraBasler): + def __init__(self, pvname_camera, name=None): + super().__init__(pvname_camera, name=name) + self.target_pos = MotorRecord(pvname_camera + ":MOTOR_PROBE", name="target_pos") + self.camCA = CameraCA(pvname_camera) + self.led = PvEnum(self.pvname_camera + ":LED", name="led") + self.target = PvEnum(self.pvname_camera + ":PROBE_SP", name="target") + if name: + self.alias = Alias(name) + self.alias.append(self.target_pos.alias) + self.alias.append(self.target.alias) + self.alias.append(self.led.alias) + def movein(self, target=1): + self.target.set_target_value(target) + + def moveout(self, target=0): + self.target.set_target_value(target) + + def __repr__(self): + s = f"**Profile Monitor {self.name}**\n" + s += f"Target in beam: {self.target.get_current_value().name}\n" + return s + +class Pprmold: def __init__(self, Id, name=None): self.Id = Id self.name = name self.target_pos = MotorRecord(Id + ":MOTOR_PROBE", name="target_pos") - self.cam = CameraCA(Id) + self.camCA = CameraCA(Id) + #self.camCS = CameraCS(Id, name) self.led = PvEnum(self.Id + ":LED", name="led") self.target = PvEnum(self.Id + ":PROBE_SP", name="target") if name: