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 #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) static PyObject* pyField_getTime(pyField *self)
{ {
DBLINK *plink = self->addr.pfield; DBLINK *plink = self->addr.pfield;
@ -239,6 +265,11 @@ static PyObject* pyField_getAlarm(pyField *self)
return Py_BuildValue("ll", (long)sevr, (long)stat); 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[] = { static PyMethodDef pyField_methods[] = {
{"name", (PyCFunction)pyField_name, METH_NOARGS, {"name", (PyCFunction)pyField_name, METH_NOARGS,
"Return Names (\"record\",\"field\")"}, "Return Names (\"record\",\"field\")"},
@ -250,10 +281,14 @@ static PyMethodDef pyField_methods[] = {
"Sets field value from a scalar"}, "Sets field value from a scalar"},
{"getarray", (PyCFunction)pyField_getarray, METH_NOARGS, {"getarray", (PyCFunction)pyField_getarray, METH_NOARGS,
"Return a numpy ndarray refering to this field for in-place operations."}, "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, {"getTime", (PyCFunction)pyField_getTime, METH_NOARGS,
"Return link target timestamp as a tuple (sec, nsec)."}, "Return link target timestamp as a tuple (sec, nsec)."},
{"getAlarm", (PyCFunction)pyField_getAlarm, METH_NOARGS, {"getAlarm", (PyCFunction)pyField_getAlarm, METH_NOARGS,
"Return link target alarm condtions as a tuple (severity, status)."}, "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} {NULL, NULL, 0, NULL}
}; };

View File

@ -168,10 +168,23 @@ class _Field(object):
lock is held (ie withing :meth:`process <DeviceSupport.process>`). 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): def getAlarm(self):
"""Returns a tuple (severity, status) with the condtion of the linked field. """Returns a tuple (severity, status) with the condtion of the linked field.
Only works for fields of type DBF_INLINK. 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 = {} _hooks = {}

View File

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