49 #include <structmember.h>
58 #include "../basecode/header.h"
59 #include "../basecode/Id.h"
60 #include "../basecode/ObjId.h"
61 #include "../utility/utility.h"
62 #include "../shell/Shell.h"
70 extern PyTypeObject
IdType;
93 if (!PyArg_ParseTuple(args,
"Os:moose_Field_init", &owner, &fieldName))
97 if (fieldName == NULL)
99 PyErr_SetString(PyExc_ValueError,
"fieldName cannot be NULL");
104 PyErr_SetString(PyExc_ValueError,
"owner cannot be NULL");
107 if (!PyObject_IsInstance(owner, (PyObject*)&
ObjIdType))
109 PyErr_SetString(PyExc_TypeError,
"Owner must be subtype of ObjId");
117 self->owner = ((
_ObjId*)owner);
118 Py_INCREF(self->owner);
119 self->name = strdup(fieldName);
136 Py_DECREF(self->owner);
137 Py_TYPE(
self)->tp_free((PyObject*)
self);
148 string fieldPath =
self->owner->oid_.path() +
"." +
self->name;
149 PyObject *
path = PyString_FromString(fieldPath.c_str());
150 long hash = PyObject_Hash(path);
162 ostringstream fieldPath;
163 fieldPath <<
self->owner->oid_.path() <<
"." <<
self->name;
164 return PyString_FromString(fieldPath.str().c_str());
168 "Base class for MOOSE fields.\n"
170 "Instances contain the field name and a pointer to the owner\n"
171 "object. Note on hash: the Field class is hashable but the hash is\n"
172 "constructed from the path of the container element and the field\n"
173 "name. Hence changing the name of the container element will cause the\n"
174 "hash to change. This is rather unusual in a moose script, but if you\n"
175 "are putting fields as dictionary keys, you should do that after names\n"
176 "of all elements have been finalized.\n"
180 PyVarObject_HEAD_INIT(NULL, 0)
197 PyObject_GenericSetAttr,
199 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
200 moose_Field_documentation,
230 self->name, key, value);
244 "LookupField is dictionary-like fields that map keys to values.\n"
245 "The keys need not be fixed, as in case of interpolation tables,\n"
246 "keys can be any number and the corresponding value is dynamically\n"
247 "computed by the method of interpolation.\n"
248 "Use moose.doc('classname.fieldname') to display builtin\n"
249 "documentation for `field` in class `classname`.\n"
254 PyVarObject_HEAD_INIT(NULL, 0)
271 PyObject_GenericSetAttr,
274 moose_LookupField_documentation,
300 PyObject * newargs = PyTuple_New(PyTuple_Size(args)+1);
301 PyObject *
name = PyString_FromString(((
_Field*)
self)->name);
307 if (PyTuple_SetItem(newargs, 0, name) != 0)
314 Py_ssize_t argc = PyTuple_Size(args);
315 for (Py_ssize_t ii = 0; ii < argc; ++ii)
317 PyObject * arg = PyTuple_GetItem(args, ii);
319 PyTuple_SetItem(newargs, ii+1, arg);
328 "DestField is a method field, i.e. it can be called like a function.\n"
329 "Use moose.doc('classname.fieldname') to display builtin\n"
330 "documentation for `field` in class `classname`.\n");
335 PyVarObject_HEAD_INIT(NULL, 0)
352 PyObject_GenericSetAttr,
355 moose_DestField_documentation,
377 "ElementField represents fields that are themselves elements. For\n"
378 "example, synapse in an IntFire neuron. Element fields can be traversed\n"
379 "like a sequence. Additionally, you can set the number of entries by\n"
380 "setting the `num` attribute to a desired value.\n");
383 "Number of entries in the field.");
386 "Path of the field element.");
389 "Name of the field element.");
392 "Reference to owner element of the field element.");
395 "Id of the field element.");
398 "dataIndex of the field element");
404 static char id[] =
"vec";
414 moose_ElementField_num_documentation,
421 moose_ElementField_path_documentation,
428 moose_ElementField_id_documentation,
435 moose_ElementField_name_documentation,
442 moose_ElementField_owner_documentation,
449 moose_ElementField_dataId_documentation,
475 PyVarObject_HEAD_INIT(NULL, 0)
476 "moose.ElementField",
495 moose_ElementField_documentation,
522 string path =
self->owner->oid_.path()+
"/";
523 path += string(self->name);
524 self->myoid =
ObjId(path);
530 if (self->owner->oid_.bad())
534 string name =
self->name;
535 name[0] = std::toupper( name[0] );
537 return Py_BuildValue(
"I", num);
542 if (self->owner->oid_.bad())
547 if (!PyInt_Check(args))
549 PyErr_SetString(PyExc_TypeError,
"moose.ElementField.setNum - needes an integer.");
552 num = PyInt_AsUnsignedLongMask(args);
555 PyErr_SetString(PyExc_RuntimeError,
"moose.ElementField.setNum : Field::set returned False.");
563 if (self->owner->oid_.bad())
568 return Py_ssize_t(num);
577 string path =
Id(self->owner->oid_.path() +
"/" + string(self->name)).
path();
578 return Py_BuildValue(
"s", path.c_str());
583 if (self->owner->oid_.bad())
587 Id myId(self->owner->oid_.path() +
"/" + string(self->name));
590 return (PyObject*)new_id;
595 return Py_BuildValue(
"s", self->name);
599 Py_INCREF(self->owner);
600 return (PyObject*)
self->owner;
604 if (self->owner->oid_.bad())
608 return Py_BuildValue(
"I", self->owner->oid_.dataIndex);
613 if (self->owner->oid_.bad())
621 PyErr_SetString(PyExc_IndexError,
"moose.ElementField.getItem: index out of bounds.");
630 PyErr_SetString(PyExc_IndexError,
"moose.ElementField.getItem: invalid index.");
640 ObjId oid(self->myoid.id, self->myoid.dataIndex, index);
649 if (self->owner->oid_.bad())
667 return PyTuple_New(0);
669 PyObject * ret = PyTuple_New((Py_ssize_t)(end - start));
670 for (
int ii = start; ii < end; ++ii)
672 ObjId oid(self->myoid.id, self->myoid.dataIndex, ii);
674 if (PyTuple_SetItem(ret, (Py_ssize_t)(ii-start), value))
678 PyErr_SetString(PyExc_RuntimeError,
"Could not assign tuple entry.");
688 PyObject * ret = NULL;
689 if (self->owner->oid_.bad())
693 char * field = PyString_AsString(attr);
699 map<string, string>::const_iterator it =
get_field_alias().find(
string(field));
702 field =
const_cast<char*
>((it->second).c_str());
706 attr = PyString_FromString(field);
711 ret = PyObject_GenericGetAttr((PyObject*)
self, attr);
723 vector < double > val;
730 vector < string > val;
751 vector < ObjId > val;
765 vector < unsigned int > val;
772 vector < unsigned long > val;
779 vector < float > val;
800 vector < short > val;
807 PyErr_SetString(PyExc_NotImplementedError,
"DataId handling not implemented yet.");
812 ret = PyObject_GenericGetAttr((PyObject*)
self, attr);
816 PyErr_SetString(PyExc_ValueError,
"unhandled field type.");
834 if (PyString_Check(attr))
836 field = string(PyString_AsString(attr));
840 PyErr_SetString(PyExc_TypeError,
"Attribute name must be a string");
845 if (fieldtype.length() == 0)
849 return PyObject_GenericSetAttr((PyObject*)
self, attr, value);
851 PyErr_SetString(PyExc_AttributeError,
"cannot add new field to ElementField objects");
857 if (!PySequence_Check(value))
861 else if (length != PySequence_Length(value))
863 PyErr_SetString(PyExc_IndexError,
"Length of the sequence on the right hand side does not match Id size.");
872 vector<double> _value;
875 for (
int ii = 0; ii < length; ++ii)
877 double v = PyFloat_AsDouble(PySequence_GetItem(value, ii));
883 double v = PyFloat_AsDouble(value);
884 _value.assign(length, v);
891 vector<string> _value;
894 for (
int ii = 0; ii < length; ++ii)
896 char * v = PyString_AsString(PySequence_GetItem(value, ii));
897 _value.push_back(
string(v));
902 char * v = PyString_AsString(value);
903 _value.assign(length,
string(v));
913 for (
int ii = 0; ii < length; ++ii)
915 int v = PyInt_AsLong(PySequence_GetItem(value, ii));
921 int v = PyInt_AsLong(value);
922 _value.assign(length, v);
929 vector<unsigned int> _value;
932 for (
int ii = 0; ii < length; ++ii)
934 unsigned int v = PyInt_AsUnsignedLongMask(PySequence_GetItem(value, ii));
940 unsigned int v = PyInt_AsUnsignedLongMask(value);
941 _value.assign(length, v);
951 for (
int ii = 0; ii < length; ++ii)
953 long v = PyInt_AsLong(PySequence_GetItem(value, ii));
959 long v = PyInt_AsLong(value);
960 _value.assign(length, v);
967 vector<unsigned long> _value;
970 for (
int ii = 0; ii < length; ++ii)
972 unsigned long v = PyInt_AsUnsignedLongMask(PySequence_GetItem(value, ii));
978 unsigned long v = PyInt_AsUnsignedLongMask(value);
979 _value.assign(length, v);
989 for (
int ii = 0; ii < length; ++ii)
991 PyObject * _v = PySequence_GetItem(value, ii);
992 bool v = (Py_True ==_v) || (PyInt_AsLong(_v) != 0);
998 bool v = (Py_True ==
value) || (PyInt_AsLong(value) != 0);
999 _value.assign(length, v);
1006 vector<char> _value;
1009 for (
int ii = 0; ii < length; ++ii)
1011 PyObject * _v = PySequence_GetItem(value, ii);
1012 char * v = PyString_AsString(_v);
1015 _value.push_back(v[0]);
1020 err << ii <<
"-th element is NUL";
1021 PyErr_SetString(PyExc_ValueError, err.str().c_str());
1028 char * v = PyString_AsString(value);
1031 _value.assign(length, v[0]);
1035 PyErr_SetString(PyExc_ValueError,
"value is an empty string");
1044 vector<short> _value;
1047 for (
int ii = 0; ii < length; ++ii)
1049 short v = PyInt_AsLong(PySequence_GetItem(value, ii));
1050 _value.push_back(v);
1055 short v = PyInt_AsLong(value);
1056 _value.assign(length, v);
1063 vector<float> _value;
1066 for (
int ii = 0; ii < length; ++ii)
1068 float v = PyFloat_AsDouble(PySequence_GetItem(value, ii));
1069 _value.push_back(v);
1074 float v = PyFloat_AsDouble(value);
1075 _value.assign(length, v);
1086 if (ret && (PyErr_Occurred() == NULL))
static PyTypeObject moose_Field
static PyGetSetDef ElementFieldGetSetters[]
static PySequenceMethods ElementFieldSequenceMethods
int moose_Field_init(_Field *self, PyObject *args, PyObject *kwargs)
PyObject * getLookupField(ObjId target, char *fieldName, PyObject *key)
PyObject * moose_DestField_call(PyObject *self, PyObject *args, PyObject *kw)
PyObject * moose_ObjId_setDestField(_ObjId *self, PyObject *args)
PyTypeObject moose_LookupField
PyTypeObject moose_DestField
Py_ssize_t moose_ElementField_getLen(_Field *self, void *closure)
const map< string, string > & get_field_alias()
int moose_ElementField_setattro(_Field *self, PyObject *attr, PyObject *value)
#define RAISE_INVALID_ID(ret, msg)
PyObject * moose_LookupField_getItem(_Field *self, PyObject *key)
long moose_Field_hash(_Field *self)
Return the hash of the string {objectpath}.{fieldName}
PyObject * moose_ElementField_getPath(_Field *self, void *closure)
void moose_Field_dealloc(_Field *self)
PyObject * moose_ElementField_getSlice(_Field *self, Py_ssize_t start, Py_ssize_t end)
PyObject * moose_ElementField_getDataId(_Field *self, void *closure)
PyDoc_STRVAR(moose_Field_documentation,"Base class for MOOSE fields.\n""\n""Instances contain the field name and a pointer to the owner\n""object. Note on hash: the Field class is hashable but the hash is\n""constructed from the path of the container element and the field\n""name. Hence changing the name of the container element will cause the\n""hash to change. This is rather unusual in a moose script, but if you\n""are putting fields as dictionary keys, you should do that after names\n""of all elements have been finalized.\n""\n")
int moose_ElementField_init(_Field *self, PyObject *args, PyObject *kwargs)
PyTypeObject moose_ElementField
PyObject * to_pytuple(void *obj, char typecode)
int setLookupField(ObjId target, char *fieldName, PyObject *key, PyObject *value)
PyObject * moose_ElementField_getNum(_Field *self, void *closure)
string getFieldType(string className, string fieldName)
static bool setVec(ObjId destId, const string &field, const vector< A > &arg)
static bool isValid(Id id)
PyObject * moose_ElementField_getOwner(_Field *self, void *closure)
PyObject * moose_ElementField_getattro(_Field *self, PyObject *attr)
int moose_LookupField_setItem(_Field *self, PyObject *key, PyObject *value)
PyObject * moose_ElementField_getName(_Field *self, void *closure)
int moose_ElementField_setNum(_Field *self, PyObject *args, void *closure)
static A get(const ObjId &dest, const string &field)
PyObject * moose_Field_repr(_Field *self)
String representation of fields is {objectpath}.{fieldName}
PyObject * moose_ElementField_getId(_Field *self, void *closure)
PyObject * moose_ElementField_getItem(_Field *self, Py_ssize_t index)
static void getVec(ObjId dest, const string &field, vector< A > &vec)
PyObject * oid_to_element(ObjId oid)
static PyMappingMethods LookupFieldMappingMethods