From 7312cdc133657416e65ce58ecea6f73300aabdb3 Mon Sep 17 00:00:00 2001 From: Sven Augustin Date: Sat, 5 Jun 2021 11:51:43 +0200 Subject: [PATCH] split sources --- kabuki/sources/__init__.py | 81 ++-------------------------------- kabuki/sources/camera.py | 45 +++++++++++++++++++ kabuki/sources/pvcollection.py | 26 +++++++++++ kabuki/sources/source.py | 15 +++++++ 4 files changed, 89 insertions(+), 78 deletions(-) create mode 100644 kabuki/sources/camera.py create mode 100644 kabuki/sources/pvcollection.py create mode 100644 kabuki/sources/source.py diff --git a/kabuki/sources/__init__.py b/kabuki/sources/__init__.py index 6ae22b6..628bb00 100644 --- a/kabuki/sources/__init__.py +++ b/kabuki/sources/__init__.py @@ -1,80 +1,5 @@ -from functools import wraps -from types import SimpleNamespace -from epics import PV - - -class Source(PV): - """ - PV, but waits for connection on creation - """ - - def __init__(self, pvname, *args, **kwargs): - self.name = pvname - super().__init__(pvname, *args, **kwargs) - self.is_connected = self.wait_for_connection() - - - -class PVCollection: - """ - Creates all PVs, then waits for connection - Disconnects all PVs - """ - - def __init__(self, name, **kwargs): - self.name = name -# self.pvnames = SimpleNamespace(**kwargs) - self.pv_dict = pv_dict = {k: PV(v) for k, v in kwargs.items()} - self.pvs = SimpleNamespace(**pv_dict) - self.is_connected = all(pv.wait_for_connection() for pv in pv_dict.values()) - - def __str__(self): - return self.name - - def disconnect(self): - for pv in self.pv_dict.values(): #TODO is it better to use: pv_dict -> pvs.__dict__ - pv.disconnect() - - - -class Camera(PVCollection): - """ - Expects: pvname = "NAME:FPICTURE" - Also creates NAME:WIDTH and NAME:HEIGHT - """ - - #TODO: could also accept base as argument, and also append ":FPICTURE" - - def __init__(self, pvname): - assert pvname.endswith(":FPICTURE") - base = pvname.rsplit(":", 1)[0] - super().__init__( - base, - image = pvname, - width = base + ":WIDTH", - height = base + ":HEIGHT" - ) - self.pvs.image.auto_monitor = True - - def get(self): - data = self.pvs.image.get() - data.shape = self.get_shape() - return data - - def get_shape(self): - width = self.pvs.width.get() - height = self.pvs.height.get() - width = int(round(width)) - height = int(round(height)) - shape = (height, width) - return shape - - def add_callback(self, callback, **kwargs): - @wraps(callback) - def wrapper(*args, value=None, **kwargs): - value.shape = self.get_shape() - return callback(*args, value=value, **kwargs) - return self.pvs.image.add_callback(callback=wrapper, with_ctrlvars=False, **kwargs) - + +from .camera import Camera +from .source import Source diff --git a/kabuki/sources/camera.py b/kabuki/sources/camera.py new file mode 100644 index 0000000..963a599 --- /dev/null +++ b/kabuki/sources/camera.py @@ -0,0 +1,45 @@ +from functools import wraps +from .pvcollection import PVCollection + + +class Camera(PVCollection): + """ + Expects: pvname = "NAME:FPICTURE" + Also creates NAME:WIDTH and NAME:HEIGHT + """ + + #TODO: could also accept base as argument, and also append ":FPICTURE" + + def __init__(self, pvname): + assert pvname.endswith(":FPICTURE") + base = pvname.rsplit(":", 1)[0] + super().__init__( + base, + image = pvname, + width = base + ":WIDTH", + height = base + ":HEIGHT" + ) + self.pvs.image.auto_monitor = True + + def get(self): + data = self.pvs.image.get() + data.shape = self.get_shape() + return data + + def get_shape(self): + width = self.pvs.width.get() + height = self.pvs.height.get() + width = int(round(width)) + height = int(round(height)) + shape = (height, width) + return shape + + def add_callback(self, callback, **kwargs): + @wraps(callback) + def wrapper(*args, value=None, **kwargs): + value.shape = self.get_shape() + return callback(*args, value=value, **kwargs) + return self.pvs.image.add_callback(callback=wrapper, with_ctrlvars=False, **kwargs) + + + diff --git a/kabuki/sources/pvcollection.py b/kabuki/sources/pvcollection.py new file mode 100644 index 0000000..0a4acd8 --- /dev/null +++ b/kabuki/sources/pvcollection.py @@ -0,0 +1,26 @@ +from types import SimpleNamespace +from epics import PV + + +class PVCollection: + """ + Creates all PVs, then waits for connection + Disconnects all PVs + """ + + def __init__(self, name, **kwargs): + self.name = name +# self.pvnames = SimpleNamespace(**kwargs) + self.pv_dict = pv_dict = {k: PV(v) for k, v in kwargs.items()} + self.pvs = SimpleNamespace(**pv_dict) + self.is_connected = all(pv.wait_for_connection() for pv in pv_dict.values()) + + def __str__(self): + return self.name + + def disconnect(self): + for pv in self.pv_dict.values(): #TODO is it better to use: pv_dict -> pvs.__dict__ + pv.disconnect() + + + diff --git a/kabuki/sources/source.py b/kabuki/sources/source.py new file mode 100644 index 0000000..344c7bc --- /dev/null +++ b/kabuki/sources/source.py @@ -0,0 +1,15 @@ +from epics import PV + + +class Source(PV): + """ + PV, but waits for connection on creation + """ + + def __init__(self, pvname, *args, **kwargs): + self.name = pvname + super().__init__(pvname, *args, **kwargs) + self.is_connected = self.wait_for_connection() + + +