diff --git a/moose-core/.travis.yml b/moose-core/.travis.yml index 37f05c9b5ec0bf2bfc119cf87ce3ddb1ae682eaa..f43c248d974eb15afc2b79e98cff0c21fb8de908 100644 --- a/moose-core/.travis.yml +++ b/moose-core/.travis.yml @@ -28,5 +28,4 @@ script: - if type python3 > /dev/null; then python3 -m compileall -q . ; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/travis_build_osx.sh; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis/travis_build_linux.sh; fi - - cd ./.travis && ./download_and_run_doqcs.sh && cd .. - set +e diff --git a/moose-core/.travis/travis_build_linux.sh b/moose-core/.travis/travis_build_linux.sh index 29136cc98788adea6e82a46829409f7791fa5c95..141cad7b8bdad51e7ad58f3a8f55011f2d3ffec8 100755 --- a/moose-core/.travis/travis_build_linux.sh +++ b/moose-core/.travis/travis_build_linux.sh @@ -22,7 +22,7 @@ set -e PYTHON2="/usr/bin/python2" PYTHON3="/usr/bin/python3" -#MAKEFLAGS="-j4" +MAKEFLAGS="-j4" # Bug: `which python` returns /opt/bin/python* etc on travis. For which numpy # many not be available. Therefore, it is neccessary to use fixed path for @@ -39,9 +39,8 @@ PYTHON3="/usr/bin/python3" make && ctest --output-on-failure cd .. # Now with boost. mkdir -p _BOOST_BUILD && cd _BOOST_BUILD && \ - cmake -DWITH_BOOST=ON -DDEBUG=ON -DPYTHON_EXECUTABLE="$PYTHON2" .. + cmake -DWITH_BOOST=ON -DDEBUG=ON -DQUIET_MODE=ON -DPYTHON_EXECUTABLE="$PYTHON2" .. make && ctest --output-on-failure - sudo make install # For testing doqcs database. cd .. # This is only applicable on linux build. diff --git a/moose-core/.travis/travis_build_osx.sh b/moose-core/.travis/travis_build_osx.sh index 36de91422a2fb7a795a4467f31a8462f65021354..e710a00eb9f3955b3d9b61f792e8ebb59ff12edb 100755 --- a/moose-core/.travis/travis_build_osx.sh +++ b/moose-core/.travis/travis_build_osx.sh @@ -21,9 +21,8 @@ set -o nounset # Treat unset variables as an error set -e ( - mkdir -p _GSL_BUILD && cd _GSL_BUILD && cmake -DDEBUG=ON -DPYTHON_EXECUTABLE=`which python` .. + mkdir -p _GSL_BUILD && cd _GSL_BUILD && cmake -DQUIET_MODE=ON -DDEBUG=ON -DPYTHON_EXECUTABLE=`which python` .. make && ctest --output-on-failure - sudo make install cd .. # Now with boost. mkdir -p _BOOST_BUILD && cd _BOOST_BUILD && cmake -DWITH_BOOST=ON -DDEBUG=ON -DPYTHON_EXECUTABLE=`which python` .. make && ctest --output-on-failure diff --git a/moose-core/MooseTests.cmake b/moose-core/MooseTests.cmake index 820a1cccafbceb1a883e8e55600fdf26cf45e1f7..6026946ded7d8a9ff912baf6c56a7e43f8d46f28 100644 --- a/moose-core/MooseTests.cmake +++ b/moose-core/MooseTests.cmake @@ -134,6 +134,15 @@ set_tests_properties(pymoose-test-calcium-hsolve PROPERTIES ENVIRONMENT "PYTHONPATH=${PROJECT_BINARY_DIR}/python" ) +# Test accessing existing path without moose.element. +ADD_TEST( NAME pymoose-test-path + COMMAND ${TEST_COMMAND} + ${PROJECT_SOURCE_DIR}/tests/python/test_paths.py + ) +set_tests_properties(pymoose-test-path + PROPERTIES ENVIRONMENT "PYTHONPATH=${PROJECT_BINARY_DIR}/python" + ) + # # NOTE: These tests are not enabled yet. They take lot of time. Not all scripts # # are fixed yet. # # Test moose-examples with very short timeout. diff --git a/moose-core/pymoose/CMakeLists.txt b/moose-core/pymoose/CMakeLists.txt index 4ccdf49556df08c67344e7819aab6820b5653603..0468f1acf63df56d323e47e5a24577be6ec425c6 100644 --- a/moose-core/pymoose/CMakeLists.txt +++ b/moose-core/pymoose/CMakeLists.txt @@ -13,10 +13,12 @@ set(PYMOOSE_SRCS add_library( _moose MODULE ${PYMOOSE_SRCS} ) set(PYMOOSE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python/moose") -EXEC_PROGRAM(${PYTHON_EXECUTABLE} - ARGS "-c 'try: import importlib.machinery; print(importlib.machinery.EXTENSION_SUFFIXES[0]) -except Exception: pass'" + +execute_process( COMMAND ${PYTHON_EXECUTABLE} -c + "try: import importlib.machinery; print(importlib.machinery.EXTENSION_SUFFIXES[0]) +except Exception: pass" OUTPUT_VARIABLE PYTHON_SO_EXTENSION + OUTPUT_STRIP_TRAILING_WHITESPACE ) message( STATUS "Python so extension ${PYTHON_SO_EXTENSION}" ) @@ -80,11 +82,9 @@ ELSE(MACOSX) endif(MACOSX) # Make this target dependant on all python files in python folder. -add_custom_target(copy_python_files ALL +add_custom_target(copy_python_files COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/python ${CMAKE_BINARY_DIR}/python - COMMAND ${CMAKE_COMMAND} -E copy - ${CMAKE_SOURCE_DIR}/VERSION ${CMAKE_BINARY_DIR}/VERSION COMMENT "Copying required python files and other files to build directory" VERBATIM ) diff --git a/moose-core/pymoose/melement.cpp b/moose-core/pymoose/melement.cpp index fdceba80eb347dfcb87ce921311da7dd88fb909a..82856488d2fe318e52b0e0a19081d9db45be4a13 100644 --- a/moose-core/pymoose/melement.cpp +++ b/moose-core/pymoose/melement.cpp @@ -67,6 +67,7 @@ #include "../basecode/Id.h" #include "../basecode/ObjId.h" #include "../utility/utility.h" +#include "../utility/print_function.hpp" #include "../shell/Shell.h" #include "moosemodule.h" @@ -81,11 +82,16 @@ extern int PyType_IsSubtype(PyTypeObject *, PyTypeObject *); PyObject * get_ObjId_attr(_ObjId * oid, string attribute) { - if (attribute == "vec"){ + if (attribute == "vec") + { return moose_ObjId_getId(oid); - } else if (attribute == "dindex"){ + } + else if (attribute == "dindex") + { return moose_ObjId_getDataIndex(oid); - } else if (attribute == "findex"){ + } + else if (attribute == "findex") + { return moose_ObjId_getFieldIndex(oid); } return NULL; @@ -100,13 +106,16 @@ int moose_ObjId_init_from_id(_ObjId * self, PyObject * args, PyObject * kwargs) if (PyArg_ParseTupleAndKeywords(args, kwargs, "I|II:moose_ObjId_init_from_id", (char**)kwlist, - &id, &data, &field)){ + &id, &data, &field)) + { PyErr_Clear(); - if (!Id::isValid(id)){ + if (!Id::isValid(id)) + { RAISE_INVALID_ID(-1, "moose_ObjId_init_from_id"); } self->oid_ = ObjId(Id(id), data, field ); - if (self->oid_.bad()){ + if (self->oid_.bad()) + { PyErr_SetString(PyExc_ValueError, "Invalid ObjId"); return -1; } @@ -116,25 +125,33 @@ int moose_ObjId_init_from_id(_ObjId * self, PyObject * args, PyObject * kwargs) if (PyArg_ParseTupleAndKeywords(args, kwargs, "O|II:moose_ObjId_init_from_id", (char**)kwlist, - &obj, &data, &field)){ + &obj, &data, &field)) + { PyErr_Clear(); // If first argument is an Id object, construct an ObjId out of it - if (Id_Check(obj)){ - if (!Id::isValid(((_Id*)obj)->id_)){ + if (Id_Check(obj)) + { + if (!Id::isValid(((_Id*)obj)->id_)) + { RAISE_INVALID_ID(-1, "moose_ObjId_init_from_id"); } self->oid_ = ObjId(((_Id*)obj)->id_, data, field ); - if (self->oid_.bad()){ + if (self->oid_.bad()) + { PyErr_SetString(PyExc_ValueError, "Invalid dataIndex/fieldIndex."); return -1; } return 0; - } else if (PyObject_IsInstance(obj, (PyObject*)&ObjIdType)){ - if (!Id::isValid(((_ObjId*)obj)->oid_.id)){ + } + else if (PyObject_IsInstance(obj, (PyObject*)&ObjIdType)) + { + if (!Id::isValid(((_ObjId*)obj)->oid_.id)) + { RAISE_INVALID_ID(-1, "moose_ObjId_init_from_id"); } self->oid_ = ((_ObjId*)obj)->oid_; - if (self->oid_.bad()){ + if (self->oid_.bad()) + { PyErr_SetString(PyExc_ValueError, "Invalid ObjId"); return -1; } @@ -162,82 +179,112 @@ int moose_ObjId_init_from_path(_ObjId * self, PyObject * args, if (PyArg_ParseTupleAndKeywords(args, kwargs, "s|IIs:moose_ObjId_init_from_path", (char**)kwlist, - &parsedPath, &numData, &isGlobal, &type)){ + &parsedPath, &numData, &isGlobal, &type)) + { parse_success = true; } // we need to clear the parse error so that the callee can try // other alternative: moose_ObjId_init_from_id PyErr_Clear(); - if (!parse_success){ + if (!parse_success) + { return -2; } string path(parsedPath); + // Remove one or more instances of '/' by a single '/' e.g. //a -> /a, // /a//b -> /a/b etc. path = moose::fix(path); - ostringstream err; + ostringstream err, warn; + // First see if there is an existing object with at path self->oid_ = ObjId(path); PyTypeObject* basetype = getBaseClass((PyObject*)self); string basetype_str; - if (type == NULL){ - if (basetype == NULL){ - PyErr_SetString(PyExc_TypeError, "Unknown class. Need a valid MOOSE class or subclass thereof."); + if (type == NULL) + { + if (basetype == NULL) + { + PyErr_SetString(PyExc_TypeError + , "Unknown class. Need a valid MOOSE class or subclass thereof." + ); return -1; } basetype_str = string(basetype->tp_name).substr(6); // remove `moose.` prefix from type name - } else { + } + else + { basetype_str = string(type); } // If oid_ is bad, it can be either a nonexistent path or the root. - if (self->oid_.bad()){ + if (self->oid_.bad()) + { // is this the root element? - if ((path == "/") || (path == "/root")){ - if ((basetype == NULL) || PyType_IsSubtype(mytype, basetype)){ + if ((path == "/") || (path == "/root")) + { + if ((basetype == NULL) || PyType_IsSubtype(mytype, basetype)) + { return 0; } - err << "cannot convert " << Field<string>::get(self->oid_, "className") + err << "cannot convert moose." << Field<string>::get(self->oid_, "className") << " to " << mytypename << "To get the existing object use `moose.element(obj)` instead."; PyErr_SetString(PyExc_TypeError, err.str().c_str()); return -1; } // no - so we need to create a new element - } else { // this is a non-root existing element + } + else // this is a non-root existing element + { // If the current class is a subclass of some predefined // moose class, do nothing. string className = self->oid_.element()->cinfo()->name(); map <string, PyTypeObject * >::iterator ii = - get_moose_classes().find( className ); + get_moose_classes().find( className ); + PyTypeObject * basetype = 0; - if ( ii != get_moose_classes().end() ) { - basetype = ii->second; - basetype_str = string(basetype->tp_name).substr(6); // remove `moose.` prefix from type name - } else { + if ( ii != get_moose_classes().end() ) + { + basetype = ii->second; + // remove `moose.` prefix from type name + basetype_str = string(basetype->tp_name).substr(6); + } + else + { err << "Unknown class: " << className << endl; basetype = getBaseClass((PyObject*)self); } - if ((basetype != NULL) && PyType_IsSubtype(mytype, basetype)){ + + // NOTE: Existing paths are handled in Shell::doCreate function. + if ((basetype != NULL) && PyType_IsSubtype(mytype, basetype)) + { + // Fine. This path already exits. + err << "Accessing existing paths using object constrcutors has been deprecated. Use " + << " moose.element to access existing object. In future " + << " this will be an error." << endl; + PyErr_WarnEx(PyExc_DeprecationWarning, err.str().c_str(), 1); return 0; } + // element exists at this path, but it does not inherit from any moose class. // throw an error - err << "cannot convert " - << className - << " to " - << mytypename + err << "cannot convert moose." << className + << " to " << mytypename << ". To get the existing object use `moose.element(obj)` instead."; PyErr_SetString(PyExc_TypeError, err.str().c_str()); return -1; } + // try to create new vec Id new_id = create_Id_from_path(path, numData, isGlobal, basetype_str); + // vec failed. throw error - if (new_id == Id() && PyErr_Occurred()){ + if (new_id == Id() && PyErr_Occurred()) + { // Py_XDECREF(self); return -1; } @@ -249,7 +296,8 @@ int moose_ObjId_init_from_path(_ObjId * self, PyObject * args, int moose_ObjId_init(_ObjId * self, PyObject * args, PyObject * kwargs) { - if (self && !PyObject_IsInstance((PyObject*)self, (PyObject*)Py_TYPE((PyObject*)self))){ + if (self && !PyObject_IsInstance((PyObject*)self, (PyObject*)Py_TYPE((PyObject*)self))) + { ostringstream error; error << "Expected an melement or subclass. Found " << Py_TYPE(self)->tp_name; @@ -257,11 +305,13 @@ int moose_ObjId_init(_ObjId * self, PyObject * args, return -1; } int ret = moose_ObjId_init_from_path(self, args, kwargs); - if (ret >= -1){ + if (ret >= -1) + { return ret; } // parsing arguments as (path, dims, classname) failed. See if it is existing Id or ObjId. - if (moose_ObjId_init_from_id(self, args, kwargs) == 0){ + if (moose_ObjId_init_from_id(self, args, kwargs) == 0) + { return 0; } PyErr_SetString(PyExc_ValueError, @@ -282,7 +332,8 @@ int moose_ObjId_init(_ObjId * self, PyObject * args, */ long moose_ObjId_hash(_ObjId * self) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(-1, "moose_ObjId_hash"); } long long id = (long long)(self->oid_.id.value()); @@ -291,16 +342,20 @@ long moose_ObjId_hash(_ObjId * self) /* attempt to make it with 32 bit system - assuming id will * have its value within least significant 16 bits and * dataIndex and fieldIndex will be limited to first 8 bits */ - if (sizeof(size_t) == 8){ + if (sizeof(size_t) == 8) + { return id << 48 | dataIndex << 16 | fieldIndex; - } else { + } + else + { return id << 16 | dataIndex << 8 | fieldIndex; } } PyObject * moose_ObjId_repr(_ObjId * self) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_repr"); } ostringstream repr; @@ -313,7 +368,8 @@ PyObject * moose_ObjId_repr(_ObjId * self) PyObject * moose_ObjId_str(_ObjId * self) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_str"); } ostringstream repr; @@ -337,7 +393,8 @@ PyDoc_STRVAR(moose_ObjId_getId_documentation, "\n"); PyObject* moose_ObjId_getId(_ObjId * self) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getId"); } extern PyTypeObject IdType; @@ -362,16 +419,19 @@ PyDoc_STRVAR(moose_ObjId_getFieldType_documentation, PyObject * moose_ObjId_getFieldType(_ObjId * self, PyObject * args) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getFieldType"); } char * fieldName = NULL; - if (!PyArg_ParseTuple(args, "s:moose_ObjId_getFieldType", &fieldName)){ + if (!PyArg_ParseTuple(args, "s:moose_ObjId_getFieldType", &fieldName)) + { return NULL; } string typeStr = getFieldType(Field<string>::get(self->oid_, "className"), string(fieldName)); - if (typeStr.length() <= 0){ + if (typeStr.length() <= 0) + { PyErr_SetString(PyExc_ValueError, "Empty string for field type. " "Field name may be incorrect."); @@ -399,11 +459,13 @@ PyDoc_STRVAR(moose_ObjId_getField_documentation, " >>> 0.0 \n"); PyObject * moose_ObjId_getField(_ObjId * self, PyObject * args) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getField"); } PyObject * attr; - if (!PyArg_ParseTuple(args, "O:moose_ObjId_getField", &attr)){ + if (!PyArg_ParseTuple(args, "O:moose_ObjId_getField", &attr)) + { return NULL; } return moose_ObjId_getattro(self, attr); @@ -422,43 +484,54 @@ PyObject * moose_ObjId_getField(_ObjId * self, PyObject * args) PyObject * moose_ObjId_getattro(_ObjId * self, PyObject * attr) { int new_attr = 0; - if (self->oid_.bad()){ + if (self->oid_.bad()) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getattro"); } // extern PyTypeObject IdType; // extern PyTypeObject ObjIdType; const char * field; char ftype; - if (PyString_Check(attr)){ + if (PyString_Check(attr)) + { field = PyString_AsString(attr); - } else { + } + else + { return PyObject_GenericGetAttr((PyObject*)self, attr); } PyObject * _ret = get_ObjId_attr(self, field); - if (_ret != NULL){ + if (_ret != NULL) + { return _ret; } string fieldName(field); string className = Field<string>::get(self->oid_, "className"); vector<string> valueFinfos = getFieldNames(className, "valueFinfo"); bool isValueField = false; - for (unsigned int ii = 0; ii < valueFinfos.size(); ++ii){ - if (fieldName == valueFinfos[ii]){ + for (unsigned int ii = 0; ii < valueFinfos.size(); ++ii) + { + if (fieldName == valueFinfos[ii]) + { isValueField = true; break; } } string type = getFieldType(className, fieldName); - if (type.empty() || !isValueField ){ + if (type.empty() || !isValueField ) + { // Check if this field name is aliased and update fieldName and type if so. map<string, string>::const_iterator it = get_field_alias().find(fieldName); - if (it != get_field_alias().end()){ + if (it != get_field_alias().end()) + { fieldName = it->second; field = fieldName.c_str(); isValueField = false; - for (unsigned int ii = 0; ii < valueFinfos.size(); ++ii){ - if (fieldName == valueFinfos[ii]){ + for (unsigned int ii = 0; ii < valueFinfos.size(); ++ii) + { + if (fieldName == valueFinfos[ii]) + { isValueField = true; break; } @@ -470,186 +543,225 @@ PyObject * moose_ObjId_getattro(_ObjId * self, PyObject * attr) new_attr = 1; } } - if (type.empty() || !isValueField){ + if (type.empty() || !isValueField) + { _ret = PyObject_GenericGetAttr((PyObject*)self, attr); - if (new_attr){ + if (new_attr) + { Py_DECREF(attr); } return _ret; } ftype = shortType(type); - if (!ftype){ + if (!ftype) + { _ret = PyObject_GenericGetAttr((PyObject*)self, attr); - if (new_attr){ + if (new_attr) + { Py_DECREF(attr); } return _ret; } fieldName= string(field); - switch(ftype){ - case 's': { - string _s = Field<string>::get(self->oid_, fieldName); - _ret = Py_BuildValue("s", _s.c_str()); - break; - } - case 'd': { - double value = Field< double >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'i': { - int value = Field<int>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'I': { - unsigned int value = Field<unsigned int>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'l': { - long value = Field<long>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'L': { - long long value = Field<long long>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'k': { - unsigned long value = Field<unsigned long>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'K': { - unsigned long long value = Field<unsigned long long>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'f': { - float value = Field<float>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'x': { - Id value = Field<Id>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'y': { - ObjId value = Field<ObjId>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'z': { - PyErr_SetString(PyExc_NotImplementedError, "DataId handling not implemented yet."); - _ret = NULL; - break; - } - case 'D': { - vector< double > value = Field< vector < double > >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'X': { // vector<Id> - vector < Id > value = Field<vector <Id> >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'Y': { // vector<ObjId> - vector < ObjId > value = Field<vector <ObjId> >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'M': { - vector< long > value = Field< vector <long> >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'P': { - vector < unsigned long > value = Field< vector < unsigned long > >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'S': { - vector < string > value = Field<vector <string> >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'v': { - vector < int > value = Field<vector <int> >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'N': { - vector <unsigned int > value = Field< vector < unsigned int> >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'T': { // vector<vector < unsigned int >> - vector < vector < unsigned int > > value = Field<vector <vector < unsigned int > > >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'Q': { // vector< vector < int > > - vector < vector < int > > value = Field<vector < vector < int > > >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'R': { // vector< vector < double > > - vector < vector < double > > value = Field<vector < vector < double > > >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'F': { - vector <float> value = Field< vector < float > >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'c': { - char value = Field<char>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'h': { - short value = Field<short>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'H': { - unsigned short value = Field<unsigned short>::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'w': { - vector < short > value = Field<vector <short> >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } - case 'C': { - vector < char > value = Field<vector <char> >::get(self->oid_, fieldName); - _ret = to_py(&value, ftype); - break; - } + switch(ftype) + { + case 's': + { + string _s = Field<string>::get(self->oid_, fieldName); + _ret = Py_BuildValue("s", _s.c_str()); + break; + } + case 'd': + { + double value = Field< double >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'i': + { + int value = Field<int>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'I': + { + unsigned int value = Field<unsigned int>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'l': + { + long value = Field<long>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'L': + { + long long value = Field<long long>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'k': + { + unsigned long value = Field<unsigned long>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'K': + { + unsigned long long value = Field<unsigned long long>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'f': + { + float value = Field<float>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'x': + { + Id value = Field<Id>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'y': + { + ObjId value = Field<ObjId>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'z': + { + PyErr_SetString(PyExc_NotImplementedError, "DataId handling not implemented yet."); + _ret = NULL; + break; + } + case 'D': + { + vector< double > value = Field< vector < double > >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'X': // vector<Id> + { + vector < Id > value = Field<vector <Id> >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'Y': // vector<ObjId> + { + vector < ObjId > value = Field<vector <ObjId> >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'M': + { + vector< long > value = Field< vector <long> >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'P': + { + vector < unsigned long > value = Field< vector < unsigned long > >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'S': + { + vector < string > value = Field<vector <string> >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'v': + { + vector < int > value = Field<vector <int> >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'N': + { + vector <unsigned int > value = Field< vector < unsigned int> >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'T': // vector<vector < unsigned int >> + { + vector < vector < unsigned int > > value = Field<vector <vector < unsigned int > > >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'Q': // vector< vector < int > > + { + vector < vector < int > > value = Field<vector < vector < int > > >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'R': // vector< vector < double > > + { + vector < vector < double > > value = Field<vector < vector < double > > >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'F': + { + vector <float> value = Field< vector < float > >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'c': + { + char value = Field<char>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'h': + { + short value = Field<short>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'H': + { + unsigned short value = Field<unsigned short>::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'w': + { + vector < short > value = Field<vector <short> >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } + case 'C': + { + vector < char > value = Field<vector <char> >::get(self->oid_, fieldName); + _ret = to_py(&value, ftype); + break; + } - case 'b': { - bool value = Field<bool>::get(self->oid_, fieldName); - if (value){ - _ret = Py_True; - Py_INCREF(Py_True); - } else { - _ret = Py_False; - Py_INCREF(Py_False); - } - break; + case 'b': + { + bool value = Field<bool>::get(self->oid_, fieldName); + if (value) + { + _ret = Py_True; + Py_INCREF(Py_True); } + else + { + _ret = Py_False; + Py_INCREF(Py_False); + } + break; + } - default: - _ret = PyObject_GenericGetAttr((PyObject*)self, attr); + default: + _ret = PyObject_GenericGetAttr((PyObject*)self, attr); } - if (new_attr){ + if (new_attr) + { Py_DECREF(attr); } return _ret; @@ -680,10 +792,12 @@ PyObject * moose_ObjId_setField(_ObjId * self, PyObject * args) { PyObject * field; PyObject * value; - if (!PyArg_ParseTuple(args, "OO:moose_ObjId_setField", &field, &value)){ + if (!PyArg_ParseTuple(args, "OO:moose_ObjId_setField", &field, &value)) + { return NULL; } - if (moose_ObjId_setattro(self, field, value) == -1){ + if (moose_ObjId_setattro(self, field, value) == -1) + { return NULL; } Py_RETURN_NONE; @@ -694,25 +808,31 @@ PyObject * moose_ObjId_setField(_ObjId * self, PyObject * args) */ int moose_ObjId_setattro(_ObjId * self, PyObject * attr, PyObject * value) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(-1, "moose_ObjId_setattro"); } const char * field; - if (PyString_Check(attr)){ + if (PyString_Check(attr)) + { field = PyString_AsString(attr); - } else { + } + else + { PyErr_SetString(PyExc_TypeError, "Attribute name must be a string"); return -1; } string fieldtype = getFieldType(Field<string>::get(self->oid_, "className"), string(field)); - if (fieldtype.length() == 0){ + if (fieldtype.length() == 0) + { // If it is instance of a MOOSE built-in class then throw // error (to avoid silently creating new attributes due to // typos). Otherwise, it must have been subclassed in // Python. Then we allow normal Pythonic behaviour and // consider such mistakes user's responsibility. string className = ((PyTypeObject*)PyObject_Type((PyObject*)self))->tp_name; - if (get_moose_classes().find(className) == get_moose_classes().end()){ + if (get_moose_classes().find(className) == get_moose_classes().end()) + { return PyObject_GenericSetAttr((PyObject*)self, PyString_FromString(field), value); } ostringstream msg; @@ -722,282 +842,364 @@ int moose_ObjId_setattro(_ObjId * self, PyObject * attr, PyObject * value) } char ftype = shortType(fieldtype); int ret = 0; - switch(ftype){ - case 'd': { - double _value = PyFloat_AsDouble(value); - ret = Field<double>::set(self->oid_, string(field), _value); - break; + switch(ftype) + { + case 'd': + { + double _value = PyFloat_AsDouble(value); + ret = Field<double>::set(self->oid_, string(field), _value); + break; + } + case 'l': + { + long _value = PyInt_AsLong(value); + if ((_value != -1) || (!PyErr_Occurred())) + { + ret = Field<long>::set(self->oid_, string(field), _value); } - case 'l': { - long _value = PyInt_AsLong(value); - if ((_value != -1) || (!PyErr_Occurred())){ - ret = Field<long>::set(self->oid_, string(field), _value); - } - break; + break; + } + case 'I': + { + unsigned long _value = PyInt_AsUnsignedLongMask(value); + ret = Field<unsigned int>::set(self->oid_, string(field), (unsigned int)_value); + break; + } + case 'k': + { + unsigned long _value = PyInt_AsUnsignedLongMask(value); + ret = Field<unsigned long>::set(self->oid_, string(field), _value); + break; + } + case 'f': + { + float _value = PyFloat_AsDouble(value); + ret = Field<float>::set(self->oid_, string(field), _value); + break; + } + case 's': + { + char * _value = PyString_AsString(value); + if (_value) + { + ret = Field<string>::set(self->oid_, string(field), string(_value)); } - case 'I': { - unsigned long _value = PyInt_AsUnsignedLongMask(value); - ret = Field<unsigned int>::set(self->oid_, string(field), (unsigned int)_value); - break; + break; + } + case 'x': // Id + { + if (value) + { + ret = Field<Id>::set(self->oid_, string(field), ((_Id*)value)->id_); } - case 'k': { - unsigned long _value = PyInt_AsUnsignedLongMask(value); - ret = Field<unsigned long>::set(self->oid_, string(field), _value); - break; + else + { + PyErr_SetString(PyExc_ValueError, "Null pointer passed as vec Id value."); + return -1; } - case 'f': { - float _value = PyFloat_AsDouble(value); - ret = Field<float>::set(self->oid_, string(field), _value); - break; + break; + } + case 'y': // ObjId + { + if (value) + { + ret = Field<ObjId>::set(self->oid_, string(field), ((_ObjId*)value)->oid_); } - case 's': { - char * _value = PyString_AsString(value); - if (_value){ - ret = Field<string>::set(self->oid_, string(field), string(_value)); - } - break; + else + { + PyErr_SetString(PyExc_ValueError, "Null pointer passed as vec Id value."); + return -1; } - case 'x': {// Id - if (value){ - ret = Field<Id>::set(self->oid_, string(field), ((_Id*)value)->id_); - } else { - PyErr_SetString(PyExc_ValueError, "Null pointer passed as vec Id value."); - return -1; - } - break; + break; + } + case 'D': //SET_VECFIELD(double, d) + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<double> field, specified value must be a sequence." ); } - case 'y': {// ObjId - if (value){ - ret = Field<ObjId>::set(self->oid_, string(field), ((_ObjId*)value)->oid_); - } else { - PyErr_SetString(PyExc_ValueError, "Null pointer passed as vec Id value."); - return -1; + else + { + Py_ssize_t length = PySequence_Length(value); + vector<double> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + double v = PyFloat_AsDouble(vo); + Py_XDECREF(vo); + _value.push_back(v); } - break; + ret = Field< vector < double > >::set(self->oid_, string(field), _value); } - case 'D': {//SET_VECFIELD(double, d) - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<double> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<double> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - double v = PyFloat_AsDouble(vo); - Py_XDECREF(vo); - _value.push_back(v); - } - ret = Field< vector < double > >::set(self->oid_, string(field), _value); - } - break; + break; + } + case 'b': + { + bool _value = (Py_True == value) || (PyInt_AsLong(value) != 0); + ret = Field<bool>::set(self->oid_, string(field), _value); + break; + } + case 'c': + { + char * _value = PyString_AsString(value); + if (_value && _value[0]) + { + ret = Field<char>::set(self->oid_, string(field), _value[0]); } - case 'b': { - bool _value = (Py_True == value) || (PyInt_AsLong(value) != 0); - ret = Field<bool>::set(self->oid_, string(field), _value); - break; + break; + } + case 'i': + { + int _value = PyInt_AsLong(value); + if ((_value != -1) || (!PyErr_Occurred())) + { + ret = Field<int>::set(self->oid_, string(field), _value); } - case 'c': { - char * _value = PyString_AsString(value); - if (_value && _value[0]){ - ret = Field<char>::set(self->oid_, string(field), _value[0]); - } - break; + break; + } + case 'h': + { + short _value = (short)PyInt_AsLong(value); + if ((_value != -1) || (!PyErr_Occurred())) + { + ret = Field<short>::set(self->oid_, string(field), _value); } - case 'i': { - int _value = PyInt_AsLong(value); - if ((_value != -1) || (!PyErr_Occurred())){ - ret = Field<int>::set(self->oid_, string(field), _value); - } - break; + break; + } + case 'z': // DataId + { + PyErr_SetString(PyExc_NotImplementedError, "DataId handling not implemented yet."); + return -1; + } + case 'v': + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<int> field, specified value must be a sequence." ); + } + Py_ssize_t length = PySequence_Length(value); + vector<int> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + int v = PyInt_AsLong(vo); + Py_XDECREF(vo); + _value.push_back(v); + } + ret = Field< vector < int > >::set(self->oid_, string(field), _value); + break; + } + case 'w': + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<short> field, specified value must be a sequence." ); } - case 'h':{ - short _value = (short)PyInt_AsLong(value); - if ((_value != -1) || (!PyErr_Occurred())){ - ret = Field<short>::set(self->oid_, string(field), _value); + else + { + Py_ssize_t length = PySequence_Length(value); + vector<short> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + short v = PyInt_AsLong(vo); + Py_XDECREF(vo); + _value.push_back(v); } - break; + ret = Field< vector < short > >::set(self->oid_, string(field), _value); } - case 'z': {// DataId - PyErr_SetString(PyExc_NotImplementedError, "DataId handling not implemented yet."); - return -1; + break; + } + case 'L': //SET_VECFIELD(long, l) + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, + "For setting vector<long> field, specified value must be a sequence." ); } - case 'v': { - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<int> field, specified value must be a sequence." ); - } + else + { Py_ssize_t length = PySequence_Length(value); - vector<int> _value; - for ( int ii = 0; ii < length; ++ii){ + vector<long> _value; + for ( int ii = 0; ii < length; ++ii) + { PyObject * vo = PySequence_GetItem(value, ii); - int v = PyInt_AsLong(vo); + long v = PyInt_AsLong(vo); Py_XDECREF(vo); _value.push_back(v); } - ret = Field< vector < int > >::set(self->oid_, string(field), _value); - break; + ret = Field< vector < long > >::set(self->oid_, string(field), _value); } - case 'w': { - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<short> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<short> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - short v = PyInt_AsLong(vo); - Py_XDECREF(vo); - _value.push_back(v); - } - ret = Field< vector < short > >::set(self->oid_, string(field), _value); - } - break; + break; + } + case 'N': //SET_VECFIELD(unsigned int, I) + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<unsigned int> field, specified value must be a sequence." ); } - case 'L': {//SET_VECFIELD(long, l) - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, - "For setting vector<long> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<long> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - long v = PyInt_AsLong(vo); - Py_XDECREF(vo); - _value.push_back(v); - } - ret = Field< vector < long > >::set(self->oid_, string(field), _value); + else + { + Py_ssize_t length = PySequence_Length(value); + vector<unsigned int> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + unsigned int v = PyInt_AsUnsignedLongMask(vo); + Py_XDECREF(vo); + _value.push_back(v); } - break; + ret = Field< vector < unsigned int > >::set(self->oid_, string(field), _value); } - case 'N': {//SET_VECFIELD(unsigned int, I) - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<unsigned int> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<unsigned int> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - unsigned int v = PyInt_AsUnsignedLongMask(vo); - Py_XDECREF(vo); - _value.push_back(v); - } - ret = Field< vector < unsigned int > >::set(self->oid_, string(field), _value); - } - break; + break; + } + case 'K': //SET_VECFIELD(unsigned long, k) + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<unsigned long> field, specified value must be a sequence." ); } - case 'K': {//SET_VECFIELD(unsigned long, k) - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<unsigned long> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<unsigned long> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - unsigned long v = PyInt_AsUnsignedLongMask(vo); - Py_XDECREF(vo); - _value.push_back(v); - } - ret = Field< vector < unsigned long > >::set(self->oid_, string(field), _value); + else + { + Py_ssize_t length = PySequence_Length(value); + vector<unsigned long> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + unsigned long v = PyInt_AsUnsignedLongMask(vo); + Py_XDECREF(vo); + _value.push_back(v); } - break; + ret = Field< vector < unsigned long > >::set(self->oid_, string(field), _value); } - case 'F': {//SET_VECFIELD(float, f) - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<float> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<float> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - float v = PyFloat_AsDouble(vo); - Py_XDECREF(vo); - _value.push_back(v); - } - ret = Field< vector < float > >::set(self->oid_, string(field), _value); - } - break; + break; + } + case 'F': //SET_VECFIELD(float, f) + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<float> field, specified value must be a sequence." ); } - case 'S': { - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<string> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<string> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - char * v = PyString_AsString(vo); - Py_XDECREF(vo); - _value.push_back(string(v)); - } - ret = Field< vector < string > >::set(self->oid_, string(field), _value); + else + { + Py_ssize_t length = PySequence_Length(value); + vector<float> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + float v = PyFloat_AsDouble(vo); + Py_XDECREF(vo); + _value.push_back(v); } - break; + ret = Field< vector < float > >::set(self->oid_, string(field), _value); } - case 'T': {// vector< vector<unsigned int> > - vector < vector <unsigned> > * _value = (vector < vector <unsigned> > *)to_cpp(value, ftype); - if (!PyErr_Occurred()){ - ret = Field < vector < vector <unsigned> > >::set(self->oid_, string(field), *_value); - } - delete _value; - break; + break; + } + case 'S': + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<string> field, specified value must be a sequence." ); } - case 'Q': {// vector< vector<int> > - vector < vector <int> > * _value = (vector < vector <int> > *)to_cpp(value, ftype); - if (!PyErr_Occurred()){ - ret = Field < vector < vector <int> > >::set(self->oid_, string(field), *_value); + else + { + Py_ssize_t length = PySequence_Length(value); + vector<string> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + char * v = PyString_AsString(vo); + Py_XDECREF(vo); + _value.push_back(string(v)); } - delete _value; - break; + ret = Field< vector < string > >::set(self->oid_, string(field), _value); } - case 'R': {// vector< vector<double> > - vector < vector <double> > * _value = (vector < vector <double> > *)to_cpp(value, ftype); - if (!PyErr_Occurred()){ - ret = Field < vector < vector <double> > >::set(self->oid_, string(field), *_value); - } - delete _value; - break; + break; + } + case 'T': // vector< vector<unsigned int> > + { + vector < vector <unsigned> > * _value = (vector < vector <unsigned> > *)to_cpp(value, ftype); + if (!PyErr_Occurred()) + { + ret = Field < vector < vector <unsigned> > >::set(self->oid_, string(field), *_value); } - case 'X': {//SET_VECFIELD(Id, f) - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<Id> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<Id> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - Id v = ((_Id*)vo)->id_; - Py_XDECREF(vo); - _value.push_back(v); - } - ret = Field< vector < Id > >::set(self->oid_, string(field), _value); + delete _value; + break; + } + case 'Q': // vector< vector<int> > + { + vector < vector <int> > * _value = (vector < vector <int> > *)to_cpp(value, ftype); + if (!PyErr_Occurred()) + { + ret = Field < vector < vector <int> > >::set(self->oid_, string(field), *_value); + } + delete _value; + break; + } + case 'R': // vector< vector<double> > + { + vector < vector <double> > * _value = (vector < vector <double> > *)to_cpp(value, ftype); + if (!PyErr_Occurred()) + { + ret = Field < vector < vector <double> > >::set(self->oid_, string(field), *_value); + } + delete _value; + break; + } + case 'X': //SET_VECFIELD(Id, f) + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<Id> field, specified value must be a sequence." ); + } + else + { + Py_ssize_t length = PySequence_Length(value); + vector<Id> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + Id v = ((_Id*)vo)->id_; + Py_XDECREF(vo); + _value.push_back(v); } - break; + ret = Field< vector < Id > >::set(self->oid_, string(field), _value); } - case 'Y': {//SET_VECFIELD(ObjId, f) - if (!PySequence_Check(value)){ - PyErr_SetString(PyExc_TypeError, "For setting vector<ObjId> field, specified value must be a sequence." ); - } else { - Py_ssize_t length = PySequence_Length(value); - vector<ObjId> _value; - for ( int ii = 0; ii < length; ++ii){ - PyObject * vo = PySequence_GetItem(value, ii); - ObjId v = ((_ObjId*)vo)->oid_; - Py_XDECREF(vo); - _value.push_back(v); - } - ret = Field< vector < ObjId > >::set(self->oid_, string(field), _value); + break; + } + case 'Y': //SET_VECFIELD(ObjId, f) + { + if (!PySequence_Check(value)) + { + PyErr_SetString(PyExc_TypeError, "For setting vector<ObjId> field, specified value must be a sequence." ); + } + else + { + Py_ssize_t length = PySequence_Length(value); + vector<ObjId> _value; + for ( int ii = 0; ii < length; ++ii) + { + PyObject * vo = PySequence_GetItem(value, ii); + ObjId v = ((_ObjId*)vo)->oid_; + Py_XDECREF(vo); + _value.push_back(v); } - break; + ret = Field< vector < ObjId > >::set(self->oid_, string(field), _value); } - default: - break; + break; + } + default: + break; } // MOOSE Field::set returns 1 for success 0 for // failure. Python treats return value 0 from stters as // success, anything else failure. - if (ret){ + if (ret) + { return 0; - } else { + } + else + { ostringstream msg; msg << "Failed to set field '" << field << "'"; PyErr_SetString(PyExc_AttributeError,msg.str().c_str()); @@ -1007,10 +1209,12 @@ int moose_ObjId_setattro(_ObjId * self, PyObject * attr, PyObject * value) PyObject * moose_ObjId_getItem(_ObjId * self, Py_ssize_t index) { - if (index < 0){ + if (index < 0) + { index += moose_ObjId_getLength(self); } - if ((index < 0) || (index >= moose_ObjId_getLength(self))){ + if ((index < 0) || (index >= moose_ObjId_getLength(self))) + { PyErr_SetString(PyExc_IndexError, "Index out of bounds."); return NULL; } @@ -1036,13 +1240,16 @@ PyObject * moose_ObjId_getItem(_ObjId * self, Py_ssize_t index) PyObject * moose_ObjId_getSlice(_ObjId * self, Py_ssize_t start, Py_ssize_t end) { Py_ssize_t len = moose_ObjId_getLength(self); - while (start < 0){ + while (start < 0) + { start += len; } - while (end < 0){ + while (end < 0) + { end += len; } - if (start > end){ + if (start > end) + { // PyErr_SetString(PyExc_IndexError, "Start index must be less than end."); // python itself returns empty tuple - follow that return PyTuple_New(0); @@ -1050,10 +1257,12 @@ PyObject * moose_ObjId_getSlice(_ObjId * self, Py_ssize_t start, Py_ssize_t end) PyObject * ret = PyTuple_New((Py_ssize_t)(end - start)); // Py_XINCREF(ret); - for ( int ii = start; ii < end; ++ii){ + for ( int ii = start; ii < end; ++ii) + { _ObjId * value = PyObject_New(_ObjId, &ObjIdType); value->oid_ = ObjId(self->oid_.id, self->oid_.dataIndex, ii); - if (PyTuple_SetItem(ret, (Py_ssize_t)(ii-start), (PyObject*)value)){ // danger - must we DECREF all prior values? + if (PyTuple_SetItem(ret, (Py_ssize_t)(ii-start), (PyObject*)value)) // danger - must we DECREF all prior values? + { Py_XDECREF(ret); // Py_XDECREF(value); PyErr_SetString(PyExc_RuntimeError, "Failed to assign tuple entry."); @@ -1067,11 +1276,13 @@ PyObject * moose_ObjId_getSlice(_ObjId * self, Py_ssize_t start, Py_ssize_t end) Py_ssize_t moose_ObjId_getLength(_ObjId * self) { Element * el = self->oid_.element(); - if (!el->hasFields()){ + if (!el->hasFields()) + { return 0; } FieldElement * fe = reinterpret_cast< FieldElement* >(el); - if (fe == NULL){ + if (fe == NULL) + { return 0; } return (Py_ssize_t)(fe->numData()); @@ -1084,13 +1295,15 @@ Py_ssize_t moose_ObjId_getLength(_ObjId * self) PyObject * getLookupField(ObjId target, char * fieldName, PyObject * key) { vector<string> type_vec; - if (parseFinfoType(Field<string>::get(target, "className"), "lookupFinfo", string(fieldName), type_vec) < 0){ + if (parseFinfoType(Field<string>::get(target, "className"), "lookupFinfo", string(fieldName), type_vec) < 0) + { ostringstream error; error << "Cannot handle key type for LookupField `" << Field<string>::get(target, "className") << "." << fieldName << "`."; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; } - if (type_vec.size() != 2){ + if (type_vec.size() != 2) + { ostringstream error; error << "LookupField type signature should be <keytype>, <valuetype>. But for `" << Field<string>::get(target, "className") << "." << fieldName << "` got " << type_vec.size() << " components." ; @@ -1100,111 +1313,137 @@ PyObject * getLookupField(ObjId target, char * fieldName, PyObject * key) PyObject * ret = NULL; char key_type_code = shortType(type_vec[0]); char value_type_code = shortType(type_vec[1]); - switch(key_type_code){ - case 'b': { - ret = lookup_value <bool> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'c': { - ret = lookup_value <char> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'h': { - ret = lookup_value <short> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'H': { - ret = lookup_value <unsigned short> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'i': { - ret = lookup_value <int> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'I': { - ret = lookup_value <unsigned int> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'l': { - ret = lookup_value <long> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'k': { - ret = lookup_value <unsigned long> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'L': { - ret = lookup_value <long long> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'K': { - ret = lookup_value <unsigned long long> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'd': { - ret = lookup_value <double> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'f': { - ret = lookup_value <float> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 's': { - ret = lookup_value <string> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'x': { - ret = lookup_value <Id> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'y': { - ret = lookup_value <ObjId> (target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'D': { - ret = lookup_value < vector <double> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'S': { - ret = lookup_value < vector <string> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'X': { - ret = lookup_value < vector <Id> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'Y': { - ret = lookup_value < vector <ObjId> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'v': { - ret = lookup_value < vector <int> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'N': { - ret = lookup_value < vector <unsigned int> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'P': { - ret = lookup_value < vector <unsigned long> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'F': { - ret = lookup_value < vector <float> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'w': { - ret = lookup_value < vector <short> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - case 'C': { - ret = lookup_value < vector <char> >(target, string(fieldName), value_type_code, key_type_code, key); - break; - } - default: - ostringstream error; - error << "Unhandled key type `" << type_vec[0] << "` for " << Field<string>::get(target, "className") << "." << fieldName; - PyErr_SetString(PyExc_TypeError, error.str().c_str()); + switch(key_type_code) + { + case 'b': + { + ret = lookup_value <bool> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'c': + { + ret = lookup_value <char> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'h': + { + ret = lookup_value <short> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'H': + { + ret = lookup_value <unsigned short> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'i': + { + ret = lookup_value <int> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'I': + { + ret = lookup_value <unsigned int> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'l': + { + ret = lookup_value <long> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'k': + { + ret = lookup_value <unsigned long> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'L': + { + ret = lookup_value <long long> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'K': + { + ret = lookup_value <unsigned long long> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'd': + { + ret = lookup_value <double> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'f': + { + ret = lookup_value <float> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 's': + { + ret = lookup_value <string> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'x': + { + ret = lookup_value <Id> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'y': + { + ret = lookup_value <ObjId> (target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'D': + { + ret = lookup_value < vector <double> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'S': + { + ret = lookup_value < vector <string> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'X': + { + ret = lookup_value < vector <Id> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'Y': + { + ret = lookup_value < vector <ObjId> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'v': + { + ret = lookup_value < vector <int> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'N': + { + ret = lookup_value < vector <unsigned int> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'P': + { + ret = lookup_value < vector <unsigned long> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'F': + { + ret = lookup_value < vector <float> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'w': + { + ret = lookup_value < vector <short> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + case 'C': + { + ret = lookup_value < vector <char> >(target, string(fieldName), value_type_code, key_type_code, key); + break; + } + default: + ostringstream error; + error << "Unhandled key type `" << type_vec[0] << "` for " << Field<string>::get(target, "className") << "." << fieldName; + PyErr_SetString(PyExc_TypeError, error.str().c_str()); } return ret; } @@ -1225,12 +1464,14 @@ PyDoc_STRVAR(moose_ObjId_getLookupField_documentation, PyObject * moose_ObjId_getLookupField(_ObjId * self, PyObject * args) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getLookupField"); } char * fieldName = NULL; PyObject * key = NULL; - if (!PyArg_ParseTuple(args, "sO:moose_ObjId_getLookupField", &fieldName, &key)){ + if (!PyArg_ParseTuple(args, "sO:moose_ObjId_getLookupField", &fieldName, &key)) + { return NULL; } return getLookupField(self->oid_, fieldName, key); @@ -1239,13 +1480,15 @@ PyObject * moose_ObjId_getLookupField(_ObjId * self, PyObject * args) int setLookupField(ObjId target, char * fieldName, PyObject * key, PyObject * value) { vector<string> type_vec; - if (parseFinfoType(Field<string>::get(target, "className"), "lookupFinfo", string(fieldName), type_vec) < 0){ + if (parseFinfoType(Field<string>::get(target, "className"), "lookupFinfo", string(fieldName), type_vec) < 0) + { ostringstream error; error << "Cannot handle key type for LookupField `" << Field<string>::get(target, "className") << "." << fieldName << "`."; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return -1; } - if (type_vec.size() != 2){ + if (type_vec.size() != 2) + { ostringstream error; error << "LookupField type signature should be <keytype>, <valuetype>. But for `" << Field<string>::get(target, "className") << "." << fieldName << "` got " << type_vec.size() << " components." ; @@ -1255,71 +1498,87 @@ int setLookupField(ObjId target, char * fieldName, PyObject * key, PyObject * va char key_type_code = shortType(type_vec[0]); char value_type_code = shortType(type_vec[1]); int ret = -1; - switch(key_type_code){ - case 'I': { - ret = set_lookup_value <unsigned int> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'k': { - ret = set_lookup_value <unsigned long> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 's': { - ret = set_lookup_value <string> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'i': { - ret = set_lookup_value <int> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'l': { - ret = set_lookup_value <long> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'L': { - ret = set_lookup_value <long long> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'K': { - ret = set_lookup_value <unsigned long long> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'b': { - ret = set_lookup_value <bool> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'c': { - ret = set_lookup_value <char> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'h': { - ret = set_lookup_value <short> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'H': { - ret = set_lookup_value <unsigned short> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'd': { - ret = set_lookup_value <double> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'f': { - ret = set_lookup_value <float> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'x': { - ret = set_lookup_value <Id> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - case 'y': { - ret = set_lookup_value <ObjId> (target, string(fieldName), value_type_code, key_type_code, key, value); - break; - } - default: - ostringstream error; - error << "setLookupField: invalid key type " << type_vec[0]; - PyErr_SetString(PyExc_TypeError, error.str().c_str()); + switch(key_type_code) + { + case 'I': + { + ret = set_lookup_value <unsigned int> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'k': + { + ret = set_lookup_value <unsigned long> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 's': + { + ret = set_lookup_value <string> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'i': + { + ret = set_lookup_value <int> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'l': + { + ret = set_lookup_value <long> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'L': + { + ret = set_lookup_value <long long> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'K': + { + ret = set_lookup_value <unsigned long long> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'b': + { + ret = set_lookup_value <bool> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'c': + { + ret = set_lookup_value <char> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'h': + { + ret = set_lookup_value <short> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'H': + { + ret = set_lookup_value <unsigned short> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'd': + { + ret = set_lookup_value <double> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'f': + { + ret = set_lookup_value <float> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'x': + { + ret = set_lookup_value <Id> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + case 'y': + { + ret = set_lookup_value <ObjId> (target, string(fieldName), value_type_code, key_type_code, key, value); + break; + } + default: + ostringstream error; + error << "setLookupField: invalid key type " << type_vec[0]; + PyErr_SetString(PyExc_TypeError, error.str().c_str()); } return ret; }// setLookupField @@ -1340,16 +1599,19 @@ PyDoc_STRVAR(moose_ObjId_setLookupField_documentation, PyObject * moose_ObjId_setLookupField(_ObjId * self, PyObject * args) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { return NULL; } PyObject * key; PyObject * value; char * field; - if (!PyArg_ParseTuple(args, "sOO:moose_ObjId_setLookupField", &field, &key, &value)){ + if (!PyArg_ParseTuple(args, "sOO:moose_ObjId_setLookupField", &field, &key, &value)) + { return NULL; } - if ( setLookupField(self->oid_, field, key, value) == 0){ + if ( setLookupField(self->oid_, field, key, value) == 0) + { Py_RETURN_NONE; } return NULL; @@ -1367,15 +1629,17 @@ PyDoc_STRVAR(moose_ObjId_setDestField_documentation, "The number and type of paramateres depend on the destFinfo to be\n" "set. Use moose.doc('{classname}.{fieldname}') to get builtin\n" "documentation on the destFinfo `fieldname`\n" - ); + ); PyObject * moose_ObjId_setDestField(_ObjId * self, PyObject * args) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_setDestField"); } PyObject * arglist[10] = {NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL}; + NULL, NULL, NULL, NULL, NULL + }; ostringstream error; ObjId oid = ((_ObjId*)self)->oid_; @@ -1385,7 +1649,8 @@ PyObject * moose_ObjId_setDestField(_ObjId * self, PyObject * args) &arglist[0], &arglist[1], &arglist[2], &arglist[3], &arglist[4], &arglist[5], &arglist[6], &arglist[7], &arglist[8], - &arglist[9])){ + &arglist[9])) + { error << "At most " << maxArgs - 1 << " arguments can be handled."; PyErr_SetString(PyExc_ValueError, error.str().c_str()); return NULL; @@ -1393,7 +1658,8 @@ PyObject * moose_ObjId_setDestField(_ObjId * self, PyObject * args) // Get the destFinfo name char * fieldName = PyString_AsString(arglist[0]); - if (!fieldName){ // not a string, raises TypeError + if (!fieldName) // not a string, raises TypeError + { error << "first argument must be a string specifying field name."; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; @@ -1402,28 +1668,39 @@ PyObject * moose_ObjId_setDestField(_ObjId * self, PyObject * args) // Try to parse the arguments. vector< string > argType; if (parseFinfoType(Field<string>::get(oid, "className"), - "destFinfo", string(fieldName), argType) < 0){ + "destFinfo", string(fieldName), argType) < 0) + { error << "Arguments not handled: " << fieldName << "("; - for (unsigned int ii = 0; ii < argType.size(); ++ii){ + for (unsigned int ii = 0; ii < argType.size(); ++ii) + { error << argType[ii] << ","; } error << ")"; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; } - if (argType.size() == 1){ - if ( arglist[1] == NULL && argType[0] == "void"){ + if (argType.size() == 1) + { + if ( arglist[1] == NULL && argType[0] == "void") + { bool ret = SetGet0::set(oid, string(fieldName)); - if (ret){ + if (ret) + { Py_RETURN_TRUE; - } else { + } + else + { Py_RETURN_FALSE; } } return setDestFinfo(oid, string(fieldName), arglist[1], argType[0]); - } else if (argType.size() == 2){ + } + else if (argType.size() == 2) + { return setDestFinfo2(oid, string(fieldName), arglist[1], shortType(argType[0]), arglist[2], shortType(argType[1])); - } else { + } + else + { error << "Can handle only up to 2 arguments" << endl; return NULL; } @@ -1436,49 +1713,70 @@ PyObject * setDestFinfo(ObjId obj, string fieldName, PyObject *arg, string argTy ostringstream error; error << "moose.setDestFinfo: "; -switch (typecode){ - case 'f': case 'd': { + switch (typecode) + { + case 'f': + case 'd': + { double param = PyFloat_AsDouble(arg); - if (typecode == 'f'){ + if (typecode == 'f') + { ret = SetGet1<float>::set(obj, fieldName, (float)param); - } else { + } + else + { ret = SetGet1<double>::set(obj, fieldName, param); } } - break; - case 's': { + break; + case 's': + { char * param = PyString_AsString(arg); ret = SetGet1<string>::set(obj, fieldName, string(param)); } - break; - case 'i': case 'l': { + break; + case 'i': + case 'l': + { long param = PyInt_AsLong(arg); - if (param == -1 && PyErr_Occurred()){ + if (param == -1 && PyErr_Occurred()) + { return NULL; } - if (typecode == 'i'){ + if (typecode == 'i') + { ret = SetGet1<int>::set(obj, fieldName, (int)param); - } else { + } + else + { ret = SetGet1<long>::set(obj, fieldName, param); } } - break; - case 'I': case 'k':{ + break; + case 'I': + case 'k': + { unsigned long param =PyLong_AsUnsignedLong(arg); - if (PyErr_Occurred()){ + if (PyErr_Occurred()) + { return NULL; } - if (typecode == 'I'){ + if (typecode == 'I') + { ret = SetGet1< unsigned int>::set(obj, fieldName, (unsigned int)param); - } else { + } + else + { ret = SetGet1<unsigned long>::set(obj, fieldName, param); } } - break; - case 'x': { + break; + case 'x': + { Id param; _Id * id = (_Id*)(arg); - if (id == NULL){ + if (id == NULL) + { error << "argument should be an vec or an melement"; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; @@ -1486,11 +1784,13 @@ switch (typecode){ param = id->id_; ret = SetGet1<Id>::set(obj, fieldName, param); } - break; - case 'y': { + break; + case 'y': + { ObjId param; _ObjId * oid = (_ObjId*)(arg); - if (oid == NULL){ + if (oid == NULL) + { error << "argument should be vec or an melement"; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; @@ -1498,66 +1798,84 @@ switch (typecode){ param = oid->oid_; ret = SetGet1<ObjId>::set(obj, fieldName, param); } - break; - case 'c': { + break; + case 'c': + { char * param = PyString_AsString(arg); - if (!param){ + if (!param) + { error << "expected argument of type char/string"; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; - } else if (strlen(param) == 0){ + } + else if (strlen(param) == 0) + { error << "Empty string not allowed."; PyErr_SetString(PyExc_ValueError, error.str().c_str()); return NULL; } ret = SetGet1<char>::set(obj, fieldName, param[0]); } - break; - //////////////////////////////////////////////////// - // We do NOT handle multiple vectors. Use the argument - // list as a single vector argument. - //////////////////////////////////////////////////// - case 'v': { + break; + //////////////////////////////////////////////////// + // We do NOT handle multiple vectors. Use the argument + // list as a single vector argument. + //////////////////////////////////////////////////// + case 'v': + { return _set_vector_destFinfo<int>(obj, string(fieldName), arg, typecode); } - case 'w': { + case 'w': + { return _set_vector_destFinfo<short>(obj, string(fieldName), arg, typecode); } - case 'L': {//SET_VECFIELD(long, l) { + case 'L': //SET_VECFIELD(long, l) { + { return _set_vector_destFinfo<long>(obj, string(fieldName), arg, typecode); } - case 'N': { //SET_VECFIELD(unsigned int, I) + case 'N': //SET_VECFIELD(unsigned int, I) + { return _set_vector_destFinfo<unsigned int>(obj, string(fieldName), arg, typecode); } - case 'K': {//SET_VECFIELD(unsigned long, k) + case 'K': //SET_VECFIELD(unsigned long, k) + { return _set_vector_destFinfo<unsigned long>(obj, string(fieldName), arg, typecode); } - case 'F': {//SET_VECFIELD(float, f) + case 'F': //SET_VECFIELD(float, f) + { return _set_vector_destFinfo<float>(obj, string(fieldName), arg, typecode); } - case 'D': {//SET_VECFIELD(double, d) + case 'D': //SET_VECFIELD(double, d) + { return _set_vector_destFinfo<double>(obj, string(fieldName), arg, typecode); } - case 'S': { + case 'S': + { return _set_vector_destFinfo<string>(obj, string(fieldName), arg, typecode); } - case 'X': { + case 'X': + { return _set_vector_destFinfo<Id>(obj, string(fieldName), arg, typecode); } - case 'Y': { + case 'Y': + { return _set_vector_destFinfo<ObjId>(obj, string(fieldName), arg, typecode); } - default: { + default: + { error << "Cannot handle argument type: " << argType; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; } -} // switch (shortType(argType[ii]) -if (ret){ - Py_RETURN_TRUE; -} else { - Py_RETURN_FALSE; -} + } // switch (shortType(argType[ii]) + if (ret) + { + Py_RETURN_TRUE; + } + else + { + Py_RETURN_FALSE; + } } @@ -1567,53 +1885,74 @@ Set destFinfo for 2 argument destination field functions. // template <class A> PyObject* setDestFinfo2(ObjId obj, string fieldName, PyObject * arg1, char type1, PyObject * arg2, char type2) { -ostringstream error; -error << "moose.setDestFinfo2: "; -switch (type2){ - case 'f': case 'd': { + ostringstream error; + error << "moose.setDestFinfo2: "; + switch (type2) + { + case 'f': + case 'd': + { double param = PyFloat_AsDouble(arg2); - if (type2 == 'f'){ + if (type2 == 'f') + { return setDestFinfo1<float>(obj, fieldName, arg1, type1, (float)param); - } else { + } + else + { return setDestFinfo1<double>(obj, fieldName, arg1, type1, param); } } - case 's': { + case 's': + { char * param = PyString_AsString(arg2); return setDestFinfo1<string>(obj, fieldName, arg1, type1, string(param)); } - case 'i': case 'l': { + case 'i': + case 'l': + { long param = PyInt_AsLong(arg2); - if (param == -1 && PyErr_Occurred()){ + if (param == -1 && PyErr_Occurred()) + { return NULL; } - if (type2 == 'i'){ + if (type2 == 'i') + { return setDestFinfo1< int>(obj, fieldName, arg1, type1, (int)param); - } else { + } + else + { return setDestFinfo1< long>(obj, fieldName, arg1, type1, param); } } - case 'I': case 'k':{ + case 'I': + case 'k': + { unsigned long param =PyLong_AsUnsignedLong(arg2); - if (PyErr_Occurred()){ + if (PyErr_Occurred()) + { return NULL; } - if (type2 == 'I'){ + if (type2 == 'I') + { return setDestFinfo1< unsigned int>(obj, fieldName, arg1, type1, (unsigned int)param); - } else { + } + else + { return setDestFinfo1< unsigned long>(obj, fieldName, arg1, type1, param); } } - case 'x': { + case 'x': + { Id param; // if (Id_SubtypeCheck(arg)){ - _Id * id = (_Id*)(arg2); - if (id == NULL){ - error << "argument should be an vec or an melement"; - PyErr_SetString(PyExc_TypeError, error.str().c_str()); - return NULL; - } - param = id->id_; + _Id * id = (_Id*)(arg2); + if (id == NULL) + { + error << "argument should be an vec or an melement"; + PyErr_SetString(PyExc_TypeError, error.str().c_str()); + return NULL; + } + param = id->id_; // } else if (ObjId_SubtypeCheck(arg)){ // _ObjId * oid = (_ObjId*)(arg); // if (oid == NULL){ @@ -1625,7 +1964,8 @@ switch (type2){ // } return setDestFinfo1< Id>(obj, fieldName, arg1, type1, param); } - case 'y': { + case 'y': + { ObjId param; // if (Id_SubtypeCheck(arg)){ // _Id * id = (_Id*)(arg); @@ -1636,35 +1976,41 @@ switch (type2){ // } // param = ObjId(id->id_); // } else if (ObjId_SubtypeCheck(arg)){ - _ObjId * oid = (_ObjId*)(arg2); - if (oid == NULL){ - error << "argument should be an vec or an melement"; - PyErr_SetString(PyExc_TypeError, error.str().c_str()); - return NULL; - } - param = oid->oid_; + _ObjId * oid = (_ObjId*)(arg2); + if (oid == NULL) + { + error << "argument should be an vec or an melement"; + PyErr_SetString(PyExc_TypeError, error.str().c_str()); + return NULL; + } + param = oid->oid_; // } return setDestFinfo1< ObjId>(obj, fieldName, arg1, type1, param); } - case 'c': { + case 'c': + { char * param = PyString_AsString(arg2); - if (!param){ + if (!param) + { error << "expected argument of type char/string"; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; - } else if (strlen(param) == 0){ + } + else if (strlen(param) == 0) + { error << "Empty string not allowed."; PyErr_SetString(PyExc_ValueError, error.str().c_str()); return NULL; } return setDestFinfo1< char>(obj, fieldName, arg1, type1, param[0]); } - default: { + default: + { error << "Unhandled argument 2 type (shortType=" << type2 << ")"; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; } -} + } } @@ -1700,35 +2046,44 @@ PyDoc_STRVAR(moose_ObjId_getFieldNames_documenation, // 2011-03-23 15:28:26 (+0530) PyObject * moose_ObjId_getFieldNames(_ObjId * self, PyObject *args) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getFieldNames"); } char * ftype = NULL; - if (!PyArg_ParseTuple(args, "|s:moose_ObjId_getFieldNames", &ftype)){ + if (!PyArg_ParseTuple(args, "|s:moose_ObjId_getFieldNames", &ftype)) + { return NULL; } string ftype_str = (ftype != NULL)? string(ftype): ""; vector<string> ret; string className = Field<string>::get(self->oid_, "className"); - if (ftype_str == ""){ - for (const char **a = getFinfoTypes(); *a; ++a){ + if (ftype_str == "") + { + for (const char **a = getFinfoTypes(); *a; ++a) + { vector<string> fields = getFieldNames(className, string(*a)); ret.insert(ret.end(), fields.begin(), fields.end()); } - } else { + } + else + { ret = getFieldNames(className, ftype_str); } PyObject * pyret = PyTuple_New((Py_ssize_t)ret.size()); - for (unsigned int ii = 0; ii < ret.size(); ++ ii ){ + for (unsigned int ii = 0; ii < ret.size(); ++ ii ) + { PyObject * fname = Py_BuildValue("s", ret[ii].c_str()); - if (!fname){ + if (!fname) + { Py_XDECREF(pyret); pyret = NULL; break; } - if (PyTuple_SetItem(pyret, (Py_ssize_t)ii, fname)){ + if (PyTuple_SetItem(pyret, (Py_ssize_t)ii, fname)) + { Py_XDECREF(pyret); // Py_DECREF(fname); pyret = NULL; @@ -1756,20 +2111,24 @@ PyDoc_STRVAR(moose_ObjId_getNeighbors_documentation, PyObject * moose_ObjId_getNeighbors(_ObjId * self, PyObject * args) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getNeighbors"); } char * field = NULL; - if (!PyArg_ParseTuple(args, "s:moose_ObjId_getNeighbors", &field)){ + if (!PyArg_ParseTuple(args, "s:moose_ObjId_getNeighbors", &field)) + { return NULL; } vector< Id > val = LookupField< string, vector< Id > >::get(self->oid_, "neighbors", string(field)); PyObject * ret = PyTuple_New((Py_ssize_t)val.size()); - for (unsigned int ii = 0; ii < val.size(); ++ ii ){ + for (unsigned int ii = 0; ii < val.size(); ++ ii ) + { _Id * entry = PyObject_New(_Id, &IdType); - if (!entry || PyTuple_SetItem(ret, (Py_ssize_t)ii, (PyObject*)entry)){ + if (!entry || PyTuple_SetItem(ret, (Py_ssize_t)ii, (PyObject*)entry)) + { Py_DECREF(ret); // Py_DECREF((PyObject*)entry); ret = NULL; @@ -1832,10 +2191,11 @@ PyDoc_STRVAR(moose_ObjId_connect_documentation, "--------\n" "moose.connect\n" "\n" - ); + ); PyObject * moose_ObjId_connect(_ObjId * self, PyObject * args) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_connect"); } extern PyTypeObject ObjIdType; @@ -1847,10 +2207,12 @@ PyObject * moose_ObjId_connect(_ObjId * self, PyObject * args) &srcField, &destPtr, &destField, - &msgType)){ + &msgType)) + { return NULL; } - if (msgType == NULL){ + if (msgType == NULL) + { msgType = default_msg_type; } _ObjId * dest = reinterpret_cast<_ObjId*>(destPtr); @@ -1859,7 +2221,8 @@ PyObject * moose_ObjId_connect(_ObjId * self, PyObject * args) string(srcField), dest->oid_, string(destField)); - if (mid.bad()){ + if (mid.bad()) + { PyErr_SetString(PyExc_NameError, "connect failed: check field names and type compatibility."); return NULL; @@ -1877,46 +2240,63 @@ PyDoc_STRVAR(moose_ObjId_richcompare_documentation, "meaningful for elements.\n"); PyObject* moose_ObjId_richcompare(_ObjId * self, PyObject * other, int op) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_richcompare"); } extern PyTypeObject ObjIdType; - if ((self != NULL && other == NULL) || (self == NULL && other != NULL)){ - if (op == Py_EQ){ + if ((self != NULL && other == NULL) || (self == NULL && other != NULL)) + { + if (op == Py_EQ) + { Py_RETURN_FALSE; - } else if (op == Py_NE){ + } + else if (op == Py_NE) + { Py_RETURN_TRUE; - } else { + } + else + { PyErr_SetString(PyExc_TypeError, "Cannot compare NULL with non-NULL"); return NULL; } } - if (!PyObject_IsInstance(other, (PyObject*)&ObjIdType)){ + if (!PyObject_IsInstance(other, (PyObject*)&ObjIdType)) + { ostringstream error; error << "Cannot compare ObjId with " << Py_TYPE(other)->tp_name; PyErr_SetString(PyExc_TypeError, error.str().c_str()); return NULL; } - if (!Id::isValid(((_ObjId*)other)->oid_.id)){ + if (!Id::isValid(((_ObjId*)other)->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_richcompare"); } string l_path = self->oid_.path(); string r_path = ((_ObjId*)other)->oid_.path(); int result = l_path.compare(r_path); - if (result == 0){ - if (op == Py_EQ || op == Py_LE || op == Py_GE){ + if (result == 0) + { + if (op == Py_EQ || op == Py_LE || op == Py_GE) + { Py_RETURN_TRUE; } Py_RETURN_FALSE; - } else if (result < 0){ - if (op == Py_LT || op == Py_LE || op == Py_NE){ + } + else if (result < 0) + { + if (op == Py_LT || op == Py_LE || op == Py_NE) + { Py_RETURN_TRUE; } Py_RETURN_FALSE; - } else { - if (op == Py_GT || op == Py_GE || op == Py_NE){ + } + else + { + if (op == Py_GT || op == Py_GE || op == Py_NE) + { Py_RETURN_TRUE; } Py_RETURN_FALSE; @@ -1933,10 +2313,11 @@ PyDoc_STRVAR(moose_ObjId_getDataIndex_documentation, " >>> comp.getDataIndex()\n" " >>> 0\n" "" - ); + ); PyObject * moose_ObjId_getDataIndex(_ObjId * self) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getDataIndex"); } PyObject * ret = Py_BuildValue("I", self->oid_.dataIndex); @@ -1948,7 +2329,8 @@ PyObject * moose_ObjId_getDataIndex(_ObjId * self) // place-holer to avoid compilation errors. PyObject * moose_ObjId_getFieldIndex(_ObjId * self) { - if (!Id::isValid(self->oid_.id)){ + if (!Id::isValid(self->oid_.id)) + { RAISE_INVALID_ID(NULL, "moose_ObjId_getFieldIndex"); } PyObject * ret = Py_BuildValue("I", self->oid_.dataIndex); @@ -1959,34 +2341,61 @@ PyObject * moose_ObjId_getFieldIndex(_ObjId * self) // Python method lists for PyObject of ObjId /////////////////////////////////////////////// -static PyMethodDef ObjIdMethods[] = { - {"getFieldType", (PyCFunction)moose_ObjId_getFieldType, METH_VARARGS, - moose_ObjId_getFieldType_documentation}, - {"getField", (PyCFunction)moose_ObjId_getField, METH_VARARGS, - moose_ObjId_getField_documentation}, - {"setField", (PyCFunction)moose_ObjId_setField, METH_VARARGS, - moose_ObjId_setField_documentation}, - {"getLookupField", (PyCFunction)moose_ObjId_getLookupField, METH_VARARGS, - moose_ObjId_getLookupField_documentation}, - {"setLookupField", (PyCFunction)moose_ObjId_setLookupField, METH_VARARGS, - moose_ObjId_setLookupField_documentation}, - {"getId", (PyCFunction)moose_ObjId_getId, METH_NOARGS, - moose_ObjId_getId_documentation}, - {"vec", (PyCFunction)moose_ObjId_getId, METH_NOARGS, - "Return the vec this element belongs to. This is overridden by the" - " attribute of the same name for quick access."}, - {"getFieldNames", (PyCFunction)moose_ObjId_getFieldNames, METH_VARARGS, - moose_ObjId_getFieldNames_documenation}, - {"getNeighbors", (PyCFunction)moose_ObjId_getNeighbors, METH_VARARGS, - moose_ObjId_getNeighbors_documentation}, - {"connect", (PyCFunction)moose_ObjId_connect, METH_VARARGS, - moose_ObjId_connect_documentation}, - {"getDataIndex", (PyCFunction)moose_ObjId_getDataIndex, METH_NOARGS, - moose_ObjId_getDataIndex_documentation}, - {"getFieldIndex", (PyCFunction)moose_ObjId_getFieldIndex, METH_NOARGS, - "Get the index of this object as a field."}, - {"setDestField", (PyCFunction)moose_ObjId_setDestField, METH_VARARGS, - moose_ObjId_setDestField_documentation}, +static PyMethodDef ObjIdMethods[] = +{ + { + "getFieldType", (PyCFunction)moose_ObjId_getFieldType, METH_VARARGS, + moose_ObjId_getFieldType_documentation + }, + { + "getField", (PyCFunction)moose_ObjId_getField, METH_VARARGS, + moose_ObjId_getField_documentation + }, + { + "setField", (PyCFunction)moose_ObjId_setField, METH_VARARGS, + moose_ObjId_setField_documentation + }, + { + "getLookupField", (PyCFunction)moose_ObjId_getLookupField, METH_VARARGS, + moose_ObjId_getLookupField_documentation + }, + { + "setLookupField", (PyCFunction)moose_ObjId_setLookupField, METH_VARARGS, + moose_ObjId_setLookupField_documentation + }, + { + "getId", (PyCFunction)moose_ObjId_getId, METH_NOARGS, + moose_ObjId_getId_documentation + }, + { + "vec", (PyCFunction)moose_ObjId_getId, METH_NOARGS, + "Return the vec this element belongs to. This is overridden by the" + " attribute of the same name for quick access." + }, + { + "getFieldNames", (PyCFunction)moose_ObjId_getFieldNames, METH_VARARGS, + moose_ObjId_getFieldNames_documenation + }, + { + "getNeighbors", (PyCFunction)moose_ObjId_getNeighbors, METH_VARARGS, + moose_ObjId_getNeighbors_documentation + }, + { + "connect", (PyCFunction)moose_ObjId_connect, METH_VARARGS, + moose_ObjId_connect_documentation + }, + { + "getDataIndex", (PyCFunction)moose_ObjId_getDataIndex, METH_NOARGS, + moose_ObjId_getDataIndex_documentation + }, + { + "getFieldIndex", (PyCFunction)moose_ObjId_getFieldIndex, METH_NOARGS, + "Get the index of this object as a field." + }, + { + "setDestField", (PyCFunction)moose_ObjId_setDestField, METH_VARARGS, + moose_ObjId_setDestField_documentation + }, {NULL, NULL, 0, NULL}, /* Sentinel */ }; @@ -2049,9 +2458,10 @@ PyDoc_STRVAR(moose_ObjId_documentation, ">>> a = Neutral('alpha') # Creates element named `alpha` under current working element\n" ">>> b = Neutral('alpha/beta') # Creates the element named `beta` under `alpha`\n" ">>> c = moose.melement(b)" - ); + ); -PyTypeObject ObjIdType = { +PyTypeObject ObjIdType = +{ PyVarObject_HEAD_INIT(NULL, 0) /* tp_head */ "moose.melement", /* tp_name */ sizeof(_ObjId), /* tp_basicsize */ diff --git a/moose-core/pymoose/moosemodule.cpp b/moose-core/pymoose/moosemodule.cpp index 54ed633eb331dfef8d2b5938782b5e48d8f2fc0f..ae638e18c3afc90267e20467fb89577ba9c95ba3 100644 --- a/moose-core/pymoose/moosemodule.cpp +++ b/moose-core/pymoose/moosemodule.cpp @@ -1,38 +1,10 @@ // moosemodule.cpp --- -// -// Filename: moosemodule.cpp -// Description: -// Author: Subhasis Ray -// Maintainer: -// Copyright (C) 2010 Subhasis Ray, all rights reserved. -// Created: Thu Mar 10 11:26:00 2011 (+0530) -// Version: -// Last-Updated: Mon 25 Apr 2016 11:17:24 AM IST -// By: Dilawar Singh -// - -// Change log: -// -// 2011-03-10 Initial version. Starting coding directly with Python -// API. Trying out direct access to Python API instead of -// going via SWIG. SWIG has this issue of creating huge -// files and the resulting binaries are also very -// large. Since we are not going to use any language but -// Python in the foreseeable future, we can avoid the bloat -// by coding directly with Python API. -// -// 2012-01-05 Much polished version. Handling destFinfos as methods in -// Python class. -// -// 2012-04-13 Finished reimplementing the meta class system using -// Python/C API. -// Decided not to expose any lower level moose API. -// -// 2012-04-20 Finalized the C interface +// For detailed log, see the git-log . +// Author : Subhasis Ray +// Maintainer : Dilawar Singh, Subhasis Ray #include <Python.h> - -#include <structmember.h> // This defines the type id macros like T_STRING +#include <structmember.h> #ifdef USE_NUMPY #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION @@ -2879,6 +2851,7 @@ PyObject * moose_ObjId_get_elementField_attr(PyObject * self, Py_INCREF(self); // compensate for stolen ref PyTuple_SetItem(args, 1, PyString_FromString(name)); _Field * ret = PyObject_New(_Field, &moose_ElementField); + // 2. Now use this arg to actually create the element field. if (moose_ElementField.tp_init((PyObject*)ret, args, NULL) != 0) { diff --git a/moose-core/pymoose/vec.cpp b/moose-core/pymoose/vec.cpp index 733d28965e96d042c5936c7ef6b6b3f8ef6a4103..e5e2ddb3ec987d5870474dfe1593239daa5fe69f 100644 --- a/moose-core/pymoose/vec.cpp +++ b/moose-core/pymoose/vec.cpp @@ -441,14 +441,10 @@ int moose_Id_init(_Id * self, PyObject * args, PyObject * kwargs) [unsigned int isGlobal] - default: 0 [string type] - default: Neutral */ - if (PyArg_ParseTupleAndKeywords(args, - kwargs, - "s|IIs:moose_Id_init", - kwlist, - &path, - &numData, - &isGlobal, - &type)) + if (PyArg_ParseTupleAndKeywords(args, kwargs, "s|IIs:moose_Id_init", + kwlist, &path, &numData, &isGlobal, + &type) + ) { // Parsing args successful, if any error happens now, // different argument processing will not help. Return error @@ -462,10 +458,9 @@ int moose_Id_init(_Id * self, PyObject * args, PyObject * kwargs) return -1; } self->id_ = Id(trimmed_path); + // Return already existing object - if (self->id_ != Id() || - trimmed_path == "/" || - trimmed_path == "/root") + if (self->id_ != Id() || trimmed_path == "/" || trimmed_path == "/root") { if ((numData > 0) && (numData != Field<unsigned int>::get(self->id_, "numData"))) { @@ -474,13 +469,10 @@ int moose_Id_init(_Id * self, PyObject * args, PyObject * kwargs) return 0; } if (type == NULL) - { type = _default_type; - } if (numData <= 0) - { numData = 1; - } + self->id_ = create_Id_from_path(trimmed_path, numData, isGlobal, type); if (self->id_ == Id() && PyErr_Occurred()) { diff --git a/moose-core/shell/Shell.cpp b/moose-core/shell/Shell.cpp index b2e3b2892e33890012b62fb65b82f9a68d71ec0b..e29b318ace7b31b0c439a6c1f18cdf0c1cea282d 100644 --- a/moose-core/shell/Shell.cpp +++ b/moose-core/shell/Shell.cpp @@ -163,39 +163,6 @@ Shell::~Shell() ; } -#ifdef CYMOOSE - -/*----------------------------------------------------------------------------- - * This function must create a fully functional Shell. Used in cython - * interface. - *-----------------------------------------------------------------------------*/ -Shell* Shell::initShell() -{ - Eref sheller = Id().eref(); - Shell* shell = reinterpret_cast< Shell* >( sheller.data() ); - return shell; -} - -Id Shell::create(string type, string name, unsigned int numData - , NodePolicy nodePolicy, unsigned int preferredNode - ) -{ - if(name.size() == 0) - return doCreate(type, Id(), name, numData, nodePolicy, preferredNode); - - string::size_type pos = name.find_last_of('/'); - string parentPath = name.substr(0, pos); - ObjId parentObj = ObjId(parentPath); - //cerr << "info: Creating Obj with parent : " << parentObj << endl; - Id id = doCreate(type, parentObj, name.substr(pos+1) - , numData, nodePolicy, preferredNode - ); - //cerr << " ++ with id " << id << endl; - return id; -} - -#endif /* ----- CYMOOSE ----- */ - void Shell::setShellElement( Element* shelle ) { shelle_ = shelle; @@ -245,12 +212,17 @@ Id Shell::doCreate( string type, ObjId parent, string name, warning( ss.str() ); return Id(); } + + // TODO: This should be an error in future. + // This logic of handling already existing path is now handled in + // melements.cpp . Calling this section should become an error in + // future. if ( Neutral::child( parent.eref(), name ) != Id() ) { stringstream ss; - ss << "Shell::doCreate: Object with same name already present: '" - << parent.path() << "/" << name << "'. No Element created"; - warning( ss.str() ); + ss << "Object with same path already present : " << parent.path() + << "/" << name; + moose::showWarn( ss.str() ); return Id(); } // Get the new Id ahead of time and pass to all nodes. @@ -269,6 +241,7 @@ Id Shell::doCreate( string type, ObjId parent, string name, nb, // Node balance configuration parentMsgIndex // Message index of child-parent msg. ); + // innerCreate( type, parent, ret, name, numData, isGlobal ); return ret; @@ -1027,7 +1000,7 @@ bool Shell::keepLooping() void Shell::warning( const string& text ) { - LOG( moose::warning, text ); + moose::showWarn( text ); } void Shell::error( const string& text ) diff --git a/moose-core/synapse/CMakeLists.txt b/moose-core/synapse/CMakeLists.txt index bb47b9779b8f3d9c7393cd01f44c27f803ee4248..f122eb4ee46b1a8b2706d5aad1deedad18d9a6e0 100644 --- a/moose-core/synapse/CMakeLists.txt +++ b/moose-core/synapse/CMakeLists.txt @@ -1,5 +1,18 @@ cmake_minimum_required(VERSION 2.8) + include_directories( ../basecode ../utility ../kinetics) include_directories( ../external/muparser/include/ ) -file(GLOB SYNAPSE_SRCS *.cpp) + +set( SYNAPSE_SRCS + GraupnerBrunel2012CaPlasticitySynHandler.cpp + RollingMatrix.cpp + SeqSynHandler.cpp + SimpleSynHandler.cpp + STDPSynapse.cpp + STDPSynHandler.cpp + Synapse.cpp + SynHandlerBase.cpp + testSynapse.cpp + ) + add_library(synapse ${SYNAPSE_SRCS} ) diff --git a/moose-core/synapse/RollingMatrix.cpp b/moose-core/synapse/RollingMatrix.cpp index 1ce87c9bccdb9307f08dd40c4cc230d02a49fc84..189d85bc64f10a611cccb12e33754739d2bcd086 100644 --- a/moose-core/synapse/RollingMatrix.cpp +++ b/moose-core/synapse/RollingMatrix.cpp @@ -11,6 +11,7 @@ using namespace std; #include "RollingMatrix.h" #include <cassert> +// #include <iostream> RollingMatrix::RollingMatrix() : nrows_(0), ncolumns_(0), currentStartRow_(0) @@ -67,9 +68,21 @@ void RollingMatrix::sumIntoRow( const vector< double >& input, unsigned int row double RollingMatrix::dotProduct( const vector< double >& input, unsigned int row, unsigned int startColumn ) const { + /// startColumn is the middle of the kernel. unsigned int index = (row + currentStartRow_) % nrows_; const SparseVector& sv = rows_[index]; + unsigned int i2 = input.size()/2; + unsigned int istart = (startColumn >= i2) ? 0 : i2-startColumn; + unsigned int colstart = (startColumn <= i2) ? 0 : startColumn - i2; + unsigned int iend = (sv.size()-startColumn > i2 ) ? input.size() : + i2 - startColumn + sv.size(); + // if ( iend >= istart ) cout << startColumn << i2 << istart << iend << colstart << "\n"; + double ret = 0; + for (unsigned int i = istart, j = 0; i < iend; ++i, ++j ) + ret += sv[j + colstart] * input[i]; + + /* double ret = 0; if ( input.size() + startColumn <= sv.size() ) { for (unsigned int i = 0; i < input.size(); ++i ) @@ -79,6 +92,7 @@ double RollingMatrix::dotProduct( const vector< double >& input, for (unsigned int i = 0; i < end; ++i ) ret += sv[i + startColumn] * input[i]; } + */ return ret; } diff --git a/moose-core/synapse/SeqSynHandler.cpp b/moose-core/synapse/SeqSynHandler.cpp index 30346936110d9c15f1ec34cc4ea8fd0e1822a457..0f29f3d4fe21bc6e4cc1930c065b2749f115fdaa 100644 --- a/moose-core/synapse/SeqSynHandler.cpp +++ b/moose-core/synapse/SeqSynHandler.cpp @@ -8,6 +8,7 @@ **********************************************************************/ #include <queue> +#include "global.h" #include "header.h" #include "Synapse.h" #include "SynEvent.h" @@ -42,17 +43,22 @@ const Cinfo* SeqSynHandler::initCinfo() "kernel with the history[time][synapse#] matrix." "\nThe local response can affect the synapse in three ways: " "1. It can sum the entire response vector, scale by the " - "*responseScale* term, and send to the synapse as a steady " + "*sequenceScale* term, and send to the synapse as a steady " "activation. Consider this a cell-wide immediate response to " "a sequence that it likes.\n" "2. It do an instantaneous scaling of the weight of each " "individual synapse by the corresponding entry in the response " - "vector. It uses the *weightScale* term to do this. Consider " + "vector. It uses the *plasticityScale* term to do this. " + "Consider " "this a short-term plasticity effect on specific synapses. \n" "3. It can do long-term plasticity of each individual synapse " "using the matched local entries in the response vector and " "individual synapse history as inputs to the learning rule. " "This is not yet implemented.\n" + "In addition to all these, the SeqSynHandler can act just like " + "a regular synapse, where it responds to individual synaptic " + "input according to the weight of the synapse. The size of " + "this component of the output is scaled by *baseScale*\n" }; static FieldElementFinfo< SynHandlerBase, Synapse > synFinfo( @@ -88,23 +94,65 @@ const Cinfo* SeqSynHandler::initCinfo() &SeqSynHandler::setHistoryTime, &SeqSynHandler::getHistoryTime ); - static ValueFinfo< SeqSynHandler, double > responseScale( - "responseScale", + static ValueFinfo< SeqSynHandler, double > baseScale( + "baseScale", + "Basal scaling factor for regular synaptic activation.", + &SeqSynHandler::setBaseScale, + &SeqSynHandler::getBaseScale + ); + static ValueFinfo< SeqSynHandler, double > sequenceScale( + "sequenceScale", "Scaling factor for sustained activation of synapse by seq", - &SeqSynHandler::setResponseScale, - &SeqSynHandler::getResponseScale + &SeqSynHandler::setSequenceScale, + &SeqSynHandler::getSequenceScale + ); + static ValueFinfo< SeqSynHandler, vector< unsigned int > > synapseOrder( + "synapseOrder", + "Mapping of synapse input order to spatial order on syn array." + "Entries in this vector are indices which must remain smaller " + "than numSynapses. The system will fix up if you mess up. " + "It does not insist on unique mappings, but these are " + "desirable as outcome is undefined for repeated entries.", + &SeqSynHandler::setSynapseOrder, + &SeqSynHandler::getSynapseOrder + ); + static ValueFinfo< SeqSynHandler, int > synapseOrderOption( + "synapseOrderOption", + "How to do the synapse order remapping. This rule stays in " + "place and guarantees safe mappings even if the number of " + "synapses is altered. Options:\n" + "-2: User ordering.\n" + "-1: Sequential ordering, 0 to numSynapses-1.\n" + "0: Random ordering using existing system seed.\n" + ">0: Random ordering using seed specified by this number\n" + "Default is -1, sequential ordering.", + &SeqSynHandler::setSynapseOrderOption, + &SeqSynHandler::getSynapseOrderOption ); static ReadOnlyValueFinfo< SeqSynHandler, double > seqActivation( "seqActivation", "Reports summed activation of synaptic channel by sequence", &SeqSynHandler::getSeqActivation ); - static ValueFinfo< SeqSynHandler, double > weightScale( - "weightScale", - "Scaling factor for weight of each synapse by response vector", - &SeqSynHandler::setWeightScale, - &SeqSynHandler::getWeightScale + static ValueFinfo< SeqSynHandler, double > plasticityScale( + "plasticityScale", + "Scaling factor for doing plasticity by scaling each synapse by response vector", + &SeqSynHandler::setPlasticityScale, + &SeqSynHandler::getPlasticityScale ); + + static ValueFinfo< SeqSynHandler, double > sequencePower( + "sequencePower", + "Exponent for the outcome of the sequential calculations. " + "This is needed because linear summation of terms in the kernel" + "means that a brief stong sequence match is no better than lots" + "of successive low matches. In other words, 12345 is no better" + "than 11111. Using an exponent lets us select the former." + "Defaults to 1.0.", + &SeqSynHandler::setSequencePower, + &SeqSynHandler::getSequencePower + ); + static ReadOnlyValueFinfo< SeqSynHandler, vector< double > > weightScaleVec( "weightScaleVec", @@ -128,10 +176,14 @@ const Cinfo* SeqSynHandler::initCinfo() &kernelWidth, // Field &seqDt, // Field &historyTime, // Field - &responseScale, // Field - &seqActivation, // Field - &weightScale, // Field - &weightScaleVec, // Field + &sequenceScale, // Field + &baseScale, // Field + &synapseOrder, // Field + &synapseOrderOption, // Field + &seqActivation, // ReadOnlyField + &plasticityScale, // Field + &sequencePower, // Field + &weightScaleVec, // ReadOnlyField &kernel, // ReadOnlyField &history // ReadOnlyField }; @@ -160,12 +212,14 @@ SeqSynHandler::SeqSynHandler() kernelWidth_( 5 ), historyTime_( 2.0 ), seqDt_ ( 1.0 ), - responseScale_( 1.0 ), - weightScale_( 0.0 ), - seqActivation_( 0.0 ) + baseScale_( 0.0 ), + sequenceScale_( 1.0 ), + plasticityScale_( 0.0 ), + sequencePower_( 1.0 ), + seqActivation_( 0.0 ), + synapseOrderOption_( -1 ) // sequential ordering { - int numHistory = static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); - history_.resize( numHistory, 0 ); + history_.resize( numHistory(), 0 ); } SeqSynHandler::~SeqSynHandler() @@ -193,10 +247,10 @@ void SeqSynHandler::vSetNumSynapses( const unsigned int v ) for ( unsigned int i = prevSize; i < v; ++i ) synapses_[i].setHandler( this ); - int numHistory = static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); - history_.resize( numHistory, v ); + history_.resize( numHistory(), v ); latestSpikes_.resize( v, 0.0 ); weightScaleVec_.resize( v, 0.0 ); + refillSynapseOrder( v ); updateKernel(); } @@ -216,6 +270,65 @@ Synapse* SeqSynHandler::vGetSynapse( unsigned int i ) } ////////////////////////////////////////////////////////////////////// + +// Checks for numbers bigger than the size. Replaces with +// values within the range that have not yet been used. +void SeqSynHandler::fixSynapseOrder() +{ + unsigned int sz = synapseOrder_.size(); + vector< unsigned int > availableEntries( sz ); + iota( availableEntries.begin(), availableEntries.end(), 0 ); + for( unsigned int i = 0; i < sz; ++i ) { + if ( synapseOrder_[i] < sz ) + availableEntries[ synapseOrder_[i] ] = sz; + } + vector< unsigned int > ae; + for( unsigned int i = 0; i < sz; ++i ) + if ( availableEntries[i] < sz ) + ae.push_back( availableEntries[i] ); + + auto jj = ae.begin(); + for( unsigned int i = 0; i < sz; ++i ) { + if ( synapseOrder_[i] >= sz ) + synapseOrder_[i] = *jj++; + } +} + +// Beautiful snippet from Lukasz Wiklendt on StackOverflow. Returns order +// of entries in a vector. +template <typename T> vector<size_t> sort_indexes(const vector<T> &v) { + // initialize original index locations + vector<size_t> idx(v.size()); + iota(idx.begin(), idx.end(), 0); + // sort indexes based on comparing values in v + sort(idx.begin(), idx.end(), + [&v](size_t i1, size_t i2) {return v[i1] < v[i2];}); + return idx; +} + +void SeqSynHandler::refillSynapseOrder( unsigned int newSize ) +{ + if ( synapseOrderOption_ <= -2 ) { // User order + synapseOrder_.resize( newSize, newSize ); + fixSynapseOrder(); + } else if ( synapseOrderOption_ == -1 ) { // Ordered + synapseOrder_.resize( newSize ); + for ( unsigned int i = 0 ; i < newSize; ++i ) + synapseOrder_[i] = i; + } else { + synapseOrder_.resize( newSize ); + if ( synapseOrderOption_ > 0 ) { // Specify seed explicitly + moose::mtseed( synapseOrderOption_ ); + } + vector< double > x; + for ( unsigned int i = 0; i < newSize; ++i ) + x.push_back( moose::mtrand() ); + auto idx = sort_indexes< double >( x ); + for ( unsigned int i = 0; i < newSize; ++i ) + synapseOrder_[i] = idx[i]; + } +} + void SeqSynHandler::updateKernel() { if ( kernelEquation_ == "" || seqDt_ < 1e-9 || historyTime_ < 1e-9 ) @@ -229,9 +342,9 @@ void SeqSynHandler::updateKernel() p.DefineConst(_T("e"), (mu::value_type)M_E); p.SetExpr( kernelEquation_ ); kernel_.clear(); - int numHistory = static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); - kernel_.resize( numHistory ); - for ( int i = 0; i < numHistory; ++i ) { + int nh = numHistory(); + kernel_.resize( nh ); + for ( int i = 0; i < nh; ++i ) { kernel_[i].resize( kernelWidth_ ); t = i * seqDt_; for ( unsigned int j = 0; j < kernelWidth_; ++j ) { @@ -268,8 +381,7 @@ void SeqSynHandler::setSeqDt( double v ) { seqDt_ = v; updateKernel(); - int numHistory = static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); - history_.resize( numHistory, vGetNumSynapses() ); + history_.resize( numHistory(), vGetNumSynapses() ); } double SeqSynHandler::getSeqDt() const @@ -280,8 +392,7 @@ double SeqSynHandler::getSeqDt() const void SeqSynHandler::setHistoryTime( double v ) { historyTime_ = v; - int numHistory = static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); - history_.resize( numHistory, vGetNumSynapses() ); + history_.resize( numHistory(), vGetNumSynapses() ); updateKernel(); } @@ -290,14 +401,24 @@ double SeqSynHandler::getHistoryTime() const return historyTime_; } -void SeqSynHandler::setResponseScale( double v ) +void SeqSynHandler::setBaseScale( double v ) +{ + baseScale_ = v; +} + +double SeqSynHandler::getBaseScale() const +{ + return baseScale_; +} + +void SeqSynHandler::setSequenceScale( double v ) { - responseScale_ = v; + sequenceScale_ = v; } -double SeqSynHandler::getResponseScale() const +double SeqSynHandler::getSequenceScale() const { - return responseScale_; + return sequenceScale_; } double SeqSynHandler::getSeqActivation() const @@ -305,26 +426,36 @@ double SeqSynHandler::getSeqActivation() const return seqActivation_; } -double SeqSynHandler::getWeightScale() const +double SeqSynHandler::getPlasticityScale() const { - return weightScale_; + return plasticityScale_; } -vector< double >SeqSynHandler::getWeightScaleVec() const +void SeqSynHandler::setPlasticityScale( double v ) { - return weightScaleVec_; + plasticityScale_ = v; } -void SeqSynHandler::setWeightScale( double v ) +double SeqSynHandler::getSequencePower() const { - weightScale_ = v; + return sequencePower_; +} + +void SeqSynHandler::setSequencePower( double v ) +{ + sequencePower_ = v; +} + +vector< double >SeqSynHandler::getWeightScaleVec() const +{ + return weightScaleVec_; } vector< double > SeqSynHandler::getKernel() const { - int numHistory = static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); + int nh = numHistory(); vector< double > ret; - for ( int i = 0; i < numHistory; ++i ) { + for ( int i = 0; i < nh; ++i ) { ret.insert( ret.end(), kernel_[i].begin(), kernel_[i].end() ); } return ret; @@ -332,17 +463,40 @@ vector< double > SeqSynHandler::getKernel() const vector< double > SeqSynHandler::getHistory() const { - int numHistory = static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); + int nh = numHistory(); int numX = vGetNumSynapses(); - vector< double > ret( numX * numHistory, 0.0 ); + vector< double > ret( numX * nh, 0.0 ); vector< double >::iterator k = ret.begin(); - for ( int i = 0; i < numHistory; ++i ) { + for ( int i = 0; i < nh; ++i ) { for ( int j = 0; j < numX; ++j ) *k++ = history_.get( i, j ); } return ret; } +void SeqSynHandler::setSynapseOrder( vector< unsigned int > v ) +{ + synapseOrder_ = v; + fixSynapseOrder(); + synapseOrderOption_ = -2; // Set the flag to say it is User defined. +} + +vector< unsigned int > SeqSynHandler::getSynapseOrder() const +{ + return synapseOrder_; +} + +void SeqSynHandler::setSynapseOrderOption( int v ) +{ + synapseOrderOption_ = v; + refillSynapseOrder( synapseOrder_.size() ); +} + +int SeqSynHandler::getSynapseOrderOption() const +{ + return synapseOrderOption_; +} + ///////////////////////////////////////////////////////////////////// void SeqSynHandler::addSpike(unsigned int index, double time, double weight) @@ -354,7 +508,9 @@ void SeqSynHandler::addSpike(unsigned int index, double time, double weight) // slice. For now, to get it going for LIF neurons, this will do. // Even in the general case we will probably have a very wide window // for the latestSpikes slice. - latestSpikes_[index] += weight; + // + // Here we reorder the entries in latestSpikes by the synapse order. + latestSpikes_[ synapseOrder_[index] ] += weight; } unsigned int SeqSynHandler::addSynapse() @@ -375,10 +531,10 @@ void SeqSynHandler::dropSynapse( unsigned int msgLookup ) void SeqSynHandler::vProcess( const Eref& e, ProcPtr p ) { // Here we look at the correlations and do something with them. - int numHistory = static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); + int nh = numHistory(); // Check if we need to do correlations at all. - if ( numHistory > 0 && kernel_.size() > 0 ) { + if ( nh > 0 && kernel_.size() > 0 ) { // Check if timestep rolls over a seqDt boundary if ( static_cast< int >( p->currTime / seqDt_ ) > static_cast< int >( (p->currTime - p->dt) / seqDt_ ) ) { @@ -388,22 +544,22 @@ void SeqSynHandler::vProcess( const Eref& e, ProcPtr p ) // Build up the sum of correlations over time vector< double > correlVec( vGetNumSynapses(), 0.0 ); - for ( int i = 0; i < numHistory; ++i ) + for ( int i = 0; i < nh; ++i ) history_.correl( correlVec, kernel_[i], i ); - if ( responseScale_ > 0.0 ) { // Sum all responses, send to chan + if ( sequenceScale_ > 0.0 ) { // Sum all responses, send to chan seqActivation_ = 0.0; for ( vector< double >::iterator y = correlVec.begin(); y != correlVec.end(); ++y ) - seqActivation_ += *y; + seqActivation_ += pow( *y, sequencePower_ ); // We'll use the seqActivation_ to send a special msg. - seqActivation_ *= responseScale_; + seqActivation_ *= sequenceScale_; } - if ( weightScale_ > 0.0 ) { // Short term changes in individual wts + if ( plasticityScale_ > 0.0 ) { // Short term changes in individual wts weightScaleVec_ = correlVec; for ( vector< double >::iterator y=weightScaleVec_.begin(); y != weightScaleVec_.end(); ++y ) - *y *= weightScale_; + *y *= plasticityScale_; } } } @@ -412,15 +568,15 @@ void SeqSynHandler::vProcess( const Eref& e, ProcPtr p ) // We can't leave it to the base class vProcess, because we need // to scale the weights individually in some cases. double activation = seqActivation_; // Start with seq activation - if ( weightScale_ > 0.0 ) { + if ( plasticityScale_ > 0.0 ) { while( !events_.empty() && events_.top().time <= p->currTime ) { - activation += events_.top().weight * + activation += events_.top().weight * baseScale_ * weightScaleVec_[ events_.top().synIndex ] / p->dt; events_.pop(); } } else { while( !events_.empty() && events_.top().time <= p->currTime ) { - activation += events_.top().weight / p->dt; + activation += baseScale_ * events_.top().weight / p->dt; events_.pop(); } } @@ -434,3 +590,8 @@ void SeqSynHandler::vReinit( const Eref& e, ProcPtr p ) while( !events_.empty() ) events_.pop(); } + +int SeqSynHandler::numHistory() const +{ + return static_cast< int >( 1.0 + floor( historyTime_ * (1.0 - 1e-6 ) / seqDt_ ) ); +} diff --git a/moose-core/synapse/SeqSynHandler.h b/moose-core/synapse/SeqSynHandler.h index 2a8d0171cfc139adc006372f789ab5ca7c5d6652..58ede36a4ef3042c185b803740ed56fb0c644baf 100644 --- a/moose-core/synapse/SeqSynHandler.h +++ b/moose-core/synapse/SeqSynHandler.h @@ -55,15 +55,28 @@ class SeqSynHandler: public SynHandlerBase double getSeqDt() const; void setHistoryTime( double v ); double getHistoryTime() const; - void setResponseScale( double v ); - double getResponseScale() const; + void setBaseScale( double v ); + double getBaseScale() const; + void setSequenceScale( double v ); + double getSequenceScale() const; + void setSynapseOrder( vector< unsigned int> v ); + vector< unsigned int> getSynapseOrder() const; + void setSynapseOrderOption( int v ); + int getSynapseOrderOption() const; double getSeqActivation() const; // summed activation of syn chan - void setWeightScale( double v ); - double getWeightScale() const; + void setPlasticityScale( double v ); + double getPlasticityScale() const; + void setSequencePower( double v ); + double getSequencePower() const; vector< double > getWeightScaleVec() const; vector< double > getKernel() const; vector< double > getHistory() const; + //////////////////////////////////////////////////////////////// + // Utility func + int numHistory() const; + void refillSynapseOrder( unsigned int newSize ); + void fixSynapseOrder(); //////////////////////////////////////////////////////////////// static const Cinfo* initCinfo(); private: @@ -84,13 +97,28 @@ class SeqSynHandler: public SynHandlerBase string kernelEquation_; unsigned int kernelWidth_; // Width in terms of number of synapses - // Time to store history. KernelDt defines num of rows + /// Time to store history. KernelDt defines num of rows double historyTime_; double seqDt_; // Time step for successive entries in kernel - // Scaling factor for sustained activation of synapse from response - double responseScale_; - // Scaling factor for weight changes in each synapse from response - double weightScale_; + /// Scaling factor for baseline synaptic responses. + double baseScale_; + /// Scaling factor for sequence recognition responses. + double sequenceScale_; + + /** + * Scaling factor for short-term plastic weight changes in each + * synapse arising from sequential input. + */ + double plasticityScale_; + + /** + * Exponent to use for the outcome of the sequential calculations. + * This is needed because linear summation of terms in the kernel + * means that a brief stong sequence match is no better than lots + * of successive low matches. In other words, 12345 is no better + * than 11111. + */ + double sequencePower_; /////////////////////////////////////////// // Some readonly fields @@ -105,8 +133,23 @@ class SeqSynHandler: public SynHandlerBase vector< double > latestSpikes_; /////////////////////////////////////////// - vector< vector< double > > kernel_; //Kernel for seq selectivity - RollingMatrix history_; // Rows = time; cols = synInputs + vector< vector< double > > kernel_; ///Kernel for seq selectivity + RollingMatrix history_; /// Rows = time; cols = synInputs + /** + * Remaps synapse order to avoid correlations based on presynaptic + * object Id order, or on connection building order. This + * undesirable ordering occurs even when random synaptic + * projections are used. User can alter as preferred. This is + * simply a look up table so that the incoming synapse index is + * remapped: index_on_Handler = synapseOrder_[original_syn_index] + * This must only have numbers from zero to numSynapses, and should + * normally have all the numbers. + */ + vector< unsigned int > synapseOrder_; + + /// Options: -2: User. -1: ordered. 0: random by system seed. + /// > 0: Random by seed specified by this number + int synapseOrderOption_; vector< Synapse > synapses_; priority_queue< PreSynEvent, vector< PreSynEvent >, CompareSynEvent > events_; diff --git a/moose-core/synapse/testSynapse.cpp b/moose-core/synapse/testSynapse.cpp index 39b083887b9fea1cad34c5778ec5ea167d614301..600d7ff3fe913565d4fc4b7dc8f9b52ac73d41ae 100644 --- a/moose-core/synapse/testSynapse.cpp +++ b/moose-core/synapse/testSynapse.cpp @@ -20,6 +20,48 @@ #include "../shell/Shell.h" #include "../randnum/randnum.h" +double doCorrel( RollingMatrix& rm, vector< vector< double >> & kernel ) +{ + int nr = kernel.size(); + vector< double > correlVec( nr, 0.0 ); + for ( int i = 0; i < nr; ++i ) + rm.correl( correlVec, kernel[i], i ); + double seqActivation = 0.0; + for ( int i = 0; i < nr; ++i ) + seqActivation += correlVec[i]; + return seqActivation; +} + +void testRollingMatrix2() +{ + int nr = 5; + RollingMatrix rm; + rm.resize( nr, nr ); + vector< vector< double > > kernel( nr ); + for ( int i = 0; i < nr; ++i ) { + kernel[i].resize( nr, 0.0 ); + rm.zeroOutRow( i ); + for ( int j = 0; j < nr; ++j ) { + kernel[i][j] = 16 - (i-j)*(i-j); // symmetric, forward + rm.sumIntoEntry( (i==j), i, j ); + } + } + double ret1 = doCorrel( rm, kernel ); + + for ( int i = 0; i < nr; ++i ) { + kernel[i].clear(); + kernel[i].resize( nr, 0.0 ); + rm.zeroOutRow( i ); + for ( int j = 0; j < nr; ++j ) { + int k = nr-i-1; + kernel[i][j] = 16 - (k-j)*(k-j); // symmetric, backwards + rm.sumIntoEntry( (k==j), i, j ); + } + } + double ret2 = doCorrel( rm, kernel ); + assert( doubleEq( ret1, ret2 ) ); +} + void testRollingMatrix() { int nr = 5; @@ -57,44 +99,59 @@ void testRollingMatrix() for ( int i = 0; i < nr; ++i ) input[i] = i + 1; - assert( doubleEq( rm.dotProduct( input, 0, 0 ), 0.0 ) ); - assert( doubleEq( rm.dotProduct( input, 1, 0 ), 1.0 ) ); - assert( doubleEq( rm.dotProduct( input, 2, 0 ), 4.0 ) ); - assert( doubleEq( rm.dotProduct( input, 3, 0 ), 9.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 0 ), 16.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 1 ), 12.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 2 ), 8.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 3 ), 4.0 ) ); - assert( doubleEq( rm.dotProduct( input, 4, 4 ), 0.0 ) ); - + assert( doubleEq( rm.dotProduct( input, 0, 5 ), 0.0 ) ); + assert( doubleEq( rm.dotProduct( input, 1, 5 ), 1.0 ) ); + assert( doubleEq( rm.dotProduct( input, 2, 5 ), 4.0 ) ); + assert( doubleEq( rm.dotProduct( input, 3, 5 ), 9.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 5 ), 16.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 6 ), 12.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 7 ), 8.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 8 ), 4.0 ) ); + assert( doubleEq( rm.dotProduct( input, 4, 9 ), 0.0 ) ); + + // Note that the input and the row are aligned at col=5, the + // middle of the input vector. rm.sumIntoRow( input, 0 ); // input == [1234500000] vector< double > corr; rm.correl( corr, input, 4 ); // rm[4] == [00040000] - assert( doubleEq( corr[0], 16.0 ) ); - assert( doubleEq( corr[1], 12.0 ) ); - assert( doubleEq( corr[2], 8.0 ) ); - assert( doubleEq( corr[3], 4.0 ) ); - assert( doubleEq( corr[4], 0.0 ) ); + assert( doubleEq( corr[0], 0.0 ) ); + assert( doubleEq( corr[1], 0.0 ) ); + assert( doubleEq( corr[2], 0.0 ) ); + assert( doubleEq( corr[3], 0.0 ) ); + assert( doubleEq( corr[4], 20.0 ) ); + assert( doubleEq( corr[5], 16.0 ) ); + assert( doubleEq( corr[6], 12.0 ) ); + assert( doubleEq( corr[7], 8.0 ) ); + assert( doubleEq( corr[8], 4.0 ) ); + assert( doubleEq( corr[9], 0.0 ) ); corr.assign( corr.size(), 0 ); rm.correl( corr, input, 0 ); // rm[0] == [1234500000] - assert( doubleEq( corr[0], 55.0 ) ); - assert( doubleEq( corr[1], 40.0 ) ); - assert( doubleEq( corr[2], 26.0 ) ); - assert( doubleEq( corr[3], 14.0 ) ); - assert( doubleEq( corr[4], 5.0 ) ); + assert( doubleEq( corr[0], 0.0 ) ); + assert( doubleEq( corr[1], 5.0 ) ); + assert( doubleEq( corr[2], 14.0 ) ); + assert( doubleEq( corr[3], 26.0 ) ); + assert( doubleEq( corr[4], 40.0 ) ); + assert( doubleEq( corr[5], 55.0 ) ); + assert( doubleEq( corr[6], 40.0 ) ); + assert( doubleEq( corr[7], 26.0 ) ); + assert( doubleEq( corr[8], 14.0 ) ); + assert( doubleEq( corr[9], 5.0 ) ); cout << "." << flush; } +// FIXME: This test is failing on travis. void testSeqSynapse() { int numSyn = 10; int kernelWidth = 5; SeqSynHandler ssh; ssh.vSetNumSynapses( numSyn ); + // for ( int i = 0; i < numSyn; ++i ) // ssh.addSynapse(); + assert( static_cast< int >( ssh.vGetNumSynapses() ) == numSyn ); ssh.setSeqDt( 1.0 ); ssh.setHistoryTime( 5.0 ); @@ -113,11 +170,12 @@ void testSeqSynapse() cout << "." << flush; - ssh.setResponseScale( 1.0 ); + ssh.setBaseScale( 1.0 ); + ssh.setSequenceScale( 1.0 ); for ( int i = 0; i < numSyn; ++i ) { ssh.addSpike( i, 0.0, 1.0 ); } - ssh.setWeightScale( 1.0 ); + ssh.setPlasticityScale( 1.0 ); ProcInfo p; Eref sheller( Id().eref() ); @@ -129,14 +187,13 @@ void testSeqSynapse() // Here we correlate the vector [1,1,1,1,1,1,1,1,1,1,1] with // the kernel [4,1,-1,-1,-1] // Other lines are zeros. - // Should really make the kernel mapping symmetrical. - assert( doubleEq( ssh.getSeqActivation(), 28.0 ) ); + assert( doubleEq( ssh.getSeqActivation(), 14.0 ) ); vector< double > wts = ssh.getWeightScaleVec(); - for ( int i = 0; i < numSyn-4; ++i ) + for ( int i = 2; i < numSyn-2; ++i ) assert( doubleEq( wts[i], 2.0 ) ); - assert( doubleEq( wts[6], 3 ) ); // Edge effects. Last -1 vanishes. - assert( doubleEq( wts[7], 4 ) ); // Edge effects. - assert( doubleEq( wts[8], 5 ) ); // Edge effects. + assert( doubleEq( wts[0], -3 ) ); // Edge effects. + assert( doubleEq( wts[1], -2 ) ); // Edge effects. + assert( doubleEq( wts[8], 3 ) ); // Edge effects. assert( doubleEq( wts[9], 4 ) ); // Edge effects. cout << "." << flush; @@ -150,6 +207,7 @@ void testSynapse() { #ifdef DO_UNIT_TESTS testRollingMatrix(); + testRollingMatrix2(); testSeqSynapse(); #endif // DO_UNIT_TESTS } diff --git a/moose-core/tests/python/test_accessing_existing_paths.py b/moose-core/tests/python/test_accessing_existing_paths.py new file mode 100644 index 0000000000000000000000000000000000000000..769c9a33a0535600b727a3814fe14a32ee9ffd5c --- /dev/null +++ b/moose-core/tests/python/test_accessing_existing_paths.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +import moose +import re + +def fixPath(path): + path = re.sub(r'/+', '/', path) + return path + +paths = [ '/a' + , '//a' + , '/a/b' + , '/a/b/' + , '//a//b/////' + , '/a/./b' + , '///a/././b' + ] +expectedPath = [fixPath(p) for p in paths] + +expectedChanges = zip(paths, expectedPath) + +for p in expectedPath: + print( 'Accessing %s' % p ) + try: + moose.Neutral(p) + except Exception as e: + print( 'Same path access by element' ) + moose.element( p ) + +foundPath = [] +for p in moose.wildcardFind('/##'): + if "/a" in p.path: + foundPath.append(p.path) + +testFailed = False +for f in foundPath: + f = re.sub(r'\[\d+\]', '', f) + if f not in expectedPath: + testFailed = True + +if testFailed: + print("Test failed on paths") diff --git a/moose-core/tests/python/test_paths.py b/moose-core/tests/python/test_paths.py new file mode 100644 index 0000000000000000000000000000000000000000..a9d8bc63abb667014e4a56ff882c6a38847d5c54 --- /dev/null +++ b/moose-core/tests/python/test_paths.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +import moose +import re + +def fixPath(path): + path = re.sub(r'/+', '/', path) + return path + +paths = [ '/a' + , '//a' + , '/a/b' + , '/a/b/' + , '//a//b/////' + , '/a/./b' + , '///a/././b' + ] +expectedPath = [fixPath(p) for p in paths] + +expectedChanges = zip(paths, expectedPath) + +for p in expectedPath: + print( 'Accessing %s' % p ) + try: + moose.Neutral(p) + except Exception as e: + print( 'Same path access by element' ) + moose.element( p ) + +foundPath = [] +for p in moose.wildcardFind('/##'): + if "/a" in p.path: + foundPath.append(p.path) + +testFailed = False +for f in foundPath: + f = re.sub(r'\[\d+\]', '', f) + if f not in expectedPath: + testFailed = True + +if testFailed: + print("Test failed on paths") + +a = moose.Neutral( '/k' ) +b = moose.Neutral( '/k' ) +h = moose.HSolve( '/h' ) +try: + h = moose.Neutral( '/h' ) + print( 'This should have failed' ) + quit(1) +except Exception as e: + print( 'Success' ) diff --git a/moose-core/tests/python/test_sbml.py b/moose-core/tests/python/test_sbml.py index 64b90bfb3dc403f35277cbc9b8bff3161aca8360..0a1eed99f2bceec3dbebbf901ac0e882d0b73028 100644 --- a/moose-core/tests/python/test_sbml.py +++ b/moose-core/tests/python/test_sbml.py @@ -18,14 +18,16 @@ import os import moose import moose.utils as mu +print( 'Using moose form %s' % moose.__file__ ) +print( '\t Moose version %s' % moose.version( ) ) + # the model lives in the same directory as the test script modeldir = os.path.dirname( os.path.realpath( __file__ ) ) def main(): modelname = os.path.join(modeldir, './chem_models/00001-sbml-l3v1.xml' ) model = moose.mooseReadSBML( modelname, '/sbml' ) - print( model ) - c = moose.Clock('/clock') + c = moose.element('/clock') moose.reinit() moose.start(200) check( ) diff --git a/moose-core/tests/python/test_warnigns.py b/moose-core/tests/python/test_warnigns.py new file mode 100644 index 0000000000000000000000000000000000000000..a68ed5e83614d183ddaf7ea176d6ac9952e0bd6a --- /dev/null +++ b/moose-core/tests/python/test_warnigns.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +import moose +print( 'Using moose from %s' % moose.__file__ ) +a = moose.Neutral( '/a' ) +b = moose.Ksolve( '/a/k' ) + +try: + c = moose.Ksolve( '/a/k' ) + d = moose.Neutral( '/a' ) + d = moose.Neutral( '/a' ) + quit(-1) +except Exception as e: + c = moose.element( '/a/k' ) + quit( 0 ) diff --git a/moose-core/utility/print_function.hpp b/moose-core/utility/print_function.hpp index d8f5831f54a12267d19fe0190a2e7ce7f9d9d608..5a1863ad375e33db482ce20e3ad793281c801b30 100644 --- a/moose-core/utility/print_function.hpp +++ b/moose-core/utility/print_function.hpp @@ -195,6 +195,7 @@ namespace moose { if(!reset) ss << T_RESET; cout << ss.str() << endl; + cout.flush( ); } /*