general get/set of array field length

This commit is contained in:
Michael Davidsaver
2013-12-14 12:33:08 -05:00
parent 22f8ee62e3
commit de28a136af
3 changed files with 57 additions and 5 deletions

View File

@ -196,6 +196,32 @@ static PyObject *pyField_getarray(pyField *self)
#endif
}
static PyObject *pyField_setlen(pyField *self, PyObject *args)
{
rset *prset = dbGetRset(&self->addr);
Py_ssize_t len;
if(!PyArg_ParseTuple(args, "n", &len))
return NULL;
if(self->addr.special!=SPC_DBADDR ||
!prset ||
!prset->put_array_info)
{
PyErr_SetString(PyExc_TypeError, "Not an array field");
}
if(len<1 || len > self->addr.no_elements) {
PyErr_Format(PyExc_ValueError, "Requested length %ld out of range [1,%lu)",
(long)len, (unsigned long)self->addr.no_elements);
return NULL;
}
prset->put_array_info(&self->addr, len);
Py_RETURN_NONE;
}
static PyObject* pyField_getTime(pyField *self)
{
DBLINK *plink = self->addr.pfield;
@ -239,6 +265,11 @@ static PyObject* pyField_getAlarm(pyField *self)
return Py_BuildValue("ll", (long)sevr, (long)stat);
}
static PyObject *pyField_len(pyField *self)
{
return PyInt_FromLong(self->addr.no_elements);
}
static PyMethodDef pyField_methods[] = {
{"name", (PyCFunction)pyField_name, METH_NOARGS,
"Return Names (\"record\",\"field\")"},
@ -250,10 +281,14 @@ static PyMethodDef pyField_methods[] = {
"Sets field value from a scalar"},
{"getarray", (PyCFunction)pyField_getarray, METH_NOARGS,
"Return a numpy ndarray refering to this field for in-place operations."},
{"putarraylen", (PyCFunction)pyField_setlen, METH_VARARGS,
"Set array field length."},
{"getTime", (PyCFunction)pyField_getTime, METH_NOARGS,
"Return link target timestamp as a tuple (sec, nsec)."},
{"getAlarm", (PyCFunction)pyField_getAlarm, METH_NOARGS,
"Return link target alarm condtions as a tuple (severity, status)."},
{"__len__", (PyCFunction)pyField_len, METH_NOARGS,
"Maximum number of elements storable in this field"},
{NULL, NULL, 0, NULL}
};

View File

@ -168,10 +168,23 @@ class _Field(object):
lock is held (ie withing :meth:`process <DeviceSupport.process>`).
"""
def putarraylen(self, len):
"""Set the number of active elements in field's array.
Requires that the underlying field be an array.
Must be less than the maximum length of the field.
"""
def getAlarm(self):
"""Returns a tuple (severity, status) with the condtion of the linked field.
Only works for fields of type DBF_INLINK.
"""
def __len__(self):
"""Returns the maximum number of elements which may be stored in the field.
This is always 1 for scalar fields.
"""
_hooks = {}

View File

@ -1,3 +1,4 @@
from __future__ import print_function
import numpy as np
import scipy as sp
@ -5,10 +6,13 @@ from numpy.random import randint, uniform
class WfSup(object):
def __init__(self, rec, args):
self.arr = rec.field('VAL').getarray()
self.x = np.arange(rec.NELM)
self.fld = rec.field('VAL')
self.arr = self.fld.getarray()
assert(len(self.fld)==rec.NELM)
self.x = np.arange(len(self.fld))
self.phase = 0.0
print("start",self)
def detach(self, rec):
pass
@ -17,7 +21,7 @@ class WfSup(object):
pha = self.phase*np.pi/180.0
self.phase = np.fmod(self.phase+10.0, 360.0)
N=randint(1, rec.NELM)
N=randint(1, len(self.fld))
val=self.arr[:N]
x=self.x[:N]
@ -28,8 +32,8 @@ class WfSup(object):
np.sin(val, out=val)
val[:]*=uniform(0.5,2.0)
val[:]+=2
self.NORD = N
self.fld.putarraylen(N)
def build(rec, args):
return WfSup(rec, args)