Files
caplot/sources.py

82 lines
2.1 KiB
Python

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.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()}
for pv in pv_dict.values():
pv.wait_for_connection()
self.pvs = SimpleNamespace(**pv_dict)
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)