summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWillem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>2016-03-01 14:47:43 +0100
committerWillem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>2016-03-01 14:47:43 +0100
commit0db21a84dd3cb0f6a78bd462a4a60a4b4a3c6fae (patch)
treea833d4787504e8612282a82c60d3984be51bdffe /src
parentda11f9e7c7559eb01cc422ac55c9f7a1cd4bb803 (diff)
parentb74e64aef7845666d27cbf7e876a6a360eefed7f (diff)
downloadastra-0db21a84dd3cb0f6a78bd462a4a60a4b4a3c6fae.tar.gz
astra-0db21a84dd3cb0f6a78bd462a4a60a4b4a3c6fae.tar.bz2
astra-0db21a84dd3cb0f6a78bd462a4a60a4b4a3c6fae.tar.xz
astra-0db21a84dd3cb0f6a78bd462a4a60a4b4a3c6fae.zip
Merge branch 'master' into indexmanager
Diffstat (limited to 'src')
-rw-r--r--src/CompositeGeometryManager.cpp272
-rw-r--r--src/PluginAlgorithm.cpp367
2 files changed, 250 insertions, 389 deletions
diff --git a/src/CompositeGeometryManager.cpp b/src/CompositeGeometryManager.cpp
index 96b28e9..c9cbaaa 100644
--- a/src/CompositeGeometryManager.cpp
+++ b/src/CompositeGeometryManager.cpp
@@ -45,14 +45,15 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
#include <cstring>
#include <sstream>
+#include <stdint.h>
#ifndef USE_PTHREADS
#include <boost/thread/mutex.hpp>
#include <boost/thread.hpp>
#endif
-namespace astra {
+namespace astra {
SGPUParams* CCompositeGeometryManager::s_params = 0;
@@ -98,6 +99,9 @@ CCompositeGeometryManager::CCompositeGeometryManager()
bool CCompositeGeometryManager::splitJobs(TJobSet &jobs, size_t maxSize, int div, TJobSet &split)
{
+ int maxBlockDim = astraCUDA3d::maxBlockDimension();
+ ASTRA_DEBUG("Found max block dim %d", maxBlockDim);
+
split.clear();
for (TJobSet::const_iterator i = jobs.begin(); i != jobs.end(); ++i)
@@ -111,7 +115,22 @@ bool CCompositeGeometryManager::splitJobs(TJobSet &jobs, size_t maxSize, int div
// b. split input part
// c. create jobs for new (input,output) subparts
- TPartList splitOutput = pOutput->split(maxSize/3, div);
+ TPartList splitOutput;
+ pOutput->splitZ(splitOutput, maxSize/3, SIZE_MAX, div);
+#if 0
+ TPartList splitOutput2;
+ for (TPartList::iterator i_out = splitOutput.begin(); i_out != splitOutput.end(); ++i_out) {
+ boost::shared_ptr<CPart> outputPart = *i_out;
+ outputPart.get()->splitX(splitOutput2, SIZE_MAX, SIZE_MAX, 1);
+ }
+ splitOutput.clear();
+ for (TPartList::iterator i_out = splitOutput2.begin(); i_out != splitOutput2.end(); ++i_out) {
+ boost::shared_ptr<CPart> outputPart = *i_out;
+ outputPart.get()->splitY(splitOutput, SIZE_MAX, SIZE_MAX, 1);
+ }
+ splitOutput2.clear();
+#endif
+
for (TJobList::const_iterator j = L.begin(); j != L.end(); ++j)
{
@@ -139,8 +158,21 @@ bool CCompositeGeometryManager::splitJobs(TJobSet &jobs, size_t maxSize, int div
size_t remainingSize = ( maxSize - outputPart->getSize() ) / 2;
- TPartList splitInput = input->split(remainingSize, 1);
+ TPartList splitInput;
+ input->splitZ(splitInput, remainingSize, maxBlockDim, 1);
delete input;
+ TPartList splitInput2;
+ for (TPartList::iterator i_in = splitInput.begin(); i_in != splitInput.end(); ++i_in) {
+ boost::shared_ptr<CPart> inputPart = *i_in;
+ inputPart.get()->splitX(splitInput2, SIZE_MAX, maxBlockDim, 1);
+ }
+ splitInput.clear();
+ for (TPartList::iterator i_in = splitInput2.begin(); i_in != splitInput2.end(); ++i_in) {
+ boost::shared_ptr<CPart> inputPart = *i_in;
+ inputPart.get()->splitY(splitInput, SIZE_MAX, maxBlockDim, 1);
+ }
+ splitInput2.clear();
+
ASTRA_DEBUG("Input split into %d parts", splitInput.size());
for (TPartList::iterator i_in = splitInput.begin();
@@ -327,10 +359,14 @@ static size_t ceildiv(size_t a, size_t b) {
return (a + b - 1) / b;
}
-static size_t computeVerticalSplit(size_t maxBlock, int div, size_t sliceCount)
+static size_t computeLinearSplit(size_t maxBlock, int div, size_t sliceCount)
{
size_t blockSize = maxBlock;
- size_t blockCount = ceildiv(sliceCount, blockSize);
+ size_t blockCount;
+ if (sliceCount <= blockSize)
+ blockCount = 1;
+ else
+ blockCount = ceildiv(sliceCount, blockSize);
// Increase number of blocks to be divisible by div
size_t divCount = div * ceildiv(blockCount, div);
@@ -410,7 +446,17 @@ SPar3DProjection* getProjectionVectors(const CParallelVecProjectionGeometry3D* p
template<class V>
-static void translateProjectionVectors(V* pProjs, int count, double dv)
+static void translateProjectionVectorsU(V* pProjs, int count, double du)
+{
+ for (int i = 0; i < count; ++i) {
+ pProjs[i].fDetSX += du * pProjs[i].fDetUX;
+ pProjs[i].fDetSY += du * pProjs[i].fDetUY;
+ pProjs[i].fDetSZ += du * pProjs[i].fDetUZ;
+ }
+}
+
+template<class V>
+static void translateProjectionVectorsV(V* pProjs, int count, double dv)
{
for (int i = 0; i < count; ++i) {
pProjs[i].fDetSX += dv * pProjs[i].fDetVX;
@@ -420,8 +466,58 @@ static void translateProjectionVectors(V* pProjs, int count, double dv)
}
+static CProjectionGeometry3D* getSubProjectionGeometryU(const CProjectionGeometry3D* pProjGeom, int u, int size)
+{
+ // First convert to vectors, then translate, then convert into new object
-static CProjectionGeometry3D* getSubProjectionGeometry(const CProjectionGeometry3D* pProjGeom, int v, int size)
+ const CConeProjectionGeometry3D* conegeom = dynamic_cast<const CConeProjectionGeometry3D*>(pProjGeom);
+ const CParallelProjectionGeometry3D* par3dgeom = dynamic_cast<const CParallelProjectionGeometry3D*>(pProjGeom);
+ const CParallelVecProjectionGeometry3D* parvec3dgeom = dynamic_cast<const CParallelVecProjectionGeometry3D*>(pProjGeom);
+ const CConeVecProjectionGeometry3D* conevec3dgeom = dynamic_cast<const CConeVecProjectionGeometry3D*>(pProjGeom);
+
+ if (conegeom || conevec3dgeom) {
+ SConeProjection* pConeProjs;
+ if (conegeom) {
+ pConeProjs = getProjectionVectors<SConeProjection>(conegeom);
+ } else {
+ pConeProjs = getProjectionVectors<SConeProjection>(conevec3dgeom);
+ }
+
+ translateProjectionVectorsU(pConeProjs, pProjGeom->getProjectionCount(), u);
+
+ CProjectionGeometry3D* ret = new CConeVecProjectionGeometry3D(pProjGeom->getProjectionCount(),
+ pProjGeom->getDetectorRowCount(),
+ size,
+ pConeProjs);
+
+
+ delete[] pConeProjs;
+ return ret;
+ } else {
+ assert(par3dgeom || parvec3dgeom);
+ SPar3DProjection* pParProjs;
+ if (par3dgeom) {
+ pParProjs = getProjectionVectors<SPar3DProjection>(par3dgeom);
+ } else {
+ pParProjs = getProjectionVectors<SPar3DProjection>(parvec3dgeom);
+ }
+
+ translateProjectionVectorsU(pParProjs, pProjGeom->getProjectionCount(), u);
+
+ CProjectionGeometry3D* ret = new CParallelVecProjectionGeometry3D(pProjGeom->getProjectionCount(),
+ pProjGeom->getDetectorRowCount(),
+ size,
+ pParProjs);
+
+ delete[] pParProjs;
+ return ret;
+ }
+
+}
+
+
+
+static CProjectionGeometry3D* getSubProjectionGeometryV(const CProjectionGeometry3D* pProjGeom, int v, int size)
{
// First convert to vectors, then translate, then convert into new object
@@ -438,7 +534,7 @@ static CProjectionGeometry3D* getSubProjectionGeometry(const CProjectionGeometry
pConeProjs = getProjectionVectors<SConeProjection>(conevec3dgeom);
}
- translateProjectionVectors(pConeProjs, pProjGeom->getProjectionCount(), v);
+ translateProjectionVectorsV(pConeProjs, pProjGeom->getProjectionCount(), v);
CProjectionGeometry3D* ret = new CConeVecProjectionGeometry3D(pProjGeom->getProjectionCount(),
size,
@@ -457,7 +553,7 @@ static CProjectionGeometry3D* getSubProjectionGeometry(const CProjectionGeometry
pParProjs = getProjectionVectors<SPar3DProjection>(parvec3dgeom);
}
- translateProjectionVectors(pParProjs, pProjGeom->getProjectionCount(), v);
+ translateProjectionVectorsV(pParProjs, pProjGeom->getProjectionCount(), v);
CProjectionGeometry3D* ret = new CParallelVecProjectionGeometry3D(pProjGeom->getProjectionCount(),
size,
@@ -476,17 +572,110 @@ static CProjectionGeometry3D* getSubProjectionGeometry(const CProjectionGeometry
// - each no bigger than maxSize
// - number of sub-parts is divisible by div
// - maybe all approximately the same size?
-CCompositeGeometryManager::TPartList CCompositeGeometryManager::CVolumePart::split(size_t maxSize, int div)
+void CCompositeGeometryManager::CVolumePart::splitX(CCompositeGeometryManager::TPartList& out, size_t maxSize, size_t maxDim, int div)
+{
+ if (true) {
+ // Split in vertical direction only at first, until we figure out
+ // a model for splitting in other directions
+
+ size_t sliceSize = ((size_t) pGeom->getGridSliceCount()) * pGeom->getGridRowCount();
+ int sliceCount = pGeom->getGridColCount();
+ size_t m = std::min(maxSize / sliceSize, maxDim);
+ size_t blockSize = computeLinearSplit(m, div, sliceCount);
+
+ int rem = sliceCount % blockSize;
+
+ ASTRA_DEBUG("From %d to %d step %d", -(rem / 2), sliceCount, blockSize);
+
+ for (int x = -(rem / 2); x < sliceCount; x += blockSize) {
+ int newsubX = x;
+ if (newsubX < 0) newsubX = 0;
+ int endX = x + blockSize;
+ if (endX > sliceCount) endX = sliceCount;
+ int size = endX - newsubX;
+
+ CVolumePart *sub = new CVolumePart();
+ sub->subX = this->subX + newsubX;
+ sub->subY = this->subY;
+ sub->subZ = this->subZ;
+
+ ASTRA_DEBUG("VolumePart split %d %d %d -> %p", sub->subX, sub->subY, sub->subZ, (void*)sub);
+
+ double shift = pGeom->getPixelLengthX() * newsubX;
+
+ sub->pData = pData;
+ sub->pGeom = new CVolumeGeometry3D(size,
+ pGeom->getGridRowCount(),
+ pGeom->getGridSliceCount(),
+ pGeom->getWindowMinX() + shift,
+ pGeom->getWindowMinY(),
+ pGeom->getWindowMinZ(),
+ pGeom->getWindowMinX() + shift + size * pGeom->getPixelLengthX(),
+ pGeom->getWindowMaxY(),
+ pGeom->getWindowMaxZ());
+
+ out.push_back(boost::shared_ptr<CPart>(sub));
+ }
+ }
+}
+
+void CCompositeGeometryManager::CVolumePart::splitY(CCompositeGeometryManager::TPartList& out, size_t maxSize, size_t maxDim, int div)
{
- TPartList ret;
+ if (true) {
+ // Split in vertical direction only at first, until we figure out
+ // a model for splitting in other directions
+
+ size_t sliceSize = ((size_t) pGeom->getGridColCount()) * pGeom->getGridSliceCount();
+ int sliceCount = pGeom->getGridRowCount();
+ size_t m = std::min(maxSize / sliceSize, maxDim);
+ size_t blockSize = computeLinearSplit(m, div, sliceCount);
+
+ int rem = sliceCount % blockSize;
+
+ ASTRA_DEBUG("From %d to %d step %d", -(rem / 2), sliceCount, blockSize);
+
+ for (int y = -(rem / 2); y < sliceCount; y += blockSize) {
+ int newsubY = y;
+ if (newsubY < 0) newsubY = 0;
+ int endY = y + blockSize;
+ if (endY > sliceCount) endY = sliceCount;
+ int size = endY - newsubY;
+ CVolumePart *sub = new CVolumePart();
+ sub->subX = this->subX;
+ sub->subY = this->subY + newsubY;
+ sub->subZ = this->subZ;
+
+ ASTRA_DEBUG("VolumePart split %d %d %d -> %p", sub->subX, sub->subY, sub->subZ, (void*)sub);
+
+ double shift = pGeom->getPixelLengthY() * newsubY;
+
+ sub->pData = pData;
+ sub->pGeom = new CVolumeGeometry3D(pGeom->getGridColCount(),
+ size,
+ pGeom->getGridSliceCount(),
+ pGeom->getWindowMinX(),
+ pGeom->getWindowMinY() + shift,
+ pGeom->getWindowMinZ(),
+ pGeom->getWindowMaxX(),
+ pGeom->getWindowMinY() + shift + size * pGeom->getPixelLengthY(),
+ pGeom->getWindowMaxZ());
+
+ out.push_back(boost::shared_ptr<CPart>(sub));
+ }
+ }
+}
+
+void CCompositeGeometryManager::CVolumePart::splitZ(CCompositeGeometryManager::TPartList& out, size_t maxSize, size_t maxDim, int div)
+{
if (true) {
// Split in vertical direction only at first, until we figure out
// a model for splitting in other directions
size_t sliceSize = ((size_t) pGeom->getGridColCount()) * pGeom->getGridRowCount();
int sliceCount = pGeom->getGridSliceCount();
- size_t blockSize = computeVerticalSplit(maxSize / sliceSize, div, sliceCount);
+ size_t m = std::min(maxSize / sliceSize, maxDim);
+ size_t blockSize = computeLinearSplit(m, div, sliceCount);
int rem = sliceCount % blockSize;
@@ -519,11 +708,9 @@ CCompositeGeometryManager::TPartList CCompositeGeometryManager::CVolumePart::spl
pGeom->getWindowMaxY(),
pGeom->getWindowMinZ() + shift + size * pGeom->getPixelLengthZ());
- ret.push_back(boost::shared_ptr<CPart>(sub));
+ out.push_back(boost::shared_ptr<CPart>(sub));
}
}
-
- return ret;
}
CCompositeGeometryManager::CVolumePart* CCompositeGeometryManager::CVolumePart::clone() const
@@ -630,7 +817,7 @@ CCompositeGeometryManager::CPart* CCompositeGeometryManager::CProjectionPart::re
if (_vmin == _vmax) {
sub->pGeom = 0;
} else {
- sub->pGeom = getSubProjectionGeometry(pGeom, _vmin, _vmax - _vmin);
+ sub->pGeom = getSubProjectionGeometryV(pGeom, _vmin, _vmax - _vmin);
}
ASTRA_DEBUG("Reduce projection from %d - %d to %d - %d", this->subZ, this->subZ + pGeom->getDetectorRowCount(), this->subZ + _vmin, this->subZ + _vmax);
@@ -639,17 +826,58 @@ CCompositeGeometryManager::CPart* CCompositeGeometryManager::CProjectionPart::re
}
-CCompositeGeometryManager::TPartList CCompositeGeometryManager::CProjectionPart::split(size_t maxSize, int div)
+void CCompositeGeometryManager::CProjectionPart::splitX(CCompositeGeometryManager::TPartList &out, size_t maxSize, size_t maxDim, int div)
+{
+ if (true) {
+ // Split in vertical direction only at first, until we figure out
+ // a model for splitting in other directions
+
+ size_t sliceSize = ((size_t) pGeom->getDetectorRowCount()) * pGeom->getProjectionCount();
+ int sliceCount = pGeom->getDetectorColCount();
+ size_t m = std::min(maxSize / sliceSize, maxDim);
+ size_t blockSize = computeLinearSplit(m, div, sliceCount);
+
+ int rem = sliceCount % blockSize;
+
+ for (int x = -(rem / 2); x < sliceCount; x += blockSize) {
+ int newsubX = x;
+ if (newsubX < 0) newsubX = 0;
+ int endX = x + blockSize;
+ if (endX > sliceCount) endX = sliceCount;
+ int size = endX - newsubX;
+
+ CProjectionPart *sub = new CProjectionPart();
+ sub->subX = this->subX + newsubX;
+ sub->subY = this->subY;
+ sub->subZ = this->subZ;
+
+ ASTRA_DEBUG("ProjectionPart split %d %d %d -> %p", sub->subX, sub->subY, sub->subZ, (void*)sub);
+
+ sub->pData = pData;
+
+ sub->pGeom = getSubProjectionGeometryU(pGeom, newsubX, size);
+
+ out.push_back(boost::shared_ptr<CPart>(sub));
+ }
+ }
+}
+
+void CCompositeGeometryManager::CProjectionPart::splitY(CCompositeGeometryManager::TPartList &out, size_t maxSize, size_t maxDim, int div)
{
- TPartList ret;
+ // TODO
+ out.push_back(boost::shared_ptr<CPart>(clone()));
+}
+void CCompositeGeometryManager::CProjectionPart::splitZ(CCompositeGeometryManager::TPartList &out, size_t maxSize, size_t maxDim, int div)
+{
if (true) {
// Split in vertical direction only at first, until we figure out
// a model for splitting in other directions
size_t sliceSize = ((size_t) pGeom->getDetectorColCount()) * pGeom->getProjectionCount();
int sliceCount = pGeom->getDetectorRowCount();
- size_t blockSize = computeVerticalSplit(maxSize / sliceSize, div, sliceCount);
+ size_t m = std::min(maxSize / sliceSize, maxDim);
+ size_t blockSize = computeLinearSplit(m, div, sliceCount);
int rem = sliceCount % blockSize;
@@ -669,14 +897,12 @@ CCompositeGeometryManager::TPartList CCompositeGeometryManager::CProjectionPart:
sub->pData = pData;
- sub->pGeom = getSubProjectionGeometry(pGeom, newsubZ, size);
+ sub->pGeom = getSubProjectionGeometryV(pGeom, newsubZ, size);
- ret.push_back(boost::shared_ptr<CPart>(sub));
+ out.push_back(boost::shared_ptr<CPart>(sub));
}
}
- return ret;
-
}
CCompositeGeometryManager::CProjectionPart* CCompositeGeometryManager::CProjectionPart::clone() const
diff --git a/src/PluginAlgorithm.cpp b/src/PluginAlgorithm.cpp
index 9fc511a..1bcfbdb 100644
--- a/src/PluginAlgorithm.cpp
+++ b/src/PluginAlgorithm.cpp
@@ -26,376 +26,11 @@ along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
$Id$
*/
-#ifdef ASTRA_PYTHON
-
#include "astra/PluginAlgorithm.h"
-#include "astra/Logging.h"
-#include "astra/Utilities.h"
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <iostream>
-#include <fstream>
-#include <string>
-
-#include <Python.h>
-#include "bytesobject.h"
namespace astra {
+CPluginAlgorithmFactory *CPluginAlgorithmFactory::m_factory = 0;
-
-void logPythonError(){
- if(PyErr_Occurred()){
- PyObject *ptype, *pvalue, *ptraceback;
- PyErr_Fetch(&ptype, &pvalue, &ptraceback);
- PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
- PyObject *traceback = PyImport_ImportModule("traceback");
- if(traceback!=NULL){
- PyObject *exc;
- if(ptraceback==NULL){
- exc = PyObject_CallMethod(traceback,"format_exception_only","OO",ptype, pvalue);
- }else{
- exc = PyObject_CallMethod(traceback,"format_exception","OOO",ptype, pvalue, ptraceback);
- }
- if(exc!=NULL){
- PyObject *six = PyImport_ImportModule("six");
- if(six!=NULL){
- PyObject *iter = PyObject_GetIter(exc);
- if(iter!=NULL){
- PyObject *line;
- std::string errStr = "";
- while(line = PyIter_Next(iter)){
- PyObject *retb = PyObject_CallMethod(six,"b","O",line);
- if(retb!=NULL){
- errStr += std::string(PyBytes_AsString(retb));
- Py_DECREF(retb);
- }
- Py_DECREF(line);
- }
- ASTRA_ERROR("%s",errStr.c_str());
- Py_DECREF(iter);
- }
- Py_DECREF(six);
- }
- Py_DECREF(exc);
- }
- Py_DECREF(traceback);
- }
- if(ptype!=NULL) Py_DECREF(ptype);
- if(pvalue!=NULL) Py_DECREF(pvalue);
- if(ptraceback!=NULL) Py_DECREF(ptraceback);
- }
-}
-
-
-CPluginAlgorithm::CPluginAlgorithm(PyObject* pyclass){
- instance = PyObject_CallObject(pyclass, NULL);
- if(instance==NULL) logPythonError();
-}
-
-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){
- logPythonError();
- return false;
- }
- m_bIsInitialized = true;
- Py_DECREF(retVal);
- return m_bIsInitialized;
-}
-
-void CPluginAlgorithm::run(int _iNrIterations){
- if(instance==NULL) return;
- PyGILState_STATE state = PyGILState_Ensure();
- PyObject *retVal = PyObject_CallMethod(instance, "run", "i",_iNrIterations);
- if(retVal==NULL){
- logPythonError();
- }else{
- Py_DECREF(retVal);
- }
- PyGILState_Release(state);
}
-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(){
- if(!Py_IsInitialized()){
- Py_Initialize();
- PyEval_InitThreads();
- }
-#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);
-}
-
-PyObject * getClassFromString(std::string str){
- std::vector<std::string> items;
- boost::split(items, str, boost::is_any_of("."));
- PyObject *pyclass = PyImport_ImportModule(items[0].c_str());
- if(pyclass==NULL){
- logPythonError();
- return NULL;
- }
- PyObject *submod = pyclass;
- for(unsigned int i=1;i<items.size();i++){
- submod = PyObject_GetAttrString(submod,items[i].c_str());
- Py_DECREF(pyclass);
- pyclass = submod;
- if(pyclass==NULL){
- logPythonError();
- return NULL;
- }
- }
- return pyclass;
-}
-
-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::registerPlugin(std::string className){
- PyObject *pyclass = getClassFromString(className);
- if(pyclass==NULL) return false;
- bool ret = registerPluginClass(pyclass);
- Py_DECREF(pyclass);
- return ret;
-}
-
-bool CPluginAlgorithmFactory::registerPluginClass(std::string name, PyObject * className){
- PyDict_SetItemString(pluginDict, name.c_str(), className);
- return true;
-}
-
-bool CPluginAlgorithmFactory::registerPluginClass(PyObject * className){
- PyObject *astra_name = PyObject_GetAttrString(className,"astra_name");
- if(astra_name==NULL){
- logPythonError();
- return false;
- }
- PyObject *retb = PyObject_CallMethod(six,"b","O",astra_name);
- if(retb!=NULL){
- PyDict_SetItemString(pluginDict,PyBytes_AsString(retb),className);
- Py_DECREF(retb);
- }else{
- logPythonError();
- }
- Py_DECREF(astra_name);
- return true;
-}
-
-CPluginAlgorithm * CPluginAlgorithmFactory::getPlugin(std::string name){
- PyObject *className = PyDict_GetItemString(pluginDict, name.c_str());
- if(className==NULL) return NULL;
- CPluginAlgorithm *alg = NULL;
- if(PyBytes_Check(className)){
- std::string str = std::string(PyBytes_AsString(className));
- PyObject *pyclass = getClassFromString(str);
- if(pyclass!=NULL){
- alg = new CPluginAlgorithm(pyclass);
- Py_DECREF(pyclass);
- }
- }else{
- alg = new CPluginAlgorithm(className);
- }
- return alg;
-}
-
-PyObject * CPluginAlgorithmFactory::getRegistered(){
- Py_INCREF(pluginDict);
- return pluginDict;
-}
-
-std::map<std::string, std::string> CPluginAlgorithmFactory::getRegisteredMap(){
- std::map<std::string, std::string> ret;
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(pluginDict, &pos, &key, &value)) {
- PyObject *keystr = PyObject_Str(key);
- if(keystr!=NULL){
- PyObject *valstr = PyObject_Str(value);
- if(valstr!=NULL){
- PyObject * keyb = PyObject_CallMethod(six,"b","O",keystr);
- if(keyb!=NULL){
- PyObject * valb = PyObject_CallMethod(six,"b","O",valstr);
- if(valb!=NULL){
- ret[PyBytes_AsString(keyb)] = PyBytes_AsString(valb);
- Py_DECREF(valb);
- }
- Py_DECREF(keyb);
- }
- Py_DECREF(valstr);
- }
- Py_DECREF(keystr);
- }
- logPythonError();
- }
- return ret;
-}
-
-std::string CPluginAlgorithmFactory::getHelp(std::string name){
- PyObject *className = PyDict_GetItemString(pluginDict, name.c_str());
- if(className==NULL){
- ASTRA_ERROR("Plugin %s not found!",name.c_str());
- PyErr_Clear();
- return "";
- }
- std::string ret = "";
- PyObject *pyclass;
- if(PyBytes_Check(className)){
- std::string str = std::string(PyBytes_AsString(className));
- pyclass = getClassFromString(str);
- }else{
- pyclass = className;
- }
- if(pyclass==NULL) return "";
- if(inspect!=NULL && six!=NULL){
- PyObject *retVal = PyObject_CallMethod(inspect,"getdoc","O",pyclass);
- if(retVal!=NULL){
- if(retVal!=Py_None){
- PyObject *retb = PyObject_CallMethod(six,"b","O",retVal);
- if(retb!=NULL){
- ret = std::string(PyBytes_AsString(retb));
- Py_DECREF(retb);
- }
- }
- Py_DECREF(retVal);
- }else{
- logPythonError();
- }
- }
- if(PyBytes_Check(className)){
- Py_DECREF(pyclass);
- }
- return ret;
-}
-
-DEFINE_SINGLETON(CPluginAlgorithmFactory);
-
-#if PY_MAJOR_VERSION >= 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<std::string> rows, row;
- boost::split(rows, str, boost::is_any_of(";"));
- PyObject *mat = PyList_New(rows.size());
- for(unsigned int i=0; i<rows.size(); i++){
- boost::split(row, rows[i], boost::is_any_of(","));
- PyObject *rowlist = PyList_New(row.size());
- for(unsigned int j=0;j<row.size();j++){
- PyList_SetItem(rowlist, j, PyFloat_FromDouble(StringUtil::stringToDouble(row[j])));
- }
- PyList_SetItem(mat, i, rowlist);
- }
- return mat;
- }
- if(str.find(",")!=std::string::npos){
- std::vector<std::string> vec;
- boost::split(vec, str, boost::is_any_of(","));
- PyObject *veclist = PyList_New(vec.size());
- for(unsigned int i=0;i<vec.size();i++){
- PyList_SetItem(veclist, i, PyFloat_FromDouble(StringUtil::stringToDouble(vec[i])));
- }
- return veclist;
- }
- try{
- return PyLong_FromLong(StringUtil::stringToInt(str));
- }catch(const StringUtil::bad_cast &){
- try{
- return PyFloat_FromDouble(StringUtil::stringToDouble(str));
- }catch(const StringUtil::bad_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<XMLNode> nodes = node.getNodes();
- std::list<XMLNode>::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