pyepics / pyepics

Python interface to Epics Channel Access
https://pyepics.github.io/pyepics/
Other
98 stars 58 forks source link

Question: how best to deal with waveform records? #5

Closed projectgus closed 11 years ago

projectgus commented 12 years ago

I've recently been implementing some controls to edit "banks" of values which are stored as arrays in waveform records.

I tried a few different approaches, including making a PV subclass that wrapped a single value from the array but otherwise behaved like a PV.

That mostly worked, but for now I've settled on subclassing the controls I need like this:

class PVItemTextCtrl(PVTextCtrl):
    """ A PVTextCtrl subclass that only sets one single item
    in an array-type waveform record.
    """
    def __init__(self, parent,  pv, index, **kws):
        self.index = index
        print pv
        PVTextCtrl.__init__(self, parent=parent, pv=pv, **kws)

    @DelayedEpicsCallback
    def OnEpicsConnect(self, pvname=None, conn=None, pv=None):
        PVTextCtrl.OnEpicsConnect(self,pvname,conn,pv)
        self._SetValue(None) # do an initial value callback, seems pyepics doesn't always send one

    def SetValue(self, value):
        "override all setvalue"
        full_value = self.pv.get(as_string=False, as_numpy=False) # as a list
        full_value[self.index] = value
        self.pv.put(full_value)

    def _SetValue(self, value):
        "set widget value"
        full_value = self.pv.get(as_string=False, as_numpy=False) # as a list
        PVTextCtrl._SetValue(self, full_value[self.index])

Does anyone else have any thoughts on how to proceed? Would a generic "PVArrayItem" class that behaves like a PV possibly be a better solution?

newville commented 12 years ago

I don't see anything wrong with this approach, but it seems a little strange to me. Is the idea that all of the values need to change in unison? I'm not sure I can say much about whether a PVArrayItem is needed. I guess that comes down to trying to determine how common is it to use elements of a waveform separately,

As an alternative, it might be interesting to consider using a subArray of length 1. That would create separate PVs on the IOC, and then you could use them as "regular PVs".

It might be worth posting this question to Tech Talk.

projectgus commented 11 years ago

Hi Matt,

Sorry for the late reply, have been sorting out cabling all week!

For these I'm really just using the waveform as a shorthand for having N discrete records. So, for instance we have a target loader where the users can enter 8 separate positions (in steps) and 8 separate labels for those positions.

I was storing them in EPICS as stringout records loader:label1 ... loader:label8 and ao records loader:position1 ... loader:position8.

But I'd much rather have one waveform (field type string) of loader:labels and one waveform (field type short) of loader:positions. Simplifies the databases, the archiving/restoring, and the Python code.

However the user interface is still just a panel with two columns of entry controls, one column for the labels and one for the positions. I want to assign each text control to a given entry in the waveform array.

Does that make sense? I can post some screenshots otherwise.

newville commented 11 years ago

Hi Angus,

Thanks, I think I understand it better now. That's a neat trick -- I might use it sometime ;). If you want to add a PVArrayItem to expose this, that would be very useful.