/*
-----------------------------------------------------------------------
Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
2014-2015, CWI, Amsterdam
Contact: astra@uantwerpen.be
Website: http://sf.net/projects/astra-toolbox
This file is part of the ASTRA Toolbox.
The ASTRA Toolbox is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The ASTRA Toolbox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the ASTRA Toolbox. If not, see .
-----------------------------------------------------------------------
$Id$
*/
#ifdef ASTRA_PYTHON
#include "astra/PluginAlgorithm.h"
#include
#include
#include
#include
#include
#include
namespace astra {
CPluginAlgorithm::CPluginAlgorithm(PyObject* pyclass){
instance = PyObject_CallObject(pyclass, NULL);
}
CPluginAlgorithm::~CPluginAlgorithm(){
if(instance!=NULL){
Py_DECREF(instance);
instance = NULL;
}
}
bool CPluginAlgorithm::initialize(const Config& _cfg){
if(instance==NULL) return false;
PyObject *cfgDict = XMLNode2dict(_cfg.self);
PyObject *retVal = PyObject_CallMethod(instance, "astra_init", "O",cfgDict);
Py_DECREF(cfgDict);
if(retVal==NULL) return false;
m_bIsInitialized = true;
Py_DECREF(retVal);
return m_bIsInitialized;
}
void CPluginAlgorithm::run(int _iNrIterations){
if(instance==NULL) return;
PyObject *retVal = PyObject_CallMethod(instance, "astra_run", "i",_iNrIterations);
if(retVal==NULL) return;
Py_DECREF(retVal);
}
void fixLapackLoading(){
// When running in Matlab, we need to force numpy
// to use its internal lapack library instead of
// Matlab's MKL library to avoid errors. To do this,
// we set Python's dlopen flags to RTLD_NOW|RTLD_DEEPBIND
// and import 'numpy.linalg.lapack_lite' here. We reset
// Python's dlopen flags afterwards.
PyObject *sys = PyImport_ImportModule("sys");
if(sys!=NULL){
PyObject *curFlags = PyObject_CallMethod(sys,"getdlopenflags",NULL);
if(curFlags!=NULL){
PyObject *retVal = PyObject_CallMethod(sys, "setdlopenflags", "i",10);
if(retVal!=NULL){
PyObject *lapack = PyImport_ImportModule("numpy.linalg.lapack_lite");
if(lapack!=NULL){
Py_DECREF(lapack);
}
PyObject_CallMethod(sys, "setdlopenflags", "O",curFlags);
Py_DECREF(retVal);
}
Py_DECREF(curFlags);
}
Py_DECREF(sys);
}
}
CPluginAlgorithmFactory::CPluginAlgorithmFactory(){
Py_Initialize();
#ifndef _MSC_VER
if(astra::running_in_matlab) fixLapackLoading();
#endif
pluginDict = PyDict_New();
inspect = PyImport_ImportModule("inspect");
six = PyImport_ImportModule("six");
}
CPluginAlgorithmFactory::~CPluginAlgorithmFactory(){
if(pluginDict!=NULL){
Py_DECREF(pluginDict);
}
if(inspect!=NULL) Py_DECREF(inspect);
if(six!=NULL) Py_DECREF(six);
}
bool CPluginAlgorithmFactory::registerPlugin(std::string name, std::string className){
PyObject *str = PyBytes_FromString(className.c_str());
PyDict_SetItemString(pluginDict, name.c_str(), str);
Py_DECREF(str);
return true;
}
bool CPluginAlgorithmFactory::registerPluginClass(std::string name, PyObject * className){
PyDict_SetItemString(pluginDict, name.c_str(), className);
return true;
}
PyObject * getClassFromString(std::string str){
std::vector items;
boost::split(items, str, boost::is_any_of("."));
PyObject *pyclass = PyImport_ImportModule(items[0].c_str());
if(pyclass==NULL) return NULL;
PyObject *submod = pyclass;
for(unsigned int i=1;i= 3
PyObject * pyStringFromString(std::string str){
return PyUnicode_FromString(str.c_str());
}
#else
PyObject * pyStringFromString(std::string str){
return PyBytes_FromString(str.c_str());
}
#endif
PyObject* stringToPythonValue(std::string str){
if(str.find(";")!=std::string::npos){
std::vector rows, row;
boost::split(rows, str, boost::is_any_of(";"));
PyObject *mat = PyList_New(rows.size());
for(unsigned int i=0; i(row[j])));
}
PyList_SetItem(mat, i, rowlist);
}
return mat;
}
if(str.find(",")!=std::string::npos){
std::vector vec;
boost::split(vec, str, boost::is_any_of(","));
PyObject *veclist = PyList_New(vec.size());
for(unsigned int i=0;i(vec[i])));
}
return veclist;
}
try{
return PyLong_FromLong(boost::lexical_cast(str));
}catch(const boost::bad_lexical_cast &){
try{
return PyFloat_FromDouble(boost::lexical_cast(str));
}catch(const boost::bad_lexical_cast &){
return pyStringFromString(str);
}
}
}
PyObject* XMLNode2dict(XMLNode node){
PyObject *dct = PyDict_New();
PyObject *opts = PyDict_New();
if(node.hasAttribute("type")){
PyObject *obj = pyStringFromString(node.getAttribute("type").c_str());
PyDict_SetItemString(dct, "type", obj);
Py_DECREF(obj);
}
std::list nodes = node.getNodes();
std::list::iterator it = nodes.begin();
while(it!=nodes.end()){
XMLNode subnode = *it;
if(subnode.getName()=="Option"){
PyObject *obj;
if(subnode.hasAttribute("value")){
obj = stringToPythonValue(subnode.getAttribute("value"));
}else{
obj = stringToPythonValue(subnode.getContent());
}
PyDict_SetItemString(opts, subnode.getAttribute("key").c_str(), obj);
Py_DECREF(obj);
}else{
PyObject *obj = stringToPythonValue(subnode.getContent());
PyDict_SetItemString(dct, subnode.getName().c_str(), obj);
Py_DECREF(obj);
}
++it;
}
PyDict_SetItemString(dct, "options", opts);
Py_DECREF(opts);
return dct;
}
}
#endif