From ba3629c6c1bc1d03ccdc6ef2aeae6872ea59559f Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Sat, 20 Jun 2015 00:33:23 +0200 Subject: Fix matlab compilation without CUDA --- matlab/mex/astra_mex_c.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp index 4a331f5..a9b9654 100644 --- a/matlab/mex/astra_mex_c.cpp +++ b/matlab/mex/astra_mex_c.cpp @@ -36,9 +36,9 @@ $Id$ #include "mexInitFunctions.h" #include "astra/Globals.h" - +#ifdef ASTRA_CUDA #include "../cuda/2d/darthelper.h" - +#endif using namespace std; using namespace astra; -- cgit v1.2.3 From f6b6a2f84806a89fe6bacc583e13cb14629fb5dc Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Sat, 20 Jun 2015 00:35:16 +0200 Subject: Actually use the rec_type argument in astra_create_reconstruction_cuda --- matlab/tools/astra_create_reconstruction_cuda.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'matlab') diff --git a/matlab/tools/astra_create_reconstruction_cuda.m b/matlab/tools/astra_create_reconstruction_cuda.m index 7d9e1dd..7d0421c 100644 --- a/matlab/tools/astra_create_reconstruction_cuda.m +++ b/matlab/tools/astra_create_reconstruction_cuda.m @@ -45,7 +45,7 @@ if strcmp(rec_type,'') end % configure -cfg = astra_struct('SIRT_CUDA'); +cfg = astra_struct(rec_type); cfg.ProjectionGeometry = proj_geom; cfg.ReconstructionGeometry = vol_geom; cfg.ProjectionDataId = sinogram_id; -- cgit v1.2.3 From 63d78fbaafa7d247347f9052db86f575d89260b7 Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Wed, 24 Jun 2015 20:28:46 +0200 Subject: Fix config to struct/dict translation for array options --- matlab/mex/mexHelpFunctions.cpp | 6 +++++- python/astra/utils.pyx | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp index 87a9672..58e84d2 100644 --- a/matlab/mex/mexHelpFunctions.cpp +++ b/matlab/mex/mexHelpFunctions.cpp @@ -336,7 +336,11 @@ mxArray* XMLNodeToStruct(astra::XMLNode node) // option if (subnode.getName() == "Option") { - mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getAttribute("value")); + if(subnode.hasAttribute("value")){ + mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getAttribute("value")); + }else{ + mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getContent()); + } } // regular content diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx index a8e9e4e..260c308 100644 --- a/python/astra/utils.pyx +++ b/python/astra/utils.pyx @@ -204,7 +204,10 @@ cdef XMLNode2dict(XMLNode node): while it != nodes.end(): subnode = deref(it) if castString(subnode.getName())=="Option": - opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getAttribute('value')) + if subnode.hasAttribute('value'): + opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getAttribute('value')) + else: + opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getContent()) else: dct[castString(subnode.getName())] = stringToPythonValue(subnode.getContent()) inc(it) -- cgit v1.2.3 From 9e3472ea9041b8755050427d8bdb8a4701019c55 Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Thu, 25 Jun 2015 21:52:07 +0200 Subject: Fix memory leak in configuration code --- matlab/mex/astra_mex_projector3d_c.cpp | 8 ++++++-- matlab/mex/astra_mex_projector_c.cpp | 9 ++++++--- python/astra/projector3d_c.pyx | 10 ++++++++-- python/astra/projector_c.pyx | 10 ++++++++-- 4 files changed, 28 insertions(+), 9 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp index c3b547f..e25802c 100644 --- a/matlab/mex/astra_mex_projector3d_c.cpp +++ b/matlab/mex/astra_mex_projector3d_c.cpp @@ -137,7 +137,9 @@ void astra_mex_projector3d_get_projection_geometry(int nlhs, mxArray* plhs[], in // step3: get projection_geometry and turn it into a MATLAB struct if (1 <= nlhs) { - plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration()); + Config *cfg = pProjector->getProjectionGeometry()->getConfiguration(); + plhs[0] = configToStruct(cfg); + delete cfg; } } @@ -163,7 +165,9 @@ void astra_mex_projector3d_get_volume_geometry(int nlhs, mxArray* plhs[], int nr // step3: get projection_geometry and turn it into a MATLAB struct if (1 <= nlhs) { - plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration()); + Config *cfg = pProjector->getVolumeGeometry()->getConfiguration(); + plhs[0] = configToStruct(cfg); + delete cfg; } } diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp index 204ba8e..bf701af 100644 --- a/matlab/mex/astra_mex_projector_c.cpp +++ b/matlab/mex/astra_mex_projector_c.cpp @@ -160,7 +160,9 @@ void astra_mex_projector_projection_geometry(int nlhs, mxArray* plhs[], int nrhs // step3: get projection_geometry and turn it into a MATLAB struct if (1 <= nlhs) { - plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration()); + Config *cfg = pProjector->getProjectionGeometry()->getConfiguration(); + plhs[0] = configToStruct(cfg); + delete cfg; } } @@ -189,8 +191,9 @@ void astra_mex_projector_volume_geometry(int nlhs, mxArray* plhs[], int nrhs, co // step3: get projection_geometry and turn it into a MATLAB struct if (1 <= nlhs) { - plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration()); - + Config *cfg = pProjector->getVolumeGeometry()->getConfiguration(); + plhs[0] = configToStruct(cfg); + delete cfg; } } diff --git a/python/astra/projector3d_c.pyx b/python/astra/projector3d_c.pyx index 8b978d7..aec9cde 100644 --- a/python/astra/projector3d_c.pyx +++ b/python/astra/projector3d_c.pyx @@ -87,12 +87,18 @@ cdef CProjector3D * getObject(i) except NULL: def projection_geometry(i): cdef CProjector3D * proj = getObject(i) - return utils.configToDict(proj.getProjectionGeometry().getConfiguration()) + cdef Config * cfg = proj.getProjectionGeometry().getConfiguration() + dct = utils.configToDict(cfg) + del cfg + return dct def volume_geometry(i): cdef CProjector3D * proj = getObject(i) - return utils.configToDict(proj.getVolumeGeometry().getConfiguration()) + cdef Config * cfg = proj.getVolumeGeometry().getConfiguration() + dct = utils.configToDict(cfg) + del cfg + return dct def weights_single_ray(i, projection_index, detector_index): diff --git a/python/astra/projector_c.pyx b/python/astra/projector_c.pyx index 9aa868e..77c64a4 100644 --- a/python/astra/projector_c.pyx +++ b/python/astra/projector_c.pyx @@ -91,12 +91,18 @@ cdef CProjector2D * getObject(i) except NULL: def projection_geometry(i): cdef CProjector2D * proj = getObject(i) - return utils.configToDict(proj.getProjectionGeometry().getConfiguration()) + cdef Config * cfg = proj.getProjectionGeometry().getConfiguration() + dct = utils.configToDict(cfg) + del cfg + return dct def volume_geometry(i): cdef CProjector2D * proj = getObject(i) - return utils.configToDict(proj.getVolumeGeometry().getConfiguration()) + cdef Config * cfg = proj.getVolumeGeometry().getConfiguration() + dct = utils.configToDict(cfg) + del cfg + return dct def weights_single_ray(i, projection_index, detector_index): -- cgit v1.2.3 From 4d39c35d6c9124c26de64c9d227a25f612903a2a Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Fri, 17 Jul 2015 13:44:59 +0200 Subject: Fix formatting when passing strings to log from high-level code --- matlab/mex/astra_mex_log_c.cpp | 8 ++++---- matlab/mex/mexInitFunctions.cpp | 2 +- python/astra/log_c.pyx | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_log_c.cpp b/matlab/mex/astra_mex_log_c.cpp index ea4621e..905612c 100644 --- a/matlab/mex/astra_mex_log_c.cpp +++ b/matlab/mex/astra_mex_log_c.cpp @@ -55,7 +55,7 @@ void astra_mex_log_debug(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prh string filename = mexToString(prhs[1]); int linenumber = (int)mxGetScalar(prhs[2]); string message = mexToString(prhs[3]); - astra::CLogger::debug(filename.c_str(),linenumber,message.c_str()); + astra::CLogger::debug(filename.c_str(),linenumber,"%s",message.c_str()); } //----------------------------------------------------------------------------------------- @@ -75,7 +75,7 @@ void astra_mex_log_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs string filename = mexToString(prhs[1]); int linenumber = (int)mxGetScalar(prhs[2]); string message = mexToString(prhs[3]); - astra::CLogger::info(filename.c_str(),linenumber,message.c_str()); + astra::CLogger::info(filename.c_str(),linenumber,"%s",message.c_str()); } //----------------------------------------------------------------------------------------- @@ -95,7 +95,7 @@ void astra_mex_log_warn(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs string filename = mexToString(prhs[1]); int linenumber = (int)mxGetScalar(prhs[2]); string message = mexToString(prhs[3]); - astra::CLogger::warn(filename.c_str(),linenumber,message.c_str()); + astra::CLogger::warn(filename.c_str(),linenumber,"%s",message.c_str()); } //----------------------------------------------------------------------------------------- @@ -115,7 +115,7 @@ void astra_mex_log_error(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prh string filename = mexToString(prhs[1]); int linenumber = (int)mxGetScalar(prhs[2]); string message = mexToString(prhs[3]); - astra::CLogger::error(filename.c_str(),linenumber,message.c_str()); + astra::CLogger::error(filename.c_str(),linenumber,"%s",message.c_str()); } //----------------------------------------------------------------------------------------- diff --git a/matlab/mex/mexInitFunctions.cpp b/matlab/mex/mexInitFunctions.cpp index d8a50d7..89a31a1 100644 --- a/matlab/mex/mexInitFunctions.cpp +++ b/matlab/mex/mexInitFunctions.cpp @@ -8,7 +8,7 @@ bool mexIsInitialized=false; * */ void logCallBack(const char *msg, size_t len){ - mexPrintf(msg); + mexPrintf("%s",msg); } /** diff --git a/python/astra/log_c.pyx b/python/astra/log_c.pyx index f16329f..55c63e6 100644 --- a/python/astra/log_c.pyx +++ b/python/astra/log_c.pyx @@ -53,19 +53,19 @@ cdef extern from "astra/Logging.h" namespace "astra::CLogger": def log_debug(sfile, sline, message): cstr = list(map(six.b,(sfile,message))) - debug(cstr[0],sline,cstr[1]) + debug(cstr[0],sline,"%s",cstr[1]) def log_info(sfile, sline, message): cstr = list(map(six.b,(sfile,message))) - info(cstr[0],sline,cstr[1]) + info(cstr[0],sline,"%s",cstr[1]) def log_warn(sfile, sline, message): cstr = list(map(six.b,(sfile,message))) - warn(cstr[0],sline,cstr[1]) + warn(cstr[0],sline,"%s",cstr[1]) def log_error(sfile, sline, message): cstr = list(map(six.b,(sfile,message))) - error(cstr[0],sline,cstr[1]) + error(cstr[0],sline,"%s",cstr[1]) def log_enable(): enable() -- cgit v1.2.3 From 18b6d25f7e4f0943b3592f3bb4f6ca5ed9c285d3 Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Fri, 19 Jun 2015 22:28:06 +0200 Subject: Add support for Python algorithm plugins --- build/linux/Makefile.in | 16 +- include/astra/AstraObjectFactory.h | 13 ++ include/astra/PluginAlgorithm.h | 85 +++++++++++ matlab/mex/astra_mex_plugin_c.cpp | 139 ++++++++++++++++++ python/astra/__init__.py | 1 + python/astra/plugin.py | 95 ++++++++++++ python/astra/plugin_c.pyx | 59 ++++++++ python/astra/utils.pyx | 72 +-------- python/docSRC/index.rst | 1 + python/docSRC/plugins.rst | 8 + samples/python/s018_plugin.py | 138 +++++++++++++++++ src/PluginAlgorithm.cpp | 294 +++++++++++++++++++++++++++++++++++++ 12 files changed, 851 insertions(+), 70 deletions(-) create mode 100644 include/astra/PluginAlgorithm.h create mode 100644 matlab/mex/astra_mex_plugin_c.cpp create mode 100644 python/astra/plugin.py create mode 100644 python/astra/plugin_c.pyx create mode 100644 python/docSRC/plugins.rst create mode 100644 samples/python/s018_plugin.py create mode 100644 src/PluginAlgorithm.cpp (limited to 'matlab') diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index 2d862f2..e209fa7 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -50,11 +50,17 @@ LDFLAGS+=-fopenmp endif ifeq ($(python),yes) -PYCPPFLAGS = ${CPPFLAGS} +PYTHON = @PYTHON@ +PYLIBDIR = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_config_var; import six; six.print_(get_config_var("LIBDIR"))') +PYINCDIR = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_python_inc; import six; six.print_(get_python_inc())') +PYLIBVER = `basename $(PYINCDIR)` +CPPFLAGS += -DASTRA_PYTHON -I$(PYINCDIR) +PYCPPFLAGS = $(CPPFLAGS) PYCPPFLAGS += -I../include -PYLDFLAGS = ${LDFLAGS} +PYLDFLAGS = $(LDFLAGS) PYLDFLAGS += -L../build/linux/.libs -PYTHON = @PYTHON@ +LIBS += -l$(PYLIBVER) +LDFLAGS += -L$(PYLIBDIR) endif BOOST_CPPFLAGS= @@ -234,6 +240,10 @@ MATLAB_MEX=\ matlab/mex/astra_mex_log_c.$(MEXSUFFIX) \ matlab/mex/astra_mex_data3d_c.$(MEXSUFFIX) +ifeq ($(python),yes) +ALL_OBJECTS+=src/PluginAlgorithm.lo +MATLAB_MEX+=matlab/mex/astra_mex_plugin_c.$(MEXSUFFIX) +endif OBJECT_DIRS = src/ tests/ cuda/2d/ cuda/3d/ matlab/mex/ ./ DEPDIRS = $(addsuffix $(DEPDIR),$(OBJECT_DIRS)) diff --git a/include/astra/AstraObjectFactory.h b/include/astra/AstraObjectFactory.h index 356acf9..325989e 100644 --- a/include/astra/AstraObjectFactory.h +++ b/include/astra/AstraObjectFactory.h @@ -40,6 +40,10 @@ $Id$ #include "AlgorithmTypelist.h" +#ifdef ASTRA_PYTHON +#include "PluginAlgorithm.h" +#endif + namespace astra { @@ -147,6 +151,15 @@ T* CAstraObjectFactory::create(const Config& _cfg) */ class _AstraExport CAlgorithmFactory : public CAstraObjectFactory {}; +#ifdef ASTRA_PYTHON +template <> +inline CAlgorithm* CAstraObjectFactory::findPlugin(std::string _sType) + { + CPluginAlgorithmFactory *fac = CPluginAlgorithmFactory::getSingletonPtr(); + return fac->getPlugin(_sType); + } +#endif + /** * Class used to create 2D projectors from a string or a config object */ diff --git a/include/astra/PluginAlgorithm.h b/include/astra/PluginAlgorithm.h new file mode 100644 index 0000000..7d6c64a --- /dev/null +++ b/include/astra/PluginAlgorithm.h @@ -0,0 +1,85 @@ +/* +----------------------------------------------------------------------- +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$ +*/ + +#ifndef _INC_ASTRA_PLUGINALGORITHM +#define _INC_ASTRA_PLUGINALGORITHM + +#ifdef ASTRA_PYTHON + +#include +#include "bytesobject.h" +#include "astra/Algorithm.h" +#include "astra/Singleton.h" +#include "astra/XMLDocument.h" +#include "astra/XMLNode.h" + +namespace astra { +class _AstraExport CPluginAlgorithm : public CAlgorithm { + +public: + + CPluginAlgorithm(PyObject* pyclass); + ~CPluginAlgorithm(); + + bool initialize(const Config& _cfg); + void run(int _iNrIterations); + +private: + PyObject * instance; + +}; + +class _AstraExport CPluginAlgorithmFactory : public Singleton { + +public: + + CPluginAlgorithmFactory(); + ~CPluginAlgorithmFactory(); + + CPluginAlgorithm * getPlugin(std::string name); + + bool registerPlugin(std::string name, std::string className); + bool registerPluginClass(std::string name, PyObject * className); + + PyObject * getRegistered(); + + std::string getHelp(std::string name); + +private: + PyObject * pluginDict; + PyObject *ospath, *inspect, *six, *astra; + std::vector getPluginPathList(); +}; + +PyObject* XMLNode2dict(XMLNode node); + +} + +#endif + +#endif \ No newline at end of file diff --git a/matlab/mex/astra_mex_plugin_c.cpp b/matlab/mex/astra_mex_plugin_c.cpp new file mode 100644 index 0000000..2d9b9a0 --- /dev/null +++ b/matlab/mex/astra_mex_plugin_c.cpp @@ -0,0 +1,139 @@ +/* +----------------------------------------------------------------------- +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$ +*/ + +/** \file astra_mex_plugin_c.cpp + * + * \brief Manages Python plugins. + */ + +#include +#include "mexHelpFunctions.h" +#include "mexInitFunctions.h" + +#include "astra/PluginAlgorithm.h" + +#include "Python.h" +#include "bytesobject.h" + +using namespace std; +using namespace astra; + + +//----------------------------------------------------------------------------------------- +/** astra_mex_plugin('get_registered'); + * + * Print registered plugins. + */ +void astra_mex_plugin_get_registered(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getSingletonPtr(); + PyObject *dict = fact->getRegistered(); + PyObject *key, *value; + Py_ssize_t pos = 0; + while (PyDict_Next(dict, &pos, &key, &value)) { + mexPrintf("%s: %s\n",PyBytes_AsString(key),PyBytes_AsString(value)); + } + Py_DECREF(dict); +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_plugin('register', name, class_name); + * + * Register plugin. + */ +void astra_mex_plugin_register(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (3 <= nrhs) { + string name = mexToString(prhs[1]); + string class_name = mexToString(prhs[2]); + astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getSingletonPtr(); + fact->registerPlugin(name, class_name); + }else{ + mexPrintf("astra_mex_plugin('register', name, class_name);\n"); + } +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_plugin('get_help', name); + * + * Get help about plugin. + */ +void astra_mex_plugin_get_help(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (2 <= nrhs) { + string name = mexToString(prhs[1]); + astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getSingletonPtr(); + mexPrintf((fact->getHelp(name)+"\n").c_str()); + }else{ + mexPrintf("astra_mex_plugin('get_help', name);\n"); + } +} + + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf(" Valid modes: register, get_registered, get_help\n"); +} + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex(type,...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + + // INPUT0: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mexToString(prhs[0]); + } else { + printHelp(); + return; + } + + initASTRAMex(); + + // SWITCH (MODE) + if (sMode == std::string("get_registered")) { + astra_mex_plugin_get_registered(nlhs, plhs, nrhs, prhs); + }else if (sMode == std::string("get_help")) { + astra_mex_plugin_get_help(nlhs, plhs, nrhs, prhs); + }else if (sMode == std::string("register")) { + astra_mex_plugin_register(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + + return; +} + + diff --git a/python/astra/__init__.py b/python/astra/__init__.py index 6c15d30..10ed74d 100644 --- a/python/astra/__init__.py +++ b/python/astra/__init__.py @@ -34,6 +34,7 @@ from . import algorithm from . import projector from . import projector3d from . import matrix +from . import plugin from . import log from .optomo import OpTomo diff --git a/python/astra/plugin.py b/python/astra/plugin.py new file mode 100644 index 0000000..ccdb2cb --- /dev/null +++ b/python/astra/plugin.py @@ -0,0 +1,95 @@ +#----------------------------------------------------------------------- +#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam +# +#Author: Daniel M. Pelt +#Contact: D.M.Pelt@cwi.nl +#Website: http://dmpelt.github.io/pyastratoolbox/ +# +# +#This file is part of the Python interface to the +#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). +# +#The Python interface to 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 Python interface to 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 Python interface to the ASTRA Toolbox. If not, see . +# +#----------------------------------------------------------------------- + +from . import plugin_c as p +from . import log + +class base(object): + + def astra_init(self, cfg): + try: + try: + req = self.required_options + except AttributeError: + log.warn("Plugin '" + self.__class__.__name__ + "' does not specify required options") + req = {} + + try: + opt = self.optional_options + except AttributeError: + log.warn("Plugin '" + self.__class__.__name__ + "' does not specify optional options") + opt = {} + + try: + optDict = cfg['options'] + except KeyError: + optDict = {} + + cfgKeys = set(optDict.keys()) + reqKeys = set(req) + optKeys = set(opt) + + if not reqKeys.issubset(cfgKeys): + for key in reqKeys.difference(cfgKeys): + log.error("Required option '" + key + "' for plugin '" + self.__class__.__name__ + "' not specified") + raise ValueError("Missing required options") + + if not cfgKeys.issubset(reqKeys | optKeys): + log.warn(self.__class__.__name__ + ": unused configuration option: " + str(list(cfgKeys.difference(reqKeys | optKeys)))) + + self.initialize(cfg) + except Exception as e: + log.error(str(e)) + raise + +def register(name, className): + """Register plugin with ASTRA. + + :param name: Plugin name to register + :type name: :class:`str` + :param className: Class name or class object to register + :type className: :class:`str` or :class:`class` + + """ + p.register(name,className) + +def get_registered(): + """Get dictionary of registered plugins. + + :returns: :class:`dict` -- Registered plugins. + + """ + return p.get_registered() + +def get_help(name): + """Get help for registered plugin. + + :param name: Plugin name to get help for + :type name: :class:`str` + :returns: :class:`str` -- Help string (docstring). + + """ + return p.get_help(name) \ No newline at end of file diff --git a/python/astra/plugin_c.pyx b/python/astra/plugin_c.pyx new file mode 100644 index 0000000..91b3cd5 --- /dev/null +++ b/python/astra/plugin_c.pyx @@ -0,0 +1,59 @@ +#----------------------------------------------------------------------- +#Copyright 2013 Centrum Wiskunde & Informatica, Amsterdam +# +#Author: Daniel M. Pelt +#Contact: D.M.Pelt@cwi.nl +#Website: http://dmpelt.github.io/pyastratoolbox/ +# +# +#This file is part of the Python interface to the +#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). +# +#The Python interface to 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 Python interface to 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 Python interface to the ASTRA Toolbox. If not, see . +# +#----------------------------------------------------------------------- +# distutils: language = c++ +# distutils: libraries = astra + +import six +import inspect + +from libcpp.string cimport string +from libcpp cimport bool + +cdef CPluginAlgorithmFactory *fact = getSingletonPtr() + +from . import utils + +cdef extern from "astra/PluginAlgorithm.h" namespace "astra": + cdef cppclass CPluginAlgorithmFactory: + bool registerPlugin(string name, string className) + bool registerPluginClass(string name, object className) + object getRegistered() + string getHelp(string name) + +cdef extern from "astra/PluginAlgorithm.h" namespace "astra::CPluginAlgorithmFactory": + cdef CPluginAlgorithmFactory* getSingletonPtr() + +def register(name, className): + if inspect.isclass(className): + fact.registerPluginClass(six.b(name), className) + else: + fact.registerPlugin(six.b(name), six.b(className)) + +def get_registered(): + return fact.getRegistered() + +def get_help(name): + return utils.wrap_from_bytes(fact.getHelp(six.b(name))) diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx index ddb37aa..3746b8e 100644 --- a/python/astra/utils.pyx +++ b/python/astra/utils.pyx @@ -30,7 +30,6 @@ cimport numpy as np import numpy as np import six from libcpp.string cimport string -from libcpp.list cimport list from libcpp.vector cimport vector from cython.operator cimport dereference as deref, preincrement as inc from cpython.version cimport PY_MAJOR_VERSION @@ -40,6 +39,9 @@ from .PyXMLDocument cimport XMLDocument from .PyXMLDocument cimport XMLNode from .PyIncludes cimport * +cdef extern from "astra/PluginAlgorithm.h" namespace "astra": + object XMLNode2dict(XMLNode) + cdef Config * dictToConfig(string rootname, dc): cdef Config * cfg = new Config() @@ -91,6 +93,8 @@ cdef void readDict(XMLNode root, _dc): dc = convert_item(_dc) for item in dc: val = dc[item] + if isinstance(val, list): + val = np.array(val,dtype=np.float64) if isinstance(val, np.ndarray): if val.size == 0: break @@ -142,69 +146,3 @@ cdef void readOptions(XMLNode node, dc): cdef configToDict(Config *cfg): return XMLNode2dict(cfg.self) -def castString3(input): - return input.decode('utf-8') - -def castString2(input): - return input - -if six.PY3: - castString = castString3 -else: - castString = castString2 - -def stringToPythonValue(inputIn): - input = castString(inputIn) - # matrix - if ';' in input: - row_strings = input.split(';') - col_strings = row_strings[0].split(',') - nRows = len(row_strings) - nCols = len(col_strings) - - out = np.empty((nRows,nCols)) - for ridx, row in enumerate(row_strings): - col_strings = row.split(',') - for cidx, col in enumerate(col_strings): - out[ridx,cidx] = float(col) - return out - - # vector - if ',' in input: - items = input.split(',') - out = np.empty(len(items)) - for idx,item in enumerate(items): - out[idx] = float(item) - return out - - try: - # integer - return int(input) - except ValueError: - try: - #float - return float(input) - except ValueError: - # string - return str(input) - - -cdef XMLNode2dict(XMLNode node): - cdef XMLNode subnode - cdef list[XMLNode] nodes - cdef list[XMLNode].iterator it - dct = {} - opts = {} - if node.hasAttribute(six.b('type')): - dct['type'] = castString(node.getAttribute(six.b('type'))) - nodes = node.getNodes() - it = nodes.begin() - while it != nodes.end(): - subnode = deref(it) - if castString(subnode.getName())=="Option": - opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getAttribute('value')) - else: - dct[castString(subnode.getName())] = stringToPythonValue(subnode.getContent()) - inc(it) - if len(opts)>0: dct['options'] = opts - return dct diff --git a/python/docSRC/index.rst b/python/docSRC/index.rst index b7cc6d6..dcc6590 100644 --- a/python/docSRC/index.rst +++ b/python/docSRC/index.rst @@ -19,6 +19,7 @@ Contents: creators functions operator + plugins matlab astra .. astra diff --git a/python/docSRC/plugins.rst b/python/docSRC/plugins.rst new file mode 100644 index 0000000..dc7c607 --- /dev/null +++ b/python/docSRC/plugins.rst @@ -0,0 +1,8 @@ +Plugins: the :mod:`plugin` module +========================================= + +.. automodule:: astra.plugin + :members: + :undoc-members: + :show-inheritance: + diff --git a/samples/python/s018_plugin.py b/samples/python/s018_plugin.py new file mode 100644 index 0000000..6677930 --- /dev/null +++ b/samples/python/s018_plugin.py @@ -0,0 +1,138 @@ +#----------------------------------------------------------------------- +#Copyright 2015 Centrum Wiskunde & Informatica, Amsterdam +# +#Author: Daniel M. Pelt +#Contact: D.M.Pelt@cwi.nl +#Website: http://dmpelt.github.io/pyastratoolbox/ +# +# +#This file is part of the Python interface to the +#All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). +# +#The Python interface to 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 Python interface to 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 Python interface to the ASTRA Toolbox. If not, see . +# +#----------------------------------------------------------------------- + +import astra +import numpy as np +import six + +# Define the plugin class (has to subclass astra.plugin.base) +# Note that usually, these will be defined in a separate package/module +class SIRTPlugin(astra.plugin.base): + """Example of an ASTRA plugin class, implementing a simple 2D SIRT algorithm. + + Optional options: + + 'rel_factor': relaxation factor + """ + required_options=[] + optional_options=['rel_factor'] + + def initialize(self,cfg): + self.W = astra.OpTomo(cfg['ProjectorId']) + self.vid = cfg['ReconstructionDataId'] + self.sid = cfg['ProjectionDataId'] + try: + self.rel = cfg['option']['rel_factor'] + except KeyError: + self.rel = 1 + + def run(self, its): + v = astra.data2d.get_shared(self.vid) + s = astra.data2d.get_shared(self.sid) + W = self.W + for i in range(its): + v[:] += self.rel*(W.T*(s - (W*v).reshape(s.shape))).reshape(v.shape)/s.size + +if __name__=='__main__': + + vol_geom = astra.create_vol_geom(256, 256) + proj_geom = astra.create_proj_geom('parallel', 1.0, 384, np.linspace(0,np.pi,180,False)) + + # As before, create a sinogram from a phantom + import scipy.io + P = scipy.io.loadmat('phantom.mat')['phantom256'] + proj_id = astra.create_projector('cuda',proj_geom,vol_geom) + + # construct the OpTomo object + W = astra.OpTomo(proj_id) + + sinogram = W * P + sinogram = sinogram.reshape([180, 384]) + + # Register the plugin with ASTRA + # A default set of plugins to load can be defined in: + # - /etc/astra-toolbox/plugins.txt + # - [ASTRA_INSTALL_PATH]/python/astra/plugins.txt + # - [USER_HOME_PATH]/.astra-toolbox/plugins.txt + # - [ASTRA_PLUGIN_PATH environment variable]/plugins.txt + # In these files, create a separate line for each plugin with: + # [PLUGIN_ASTRA_NAME] [FULL_PLUGIN_CLASS] + # + # So in this case, it would be a line: + # SIRT-PLUGIN s018_plugin.SIRTPlugin + # + astra.plugin.register('SIRT-PLUGIN','s018_plugin.SIRTPlugin') + + # To get help on a registered plugin, use get_help + six.print_(astra.plugin.get_help('SIRT-PLUGIN')) + + # Create data structures + sid = astra.data2d.create('-sino', proj_geom, sinogram) + vid = astra.data2d.create('-vol', vol_geom) + + # Create config using plugin name + cfg = astra.astra_dict('SIRT-PLUGIN') + cfg['ProjectorId'] = proj_id + cfg['ProjectionDataId'] = sid + cfg['ReconstructionDataId'] = vid + + # Create algorithm object + alg_id = astra.algorithm.create(cfg) + + # Run algorithm for 100 iterations + astra.algorithm.run(alg_id, 100) + + # Get reconstruction + rec = astra.data2d.get(vid) + + # Options for the plugin go in cfg['option'] + cfg = astra.astra_dict('SIRT-PLUGIN') + cfg['ProjectorId'] = proj_id + cfg['ProjectionDataId'] = sid + cfg['ReconstructionDataId'] = vid + cfg['option'] = {} + cfg['option']['rel_factor'] = 1.5 + alg_id_rel = astra.algorithm.create(cfg) + astra.algorithm.run(alg_id_rel, 100) + rec_rel = astra.data2d.get(vid) + + # We can also use OpTomo to call the plugin + rec_op = W.reconstruct('SIRT-PLUGIN', sinogram, 100, extraOptions={'rel_factor':1.5}) + + import pylab as pl + pl.gray() + pl.figure(1) + pl.imshow(rec,vmin=0,vmax=1) + pl.figure(2) + pl.imshow(rec_rel,vmin=0,vmax=1) + pl.figure(3) + pl.imshow(rec_op,vmin=0,vmax=1) + pl.show() + + # Clean up. + astra.projector.delete(proj_id) + astra.algorithm.delete([alg_id, alg_id_rel]) + astra.data2d.delete([vid, sid]) diff --git a/src/PluginAlgorithm.cpp b/src/PluginAlgorithm.cpp new file mode 100644 index 0000000..df13f31 --- /dev/null +++ b/src/PluginAlgorithm.cpp @@ -0,0 +1,294 @@ +/* +----------------------------------------------------------------------- +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, "run", "i",_iNrIterations); + if(retVal==NULL) return; + Py_DECREF(retVal); +} + +const char ps = +#ifdef _WIN32 + '\\'; +#else + '/'; +#endif + +std::vector CPluginAlgorithmFactory::getPluginPathList(){ + std::vector list; + list.push_back("/etc/astra-toolbox"); + PyObject *ret, *retb; + ret = PyObject_CallMethod(inspect,"getfile","O",astra); + if(ret!=NULL){ + retb = PyObject_CallMethod(six,"b","O",ret); + Py_DECREF(ret); + if(retb!=NULL){ + std::string astra_inst (PyBytes_AsString(retb)); + Py_DECREF(retb); + ret = PyObject_CallMethod(ospath,"dirname","s",astra_inst.c_str()); + if(ret!=NULL){ + retb = PyObject_CallMethod(six,"b","O",ret); + Py_DECREF(ret); + if(retb!=NULL){ + list.push_back(std::string(PyBytes_AsString(retb))); + Py_DECREF(retb); + } + } + } + } + ret = PyObject_CallMethod(ospath,"expanduser","s","~"); + if(ret!=NULL){ + retb = PyObject_CallMethod(six,"b","O",ret); + Py_DECREF(ret); + if(retb!=NULL){ + list.push_back(std::string(PyBytes_AsString(retb)) + ps + ".astra-toolbox"); + Py_DECREF(retb); + } + } + const char *envval = getenv("ASTRA_PLUGIN_PATH"); + if(envval!=NULL){ + list.push_back(std::string(envval)); + } + return list; +} + +CPluginAlgorithmFactory::CPluginAlgorithmFactory(){ + Py_Initialize(); + pluginDict = PyDict_New(); + ospath = PyImport_ImportModule("os.path"); + inspect = PyImport_ImportModule("inspect"); + six = PyImport_ImportModule("six"); + astra = PyImport_ImportModule("astra"); + std::vector fls = getPluginPathList(); + std::vector items; + for(unsigned int i=0;i 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 = stringToPythonValue(subnode.getAttribute("value")); + 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 \ No newline at end of file -- cgit v1.2.3 From 3d136b7c819b0b142ad056bf01c8c1191eea9ba0 Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Fri, 17 Jul 2015 16:22:05 +0200 Subject: Fix numpy lapack loading when running in Matlab --- include/astra/Globals.h | 2 ++ matlab/mex/mexInitFunctions.cpp | 3 +++ src/Globals.cpp | 3 +++ src/PluginAlgorithm.cpp | 29 +++++++++++++++++++++++++++++ 4 files changed, 37 insertions(+) (limited to 'matlab') diff --git a/include/astra/Globals.h b/include/astra/Globals.h index 4de07d1..dc2d7e6 100644 --- a/include/astra/Globals.h +++ b/include/astra/Globals.h @@ -146,6 +146,8 @@ namespace astra { const float32 PIdiv2 = PI / 2; const float32 PIdiv4 = PI / 4; const float32 eps = 1e-7f; + + extern bool running_in_matlab; } //---------------------------------------------------------------------------------------- diff --git a/matlab/mex/mexInitFunctions.cpp b/matlab/mex/mexInitFunctions.cpp index d8a50d7..c11c7d5 100644 --- a/matlab/mex/mexInitFunctions.cpp +++ b/matlab/mex/mexInitFunctions.cpp @@ -17,6 +17,9 @@ void logCallBack(const char *msg, size_t len){ */ void initASTRAMex(){ if(mexIsInitialized) return; + + astra::running_in_matlab=true; + if(!astra::CLogger::setCallbackScreen(&logCallBack)){ mexErrMsgTxt("Error initializing mex functions."); } diff --git a/src/Globals.cpp b/src/Globals.cpp index 813f9c9..904a459 100644 --- a/src/Globals.cpp +++ b/src/Globals.cpp @@ -28,5 +28,8 @@ $Id$ #include "astra/Globals.h" +namespace astra{ + bool running_in_matlab=false; +} // nothing to see here :) diff --git a/src/PluginAlgorithm.cpp b/src/PluginAlgorithm.cpp index 8ba6631..c26ee3f 100644 --- a/src/PluginAlgorithm.cpp +++ b/src/PluginAlgorithm.cpp @@ -67,8 +67,37 @@ void CPluginAlgorithm::run(int _iNrIterations){ 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"); -- cgit v1.2.3 From d91b51f6d58003de84a9d6dd8189fceba0e81a5a Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Mon, 20 Jul 2015 14:07:21 +0200 Subject: Allow registering plugins without explicit name, and fix exception handling when running in Matlab --- include/astra/PluginAlgorithm.h | 3 ++ matlab/mex/astra_mex_plugin_c.cpp | 23 ++++------ python/astra/plugin.py | 71 ++++++++++++----------------- python/astra/plugin_c.pyx | 14 ++++-- samples/python/s018_plugin.py | 23 +++++----- src/PluginAlgorithm.cpp | 95 +++++++++++++++++++++++++++++++-------- 6 files changed, 138 insertions(+), 91 deletions(-) (limited to 'matlab') diff --git a/include/astra/PluginAlgorithm.h b/include/astra/PluginAlgorithm.h index a82c579..b56228e 100644 --- a/include/astra/PluginAlgorithm.h +++ b/include/astra/PluginAlgorithm.h @@ -64,9 +64,12 @@ public: CPluginAlgorithm * getPlugin(std::string name); bool registerPlugin(std::string name, std::string className); + bool registerPlugin(std::string className); bool registerPluginClass(std::string name, PyObject * className); + bool registerPluginClass(PyObject * className); PyObject * getRegistered(); + std::map getRegisteredMap(); std::string getHelp(std::string name); diff --git a/matlab/mex/astra_mex_plugin_c.cpp b/matlab/mex/astra_mex_plugin_c.cpp index 2d9b9a0..177fcf4 100644 --- a/matlab/mex/astra_mex_plugin_c.cpp +++ b/matlab/mex/astra_mex_plugin_c.cpp @@ -37,9 +37,6 @@ $Id$ #include "astra/PluginAlgorithm.h" -#include "Python.h" -#include "bytesobject.h" - using namespace std; using namespace astra; @@ -52,29 +49,25 @@ using namespace astra; void astra_mex_plugin_get_registered(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getSingletonPtr(); - PyObject *dict = fact->getRegistered(); - PyObject *key, *value; - Py_ssize_t pos = 0; - while (PyDict_Next(dict, &pos, &key, &value)) { - mexPrintf("%s: %s\n",PyBytes_AsString(key),PyBytes_AsString(value)); + std::map mp = fact->getRegisteredMap(); + for(std::map::iterator it=mp.begin();it!=mp.end();it++){ + mexPrintf("%s: %s\n",it->first.c_str(), it->second.c_str()); } - Py_DECREF(dict); } //----------------------------------------------------------------------------------------- -/** astra_mex_plugin('register', name, class_name); +/** astra_mex_plugin('register', class_name); * * Register plugin. */ void astra_mex_plugin_register(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { - if (3 <= nrhs) { - string name = mexToString(prhs[1]); - string class_name = mexToString(prhs[2]); + if (2 <= nrhs) { + string class_name = mexToString(prhs[1]); astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getSingletonPtr(); - fact->registerPlugin(name, class_name); + fact->registerPlugin(class_name); }else{ - mexPrintf("astra_mex_plugin('register', name, class_name);\n"); + mexPrintf("astra_mex_plugin('register', class_name);\n"); } } diff --git a/python/astra/plugin.py b/python/astra/plugin.py index f8fc3bd..4b32e6e 100644 --- a/python/astra/plugin.py +++ b/python/astra/plugin.py @@ -32,60 +32,47 @@ import traceback class base(object): def astra_init(self, cfg): - try: - args, varargs, varkw, defaults = inspect.getargspec(self.initialize) - if not defaults is None: - nopt = len(defaults) - else: - nopt = 0 - if nopt>0: - req = args[2:-nopt] - opt = args[-nopt:] - else: - req = args[2:] - opt = [] + args, varargs, varkw, defaults = inspect.getargspec(self.initialize) + if not defaults is None: + nopt = len(defaults) + else: + nopt = 0 + if nopt>0: + req = args[2:-nopt] + opt = args[-nopt:] + else: + req = args[2:] + opt = [] - try: - optDict = cfg['options'] - except KeyError: - optDict = {} + try: + optDict = cfg['options'] + except KeyError: + optDict = {} - cfgKeys = set(optDict.keys()) - reqKeys = set(req) - optKeys = set(opt) + cfgKeys = set(optDict.keys()) + reqKeys = set(req) + optKeys = set(opt) - if not reqKeys.issubset(cfgKeys): - for key in reqKeys.difference(cfgKeys): - log.error("Required option '" + key + "' for plugin '" + self.__class__.__name__ + "' not specified") - raise ValueError("Missing required options") + if not reqKeys.issubset(cfgKeys): + for key in reqKeys.difference(cfgKeys): + log.error("Required option '" + key + "' for plugin '" + self.__class__.__name__ + "' not specified") + raise ValueError("Missing required options") - if not cfgKeys.issubset(reqKeys | optKeys): - log.warn(self.__class__.__name__ + ": unused configuration option: " + str(list(cfgKeys.difference(reqKeys | optKeys)))) + if not cfgKeys.issubset(reqKeys | optKeys): + log.warn(self.__class__.__name__ + ": unused configuration option: " + str(list(cfgKeys.difference(reqKeys | optKeys)))) - args = [optDict[k] for k in req] - kwargs = dict((k,optDict[k]) for k in opt if k in optDict) - self.initialize(cfg, *args, **kwargs) - except Exception: - log.error(traceback.format_exc().replace("%","%%")) - raise + args = [optDict[k] for k in req] + kwargs = dict((k,optDict[k]) for k in opt if k in optDict) + self.initialize(cfg, *args, **kwargs) - def astra_run(self, its): - try: - self.run(its) - except Exception: - log.error(traceback.format_exc().replace("%","%%")) - raise - -def register(name, className): +def register(className): """Register plugin with ASTRA. - :param name: Plugin name to register - :type name: :class:`str` :param className: Class name or class object to register :type className: :class:`str` or :class:`class` """ - p.register(name,className) + p.register(className) def get_registered(): """Get dictionary of registered plugins. diff --git a/python/astra/plugin_c.pyx b/python/astra/plugin_c.pyx index 91b3cd5..8d6816b 100644 --- a/python/astra/plugin_c.pyx +++ b/python/astra/plugin_c.pyx @@ -38,7 +38,9 @@ from . import utils cdef extern from "astra/PluginAlgorithm.h" namespace "astra": cdef cppclass CPluginAlgorithmFactory: + bool registerPlugin(string className) bool registerPlugin(string name, string className) + bool registerPluginClass(object className) bool registerPluginClass(string name, object className) object getRegistered() string getHelp(string name) @@ -46,11 +48,17 @@ cdef extern from "astra/PluginAlgorithm.h" namespace "astra": cdef extern from "astra/PluginAlgorithm.h" namespace "astra::CPluginAlgorithmFactory": cdef CPluginAlgorithmFactory* getSingletonPtr() -def register(name, className): +def register(className, name=None): if inspect.isclass(className): - fact.registerPluginClass(six.b(name), className) + if name==None: + fact.registerPluginClass(className) + else: + fact.registerPluginClass(six.b(name), className) else: - fact.registerPlugin(six.b(name), six.b(className)) + if name==None: + fact.registerPlugin(six.b(className)) + else: + fact.registerPlugin(six.b(name), six.b(className)) def get_registered(): return fact.getRegistered() diff --git a/samples/python/s018_plugin.py b/samples/python/s018_plugin.py index 90e09ac..31cca95 100644 --- a/samples/python/s018_plugin.py +++ b/samples/python/s018_plugin.py @@ -38,6 +38,10 @@ class SIRTPlugin(astra.plugin.base): 'rel_factor': relaxation factor (optional) """ + # The astra_name variable defines the name to use to + # call the plugin from ASTRA + astra_name = "SIRT-PLUGIN" + def initialize(self,cfg, rel_factor = 1): self.W = astra.OpTomo(cfg['ProjectorId']) self.vid = cfg['ReconstructionDataId'] @@ -68,18 +72,13 @@ if __name__=='__main__': sinogram = sinogram.reshape([180, 384]) # Register the plugin with ASTRA - # A default set of plugins to load can be defined in: - # - /etc/astra-toolbox/plugins.txt - # - [ASTRA_INSTALL_PATH]/python/astra/plugins.txt - # - [USER_HOME_PATH]/.astra-toolbox/plugins.txt - # - [ASTRA_PLUGIN_PATH environment variable]/plugins.txt - # In these files, create a separate line for each plugin with: - # [PLUGIN_ASTRA_NAME] [FULL_PLUGIN_CLASS] - # - # So in this case, it would be a line: - # SIRT-PLUGIN s018_plugin.SIRTPlugin - # - astra.plugin.register('SIRT-PLUGIN','s018_plugin.SIRTPlugin') + # First we import the package that contains the plugin + import s018_plugin + # Then, we register the plugin class with ASTRA + astra.plugin.register(s018_plugin.SIRTPlugin) + + # Get a list of registered plugins + six.print_(astra.plugin.get_registered()) # To get help on a registered plugin, use get_help six.print_(astra.plugin.get_help('SIRT-PLUGIN')) diff --git a/src/PluginAlgorithm.cpp b/src/PluginAlgorithm.cpp index d6cf731..7f7ff61 100644 --- a/src/PluginAlgorithm.cpp +++ b/src/PluginAlgorithm.cpp @@ -100,7 +100,10 @@ bool CPluginAlgorithm::initialize(const Config& _cfg){ PyObject *cfgDict = XMLNode2dict(_cfg.self); PyObject *retVal = PyObject_CallMethod(instance, "astra_init", "O",cfgDict); Py_DECREF(cfgDict); - if(retVal==NULL) return false; + if(retVal==NULL){ + logPythonError(); + return false; + } m_bIsInitialized = true; Py_DECREF(retVal); return m_bIsInitialized; @@ -108,8 +111,11 @@ bool CPluginAlgorithm::initialize(const Config& _cfg){ void CPluginAlgorithm::run(int _iNrIterations){ if(instance==NULL) return; - PyObject *retVal = PyObject_CallMethod(instance, "astra_run", "i",_iNrIterations); - if(retVal==NULL) return; + PyObject *retVal = PyObject_CallMethod(instance, "run", "i",_iNrIterations); + if(retVal==NULL){ + logPythonError(); + return; + } Py_DECREF(retVal); } @@ -157,18 +163,6 @@ CPluginAlgorithmFactory::~CPluginAlgorithmFactory(){ 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(".")); @@ -190,6 +184,43 @@ PyObject * getClassFromString(std::string str){ 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; @@ -212,12 +243,34 @@ PyObject * CPluginAlgorithmFactory::getRegistered(){ return pluginDict; } +std::map CPluginAlgorithmFactory::getRegisteredMap(){ + std::map ret; + PyObject *key, *value; + Py_ssize_t pos = 0; + while (PyDict_Next(pluginDict, &pos, &key, &value)) { + PyObject * keyb = PyObject_Bytes(key); + PyObject * valb = PyObject_Bytes(value); + ret[PyBytes_AsString(keyb)] = PyBytes_AsString(valb); + Py_DECREF(keyb); + Py_DECREF(valb); + } + return ret; +} + std::string CPluginAlgorithmFactory::getHelp(std::string name){ PyObject *className = PyDict_GetItemString(pluginDict, name.c_str()); - if(className==NULL) return ""; - std::string str = std::string(PyBytes_AsString(className)); + if(className==NULL){ + ASTRA_ERROR("Plugin %s not found!",name.c_str()); + return ""; + } std::string ret = ""; - PyObject *pyclass = getClassFromString(str); + 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); @@ -228,9 +281,13 @@ std::string CPluginAlgorithmFactory::getHelp(std::string name){ ret = std::string(PyBytes_AsString(retb)); Py_DECREF(retb); } + }else{ + logPythonError(); } } - Py_DECREF(pyclass); + if(PyBytes_Check(className)){ + Py_DECREF(pyclass); + } return ret; } -- cgit v1.2.3 From db8587475efd44bc728caa79cd7ae7120eaf045b Mon Sep 17 00:00:00 2001 From: "Daniel M. Pelt" Date: Tue, 21 Jul 2015 15:15:08 +0200 Subject: Add matlab plugin .m file --- matlab/tools/astra_mex_plugin.m | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 matlab/tools/astra_mex_plugin.m (limited to 'matlab') diff --git a/matlab/tools/astra_mex_plugin.m b/matlab/tools/astra_mex_plugin.m new file mode 100644 index 0000000..4159365 --- /dev/null +++ b/matlab/tools/astra_mex_plugin.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex_plugin(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% astra_mex_plugin. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the ASTRA Toolbox +% +% Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp +% 2014-2015, CWI, Amsterdam +% License: Open Source under GPLv3 +% Contact: astra@uantwerpen.be +% Website: http://sf.net/projects/astra-toolbox +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_plugin_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_plugin_c(varargin{:}); +end \ No newline at end of file -- cgit v1.2.3 From 026aa46c5db24ddd687cec0fa6e056a2ee3790c5 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 12 Aug 2015 15:45:12 +0200 Subject: Fix algorithm object leak in astra_create_fbp_reconstruction.m --- matlab/tools/astra_create_fbp_reconstruction.m | 1 + 1 file changed, 1 insertion(+) (limited to 'matlab') diff --git a/matlab/tools/astra_create_fbp_reconstruction.m b/matlab/tools/astra_create_fbp_reconstruction.m index 5540f27..a2561b7 100644 --- a/matlab/tools/astra_create_fbp_reconstruction.m +++ b/matlab/tools/astra_create_fbp_reconstruction.m @@ -19,6 +19,7 @@ cfg.ProjectorId = proj_id; cfg.Options.GPUindex = 0; alg_id = astra_mex_algorithm('create', cfg); astra_mex_algorithm('run', alg_id); +astra_mex_algorithm('delete', alg_id); if numel(sinogram) ~= 1 astra_mex_data2d('delete', sinogram_id); -- cgit v1.2.3 From 9cfe943682bd6e02d5fb8493cb9c4c98623cb441 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Fri, 4 Sep 2015 14:16:41 +0200 Subject: Fix algorithm leak in opTomo --- matlab/tools/opTomo.m | 2 ++ 1 file changed, 2 insertions(+) (limited to 'matlab') diff --git a/matlab/tools/opTomo.m b/matlab/tools/opTomo.m index 14128d2..71dfb1e 100644 --- a/matlab/tools/opTomo.m +++ b/matlab/tools/opTomo.m @@ -248,6 +248,7 @@ classdef opTomo < opSpot % cleanup astra_mex_data3d('delete', vol_id); astra_mex_data3d('delete', sino_id); + astra_mex_algorithm('delete', alg_id); else % X is passed as a vector, reshape it into projection data x = reshape(x, op.proj_size); @@ -272,6 +273,7 @@ classdef opTomo < opSpot % cleanup astra_mex_data3d('delete', vol_id); astra_mex_data3d('delete', sino_id); + astra_mex_algorithm('delete', alg_id); end end % opTomo_intrnl3D -- cgit v1.2.3 From 11717f66b49fbe41faf923f267c6893ce9af46ad Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Thu, 17 Sep 2015 16:54:37 +0200 Subject: Use mxLogical instead of bool. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should improve compatibility with Octave according to Christian Häggström. --- matlab/mex/astra_mex_data2d_c.cpp | 4 ++-- matlab/mex/astra_mex_matrix_c.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp index 909d229..935e476 100644 --- a/matlab/mex/astra_mex_data2d_c.cpp +++ b/matlab/mex/astra_mex_data2d_c.cpp @@ -222,7 +222,7 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra // logical data if (mxIsLogical(prhs[3])) { - bool* pbMatlabData = mxGetLogicals(prhs[3]); + mxLogical* pbMatlabData = mxGetLogicals(prhs[3]); int i = 0; int col, row; for (col = 0; col < dims[1]; ++col) { @@ -322,7 +322,7 @@ void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray* // logical data if (mxIsLogical(prhs[2])) { - bool* pbMatlabData = mxGetLogicals(prhs[2]); + mxLogical* pbMatlabData = mxGetLogicals(prhs[2]); int i = 0; int col, row; for (col = 0; col < dims[1]; ++col) { diff --git a/matlab/mex/astra_mex_matrix_c.cpp b/matlab/mex/astra_mex_matrix_c.cpp index aa31383..e07ddb6 100644 --- a/matlab/mex/astra_mex_matrix_c.cpp +++ b/matlab/mex/astra_mex_matrix_c.cpp @@ -112,7 +112,7 @@ static bool matlab_to_astra(const mxArray* _rhs, CSparseMatrix* _pMatrix) mwIndex *colStarts = mxGetJc(_rhs); mwIndex *rowIndices = mxGetIr(_rhs); double *floatValues = 0; - bool *boolValues = 0; + mxLogical *boolValues = 0; bool bLogical = mxIsLogical(_rhs); if (bLogical) boolValues = mxGetLogicals(_rhs); -- cgit v1.2.3 From c39b12fc42a7254bad1e68cbdb948eee0421ad81 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 16 Sep 2015 16:44:10 +0200 Subject: Let astra_create_vol_geom also generate flexible volume geometries --- matlab/tools/astra_create_vol_geom.m | 15 +++++++++++++++ python/astra/creators.py | 15 +++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'matlab') diff --git a/matlab/tools/astra_create_vol_geom.m b/matlab/tools/astra_create_vol_geom.m index ea975e6..a3ba7de 100644 --- a/matlab/tools/astra_create_vol_geom.m +++ b/matlab/tools/astra_create_vol_geom.m @@ -15,6 +15,7 @@ function vol_geom = astra_create_vol_geom(varargin) % vol_geom: MATLAB struct containing all information of the geometry. %-------------------------------------------------------------------------- % vol_geom = astra_create_vol_geom(row_count, col_count, slice_count); +% vol_geom = astra_create_vol_geom(row_count, col_count, slice_count, min_x, max_x, min_y, max_y, min_z, max_z); % % Create a 3D volume geometry. See the API for more information. % row_count: number of rows. @@ -93,4 +94,18 @@ elseif numel(varargin) == 3 vol_geom.GridRowCount = varargin{1}; vol_geom.GridColCount = varargin{2}; vol_geom.GridSliceCount = varargin{3}; + +% astra_create_vol_geom(row_count, col_count, slice_count, min_x, max_x, min_y, max_y, min_z, max_z) +elseif numel(varargin) == 9 + vol_geom = struct(); + vol_geom.GridRowCount = varargin{1}; + vol_geom.GridColCount = varargin{2}; + vol_geom.GridSliceCount = varargin{3}; + vol_geom.option.WindowMinX = varargin{4}; + vol_geom.option.WindowMaxX = varargin{5}; + vol_geom.option.WindowMinY = varargin{6}; + vol_geom.option.WindowMaxY = varargin{7}; + vol_geom.option.WindowMinZ = varargin{8}; + vol_geom.option.WindowMaxZ = varargin{9}; + end diff --git a/python/astra/creators.py b/python/astra/creators.py index 68bc8a2..f3474d8 100644 --- a/python/astra/creators.py +++ b/python/astra/creators.py @@ -72,6 +72,10 @@ This method can be called in a number of ways: ``create_vol_geom(M, N, Z)``: :returns: A 3D volume geometry of size :math:`M \\times N \\times Z`. +``create_vol_geom(M, N, Z, minx, maxx, miny, maxy, minz, maxz)``: + :returns: A 3D volume geometry of size :math:`M \\times N \\times Z`, windowed as :math:`minx \\leq x \\leq maxx` and :math:`miny \\leq y \\leq maxy` and :math:`minz \\leq z \\leq maxz` . + + """ vol_geom = {'option': {}} # astra_create_vol_geom(row_count) @@ -122,6 +126,17 @@ This method can be called in a number of ways: vol_geom['GridRowCount'] = varargin[0] vol_geom['GridColCount'] = varargin[1] vol_geom['GridSliceCount'] = varargin[2] + # astra_create_vol_geom(row_count, col_count, slice_count, min_x, max_x, min_y, max_y, min_z, max_z) + elif len(varargin) == 9: + vol_geom['GridRowCount'] = varargin[0] + vol_geom['GridColCount'] = varargin[1] + vol_geom['GridSliceCount'] = varargin[2] + vol_geom['option']['WindowMinX'] = varargin[3] + vol_geom['option']['WindowMaxX'] = varargin[4] + vol_geom['option']['WindowMinY'] = varargin[5] + vol_geom['option']['WindowMaxY'] = varargin[6] + vol_geom['option']['WindowMinZ'] = varargin[7] + vol_geom['option']['WindowMaxZ'] = varargin[8] return vol_geom -- cgit v1.2.3 From 1cc67c1e4d9b6b24c096f52d6f086a3f224ece8a Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 7 Oct 2015 17:29:20 +0200 Subject: Add astra_mex_direct('FP3D'/'BP3D', ...) --- build/linux/Makefile.in | 3 +- matlab/mex/astra_mex_direct_c.cpp | 332 ++++++++++++++++++++++++++++++++++++++ matlab/tools/astra_mex_direct.m | 24 +++ 3 files changed, 358 insertions(+), 1 deletion(-) create mode 100755 matlab/mex/astra_mex_direct_c.cpp create mode 100644 matlab/tools/astra_mex_direct.m (limited to 'matlab') diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index 2d862f2..abbebe2 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -232,7 +232,8 @@ MATLAB_MEX=\ matlab/mex/astra_mex_projector_c.$(MEXSUFFIX) \ matlab/mex/astra_mex_projector3d_c.$(MEXSUFFIX) \ matlab/mex/astra_mex_log_c.$(MEXSUFFIX) \ - matlab/mex/astra_mex_data3d_c.$(MEXSUFFIX) + matlab/mex/astra_mex_data3d_c.$(MEXSUFFIX) \ + matlab/mex/astra_mex_direct_c.$(MEXSUFFIX) OBJECT_DIRS = src/ tests/ cuda/2d/ cuda/3d/ matlab/mex/ ./ diff --git a/matlab/mex/astra_mex_direct_c.cpp b/matlab/mex/astra_mex_direct_c.cpp new file mode 100755 index 0000000..94eb1cd --- /dev/null +++ b/matlab/mex/astra_mex_direct_c.cpp @@ -0,0 +1,332 @@ +/* +----------------------------------------------------------------------- +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$ +*/ + +/** \file astra_mex_direct_c.cpp + * + * \brief Utility functions for low-overhead FP and BP calls. + */ +#include +#include "mexHelpFunctions.h" +#include "mexCopyDataHelpFunctions.h" +#include "mexDataManagerHelpFunctions.h" + +#include + +#include "astra/Globals.h" + +#include "astra/AstraObjectManager.h" + +#include "astra/Float32ProjectionData2D.h" +#include "astra/Float32VolumeData2D.h" +#include "astra/CudaProjector3D.h" +#include "astra/Projector3D.h" +#include "astra/Float32ProjectionData3DMemory.h" +#include "astra/Float32VolumeData3DMemory.h" + +#include "astra/CudaForwardProjectionAlgorithm3D.h" + +#include "astra/CudaBackProjectionAlgorithm3D.h" + +using namespace std; +using namespace astra; + +#define USE_MATLAB_UNDOCUMENTED + + +class CFloat32CustomMemory_simple : public astra::CFloat32CustomMemory { +public: + CFloat32CustomMemory_simple(float *ptr) { m_fPtr = ptr; } + ~CFloat32CustomMemory_simple() { } +}; + +#ifdef ASTRA_CUDA + +//----------------------------------------------------------------------------------------- +/** + * projection = astra_mex_direct_c('FP3D', projector_id, volume); + * Both 'projection' and 'volume' are Matlab arrays. + */ +void astra_mex_direct_fp3d(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[]) +{ + // TODO: Add an optional way of specifying extra options + + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. Syntax: astra_mex_direct_c('FP3D', projector_id, data)"); + return; + } + + int iPid = (int)(mxGetScalar(prhs[1])); + astra::CProjector3D* pProjector; + pProjector = astra::CProjector3DManager::getSingleton().get(iPid); + if (!pProjector) { + mexErrMsgTxt("Projector not found."); + return; + } + if (!pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized."); + return; + } + bool isCuda = false; + if (dynamic_cast(pProjector)) + isCuda = true; + if (!isCuda) { + mexErrMsgTxt("Only CUDA projectors are currently supported."); + return; + } + + astra::CVolumeGeometry3D* pVolGeom = pProjector->getVolumeGeometry(); + astra::CProjectionGeometry3D* pProjGeom = pProjector->getProjectionGeometry(); + + const mxArray* const data = prhs[2]; + if (!checkDataType(data)) { + mexErrMsgTxt("Data must be single or double."); + return; + } + + if (!checkDataSize(data, pVolGeom)) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry."); + return; + } + + + // Allocate input data + astra::CFloat32VolumeData3DMemory* pInput; + if (mxIsSingle(data)) { + astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(data)); + pInput = new astra::CFloat32VolumeData3DMemory(pVolGeom, m); + } else { + pInput = new astra::CFloat32VolumeData3DMemory(pVolGeom); + copyMexToCFloat32Array(data, pInput->getData(), pInput->getSize()); + } + + + // Allocate output data + // If the input is single, we also allocate single output. + // Otherwise, double. + astra::CFloat32ProjectionData3DMemory* pOutput; + mxArray *pOutputMx; + if (mxIsSingle(data)) { + mwSize dims[3]; + dims[0] = pProjGeom->getDetectorColCount(); + dims[1] = pProjGeom->getProjectionCount(); + dims[2] = pProjGeom->getDetectorRowCount(); + pOutputMx = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL); + + astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(pOutputMx)); + pOutput = new astra::CFloat32ProjectionData3DMemory(pProjGeom, m); + } else { + pOutput = new astra::CFloat32ProjectionData3DMemory(pProjGeom); + } + + // Perform FP + + astra::CCudaForwardProjectionAlgorithm3D* pAlg; + pAlg = new astra::CCudaForwardProjectionAlgorithm3D(); + pAlg->initialize(pProjector, pOutput, pInput); + + if (!pAlg->isInitialized()) { + mexErrMsgTxt("Error initializing algorithm."); + // TODO: Delete pOutputMx? + delete pAlg; + delete pInput; + delete pOutput; + return; + } + + pAlg->run(); + + delete pAlg; + + + if (mxIsSingle(data)) { + + } else { + pOutputMx = createEquivMexArray(pOutput); + copyCFloat32ArrayToMex(pOutput->getData(), pOutputMx); + } + plhs[0] = pOutputMx; + + delete pOutput; + delete pInput; +} +//----------------------------------------------------------------------------------------- +/** + * projection = astra_mex_direct_c('BP3D', projector_id, volume); + * Both 'projection' and 'volume' are Matlab arrays. + */ +void astra_mex_direct_bp3d(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[]) +{ + // TODO: Add an optional way of specifying extra options + + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. Syntax: astra_mex_direct_c('BP3D', projector_id, data)"); + return; + } + + int iPid = (int)(mxGetScalar(prhs[1])); + astra::CProjector3D* pProjector; + pProjector = astra::CProjector3DManager::getSingleton().get(iPid); + if (!pProjector) { + mexErrMsgTxt("Projector not found."); + return; + } + if (!pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized."); + return; + } + bool isCuda = false; + if (dynamic_cast(pProjector)) + isCuda = true; + if (!isCuda) { + mexErrMsgTxt("Only CUDA projectors are currently supported."); + return; + } + + astra::CVolumeGeometry3D* pVolGeom = pProjector->getVolumeGeometry(); + astra::CProjectionGeometry3D* pProjGeom = pProjector->getProjectionGeometry(); + + const mxArray* const data = prhs[2]; + if (!checkDataType(data)) { + mexErrMsgTxt("Data must be single or double."); + return; + } + + if (!checkDataSize(data, pProjGeom)) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry."); + return; + } + + + // Allocate input data + astra::CFloat32ProjectionData3DMemory* pInput; + if (mxIsSingle(data)) { + astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(data)); + pInput = new astra::CFloat32ProjectionData3DMemory(pProjGeom, m); + } else { + pInput = new astra::CFloat32ProjectionData3DMemory(pProjGeom); + copyMexToCFloat32Array(data, pInput->getData(), pInput->getSize()); + } + + + // Allocate output data + // If the input is single, we also allocate single output. + // Otherwise, double. + astra::CFloat32VolumeData3DMemory* pOutput; + mxArray *pOutputMx; + if (mxIsSingle(data)) { + mwSize dims[3]; + dims[0] = pVolGeom->getGridColCount(); + dims[1] = pVolGeom->getGridRowCount(); + dims[2] = pVolGeom->getGridSliceCount(); + pOutputMx = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL); + + astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(pOutputMx)); + pOutput = new astra::CFloat32VolumeData3DMemory(pVolGeom, m); + } else { + pOutput = new astra::CFloat32VolumeData3DMemory(pVolGeom); + } + + // Perform BP + + astra::CCudaBackProjectionAlgorithm3D* pAlg; + pAlg = new astra::CCudaBackProjectionAlgorithm3D(); + pAlg->initialize(pProjector, pInput, pOutput); + + if (!pAlg->isInitialized()) { + mexErrMsgTxt("Error initializing algorithm."); + // TODO: Delete pOutputMx? + delete pAlg; + delete pInput; + delete pOutput; + return; + } + + pAlg->run(); + + delete pAlg; + + + if (mxIsSingle(data)) { + + } else { + pOutputMx = createEquivMexArray(pOutput); + copyCFloat32ArrayToMex(pOutput->getData(), pOutputMx); + } + plhs[0] = pOutputMx; + + delete pOutput; + delete pInput; +} + +#endif + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf("Valid modes: FP3D, BP3D\n"); +} + + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex_direct_c(mode,...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + + // INPUT: Mode + string sMode; + if (1 <= nrhs) { + sMode = mexToString(prhs[0]); + } else { + printHelp(); + return; + } + +#ifndef ASTRA_CUDA + mexErrMsgTxt("Only CUDA projectors are currently supported."); + return; +#else + + // 3D data + if (sMode == "FP3D") { + astra_mex_direct_fp3d(nlhs, plhs, nrhs, prhs); + } else if (sMode == "BP3D") { + astra_mex_direct_bp3d(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } +#endif + + return; +} + + diff --git a/matlab/tools/astra_mex_direct.m b/matlab/tools/astra_mex_direct.m new file mode 100644 index 0000000..58c4fd2 --- /dev/null +++ b/matlab/tools/astra_mex_direct.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex_direct(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% astra_mex_data3d. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the ASTRA Toolbox +% +% Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp +% 2014-2015, CWI, Amsterdam +% License: Open Source under GPLv3 +% Contact: astra@uantwerpen.be +% Website: http://sf.net/projects/astra-toolbox +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_direct_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_direct_c(varargin{:}); +end -- cgit v1.2.3 From 793afbc3fa1cca64292716869e503cb66942606d Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 7 Oct 2015 17:29:40 +0200 Subject: Build astra_mex_direct in MSVC --- astra_vc09.sln | 22 ++ astra_vc11.sln | 22 ++ build/msvc/gen.py | 15 +- matlab/mex/astra_mex_direct_vc09.vcproj | 612 +++++++++++++++++++++++++++++++ matlab/mex/astra_mex_direct_vc11.vcxproj | 306 ++++++++++++++++ 5 files changed, 975 insertions(+), 2 deletions(-) create mode 100644 matlab/mex/astra_mex_direct_vc09.vcproj create mode 100644 matlab/mex/astra_mex_direct_vc11.vcxproj (limited to 'matlab') diff --git a/astra_vc09.sln b/astra_vc09.sln index 9b93a0f..371e9b1 100644 --- a/astra_vc09.sln +++ b/astra_vc09.sln @@ -48,6 +48,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astra_mex_log", "matlab\mex {12926444-6723-46A8-B388-12E65E0577FA} = {12926444-6723-46A8-B388-12E65E0577FA} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astra_mex_direct", "matlab\mex\astra_mex_direct_vc09.vcproj", "{85FE09A6-FA49-4314-A2B1-59D77C7442A8}" + ProjectSection(ProjectDependencies) = postProject + {12926444-6723-46A8-B388-12E65E0577FA} = {12926444-6723-46A8-B388-12E65E0577FA} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_CUDA|Win32 = Debug_CUDA|Win32 @@ -204,6 +209,22 @@ Global {CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8}.Release|Win32.Build.0 = Release|Win32 {CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8}.Release|x64.ActiveCfg = Release|x64 {CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8}.Release|x64.Build.0 = Release|x64 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug_CUDA|Win32.ActiveCfg = Debug_CUDA|Win32 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug_CUDA|Win32.Build.0 = Debug_CUDA|Win32 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug_CUDA|x64.ActiveCfg = Debug_CUDA|x64 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug_CUDA|x64.Build.0 = Debug_CUDA|x64 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug|Win32.ActiveCfg = Debug|Win32 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug|Win32.Build.0 = Debug|Win32 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug|x64.ActiveCfg = Debug|x64 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug|x64.Build.0 = Debug|x64 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release_CUDA|Win32.ActiveCfg = Release_CUDA|Win32 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release_CUDA|Win32.Build.0 = Release_CUDA|Win32 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release_CUDA|x64.ActiveCfg = Release_CUDA|x64 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release_CUDA|x64.Build.0 = Release_CUDA|x64 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release|Win32.ActiveCfg = Release|Win32 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release|Win32.Build.0 = Release|Win32 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release|x64.ActiveCfg = Release|x64 + {85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -217,5 +238,6 @@ Global {4DD6056F-8EEE-4C9A-B2A9-923F01A32E97} = {33EF0AC5-B475-40BF-BAE5-67075B204D10} {F94CCD79-AA11-42DF-AC8A-6C9D2238A883} = {33EF0AC5-B475-40BF-BAE5-67075B204D10} {CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8} = {33EF0AC5-B475-40BF-BAE5-67075B204D10} + {85FE09A6-FA49-4314-A2B1-59D77C7442A8} = {33EF0AC5-B475-40BF-BAE5-67075B204D10} EndGlobalSection EndGlobal diff --git a/astra_vc11.sln b/astra_vc11.sln index 2832eab..92fb584 100644 --- a/astra_vc11.sln +++ b/astra_vc11.sln @@ -48,6 +48,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astra_mex_log", "matlab\mex {BE9F1326-527C-4284-AE2C-D1E25D539CEA} = {BE9F1326-527C-4284-AE2C-D1E25D539CEA} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astra_mex_direct", "matlab\mex\astra_mex_direct_vc11.vcxproj", "{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}" + ProjectSection(ProjectDependencies) = postProject + {BE9F1326-527C-4284-AE2C-D1E25D539CEA} = {BE9F1326-527C-4284-AE2C-D1E25D539CEA} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_CUDA|Win32 = Debug_CUDA|Win32 @@ -204,6 +209,22 @@ Global {03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E}.Release|Win32.Build.0 = Release|Win32 {03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E}.Release|x64.ActiveCfg = Release|x64 {03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E}.Release|x64.Build.0 = Release|x64 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug_CUDA|Win32.ActiveCfg = Debug_CUDA|Win32 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug_CUDA|Win32.Build.0 = Debug_CUDA|Win32 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug_CUDA|x64.ActiveCfg = Debug_CUDA|x64 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug_CUDA|x64.Build.0 = Debug_CUDA|x64 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug|Win32.ActiveCfg = Debug|Win32 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug|Win32.Build.0 = Debug|Win32 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug|x64.ActiveCfg = Debug|x64 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug|x64.Build.0 = Debug|x64 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release_CUDA|Win32.ActiveCfg = Release_CUDA|Win32 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release_CUDA|Win32.Build.0 = Release_CUDA|Win32 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release_CUDA|x64.ActiveCfg = Release_CUDA|x64 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release_CUDA|x64.Build.0 = Release_CUDA|x64 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release|Win32.ActiveCfg = Release|Win32 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release|Win32.Build.0 = Release|Win32 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release|x64.ActiveCfg = Release|x64 + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -217,5 +238,6 @@ Global {4DD6056F-8EEE-4C9A-B2A9-923F01A32E97} = {5E99A109-374E-4102-BE9B-99BA1FA8AA30} {F94CCD79-AA11-42DF-AC8A-6C9D2238A883} = {5E99A109-374E-4102-BE9B-99BA1FA8AA30} {03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E} = {5E99A109-374E-4102-BE9B-99BA1FA8AA30} + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7} = {5E99A109-374E-4102-BE9B-99BA1FA8AA30} EndGlobalSection EndGlobal diff --git a/build/msvc/gen.py b/build/msvc/gen.py index aeca3b0..a9bc494 100644 --- a/build/msvc/gen.py +++ b/build/msvc/gen.py @@ -24,6 +24,7 @@ P4 = create_mex_project("astra_mex_matrix", "9D041710-2119-4230-BCF2-5FBE753FDE4 P5 = create_mex_project("astra_mex_projector", "4DD6056F-8EEE-4C9A-B2A9-923F01A32E97", "4DD6056F-8EEE-4C9A-B2A9-923F01A32E97") P6 = create_mex_project("astra_mex_projector3d", "F94CCD79-AA11-42DF-AC8A-6C9D2238A883", "F94CCD79-AA11-42DF-AC8A-6C9D2238A883") P7 = create_mex_project("astra_mex_log", "03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E", "CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8") +P8 = create_mex_project("astra_mex_direct", "0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7", "85FE09A6-FA49-4314-A2B1-59D77C7442A8") F_astra_mex = { "type": siguid, "name": "astra_mex", @@ -31,7 +32,7 @@ F_astra_mex = { "type": siguid, "file09": "astra_mex", "uuid11": "5E99A109-374E-4102-BE9B-99BA1FA8AA30", "uuid09": "33EF0AC5-B475-40BF-BAE5-67075B204D10", - "entries": [ P0, P1, P2, P3, P4, P5, P6, P7 ] } + "entries": [ P0, P1, P2, P3, P4, P5, P6, P7, P8 ] } P0["files"] = [ @@ -98,6 +99,14 @@ P7["files"] = [ "mexInitFunctions.cpp", "mexInitFunctions.h", ] +P8["files"] = [ +"astra_mex_direct_c.cpp", +"mexHelpFunctions.cpp", +"mexHelpFunctions.h", +"mexInitFunctions.cpp", +"mexInitFunctions.h", +] + @@ -407,7 +416,7 @@ for f in P_astra["filters"]: P_astra["files"].extend(P_astra["filters"][f][1:]) P_astra["files"].sort() -projects = [ P_astra, F_astra_mex, P0, P1, P2, P3, P4, P5, P6, P7 ] +projects = [ P_astra, F_astra_mex, P0, P1, P2, P3, P4, P5, P6, P7, P8 ] bom = "\xef\xbb\xbf" @@ -1111,6 +1120,7 @@ if sys.argv[1] in ["vc11", "all"]: write_mex_project11(P5) write_mex_project11(P6) write_mex_project11(P7) + write_mex_project11(P8) if sys.argv[1] in ["vc09", "all"]: # HACK @@ -1126,3 +1136,4 @@ if sys.argv[1] in ["vc09", "all"]: write_mex_project09(P5) write_mex_project09(P6) write_mex_project09(P7) + write_mex_project09(P8) diff --git a/matlab/mex/astra_mex_direct_vc09.vcproj b/matlab/mex/astra_mex_direct_vc09.vcproj new file mode 100644 index 0000000..04b49ac --- /dev/null +++ b/matlab/mex/astra_mex_direct_vc09.vcproj @@ -0,0 +1,612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/matlab/mex/astra_mex_direct_vc11.vcxproj b/matlab/mex/astra_mex_direct_vc11.vcxproj new file mode 100644 index 0000000..15c3c06 --- /dev/null +++ b/matlab/mex/astra_mex_direct_vc11.vcxproj @@ -0,0 +1,306 @@ + + + + + Debug_CUDA + Win32 + + + Debug_CUDA + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release_CUDA + Win32 + + + Release_CUDA + x64 + + + Release + Win32 + + + Release + x64 + + + + astra_mex_direct + {0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7} + astraMatlab + + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + DynamicLibrary + v110 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>11.0.60610.1 + + + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + $(ProjectName)_c + .mexw32 + + + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + $(ProjectName)_c + .mexw64 + + + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + $(ProjectName)_c + .mexw32 + + + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + $(ProjectName)_c + .mexw64 + + + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + $(ProjectName)_c + .mexw32 + + + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + $(ProjectName)_c + .mexw64 + + + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + $(ProjectName)_c + .mexw32 + + + $(SolutionDir)bin\$(Platform)\$(Configuration)\ + $(OutDir)obj\$(ProjectName)\ + $(ProjectName)_c + .mexw64 + + + + MultiThreadedDebugDLL + $(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories) + true + StreamingSIMDExtensions2 + Disabled + ASTRA_CUDA;__SSE2__;%(PreprocessorDefinitions) + true + + + $(OutDir)$(ProjectName)_c.mexw32 + AstraCuda32D.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies) + ..\..\lib\win32\;..\..\bin\win32\Debug_CUDA;$(MATLAB_ROOT)\extern\lib\win32\microsoft;%(AdditionalLibraryDirectories) + mex.def + true + + + + + MultiThreadedDebugDLL + $(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories) + true + Disabled + ASTRA_CUDA;__SSE2__;%(PreprocessorDefinitions) + true + + + $(OutDir)$(ProjectName)_c.mexw64 + AstraCuda64D.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies) + ..\..\lib\x64\;..\..\bin\x64\Debug_CUDA;$(MATLAB_ROOT)\extern\lib\win64\microsoft;%(AdditionalLibraryDirectories) + mex.def + true + + + + + MultiThreadedDebugDLL + $(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories) + true + StreamingSIMDExtensions2 + Disabled + __SSE2__;%(PreprocessorDefinitions) + true + + + $(OutDir)$(ProjectName)_c.mexw32 + Astra32D.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies) + ..\..\lib\win32\;..\..\bin\win32\Debug;$(MATLAB_ROOT)\extern\lib\win32\microsoft;%(AdditionalLibraryDirectories) + mex.def + true + + + + + MultiThreadedDebugDLL + $(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories) + true + Disabled + __SSE2__;%(PreprocessorDefinitions) + true + + + $(OutDir)$(ProjectName)_c.mexw64 + Astra64D.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies) + ..\..\lib\x64\;..\..\bin\x64\Debug;$(MATLAB_ROOT)\extern\lib\win64\microsoft;%(AdditionalLibraryDirectories) + mex.def + true + + + + + MultiThreadedDLL + $(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories) + true + StreamingSIMDExtensions2 + MaxSpeed + ASTRA_CUDA;__SSE2__;%(PreprocessorDefinitions) + true + + + $(OutDir)$(ProjectName)_c.mexw32 + AstraCuda32.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies) + ..\..\lib\win32\;..\..\bin\win32\Release_CUDA;$(MATLAB_ROOT)\extern\lib\win32\microsoft;%(AdditionalLibraryDirectories) + mex.def + true + + + + + MultiThreadedDLL + $(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories) + true + MaxSpeed + ASTRA_CUDA;__SSE2__;%(PreprocessorDefinitions) + true + + + $(OutDir)$(ProjectName)_c.mexw64 + AstraCuda64.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies) + ..\..\lib\x64\;..\..\bin\x64\Release_CUDA;$(MATLAB_ROOT)\extern\lib\win64\microsoft;%(AdditionalLibraryDirectories) + mex.def + true + + + + + MultiThreadedDLL + $(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories) + true + StreamingSIMDExtensions2 + MaxSpeed + __SSE2__;%(PreprocessorDefinitions) + true + + + $(OutDir)$(ProjectName)_c.mexw32 + Astra32.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies) + ..\..\lib\win32\;..\..\bin\win32\Release;$(MATLAB_ROOT)\extern\lib\win32\microsoft;%(AdditionalLibraryDirectories) + mex.def + true + + + + + MultiThreadedDLL + $(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories) + true + MaxSpeed + __SSE2__;%(PreprocessorDefinitions) + true + + + $(OutDir)$(ProjectName)_c.mexw64 + Astra64.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies) + ..\..\lib\x64\;..\..\bin\x64\Release;$(MATLAB_ROOT)\extern\lib\win64\microsoft;%(AdditionalLibraryDirectories) + mex.def + true + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3 From 0ebd8dfe60cc0d1f05d65d3840278defce0da091 Mon Sep 17 00:00:00 2001 From: Nicola Vigano Date: Wed, 7 Oct 2015 17:25:06 +0200 Subject: Add options passing to projectors from matlab Signed-off-by: Nicola Vigano --- matlab/tools/astra_create_projector.m | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'matlab') diff --git a/matlab/tools/astra_create_projector.m b/matlab/tools/astra_create_projector.m index da9c083..9bbef9e 100644 --- a/matlab/tools/astra_create_projector.m +++ b/matlab/tools/astra_create_projector.m @@ -1,7 +1,7 @@ -function proj_id = astra_create_projector(type, proj_geom, vol_geom) +function proj_id = astra_create_projector(type, proj_geom, vol_geom, options) %-------------------------------------------------------------------------- -% proj_id = astra_create_projector(type, proj_geom, vol_geom) +% proj_id = astra_create_projector(type, proj_geom, vol_geom, options) % % Create a new projector object based on projection and volume geometry. % Used when the default values of each projector are sufficient. @@ -9,6 +9,7 @@ function proj_id = astra_create_projector(type, proj_geom, vol_geom) % type: type of the projector. 'blob', 'line', 'linear' 'strip', ... See API for more information. % proj_geom: MATLAB struct containing the projection geometry. % vol_geom: MATLAB struct containing the volume geometry. +% options: Optional MATLAB struct containing projector options (like: 'GPUindex', 'DetectorSuperSampling', and 'VoxelSuperSampling') % proj_id: identifier of the projector as it is now stored in the astra-library. %-------------------------------------------------------------------------- %-------------------------------------------------------------------------- @@ -38,6 +39,10 @@ if strcmp(type,'blob') cfg_proj.Kernel.KernelValues = blob_values; end +if exist('options', 'var') + cfg_proj.options = options; +end + if strcmp(type,'linear3d') || strcmp(type,'linearcone') || strcmp(type,'cuda3d') proj_id = astra_mex_projector3d('create', cfg_proj); else -- cgit v1.2.3 From 37dd051faf2a8085c1abb5623eb5e79363471642 Mon Sep 17 00:00:00 2001 From: Nicola Vigano Date: Thu, 2 Apr 2015 17:07:25 +0200 Subject: astra_mex_direct: Don't initialize newly allocated mxArray This avoids letting matlab initialize the memory we will overwrite shortly after. --- matlab/mex/astra_mex_direct_c.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_direct_c.cpp b/matlab/mex/astra_mex_direct_c.cpp index 94eb1cd..38b3f59 100755 --- a/matlab/mex/astra_mex_direct_c.cpp +++ b/matlab/mex/astra_mex_direct_c.cpp @@ -135,7 +135,15 @@ void astra_mex_direct_fp3d(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* dims[0] = pProjGeom->getDetectorColCount(); dims[1] = pProjGeom->getProjectionCount(); dims[2] = pProjGeom->getDetectorRowCount(); - pOutputMx = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL); + + // Allocate uninitialized mxArray of size dims. + // (It will be zeroed by CudaForwardProjectionAlgorithm3D) + const mwSize zero_dims[2] = {0, 0}; + pOutputMx = mxCreateNumericArray(2, zero_dims, mxSINGLE_CLASS, mxREAL); + mxSetDimensions(pOutputMx, dims, 3); + const mwSize num_elems = mxGetNumberOfElements(pOutputMx); + const mwSize elem_size = mxGetElementSize(pOutputMx); + mxSetData(pOutputMx, mxMalloc(elem_size * num_elems)); astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(pOutputMx)); pOutput = new astra::CFloat32ProjectionData3DMemory(pProjGeom, m); @@ -243,7 +251,15 @@ void astra_mex_direct_bp3d(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* dims[0] = pVolGeom->getGridColCount(); dims[1] = pVolGeom->getGridRowCount(); dims[2] = pVolGeom->getGridSliceCount(); - pOutputMx = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL); + + // Allocate uninitialized mxArray of size dims. + // (It will be zeroed by CudaBackProjectionAlgorithm3D) + const mwSize zero_dims[2] = {0, 0}; + pOutputMx = mxCreateNumericArray(2, zero_dims, mxSINGLE_CLASS, mxREAL); + mxSetDimensions(pOutputMx, dims, 3); + const mwSize num_elems = mxGetNumberOfElements(pOutputMx); + const mwSize elem_size = mxGetElementSize(pOutputMx); + mxSetData(pOutputMx, mxMalloc(elem_size * num_elems)); astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(pOutputMx)); pOutput = new astra::CFloat32VolumeData3DMemory(pVolGeom, m); -- cgit v1.2.3 From 6d57f7874713e6632c2e49590538c6a48ddcc311 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 2 Dec 2015 14:53:36 +0100 Subject: Fix Windows builds of astra_mex_direct --- build/msvc/gen.py | 4 ++++ matlab/mex/astra_mex_direct_vc09.vcproj | 16 ++++++++++++++++ matlab/mex/astra_mex_direct_vc11.vcxproj | 4 ++++ 3 files changed, 24 insertions(+) (limited to 'matlab') diff --git a/build/msvc/gen.py b/build/msvc/gen.py index a9bc494..72d4582 100644 --- a/build/msvc/gen.py +++ b/build/msvc/gen.py @@ -103,6 +103,10 @@ P8["files"] = [ "astra_mex_direct_c.cpp", "mexHelpFunctions.cpp", "mexHelpFunctions.h", +"mexCopyDataHelpFunctions.cpp", +"mexCopyDataHelpFunctions.h", +"mexDataManagerHelpFunctions.cpp", +"mexDataManagerHelpFunctions.h", "mexInitFunctions.cpp", "mexInitFunctions.h", ] diff --git a/matlab/mex/astra_mex_direct_vc09.vcproj b/matlab/mex/astra_mex_direct_vc09.vcproj index 04b49ac..5d27c65 100644 --- a/matlab/mex/astra_mex_direct_vc09.vcproj +++ b/matlab/mex/astra_mex_direct_vc09.vcproj @@ -598,6 +598,22 @@ RelativePath=".\mexHelpFunctions.h" > + + + + + + + + diff --git a/matlab/mex/astra_mex_direct_vc11.vcxproj b/matlab/mex/astra_mex_direct_vc11.vcxproj index 15c3c06..bc2db62 100644 --- a/matlab/mex/astra_mex_direct_vc11.vcxproj +++ b/matlab/mex/astra_mex_direct_vc11.vcxproj @@ -294,10 +294,14 @@ + + + + -- cgit v1.2.3 From fc86917da1a175c04e9bd2e5f0bedb0a48a81c26 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Thu, 17 Dec 2015 14:37:41 +0100 Subject: Replace boost::lexical_cast by stringstreams This is to avoid the dependence of lexical_cast on the current locale. The stringstreams used for the new string parsing/output functions are explicitly imbued with the C/classic locale. --- build/linux/configure.ac | 1 - include/astra/Utilities.h | 51 ++++++++++++++++ include/astra/XMLNode.h | 8 +++ matlab/mex/mexHelpFunctions.cpp | 8 +-- matlab/mex/mexHelpFunctions.h | 1 - src/ArtAlgorithm.cpp | 2 - src/BackProjectionAlgorithm.cpp | 2 - src/CglsAlgorithm.cpp | 2 - src/ConeProjectionGeometry3D.cpp | 5 +- src/ConeVecProjectionGeometry3D.cpp | 30 ++++----- src/CudaBackProjectionAlgorithm3D.cpp | 2 - src/CudaCglsAlgorithm3D.cpp | 2 - src/CudaDartMaskAlgorithm.cpp | 5 +- src/CudaDartMaskAlgorithm3D.cpp | 5 +- src/CudaDartSmoothingAlgorithm.cpp | 5 +- src/CudaDartSmoothingAlgorithm3D.cpp | 5 +- src/CudaDataOperationAlgorithm.cpp | 5 +- src/CudaFDKAlgorithm3D.cpp | 2 - src/CudaFilteredBackProjectionAlgorithm.cpp | 13 ++-- src/CudaForwardProjectionAlgorithm.cpp | 8 +-- src/CudaForwardProjectionAlgorithm3D.cpp | 8 +-- src/CudaReconstructionAlgorithm2D.cpp | 2 - src/CudaRoiSelectAlgorithm.cpp | 3 +- src/CudaSirtAlgorithm.cpp | 5 +- src/CudaSirtAlgorithm3D.cpp | 2 - src/FanFlatBeamLineKernelProjector2D.cpp | 1 - src/FanFlatBeamStripKernelProjector2D.cpp | 1 - src/FanFlatProjectionGeometry2D.cpp | 5 +- src/FanFlatVecProjectionGeometry2D.cpp | 15 +++-- src/FilteredBackProjectionAlgorithm.cpp | 8 +-- src/ForwardProjectionAlgorithm.cpp | 12 ++-- src/ParallelBeamBlobKernelProjector2D.cpp | 7 +-- src/ParallelBeamLineKernelProjector2D.cpp | 1 - src/ParallelBeamLinearKernelProjector2D.cpp | 1 - src/ParallelBeamStripKernelProjector2D.cpp | 1 - src/ParallelProjectionGeometry2D.cpp | 1 - src/ParallelProjectionGeometry3D.cpp | 1 - src/ParallelVecProjectionGeometry3D.cpp | 30 ++++----- src/PluginAlgorithm.cpp | 14 ++--- src/ProjectionGeometry2D.cpp | 6 +- src/ProjectionGeometry3D.cpp | 10 ++- src/ReconstructionAlgorithm2D.cpp | 12 ++-- src/ReconstructionAlgorithm3D.cpp | 12 ++-- src/ReconstructionAlgorithmMultiSlice2D.cpp | 8 +-- src/SartAlgorithm.cpp | 2 - src/SirtAlgorithm.cpp | 2 - src/SparseMatrixProjectionGeometry2D.cpp | 3 +- src/SparseMatrixProjector2D.cpp | 1 - src/Utilities.cpp | 95 +++++++++++++++++++++++++++++ src/VolumeGeometry2D.cpp | 5 +- src/VolumeGeometry3D.cpp | 8 +-- src/XMLNode.cpp | 77 +++++++++-------------- 52 files changed, 297 insertions(+), 224 deletions(-) (limited to 'matlab') diff --git a/build/linux/configure.ac b/build/linux/configure.ac index 85e4324..9b6f7ab 100644 --- a/build/linux/configure.ac +++ b/build/linux/configure.ac @@ -73,7 +73,6 @@ AC_SUBST(HAVEBOOSTUTF) AC_SUBST(LIBS_BOOSTUTF) BOOSTok=yes -AC_CHECK_HEADER([boost/lexical_cast.hpp],[],[BOOSTok=no],[]) AC_CHECK_HEADER([boost/any.hpp],[],[BOOSTok=no],[]) dnl AC_CHECK_HEADER([boost/thread.hpp],[],[BOOSTok=no],[]) dnl AC_CHECK_HEADER([boost/bind.hpp],[],[BOOSTok=no],[]) diff --git a/include/astra/Utilities.h b/include/astra/Utilities.h index a3655a8..3ae0e6c 100644 --- a/include/astra/Utilities.h +++ b/include/astra/Utilities.h @@ -39,6 +39,57 @@ namespace astra { +namespace StringUtil { + +// Exception thrown by functions below +class bad_cast : public std::exception { +public: + bad_cast() { } +}; + + +//< Parse string as int. +//< Throw exception on failure. +int stringToInt(const std::string& s); + +//< Parse string as float. +//< Throw exception on failure. +float stringToFloat(const std::string& s); + +//< Parse string as double. +//< Throw exception on failure. +double stringToDouble(const std::string& s); + +template +T stringTo(const std::string& s); + +//< Parse comma/semicolon-separated string as float vector. +//< Throw exception on failure. +std::vector stringToFloatVector(const std::string& s); + +//< Parse comma/semicolon-separated string as double vector. +//< Throw exception on failure. +std::vector stringToDoubleVector(const std::string& s); + +template +std::vector stringToVector(const std::string& s); + + + +//< Generate string from float. +std::string floatToString(float f); + +//< Generate string from double. +std::string doubleToString(double f); + +template +std::string toString(T f); + +} + + + + template std::map mergeMap(std::map _mMap1, std::map _mMap2) { diff --git a/include/astra/XMLNode.h b/include/astra/XMLNode.h index 4d29d5c..7d1edf5 100644 --- a/include/astra/XMLNode.h +++ b/include/astra/XMLNode.h @@ -101,6 +101,12 @@ public: */ string getContent() const; + /** Get the content of the XML node as an integer + * + * @return node content + */ + int getContentInt() const; + /** Get the content of the XML node as a numerical. * * @return node content @@ -152,6 +158,7 @@ public: */ float32 getAttributeNumerical(string _sName, float32 _fDefaultValue = 0) const; double getAttributeNumericalDouble(string _sName, double _fDefaultValue = 0) const; + int getAttributeInt(string _sName, int _fDefaultValue = 0) const; /** Get the value of a boolean attribute. * @@ -186,6 +193,7 @@ public: * @return option value, _fDefaultValue if the option doesn't exist */ float32 getOptionNumerical(string _sKey, float32 _fDefaultValue = 0) const; + int getOptionInt(string _sKey, int _fDefaultValue = 0) const; /** Get the value of an option within this XML Node * diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp index 58e84d2..13c4ade 100644 --- a/matlab/mex/mexHelpFunctions.cpp +++ b/matlab/mex/mexHelpFunctions.cpp @@ -31,9 +31,9 @@ $Id$ * \brief Contains some functions for interfacing matlab with c data structures */ #include "mexHelpFunctions.h" +#include "astra/Utilities.h" #include -#include #include #include #include @@ -58,7 +58,7 @@ string mexToString(const mxArray* pInput) // is scalar? if (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1) { - return boost::lexical_cast(mxGetScalar(pInput)); + return StringUtil::doubleToString(mxGetScalar(pInput)); } return ""; @@ -378,7 +378,7 @@ mxArray* stringToMxArray(std::string input) boost::split(col_strings, row_strings[row], boost::is_any_of(",")); // check size for (unsigned int col = 0; col < col_strings.size(); col++) { - out[col*rows + row] = boost::lexical_cast(col_strings[col]); + out[col*rows + row] = StringUtil::stringToFloat(col_strings[col]); } } return pMatrix; @@ -397,7 +397,7 @@ mxArray* stringToMxArray(std::string input) // loop elements for (unsigned int i = 0; i < items.size(); i++) { - out[i] = boost::lexical_cast(items[i]); + out[i] = StringUtil::stringToFloat(items[i]); } return pVector; } diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h index 3ac5bd8..07edc64 100644 --- a/matlab/mex/mexHelpFunctions.h +++ b/matlab/mex/mexHelpFunctions.h @@ -37,7 +37,6 @@ $Id$ #include #include -#include #include #include "astra/Globals.h" diff --git a/src/ArtAlgorithm.cpp b/src/ArtAlgorithm.cpp index 6a699ec..b59bd93 100644 --- a/src/ArtAlgorithm.cpp +++ b/src/ArtAlgorithm.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/ArtAlgorithm.h" -#include - #include "astra/AstraObjectManager.h" using namespace std; diff --git a/src/BackProjectionAlgorithm.cpp b/src/BackProjectionAlgorithm.cpp index f561a90..c9beee1 100644 --- a/src/BackProjectionAlgorithm.cpp +++ b/src/BackProjectionAlgorithm.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/BackProjectionAlgorithm.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/DataProjectorPolicies.h" diff --git a/src/CglsAlgorithm.cpp b/src/CglsAlgorithm.cpp index b9031e3..1ca2549 100644 --- a/src/CglsAlgorithm.cpp +++ b/src/CglsAlgorithm.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/CglsAlgorithm.h" -#include - #include "astra/AstraObjectManager.h" using namespace std; diff --git a/src/ConeProjectionGeometry3D.cpp b/src/ConeProjectionGeometry3D.cpp index 18f0f8a..99b4bf4 100644 --- a/src/ConeProjectionGeometry3D.cpp +++ b/src/ConeProjectionGeometry3D.cpp @@ -31,7 +31,6 @@ $Id$ #include "astra/Logging.h" #include "astra/GeometryUtil3D.h" -#include #include using namespace std; @@ -90,13 +89,13 @@ bool CConeProjectionGeometry3D::initialize(const Config& _cfg) // Required: DistanceOriginDetector XMLNode node = _cfg.self.getSingleNode("DistanceOriginDetector"); ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginDetector tag specified."); - m_fOriginDetectorDistance = boost::lexical_cast(node.getContent()); + m_fOriginDetectorDistance = node.getContentNumerical(); CC.markNodeParsed("DistanceOriginDetector"); // Required: DetectorOriginSource node = _cfg.self.getSingleNode("DistanceOriginSource"); ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginSource tag specified."); - m_fOriginSourceDistance = boost::lexical_cast(node.getContent()); + m_fOriginSourceDistance = node.getContentNumerical(); CC.markNodeParsed("DistanceOriginSource"); // success diff --git a/src/ConeVecProjectionGeometry3D.cpp b/src/ConeVecProjectionGeometry3D.cpp index 86e3bd6..f4f900d 100644 --- a/src/ConeVecProjectionGeometry3D.cpp +++ b/src/ConeVecProjectionGeometry3D.cpp @@ -27,9 +27,9 @@ $Id$ */ #include "astra/ConeVecProjectionGeometry3D.h" +#include "astra/Utilities.h" #include -#include using namespace std; @@ -82,13 +82,13 @@ bool CConeVecProjectionGeometry3D::initialize(const Config& _cfg) // Required: DetectorRowCount node = _cfg.self.getSingleNode("DetectorRowCount"); ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = boost::lexical_cast(node.getContent()); + m_iDetectorRowCount = node.getContentInt(); CC.markNodeParsed("DetectorRowCount"); // Required: DetectorColCount node = _cfg.self.getSingleNode("DetectorColCount"); ASTRA_CONFIG_CHECK(node, "ConeVecProjectionGeometry3D", "No DetectorColCount tag specified."); - m_iDetectorColCount = boost::lexical_cast(node.getContent()); + m_iDetectorColCount = node.getContentInt(); m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; CC.markNodeParsed("DetectorColCount"); @@ -212,18 +212,18 @@ Config* CConeVecProjectionGeometry3D::getConfiguration() const std::string vectors = ""; for (int i = 0; i < m_iProjectionAngleCount; ++i) { SConeProjection& p = m_pProjectionAngles[i]; - vectors += boost::lexical_cast(p.fSrcX) + ","; - vectors += boost::lexical_cast(p.fSrcY) + ","; - vectors += boost::lexical_cast(p.fSrcZ) + ","; - vectors += boost::lexical_cast(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetVX + 0.5f*m_iDetectorColCount*p.fDetUX) + ","; - vectors += boost::lexical_cast(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetVY + 0.5f*m_iDetectorColCount*p.fDetUY) + ","; - vectors += boost::lexical_cast(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetVZ + 0.5f*m_iDetectorColCount*p.fDetUZ) + ","; - vectors += boost::lexical_cast(p.fDetUX) + ","; - vectors += boost::lexical_cast(p.fDetUY) + ","; - vectors += boost::lexical_cast(p.fDetUZ) + ","; - vectors += boost::lexical_cast(p.fDetVX) + ","; - vectors += boost::lexical_cast(p.fDetVY) + ","; - vectors += boost::lexical_cast(p.fDetVZ); + vectors += StringUtil::toString(p.fSrcX) + ","; + vectors += StringUtil::toString(p.fSrcY) + ","; + vectors += StringUtil::toString(p.fSrcZ) + ","; + vectors += StringUtil::toString(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetVX + 0.5f*m_iDetectorColCount*p.fDetUX) + ","; + vectors += StringUtil::toString(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetVY + 0.5f*m_iDetectorColCount*p.fDetUY) + ","; + vectors += StringUtil::toString(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetVZ + 0.5f*m_iDetectorColCount*p.fDetUZ) + ","; + vectors += StringUtil::toString(p.fDetUX) + ","; + vectors += StringUtil::toString(p.fDetUY) + ","; + vectors += StringUtil::toString(p.fDetUZ) + ","; + vectors += StringUtil::toString(p.fDetVX) + ","; + vectors += StringUtil::toString(p.fDetVY) + ","; + vectors += StringUtil::toString(p.fDetVZ); if (i < m_iProjectionAngleCount-1) vectors += ';'; } cfg->self.addChildNode("Vectors", vectors); diff --git a/src/CudaBackProjectionAlgorithm3D.cpp b/src/CudaBackProjectionAlgorithm3D.cpp index ce8e111..76d7b35 100644 --- a/src/CudaBackProjectionAlgorithm3D.cpp +++ b/src/CudaBackProjectionAlgorithm3D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/CudaBackProjectionAlgorithm3D.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/CudaProjector3D.h" diff --git a/src/CudaCglsAlgorithm3D.cpp b/src/CudaCglsAlgorithm3D.cpp index abc18d1..930a71e 100644 --- a/src/CudaCglsAlgorithm3D.cpp +++ b/src/CudaCglsAlgorithm3D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/CudaCglsAlgorithm3D.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/CudaProjector3D.h" diff --git a/src/CudaDartMaskAlgorithm.cpp b/src/CudaDartMaskAlgorithm.cpp index 950b428..c2a4cca 100644 --- a/src/CudaDartMaskAlgorithm.cpp +++ b/src/CudaDartMaskAlgorithm.cpp @@ -34,7 +34,6 @@ $Id$ #include "../cuda/2d/algo.h" #include "astra/AstraObjectManager.h" -#include using namespace std; @@ -67,14 +66,14 @@ bool CCudaDartMaskAlgorithm::initialize(const Config& _cfg) // reconstruction data XMLNode node = _cfg.self.getSingleNode("SegmentationDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No SegmentationDataId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pSegmentation = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("SegmentationDataId"); // reconstruction data node = _cfg.self.getSingleNode("MaskDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No MaskDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pMask = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("MaskDataId"); diff --git a/src/CudaDartMaskAlgorithm3D.cpp b/src/CudaDartMaskAlgorithm3D.cpp index b0dfc5b..dd12c58 100644 --- a/src/CudaDartMaskAlgorithm3D.cpp +++ b/src/CudaDartMaskAlgorithm3D.cpp @@ -34,7 +34,6 @@ $Id$ #include "../cuda/3d/dims3d.h" #include "astra/AstraObjectManager.h" -#include using namespace std; @@ -67,14 +66,14 @@ bool CCudaDartMaskAlgorithm3D::initialize(const Config& _cfg) // reconstruction data XMLNode node = _cfg.self.getSingleNode("SegmentationDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No SegmentationDataId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pSegmentation = dynamic_cast(CData3DManager::getSingleton().get(id)); CC.markNodeParsed("SegmentationDataId"); // reconstruction data node = _cfg.self.getSingleNode("MaskDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No MaskDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pMask = dynamic_cast(CData3DManager::getSingleton().get(id)); CC.markNodeParsed("MaskDataId"); diff --git a/src/CudaDartSmoothingAlgorithm.cpp b/src/CudaDartSmoothingAlgorithm.cpp index 7e22809..425f0a3 100644 --- a/src/CudaDartSmoothingAlgorithm.cpp +++ b/src/CudaDartSmoothingAlgorithm.cpp @@ -34,7 +34,6 @@ $Id$ #include "../cuda/2d/algo.h" #include "astra/AstraObjectManager.h" -#include using namespace std; @@ -67,14 +66,14 @@ bool CCudaDartSmoothingAlgorithm::initialize(const Config& _cfg) // reconstruction data XMLNode node = _cfg.self.getSingleNode("InDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No InDataId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pIn = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("InDataId"); // reconstruction data node = _cfg.self.getSingleNode("OutDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No OutDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pOut = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("OutDataId"); diff --git a/src/CudaDartSmoothingAlgorithm3D.cpp b/src/CudaDartSmoothingAlgorithm3D.cpp index 9c4437a..df7e0df 100644 --- a/src/CudaDartSmoothingAlgorithm3D.cpp +++ b/src/CudaDartSmoothingAlgorithm3D.cpp @@ -34,7 +34,6 @@ $Id$ #include "../cuda/3d/dims3d.h" #include "astra/AstraObjectManager.h" -#include using namespace std; @@ -67,14 +66,14 @@ bool CCudaDartSmoothingAlgorithm3D::initialize(const Config& _cfg) // reconstruction data XMLNode node = _cfg.self.getSingleNode("InDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No InDataId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pIn = dynamic_cast(CData3DManager::getSingleton().get(id)); CC.markNodeParsed("InDataId"); // reconstruction data node = _cfg.self.getSingleNode("OutDataId"); ASTRA_CONFIG_CHECK(node, "CudaDartMask", "No OutDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pOut = dynamic_cast(CData3DManager::getSingleton().get(id)); CC.markNodeParsed("OutDataId"); diff --git a/src/CudaDataOperationAlgorithm.cpp b/src/CudaDataOperationAlgorithm.cpp index ae133c2..15886a4 100644 --- a/src/CudaDataOperationAlgorithm.cpp +++ b/src/CudaDataOperationAlgorithm.cpp @@ -35,7 +35,6 @@ $Id$ #include "../cuda/2d/arith.h" #include "astra/AstraObjectManager.h" -#include using namespace std; @@ -78,7 +77,7 @@ bool CCudaDataOperationAlgorithm::initialize(const Config& _cfg) ASTRA_CONFIG_CHECK(node, "CCudaDataOperationAlgorithm", "No DataId tag specified."); vector data = node.getContentArray(); for (vector::iterator it = data.begin(); it != data.end(); it++){ - int id = boost::lexical_cast(*it); + int id = StringUtil::stringToInt(*it); m_pData.push_back(dynamic_cast(CData2DManager::getSingleton().get(id))); } CC.markNodeParsed("DataId"); @@ -97,7 +96,7 @@ bool CCudaDataOperationAlgorithm::initialize(const Config& _cfg) CC.markOptionParsed("GPUIndex"); if (_cfg.self.hasOption("MaskId")) { - int id = boost::lexical_cast(_cfg.self.getOption("MaskId")); + int id = _cfg.self.getOptionInt("MaskId"); m_pMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } CC.markOptionParsed("MaskId"); diff --git a/src/CudaFDKAlgorithm3D.cpp b/src/CudaFDKAlgorithm3D.cpp index 1316daa..b5ce545 100644 --- a/src/CudaFDKAlgorithm3D.cpp +++ b/src/CudaFDKAlgorithm3D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/CudaFDKAlgorithm3D.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/CudaProjector3D.h" diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp index bcd70c4..aa97eec 100644 --- a/src/CudaFilteredBackProjectionAlgorithm.cpp +++ b/src/CudaFilteredBackProjectionAlgorithm.cpp @@ -28,7 +28,6 @@ $Id$ #include #include -#include #include #include "astra/AstraObjectManager.h" @@ -100,7 +99,7 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) XMLNode node = _cfg.self.getSingleNode("ProjectorId"); CCudaProjector2D* pCudaProjector = 0; if (node) { - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); CProjector2D *projector = CProjector2DManager::getSingleton().get(id); pCudaProjector = dynamic_cast(projector); if (!pCudaProjector) { @@ -113,14 +112,14 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) // sinogram data node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ProjectionDataId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("ProjectionDataId"); // reconstruction data node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pReconstruction = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("ReconstructionDataId"); @@ -140,7 +139,7 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) node = _cfg.self.getSingleNode("FilterSinogramId"); if (node) { - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); const CFloat32ProjectionData2D * pFilterData = dynamic_cast(CData2DManager::getSingleton().get(id)); m_iFilterWidth = pFilterData->getGeometry()->getDetectorCount(); int iFilterProjectionCount = pFilterData->getGeometry()->getProjectionAngleCount(); @@ -159,7 +158,7 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) node = _cfg.self.getSingleNode("FilterParameter"); if (node) { - float fParameter = boost::lexical_cast(node.getContent()); + float fParameter = node.getContentNumerical(); m_fFilterParameter = fParameter; } else @@ -172,7 +171,7 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) node = _cfg.self.getSingleNode("FilterD"); if (node) { - float fD = boost::lexical_cast(node.getContent()); + float fD = node.getContentNumerical(); m_fFilterD = fD; } else diff --git a/src/CudaForwardProjectionAlgorithm.cpp b/src/CudaForwardProjectionAlgorithm.cpp index d38469c..80f2e02 100644 --- a/src/CudaForwardProjectionAlgorithm.cpp +++ b/src/CudaForwardProjectionAlgorithm.cpp @@ -35,8 +35,6 @@ $Id$ #include #include -#include - #include "astra/AstraObjectManager.h" #include "astra/ParallelProjectionGeometry2D.h" #include "astra/FanFlatProjectionGeometry2D.h" @@ -97,7 +95,7 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg) m_pProjector = 0; XMLNode node = _cfg.self.getSingleNode("ProjectorId"); if (node) { - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pProjector = CProjector2DManager::getSingleton().get(id); } CC.markNodeParsed("ProjectorId"); @@ -107,14 +105,14 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg) // sinogram data node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "FP_CUDA", "No ProjectionDataId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("ProjectionDataId"); // volume data node = _cfg.self.getSingleNode("VolumeDataId"); ASTRA_CONFIG_CHECK(node, "FP_CUDA", "No VolumeDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pVolume = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("VolumeDataId"); diff --git a/src/CudaForwardProjectionAlgorithm3D.cpp b/src/CudaForwardProjectionAlgorithm3D.cpp index 209f5a5..f709e34 100644 --- a/src/CudaForwardProjectionAlgorithm3D.cpp +++ b/src/CudaForwardProjectionAlgorithm3D.cpp @@ -30,8 +30,6 @@ $Id$ #ifdef ASTRA_CUDA -#include - #include "astra/AstraObjectManager.h" #include "astra/CudaProjector3D.h" @@ -103,14 +101,14 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg) // sinogram data node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "CudaForwardProjection3D", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pProjections = dynamic_cast(CData3DManager::getSingleton().get(id)); CC.markNodeParsed("ProjectionDataId"); // reconstruction data node = _cfg.self.getSingleNode("VolumeDataId"); ASTRA_CONFIG_CHECK(node, "CudaForwardProjection3D", "No VolumeDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pVolume = dynamic_cast(CData3DManager::getSingleton().get(id)); CC.markNodeParsed("VolumeDataId"); @@ -118,7 +116,7 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg) node = _cfg.self.getSingleNode("ProjectorId"); m_pProjector = 0; if (node) { - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pProjector = CProjector3DManager::getSingleton().get(id); } CC.markNodeParsed("ProjectorId"); diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp index 71dddf7..5a1910c 100644 --- a/src/CudaReconstructionAlgorithm2D.cpp +++ b/src/CudaReconstructionAlgorithm2D.cpp @@ -30,8 +30,6 @@ $Id$ #include "astra/CudaReconstructionAlgorithm2D.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/FanFlatProjectionGeometry2D.h" #include "astra/FanFlatVecProjectionGeometry2D.h" diff --git a/src/CudaRoiSelectAlgorithm.cpp b/src/CudaRoiSelectAlgorithm.cpp index 7635c69..dfb8056 100644 --- a/src/CudaRoiSelectAlgorithm.cpp +++ b/src/CudaRoiSelectAlgorithm.cpp @@ -34,7 +34,6 @@ $Id$ #include "../cuda/2d/algo.h" #include "astra/AstraObjectManager.h" -#include using namespace std; @@ -68,7 +67,7 @@ bool CCudaRoiSelectAlgorithm::initialize(const Config& _cfg) // reconstruction data XMLNode node = _cfg.self.getSingleNode("DataId"); ASTRA_CONFIG_CHECK(node, "CudaRoiSelect", "No DataId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pData = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("DataId"); diff --git a/src/CudaSirtAlgorithm.cpp b/src/CudaSirtAlgorithm.cpp index ab0a418..33e381a 100644 --- a/src/CudaSirtAlgorithm.cpp +++ b/src/CudaSirtAlgorithm.cpp @@ -30,7 +30,6 @@ $Id$ #include "astra/CudaSirtAlgorithm.h" -#include #include "astra/AstraObjectManager.h" #include "../cuda/2d/sirt.h" @@ -77,12 +76,12 @@ bool CCudaSirtAlgorithm::initialize(const Config& _cfg) // min/max masks if (_cfg.self.hasOption("MinMaskId")) { - int id = boost::lexical_cast(_cfg.self.getOption("MinMaskId")); + int id = _cfg.self.getOptionInt("MinMaskId"); m_pMinMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } CC.markOptionParsed("MinMaskId"); if (_cfg.self.hasOption("MaxMaskId")) { - int id = boost::lexical_cast(_cfg.self.getOption("MaxMaskId")); + int id = _cfg.self.getOptionInt("MaxMaskId"); m_pMaxMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } CC.markOptionParsed("MaxMaskId"); diff --git a/src/CudaSirtAlgorithm3D.cpp b/src/CudaSirtAlgorithm3D.cpp index 1fa0da2..605c470 100644 --- a/src/CudaSirtAlgorithm3D.cpp +++ b/src/CudaSirtAlgorithm3D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/CudaSirtAlgorithm3D.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/ConeProjectionGeometry3D.h" diff --git a/src/FanFlatBeamLineKernelProjector2D.cpp b/src/FanFlatBeamLineKernelProjector2D.cpp index 0681715..fd4195b 100644 --- a/src/FanFlatBeamLineKernelProjector2D.cpp +++ b/src/FanFlatBeamLineKernelProjector2D.cpp @@ -30,7 +30,6 @@ $Id$ #include #include -#include #include "astra/DataProjectorPolicies.h" diff --git a/src/FanFlatBeamStripKernelProjector2D.cpp b/src/FanFlatBeamStripKernelProjector2D.cpp index e94d3da..b48beab 100644 --- a/src/FanFlatBeamStripKernelProjector2D.cpp +++ b/src/FanFlatBeamStripKernelProjector2D.cpp @@ -29,7 +29,6 @@ $Id$ #include "astra/FanFlatBeamStripKernelProjector2D.h" #include -#include #include "astra/DataProjectorPolicies.h" diff --git a/src/FanFlatProjectionGeometry2D.cpp b/src/FanFlatProjectionGeometry2D.cpp index 32a19bc..8bee0d6 100644 --- a/src/FanFlatProjectionGeometry2D.cpp +++ b/src/FanFlatProjectionGeometry2D.cpp @@ -30,7 +30,6 @@ $Id$ #include #include -#include using namespace std; @@ -136,13 +135,13 @@ bool CFanFlatProjectionGeometry2D::initialize(const Config& _cfg) // Required: DistanceOriginDetector XMLNode node = _cfg.self.getSingleNode("DistanceOriginDetector"); ASTRA_CONFIG_CHECK(node, "FanFlatProjectionGeometry2D", "No DistanceOriginDetector tag specified."); - m_fOriginDetectorDistance = boost::lexical_cast(node.getContent()); + m_fOriginDetectorDistance = node.getContentNumerical(); CC.markNodeParsed("DistanceOriginDetector"); // Required: DetectorOriginSource node = _cfg.self.getSingleNode("DistanceOriginSource"); ASTRA_CONFIG_CHECK(node, "FanFlatProjectionGeometry2D", "No DistanceOriginSource tag specified."); - m_fOriginSourceDistance = boost::lexical_cast(node.getContent()); + m_fOriginSourceDistance = node.getContentNumerical(); CC.markNodeParsed("DistanceOriginSource"); // success diff --git a/src/FanFlatVecProjectionGeometry2D.cpp b/src/FanFlatVecProjectionGeometry2D.cpp index 4104379..0b76fc5 100644 --- a/src/FanFlatVecProjectionGeometry2D.cpp +++ b/src/FanFlatVecProjectionGeometry2D.cpp @@ -30,7 +30,6 @@ $Id$ #include #include -#include using namespace std; @@ -125,7 +124,7 @@ bool CFanFlatVecProjectionGeometry2D::initialize(const Config& _cfg) // Required: DetectorCount node = _cfg.self.getSingleNode("DetectorCount"); ASTRA_CONFIG_CHECK(node, "FanFlatVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorCount = boost::lexical_cast(node.getContent()); + m_iDetectorCount = node.getContentInt(); CC.markNodeParsed("DetectorCount"); // Required: Vectors @@ -235,12 +234,12 @@ Config* CFanFlatVecProjectionGeometry2D::getConfiguration() const std::string vectors = ""; for (int i = 0; i < m_iProjectionAngleCount; ++i) { SFanProjection& p = m_pProjectionAngles[i]; - vectors += boost::lexical_cast(p.fSrcX) + ","; - vectors += boost::lexical_cast(p.fSrcY) + ","; - vectors += boost::lexical_cast(p.fDetSX + 0.5f * m_iDetectorCount * p.fDetUX) + ","; - vectors += boost::lexical_cast(p.fDetSY + 0.5f * m_iDetectorCount * p.fDetUY) + ","; - vectors += boost::lexical_cast(p.fDetUX) + ","; - vectors += boost::lexical_cast(p.fDetUY); + vectors += StringUtil::toString(p.fSrcX) + ","; + vectors += StringUtil::toString(p.fSrcY) + ","; + vectors += StringUtil::toString(p.fDetSX + 0.5f * m_iDetectorCount * p.fDetUX) + ","; + vectors += StringUtil::toString(p.fDetSY + 0.5f * m_iDetectorCount * p.fDetUY) + ","; + vectors += StringUtil::toString(p.fDetUX) + ","; + vectors += StringUtil::toString(p.fDetUY); if (i < m_iProjectionAngleCount-1) vectors += ';'; } cfg->self.addChildNode("Vectors", vectors); diff --git a/src/FilteredBackProjectionAlgorithm.cpp b/src/FilteredBackProjectionAlgorithm.cpp index f494d22..c195578 100644 --- a/src/FilteredBackProjectionAlgorithm.cpp +++ b/src/FilteredBackProjectionAlgorithm.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/FilteredBackProjectionAlgorithm.h" -#include - #include #include #include @@ -96,19 +94,19 @@ bool CFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) // projector XMLNode node = _cfg.self.getSingleNode("ProjectorId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectorId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pProjector = CProjector2DManager::getSingleton().get(id); // sinogram data node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); // volume data node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "FilteredBackProjection", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pReconstruction = dynamic_cast(CData2DManager::getSingleton().get(id)); node = _cfg.self.getSingleNode("ProjectionIndex"); diff --git a/src/ForwardProjectionAlgorithm.cpp b/src/ForwardProjectionAlgorithm.cpp index f356824..dcf5790 100644 --- a/src/ForwardProjectionAlgorithm.cpp +++ b/src/ForwardProjectionAlgorithm.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/ForwardProjectionAlgorithm.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/DataProjectorPolicies.h" @@ -128,32 +126,32 @@ bool CForwardProjectionAlgorithm::initialize(const Config& _cfg) // projector XMLNode node = _cfg.self.getSingleNode("ProjectorId"); ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No ProjectorId tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pProjector = CProjector2DManager::getSingleton().get(id); // sinogram data node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); // volume data node = _cfg.self.getSingleNode("VolumeDataId"); ASTRA_CONFIG_CHECK(node, "ForwardProjection", "No VolumeDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pVolume = dynamic_cast(CData2DManager::getSingleton().get(id)); // volume mask if (_cfg.self.hasOption("VolumeMaskId")) { m_bUseVolumeMask = true; - id = boost::lexical_cast(_cfg.self.getOption("VolumeMaskId")); + id = _cfg.self.getOptionInt("VolumeMaskId"); m_pVolumeMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } // sino mask if (_cfg.self.hasOption("SinogramMaskId")) { m_bUseSinogramMask = true; - id = boost::lexical_cast(_cfg.self.getOption("SinogramMaskId")); + id = _cfg.self.getOptionInt("SinogramMaskId"); m_pSinogramMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } diff --git a/src/ParallelBeamBlobKernelProjector2D.cpp b/src/ParallelBeamBlobKernelProjector2D.cpp index 4559a48..679d5c6 100644 --- a/src/ParallelBeamBlobKernelProjector2D.cpp +++ b/src/ParallelBeamBlobKernelProjector2D.cpp @@ -29,7 +29,6 @@ $Id$ #include "astra/ParallelBeamBlobKernelProjector2D.h" #include -#include #include "astra/DataProjectorPolicies.h" @@ -134,17 +133,17 @@ bool CParallelBeamBlobKernelProjector2D::initialize(const Config& _cfg) // Required: KernelSize XMLNode node2 = node.getSingleNode("KernelSize"); ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/KernelSize tag specified."); - m_fBlobSize = boost::lexical_cast(node2.getContent()); + m_fBlobSize = node2.getContentNumerical(); // Required: SampleRate node2 = node.getSingleNode("SampleRate"); ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/SampleRate tag specified."); - m_fBlobSampleRate = boost::lexical_cast(node2.getContent()); + m_fBlobSampleRate = node2.getContentNumerical(); // Required: SampleCount node2 = node.getSingleNode("SampleCount"); ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/SampleCount tag specified."); - m_iBlobSampleCount = boost::lexical_cast(node2.getContent()); + m_iBlobSampleCount = node2.getContentInt(); // Required: KernelValues node2 = node.getSingleNode("KernelValues"); diff --git a/src/ParallelBeamLineKernelProjector2D.cpp b/src/ParallelBeamLineKernelProjector2D.cpp index 5a23413..e4a1bff 100644 --- a/src/ParallelBeamLineKernelProjector2D.cpp +++ b/src/ParallelBeamLineKernelProjector2D.cpp @@ -29,7 +29,6 @@ $Id$ #include "astra/ParallelBeamLineKernelProjector2D.h" #include -#include #include "astra/DataProjectorPolicies.h" diff --git a/src/ParallelBeamLinearKernelProjector2D.cpp b/src/ParallelBeamLinearKernelProjector2D.cpp index a710664..27aa168 100644 --- a/src/ParallelBeamLinearKernelProjector2D.cpp +++ b/src/ParallelBeamLinearKernelProjector2D.cpp @@ -29,7 +29,6 @@ $Id$ #include "astra/ParallelBeamLinearKernelProjector2D.h" #include -#include #include "astra/DataProjectorPolicies.h" diff --git a/src/ParallelBeamStripKernelProjector2D.cpp b/src/ParallelBeamStripKernelProjector2D.cpp index 44c6fec..3f4e7f3 100644 --- a/src/ParallelBeamStripKernelProjector2D.cpp +++ b/src/ParallelBeamStripKernelProjector2D.cpp @@ -29,7 +29,6 @@ $Id$ #include "astra/ParallelBeamStripKernelProjector2D.h" #include -#include #include "astra/DataProjectorPolicies.h" diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp index 7260b83..cc2a129 100644 --- a/src/ParallelProjectionGeometry2D.cpp +++ b/src/ParallelProjectionGeometry2D.cpp @@ -27,7 +27,6 @@ $Id$ */ #include "astra/ParallelProjectionGeometry2D.h" -#include #include diff --git a/src/ParallelProjectionGeometry3D.cpp b/src/ParallelProjectionGeometry3D.cpp index 7b64fd9..2f80883 100644 --- a/src/ParallelProjectionGeometry3D.cpp +++ b/src/ParallelProjectionGeometry3D.cpp @@ -30,7 +30,6 @@ $Id$ #include "astra/GeometryUtil3D.h" -#include #include using namespace std; diff --git a/src/ParallelVecProjectionGeometry3D.cpp b/src/ParallelVecProjectionGeometry3D.cpp index d04400b..3172818 100644 --- a/src/ParallelVecProjectionGeometry3D.cpp +++ b/src/ParallelVecProjectionGeometry3D.cpp @@ -27,9 +27,9 @@ $Id$ */ #include "astra/ParallelVecProjectionGeometry3D.h" +#include "astra/Utilities.h" #include -#include using namespace std; @@ -82,13 +82,13 @@ bool CParallelVecProjectionGeometry3D::initialize(const Config& _cfg) // Required: DetectorRowCount node = _cfg.self.getSingleNode("DetectorRowCount"); ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = boost::lexical_cast(node.getContent()); + m_iDetectorRowCount = node.getContentInt(); CC.markNodeParsed("DetectorRowCount"); // Required: DetectorCount node = _cfg.self.getSingleNode("DetectorColCount"); ASTRA_CONFIG_CHECK(node, "", "No DetectorColCount tag specified."); - m_iDetectorColCount = boost::lexical_cast(node.getContent()); + m_iDetectorColCount = node.getContentInt(); m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; CC.markNodeParsed("DetectorColCount"); @@ -212,18 +212,18 @@ Config* CParallelVecProjectionGeometry3D::getConfiguration() const std::string vectors = ""; for (int i = 0; i < m_iProjectionAngleCount; ++i) { SPar3DProjection& p = m_pProjectionAngles[i]; - vectors += boost::lexical_cast(p.fRayX) + ","; - vectors += boost::lexical_cast(p.fRayY) + ","; - vectors += boost::lexical_cast(p.fRayZ) + ","; - vectors += boost::lexical_cast(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetVX + 0.5f*m_iDetectorColCount*p.fDetUX) + ","; - vectors += boost::lexical_cast(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetVY + 0.5f*m_iDetectorColCount*p.fDetUY) + ","; - vectors += boost::lexical_cast(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetVZ + 0.5f*m_iDetectorColCount*p.fDetUZ) + ","; - vectors += boost::lexical_cast(p.fDetUX) + ","; - vectors += boost::lexical_cast(p.fDetUY) + ","; - vectors += boost::lexical_cast(p.fDetUZ) + ","; - vectors += boost::lexical_cast(p.fDetVX) + ","; - vectors += boost::lexical_cast(p.fDetVY) + ","; - vectors += boost::lexical_cast(p.fDetVZ); + vectors += StringUtil::toString(p.fRayX) + ","; + vectors += StringUtil::toString(p.fRayY) + ","; + vectors += StringUtil::toString(p.fRayZ) + ","; + vectors += StringUtil::toString(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetVX + 0.5f*m_iDetectorColCount*p.fDetUX) + ","; + vectors += StringUtil::toString(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetVY + 0.5f*m_iDetectorColCount*p.fDetUY) + ","; + vectors += StringUtil::toString(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetVZ + 0.5f*m_iDetectorColCount*p.fDetUZ) + ","; + vectors += StringUtil::toString(p.fDetUX) + ","; + vectors += StringUtil::toString(p.fDetUY) + ","; + vectors += StringUtil::toString(p.fDetUZ) + ","; + vectors += StringUtil::toString(p.fDetVX) + ","; + vectors += StringUtil::toString(p.fDetVY) + ","; + vectors += StringUtil::toString(p.fDetVZ); if (i < m_iProjectionAngleCount-1) vectors += ';'; } cfg->self.addChildNode("Vectors", vectors); diff --git a/src/PluginAlgorithm.cpp b/src/PluginAlgorithm.cpp index 8f7dfc5..9fc511a 100644 --- a/src/PluginAlgorithm.cpp +++ b/src/PluginAlgorithm.cpp @@ -30,9 +30,9 @@ $Id$ #include "astra/PluginAlgorithm.h" #include "astra/Logging.h" +#include "astra/Utilities.h" #include #include -#include #include #include #include @@ -338,7 +338,7 @@ PyObject* stringToPythonValue(std::string str){ boost::split(row, rows[i], boost::is_any_of(",")); PyObject *rowlist = PyList_New(row.size()); for(unsigned int j=0;j(row[j]))); + PyList_SetItem(rowlist, j, PyFloat_FromDouble(StringUtil::stringToDouble(row[j]))); } PyList_SetItem(mat, i, rowlist); } @@ -349,16 +349,16 @@ PyObject* stringToPythonValue(std::string str){ boost::split(vec, str, boost::is_any_of(",")); PyObject *veclist = PyList_New(vec.size()); for(unsigned int i=0;i(vec[i]))); + PyList_SetItem(veclist, i, PyFloat_FromDouble(StringUtil::stringToDouble(vec[i]))); } return veclist; } try{ - return PyLong_FromLong(boost::lexical_cast(str)); - }catch(const boost::bad_lexical_cast &){ + return PyLong_FromLong(StringUtil::stringToInt(str)); + }catch(const StringUtil::bad_cast &){ try{ - return PyFloat_FromDouble(boost::lexical_cast(str)); - }catch(const boost::bad_lexical_cast &){ + return PyFloat_FromDouble(StringUtil::stringToDouble(str)); + }catch(const StringUtil::bad_cast &){ return pyStringFromString(str); } } diff --git a/src/ProjectionGeometry2D.cpp b/src/ProjectionGeometry2D.cpp index b89605b..8ce06dc 100644 --- a/src/ProjectionGeometry2D.cpp +++ b/src/ProjectionGeometry2D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/ProjectionGeometry2D.h" -#include - using namespace std; namespace astra @@ -126,13 +124,13 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg) // Required: DetectorWidth XMLNode node = _cfg.self.getSingleNode("DetectorWidth"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorWidth tag specified."); - m_fDetectorWidth = boost::lexical_cast(node.getContent()); + m_fDetectorWidth = node.getContentNumerical(); CC.markNodeParsed("DetectorWidth"); // Required: DetectorCount node = _cfg.self.getSingleNode("DetectorCount"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry2D", "No DetectorCount tag specified."); - m_iDetectorCount = boost::lexical_cast(node.getContent()); + m_iDetectorCount = node.getContentInt(); CC.markNodeParsed("DetectorCount"); // Required: ProjectionAngles diff --git a/src/ProjectionGeometry3D.cpp b/src/ProjectionGeometry3D.cpp index ef0246c..281db7c 100644 --- a/src/ProjectionGeometry3D.cpp +++ b/src/ProjectionGeometry3D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/ProjectionGeometry3D.h" -#include - using namespace std; namespace astra @@ -151,25 +149,25 @@ bool CProjectionGeometry3D::initialize(const Config& _cfg) // Required: DetectorWidth XMLNode node = _cfg.self.getSingleNode("DetectorSpacingX"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingX tag specified."); - m_fDetectorSpacingX = boost::lexical_cast(node.getContent()); + m_fDetectorSpacingX = node.getContentNumerical(); CC.markNodeParsed("DetectorSpacingX"); // Required: DetectorHeight node = _cfg.self.getSingleNode("DetectorSpacingY"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorSpacingY tag specified."); - m_fDetectorSpacingY = boost::lexical_cast(node.getContent()); + m_fDetectorSpacingY = node.getContentNumerical(); CC.markNodeParsed("DetectorSpacingY"); // Required: DetectorRowCount node = _cfg.self.getSingleNode("DetectorRowCount"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorRowCount tag specified."); - m_iDetectorRowCount = boost::lexical_cast(node.getContent()); + m_iDetectorRowCount = node.getContentInt(); CC.markNodeParsed("DetectorRowCount"); // Required: DetectorCount node = _cfg.self.getSingleNode("DetectorColCount"); ASTRA_CONFIG_CHECK(node, "ProjectionGeometry3D", "No DetectorColCount tag specified."); - m_iDetectorColCount = boost::lexical_cast(node.getContent()); + m_iDetectorColCount = node.getContentInt(); m_iDetectorTotCount = m_iDetectorRowCount * m_iDetectorColCount; CC.markNodeParsed("DetectorColCount"); diff --git a/src/ReconstructionAlgorithm2D.cpp b/src/ReconstructionAlgorithm2D.cpp index 4575ff7..1c6d855 100644 --- a/src/ReconstructionAlgorithm2D.cpp +++ b/src/ReconstructionAlgorithm2D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/ReconstructionAlgorithm2D.h" -#include - #include "astra/AstraObjectManager.h" using namespace std; @@ -90,7 +88,7 @@ bool CReconstructionAlgorithm2D::initialize(const Config& _cfg) } int id; if (node) { - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pProjector = CProjector2DManager::getSingleton().get(id); } else { m_pProjector = 0; @@ -100,21 +98,21 @@ bool CReconstructionAlgorithm2D::initialize(const Config& _cfg) // sinogram data node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("ProjectionDataId"); // reconstruction data node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pReconstruction = dynamic_cast(CData2DManager::getSingleton().get(id)); CC.markNodeParsed("ReconstructionDataId"); // fixed mask if (_cfg.self.hasOption("ReconstructionMaskId")) { m_bUseReconstructionMask = true; - id = boost::lexical_cast(_cfg.self.getOption("ReconstructionMaskId")); + id = _cfg.self.getOptionInt("ReconstructionMaskId"); m_pReconstructionMask = dynamic_cast(CData2DManager::getSingleton().get(id)); ASTRA_CONFIG_CHECK(m_pReconstructionMask, "Reconstruction2D", "Invalid ReconstructionMaskId."); } @@ -123,7 +121,7 @@ bool CReconstructionAlgorithm2D::initialize(const Config& _cfg) // fixed mask if (_cfg.self.hasOption("SinogramMaskId")) { m_bUseSinogramMask = true; - id = boost::lexical_cast(_cfg.self.getOption("SinogramMaskId")); + id = _cfg.self.getOptionInt("SinogramMaskId"); m_pSinogramMask = dynamic_cast(CData2DManager::getSingleton().get(id)); ASTRA_CONFIG_CHECK(m_pSinogramMask, "Reconstruction2D", "Invalid SinogramMaskId."); } diff --git a/src/ReconstructionAlgorithm3D.cpp b/src/ReconstructionAlgorithm3D.cpp index 13d4b07..55f1031 100644 --- a/src/ReconstructionAlgorithm3D.cpp +++ b/src/ReconstructionAlgorithm3D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/ReconstructionAlgorithm3D.h" -#include - #include "astra/AstraObjectManager.h" using namespace std; @@ -111,7 +109,7 @@ bool CReconstructionAlgorithm3D::initialize(const Config& _cfg) node = _cfg.self.getSingleNode("ProjectorId"); m_pProjector = 0; if (node) { - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pProjector = CProjector3DManager::getSingleton().get(id); if (!m_pProjector) { // TODO: Report @@ -122,21 +120,21 @@ bool CReconstructionAlgorithm3D::initialize(const Config& _cfg) // sinogram data node = _cfg.self.getSingleNode("ProjectionDataId"); ASTRA_CONFIG_CHECK(node, "Reconstruction3D", "No ProjectionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pSinogram = dynamic_cast(CData3DManager::getSingleton().get(id)); CC.markNodeParsed("ProjectionDataId"); // reconstruction data node = _cfg.self.getSingleNode("ReconstructionDataId"); ASTRA_CONFIG_CHECK(node, "Reconstruction3D", "No ReconstructionDataId tag specified."); - id = boost::lexical_cast(node.getContent()); + id = node.getContentInt(); m_pReconstruction = dynamic_cast(CData3DManager::getSingleton().get(id)); CC.markNodeParsed("ReconstructionDataId"); // fixed mask if (_cfg.self.hasOption("ReconstructionMaskId")) { m_bUseReconstructionMask = true; - id = boost::lexical_cast(_cfg.self.getOption("ReconstructionMaskId")); + id = _cfg.self.getOptionInt("ReconstructionMaskId"); m_pReconstructionMask = dynamic_cast(CData3DManager::getSingleton().get(id)); } CC.markOptionParsed("ReconstructionMaskId"); @@ -144,7 +142,7 @@ bool CReconstructionAlgorithm3D::initialize(const Config& _cfg) // fixed mask if (_cfg.self.hasOption("SinogramMaskId")) { m_bUseSinogramMask = true; - id = boost::lexical_cast(_cfg.self.getOption("SinogramMaskId")); + id = _cfg.self.getOptionInt("SinogramMaskId"); m_pSinogramMask = dynamic_cast(CData3DManager::getSingleton().get(id)); } CC.markOptionParsed("SinogramMaskId"); diff --git a/src/ReconstructionAlgorithmMultiSlice2D.cpp b/src/ReconstructionAlgorithmMultiSlice2D.cpp index fe64c86..39c337f 100644 --- a/src/ReconstructionAlgorithmMultiSlice2D.cpp +++ b/src/ReconstructionAlgorithmMultiSlice2D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/ReconstructionAlgorithmMultiSlice2D.h" -#include - #include "astra/AstraObjectManager.h" using namespace std; @@ -96,7 +94,7 @@ bool CReconstructionAlgorithmMultiSlice2D::initialize(const Config& _cfg) // projector XMLNode* node = _cfg.self->getSingleNode("ProjectorId"); ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectorId tag specified."); - int id = boost::lexical_cast(node->getContent()); + int id = node->getContentInt(); m_pProjector = CProjector2DManager::getSingleton().get(id); ASTRA_DELETE(node); CC.markNodeParsed("ProjectorId"); @@ -125,7 +123,7 @@ bool CReconstructionAlgorithmMultiSlice2D::initialize(const Config& _cfg) // reconstruction masks if (_cfg.self->hasOption("ReconstructionMaskId")) { m_bUseReconstructionMask = true; - id = boost::lexical_cast(_cfg.self->getOption("ReconstructionMaskId")); + id = _cfg.self->getOptionInt("ReconstructionMaskId"); m_pReconstructionMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } CC.markOptionParsed("ReconstructionMaskId"); @@ -133,7 +131,7 @@ bool CReconstructionAlgorithmMultiSlice2D::initialize(const Config& _cfg) // sinogram masks if (_cfg.self->hasOption("SinogramMaskId")) { m_bUseSinogramMask = true; - id = boost::lexical_cast(_cfg.self->getOption("SinogramMaskId")); + id = _cfg.self->getOptionInt("SinogramMaskId"); m_pSinogramMask = dynamic_cast(CData2DManager::getSingleton().get(id)); } CC.markOptionParsed("SinogramMaskId"); diff --git a/src/SartAlgorithm.cpp b/src/SartAlgorithm.cpp index e4dc5c7..9346160 100644 --- a/src/SartAlgorithm.cpp +++ b/src/SartAlgorithm.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/SartAlgorithm.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/DataProjectorPolicies.h" diff --git a/src/SirtAlgorithm.cpp b/src/SirtAlgorithm.cpp index ae3b3bc..d9f3a65 100644 --- a/src/SirtAlgorithm.cpp +++ b/src/SirtAlgorithm.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/SirtAlgorithm.h" -#include - #include "astra/AstraObjectManager.h" #include "astra/DataProjectorPolicies.h" diff --git a/src/SparseMatrixProjectionGeometry2D.cpp b/src/SparseMatrixProjectionGeometry2D.cpp index 073720f..358c992 100644 --- a/src/SparseMatrixProjectionGeometry2D.cpp +++ b/src/SparseMatrixProjectionGeometry2D.cpp @@ -28,7 +28,6 @@ $Id$ #include "astra/SparseMatrixProjectionGeometry2D.h" -#include #include "astra/AstraObjectManager.h" @@ -100,7 +99,7 @@ bool CSparseMatrixProjectionGeometry2D::initialize(const Config& _cfg) // get matrix XMLNode node = _cfg.self.getSingleNode("MatrixID"); ASTRA_CONFIG_CHECK(node, "SparseMatrixProjectionGeometry2D", "No MatrixID tag specified."); - int id = boost::lexical_cast(node.getContent()); + int id = node.getContentInt(); m_pMatrix = CMatrixManager::getSingleton().get(id); CC.markNodeParsed("MatrixID"); diff --git a/src/SparseMatrixProjector2D.cpp b/src/SparseMatrixProjector2D.cpp index bc2e974..be7e069 100644 --- a/src/SparseMatrixProjector2D.cpp +++ b/src/SparseMatrixProjector2D.cpp @@ -29,7 +29,6 @@ $Id$ #include "astra/SparseMatrixProjector2D.h" #include -#include #include "astra/DataProjectorPolicies.h" diff --git a/src/Utilities.cpp b/src/Utilities.cpp index cb54e93..4b80503 100644 --- a/src/Utilities.cpp +++ b/src/Utilities.cpp @@ -28,4 +28,99 @@ $Id$ #include "astra/Utilities.h" +#include +#include +#include +#include +#include +#include + +namespace astra { + +namespace StringUtil { + +int stringToInt(const std::string& s) +{ + double i; + std::istringstream iss(s); + iss.imbue(std::locale::classic()); + iss >> i; + if (iss.fail() || !iss.eof()) + throw bad_cast(); + return i; + +} + +float stringToFloat(const std::string& s) +{ + return (float)stringToDouble(s); +} + +double stringToDouble(const std::string& s) +{ + double f; + std::istringstream iss(s); + iss.imbue(std::locale::classic()); + iss >> f; + if (iss.fail() || !iss.eof()) + throw bad_cast(); + return f; +} + +template<> float stringTo(const std::string& s) { return stringToFloat(s); } +template<> double stringTo(const std::string& s) { return stringToDouble(s); } + +std::vector stringToFloatVector(const std::string &s) +{ + return stringToVector(s); +} + +std::vector stringToDoubleVector(const std::string &s) +{ + return stringToVector(s); +} + +template +std::vector stringToVector(const std::string& s) +{ + // split + std::vector items; + boost::split(items, s, boost::is_any_of(",;")); + + // init list + std::vector out; + out.resize(items.size()); + + // loop elements + for (unsigned int i = 0; i < items.size(); i++) { + out[i] = stringTo(items[i]); + } + return out; +} + + +std::string floatToString(float f) +{ + std::ostringstream s; + s.imbue(std::locale::classic()); + s << std::setprecision(9) << f; + return s.str(); +} + +std::string doubleToString(double f) +{ + std::ostringstream s; + s.imbue(std::locale::classic()); + s << std::setprecision(17) << f; + return s.str(); +} + + +template<> std::string toString(float f) { return floatToString(f); } +template<> std::string toString(double f) { return doubleToString(f); } + + +} + +} diff --git a/src/VolumeGeometry2D.cpp b/src/VolumeGeometry2D.cpp index 6eea1b2..9d74e47 100644 --- a/src/VolumeGeometry2D.cpp +++ b/src/VolumeGeometry2D.cpp @@ -28,7 +28,6 @@ $Id$ #include "astra/VolumeGeometry2D.h" -#include #include namespace astra @@ -166,13 +165,13 @@ bool CVolumeGeometry2D::initialize(const Config& _cfg) // Required: GridColCount XMLNode node = _cfg.self.getSingleNode("GridColCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridColCount tag specified."); - m_iGridColCount = boost::lexical_cast(node.getContent()); + m_iGridColCount = node.getContentInt(); CC.markNodeParsed("GridColCount"); // Required: GridRowCount node = _cfg.self.getSingleNode("GridRowCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridRowCount tag specified."); - m_iGridRowCount = boost::lexical_cast(node.getContent()); + m_iGridRowCount = node.getContentInt(); CC.markNodeParsed("GridRowCount"); // Optional: Window minima and maxima diff --git a/src/VolumeGeometry3D.cpp b/src/VolumeGeometry3D.cpp index 3de146f..5d72c24 100644 --- a/src/VolumeGeometry3D.cpp +++ b/src/VolumeGeometry3D.cpp @@ -28,8 +28,6 @@ $Id$ #include "astra/VolumeGeometry3D.h" -#include - namespace astra { @@ -196,19 +194,19 @@ bool CVolumeGeometry3D::initialize(const Config& _cfg) // Required: GridColCount XMLNode node = _cfg.self.getSingleNode("GridColCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridColCount tag specified."); - m_iGridColCount = boost::lexical_cast(node.getContent()); + m_iGridColCount = node.getContentInt(); CC.markNodeParsed("GridColCount"); // Required: GridRowCount node = _cfg.self.getSingleNode("GridRowCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridRowCount tag specified."); - m_iGridRowCount = boost::lexical_cast(node.getContent()); + m_iGridRowCount = node.getContentInt(); CC.markNodeParsed("GridRowCount"); // Required: GridRowCount node = _cfg.self.getSingleNode("GridSliceCount"); ASTRA_CONFIG_CHECK(node, "ReconstructionGeometry2D", "No GridSliceCount tag specified."); - m_iGridSliceCount = boost::lexical_cast(node.getContent()); + m_iGridSliceCount = node.getContentInt(); CC.markNodeParsed("GridSliceCount"); // Optional: Window minima and maxima diff --git a/src/XMLNode.cpp b/src/XMLNode.cpp index 0ec701f..40a9b22 100644 --- a/src/XMLNode.cpp +++ b/src/XMLNode.cpp @@ -31,12 +31,6 @@ $Id$ #include "rapidxml/rapidxml.hpp" #include "rapidxml/rapidxml_print.hpp" -#include -#include -#include -#include - - using namespace rapidxml; using namespace astra; @@ -138,8 +132,13 @@ string XMLNode::getContent() const // Get node content - NUMERICAL float32 XMLNode::getContentNumerical() const { - return boost::lexical_cast(getContent()); + return StringUtil::stringToFloat(getContent()); } +int XMLNode::getContentInt() const +{ + return StringUtil::stringToInt(getContent()); +} + //----------------------------------------------------------------------------- // Get node content - BOOLEAN @@ -154,7 +153,7 @@ bool XMLNode::getContentBool() const vector XMLNode::getContentArray() const { // get listsize - int iSize = boost::lexical_cast(getAttribute("listsize")); + int iSize = StringUtil::stringToInt(getAttribute("listsize")); // create result array vector res(iSize); // loop all list item nodes @@ -175,40 +174,12 @@ vector XMLNode::getContentArray() const // NB: A 2D matrix is returned as a linear list vector XMLNode::getContentNumericalArray() const { - string input = getContent(); - - // split - std::vector items; - boost::split(items, input, boost::is_any_of(",;")); - - // init list - vector out; - out.resize(items.size()); - - // loop elements - for (unsigned int i = 0; i < items.size(); i++) { - out[i] = boost::lexical_cast(items[i]); - } - return out; + return StringUtil::stringToFloatVector(getContent()); } vector XMLNode::getContentNumericalArrayDouble() const { - string input = getContent(); - - // split - std::vector items; - boost::split(items, input, boost::is_any_of(",;")); - - // init list - vector out; - out.resize(items.size()); - - // loop elements - for (unsigned int i = 0; i < items.size(); i++) { - out[i] = boost::lexical_cast(items[i]); - } - return out; + return StringUtil::stringToDoubleVector(getContent()); } //----------------------------------------------------------------------------- @@ -235,14 +206,20 @@ string XMLNode::getAttribute(string _sName, string _sDefaultValue) const float32 XMLNode::getAttributeNumerical(string _sName, float32 _fDefaultValue) const { if (!hasAttribute(_sName)) return _fDefaultValue; - return boost::lexical_cast(getAttribute(_sName)); + return StringUtil::stringToFloat(getAttribute(_sName)); } double XMLNode::getAttributeNumericalDouble(string _sName, double _fDefaultValue) const { if (!hasAttribute(_sName)) return _fDefaultValue; - return boost::lexical_cast(getAttribute(_sName)); + return StringUtil::stringToDouble(getAttribute(_sName)); +} +int XMLNode::getAttributeInt(string _sName, int _iDefaultValue) const +{ + if (!hasAttribute(_sName)) return _iDefaultValue; + return StringUtil::stringToInt(getAttribute(_sName)); } + //----------------------------------------------------------------------------- // Get attribute - BOOLEAN bool XMLNode::getAttributeBool(string _sName, bool _bDefaultValue) const @@ -287,9 +264,15 @@ string XMLNode::getOption(string _sKey, string _sDefaultValue) const float32 XMLNode::getOptionNumerical(string _sKey, float32 _fDefaultValue) const { if (!hasOption(_sKey)) return _fDefaultValue; - return boost::lexical_cast(getOption(_sKey)); + return StringUtil::stringToFloat(getOption(_sKey)); +} +int XMLNode::getOptionInt(string _sKey, int _iDefaultValue) const +{ + if (!hasOption(_sKey)) return _iDefaultValue; + return StringUtil::stringToInt(getOption(_sKey)); } + //----------------------------------------------------------------------------- // Get option - BOOL bool XMLNode::getOptionBool(string _sKey, bool _bDefaultValue) const @@ -386,7 +369,7 @@ void XMLNode::setContent(string _sText) // Set content - FLOAT void XMLNode::setContent(float32 _fValue) { - setContent(boost::lexical_cast(_fValue)); + setContent(StringUtil::floatToString(_fValue)); } //----------------------------------------------------------------------------- @@ -394,9 +377,9 @@ void XMLNode::setContent(float32 _fValue) template static std::string setContentList_internal(T* pfList, int _iSize) { - std::string str = (_iSize > 0) ? boost::lexical_cast(pfList[0]) : ""; + std::string str = (_iSize > 0) ? StringUtil::toString(pfList[0]) : ""; for (int i = 1; i < _iSize; i++) { - str += "," + boost::lexical_cast(pfList[i]); + str += "," + StringUtil::toString(pfList[i]); } return str; } @@ -431,9 +414,9 @@ static std::string setContentMatrix_internal(T* _pfMatrix, int _iWidth, int _iHe for (int y = 0; y < _iHeight; ++y) { if (_iWidth > 0) - str += boost::lexical_cast(_pfMatrix[0*s1 + y*s2]); + str += StringUtil::toString(_pfMatrix[0*s1 + y*s2]); for (int x = 1; x < _iWidth; x++) - str += "," + boost::lexical_cast(_pfMatrix[x*s1 + y*s2]); + str += "," + StringUtil::toString(_pfMatrix[x*s1 + y*s2]); if (y != _iHeight-1) str += ";"; @@ -468,7 +451,7 @@ void XMLNode::addAttribute(string _sName, string _sText) // Add attribute - FLOAT void XMLNode::addAttribute(string _sName, float32 _fValue) { - addAttribute(_sName, boost::lexical_cast(_fValue)); + addAttribute(_sName, StringUtil::floatToString(_fValue)); } //----------------------------------------------------------------------------- -- cgit v1.2.3 From e5edadc1db1eac9057ed6b726e1ce6b8e7126ed0 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Tue, 5 Jan 2016 16:20:14 +0100 Subject: Remove (long) obsolete file --- matlab/mex/astra_mex.cpp | 124 ----------------------------------------------- 1 file changed, 124 deletions(-) delete mode 100644 matlab/mex/astra_mex.cpp (limited to 'matlab') diff --git a/matlab/mex/astra_mex.cpp b/matlab/mex/astra_mex.cpp deleted file mode 100644 index 4bf42dd..0000000 --- a/matlab/mex/astra_mex.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* ------------------------------------------------------------------------ -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$ -*/ - -#include -#include "mexHelpFunctions.h" -#include "mexInitFunctions.h" - -#include "astra/Globals.h" - -using namespace std; -using namespace astra; - - -//----------------------------------------------------------------------------------------- -/** astra_mex('credits'); - * - * Print Credits - */ -void astra_mex_credits(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) -{ - cout << "All Scale Tomographic Reconstruction Antwerp Toolbox (ASTRA-Toolbox) was developed at the University of Antwerp by" << endl; - cout << " * Joost Batenburg, PhD" << endl; - cout << " * Gert Merckx" << endl; - cout << " * Willem Jan Palenstijn" << endl; - cout << " * Tom Roelandts" << endl; - cout << " * Prof. Dr. Jan Sijbers" << endl; - cout << " * Wim van Aarle" << endl; - cout << " * Sander van der Maar" << endl; - cout << " * Gert Van Gompel, PhD" << endl; -} - -//----------------------------------------------------------------------------------------- -/** use_cuda = astra_mex('use_cuda'); - * - * Is CUDA enabled? - */ -void astra_mex_use_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) -{ - if (1 <= nlhs) { - plhs[0] = mxCreateDoubleScalar(astra::cudaEnabled() ? 1 : 0); - } -} - -//----------------------------------------------------------------------------------------- -/** version_number = astra_mex('version'); - * - * Fetch the version number of the toolbox. - */ -void astra_mex_version(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) -{ - if (1 <= nlhs) { - plhs[0] = mxCreateDoubleScalar(astra::getVersion()); - } else { - cout << "astra toolbox version " << astra::getVersionString() << endl; - } -} - -//----------------------------------------------------------------------------------------- - -static void printHelp() -{ - mexPrintf("Please specify a mode of operation.\n"); - mexPrintf(" Valid modes: version, use_cuda, credits\n"); -} - -//----------------------------------------------------------------------------------------- -/** - * ... = astra_mex(type,...); - */ -void mexFunction(int nlhs, mxArray* plhs[], - int nrhs, const mxArray* prhs[]) -{ - - // INPUT0: Mode - string sMode = ""; - if (1 <= nrhs) { - sMode = mex_util_get_string(prhs[0]); - } else { - printHelp(); - return; - } - - initASTRAMex(); - - // SWITCH (MODE) - if (sMode == std::string("version")) { - astra_mex_version(nlhs, plhs, nrhs, prhs); - } else if (sMode == std::string("use_cuda")) { - astra_mex_use_cuda(nlhs, plhs, nrhs, prhs); - } else if (sMode == std::string("credits")) { - astra_mex_credits(nlhs, plhs, nrhs, prhs); - } else { - printHelp(); - } - - return; -} - - -- cgit v1.2.3 From 62f66d27fc4d2b3c61e3f18ad14eeac742cb96ec Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Tue, 5 Jan 2016 16:32:26 +0100 Subject: Update credits --- matlab/mex/astra_mex_c.cpp | 21 ++++++++++++--------- python/astra/astra_c.pyx | 28 +++++++++++++--------------- 2 files changed, 25 insertions(+), 24 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp index a9b9654..d34334c 100644 --- a/matlab/mex/astra_mex_c.cpp +++ b/matlab/mex/astra_mex_c.cpp @@ -50,16 +50,19 @@ using namespace astra; */ void astra_mex_credits(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { - mexPrintf("All Scale Tomographic Reconstruction Antwerp Toolbox (ASTRA-Toolbox) was developed at the University of Antwerp by\n"); + mexPrintf("The ASTRA Toolbox has been developed at the University of Antwerp and CWI, Amsterdam by\n"); mexPrintf(" * Prof. dr. Joost Batenburg\n"); - mexPrintf(" * Andrei Dabravolski\n"); - mexPrintf(" * Gert Merckx\n"); - mexPrintf(" * Willem Jan Palenstijn\n"); - mexPrintf(" * Tom Roelandts\n"); mexPrintf(" * Prof. dr. Jan Sijbers\n"); - mexPrintf(" * dr. Wim van Aarle\n"); - mexPrintf(" * Sander van der Maar\n"); - mexPrintf(" * dr. Gert Van Gompel\n"); + mexPrintf(" * Dr. Jeroen Bedorf\n"); + mexPrintf(" * Dr. Folkert Bleichrodt\n"); + mexPrintf(" * Dr. Andrei Dabravolski\n"); + mexPrintf(" * Dr. Willem Jan Palenstijn\n"); + mexPrintf(" * Dr. Tom Roelandts\n"); + mexPrintf(" * Dr. Wim van Aarle\n"); + mexPrintf(" * Dr. Gert Van Gompel\n"); + mexPrintf(" * Sander van der Maar, MSc.\n"); + mexPrintf(" * Gert Merckx, MSc.\n"); + mexPrintf(" * Daan Pelt, MSc.\n"); } //----------------------------------------------------------------------------------------- @@ -100,7 +103,7 @@ void astra_mex_version(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[ if (1 <= nlhs) { plhs[0] = mxCreateDoubleScalar(astra::getVersion()); } else { - mexPrintf("astra toolbox version %s\n", astra::getVersionString()); + mexPrintf("ASTRA Toolbox version %s\n", astra::getVersionString()); } } diff --git a/python/astra/astra_c.pyx b/python/astra/astra_c.pyx index 342a214..6b246b6 100644 --- a/python/astra/astra_c.pyx +++ b/python/astra/astra_c.pyx @@ -45,21 +45,19 @@ ELSE: pass def credits(): - six.print_(""" -All Scale Tomographic Reconstruction Antwerp Toolbox (ASTRA-Toolbox) -was developed at the University of Antwerp by - * Prof. dr. Joost Batenburg - * Andrei Dabravolski - * Gert Merckx - * Willem Jan Palenstijn - * Tom Roelandts - * Prof. dr. Jan Sijbers - * dr. Wim van Aarle - * Sander van der Maar - * dr. Gert Van Gompel - -Python interface written by - * Daniel M. Pelt (CWI, Amsterdam)""") + six.print_("""The ASTRA Toolbox has been developed at the University of Antwerp and CWI, Amsterdam by + * Prof. dr. Joost Batenburg + * Prof. dr. Jan Sijbers + * Dr. Jeroen Bedorf + * Dr. Folkert Bleichrodt + * Dr. Andrei Dabravolski + * Dr. Willem Jan Palenstijn + * Dr. Tom Roelandts + * Dr. Wim van Aarle + * Dr. Gert Van Gompel + * Sander van der Maar, MSc. + * Gert Merckx, MSc. + * Daan Pelt, MSc.""") def use_cuda(): -- cgit v1.2.3 From 687c5e244e46e51786afad77f5015cae9abad129 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 6 Jan 2016 15:10:34 +0100 Subject: Add multi-GPU support to CompositeGeometryManager --- cuda/3d/mem3d.h | 2 + include/astra/CompositeGeometryManager.h | 16 ++ matlab/mex/astra_mex_c.cpp | 45 +++- src/CompositeGeometryManager.cpp | 434 +++++++++++++++++++++++-------- 4 files changed, 378 insertions(+), 119 deletions(-) (limited to 'matlab') diff --git a/cuda/3d/mem3d.h b/cuda/3d/mem3d.h index 82bad19..acb72cb 100644 --- a/cuda/3d/mem3d.h +++ b/cuda/3d/mem3d.h @@ -87,6 +87,8 @@ bool copyFromGPUMemory(float *dst, MemHandle3D src, const SSubDimensions3D &pos) bool freeGPUMemory(MemHandle3D handle); +bool setGPUIndex(int index); + bool FP(const astra::CProjectionGeometry3D* pProjGeom, MemHandle3D projData, const astra::CVolumeGeometry3D* pVolGeom, MemHandle3D volData, int iDetectorSuperSampling, astra::Cuda3DProjectionKernel projKernel); diff --git a/include/astra/CompositeGeometryManager.h b/include/astra/CompositeGeometryManager.h index 6610151..49d02a7 100644 --- a/include/astra/CompositeGeometryManager.h +++ b/include/astra/CompositeGeometryManager.h @@ -50,9 +50,16 @@ class CProjectionGeometry3D; class CProjector3D; +struct SGPUParams { + std::vector GPUIndices; + size_t memory; +}; + class _AstraExport CCompositeGeometryManager { public: + CCompositeGeometryManager(); + class CPart; typedef std::list > TPartList; class CPart { @@ -139,10 +146,19 @@ public: bool doFP(CProjector3D *pProjector, const std::vector& volData, const std::vector& projData); bool doBP(CProjector3D *pProjector, const std::vector& volData, const std::vector& projData); + void setGPUIndices(const std::vector& GPUIndices); + + static void setGlobalGPUParams(const SGPUParams& params); + protected: bool splitJobs(TJobSet &jobs, size_t maxSize, int div, TJobSet &split); + std::vector m_GPUIndices; + size_t m_iMaxSize; + + + static SGPUParams* s_params; }; } diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp index d34334c..fdf4f33 100644 --- a/matlab/mex/astra_mex_c.cpp +++ b/matlab/mex/astra_mex_c.cpp @@ -38,6 +38,7 @@ $Id$ #include "astra/Globals.h" #ifdef ASTRA_CUDA #include "../cuda/2d/darthelper.h" +#include "astra/CompositeGeometryManager.h" #endif using namespace std; using namespace astra; @@ -83,12 +84,46 @@ void astra_mex_use_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs * Set active GPU */ void astra_mex_set_gpu_index(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) -{ +{ #ifdef ASTRA_CUDA - if (nrhs >= 2) { - bool ret = astraCUDA::setGPUIndex((int)mxGetScalar(prhs[1])); - if (!ret) - mexPrintf("Failed to set GPU %d\n", (int)mxGetScalar(prhs[1])); + bool usage = false; + if (nrhs != 2 && nrhs != 4) { + usage = true; + } + + astra::SGPUParams params; + params.memory = 0; + + if (!usage && nrhs >= 4) { + std::string s = mexToString(prhs[2]); + if (s != "memory") { + usage = true; + } else { + params.memory = (size_t)mxGetScalar(prhs[3]); + } + } + + if (!usage && nrhs >= 2) { + int n = mxGetN(prhs[1]) * mxGetM(prhs[1]); + params.GPUIndices.resize(n); + double* pdMatlabData = mxGetPr(prhs[1]); + for (int i = 0; i < n; ++i) + params.GPUIndices[i] = (int)pdMatlabData[i]; + + + astra::CCompositeGeometryManager::setGlobalGPUParams(params); + + + // Set first GPU + if (n >= 1) { + bool ret = astraCUDA::setGPUIndex((int)pdMatlabData[0]); + if (!ret) + mexPrintf("Failed to set GPU %d\n", (int)pdMatlabData[0]); + } + } + + if (usage) { + mexPrintf("Usage: astra_mex('set_gpu_index', index/indices [, 'memory', memory])"); } #endif } diff --git a/src/CompositeGeometryManager.cpp b/src/CompositeGeometryManager.cpp index eed06c4..d1b713e 100644 --- a/src/CompositeGeometryManager.cpp +++ b/src/CompositeGeometryManager.cpp @@ -44,11 +44,31 @@ along with the ASTRA Toolbox. If not, see . #include "../cuda/3d/mem3d.h" #include +#include + +#ifndef USE_PTHREADS +#include +#include +#endif namespace astra { + +SGPUParams* CCompositeGeometryManager::s_params = 0; + +CCompositeGeometryManager::CCompositeGeometryManager() +{ + m_iMaxSize = 0; + + if (s_params) { + m_iMaxSize = s_params->memory; + m_GPUIndices = s_params->GPUIndices; + } +} + + // JOB: -// +// // VolumePart // ProjectionPart // FP-or-BP @@ -76,7 +96,6 @@ namespace astra { // (First approach: 0.5/0.5) - bool CCompositeGeometryManager::splitJobs(TJobSet &jobs, size_t maxSize, int div, TJobSet &split) { split.clear(); @@ -848,6 +867,260 @@ bool CCompositeGeometryManager::doBP(CProjector3D *pProjector, const std::vector +static bool doJob(const CCompositeGeometryManager::TJobSet::const_iterator& iter) +{ + CCompositeGeometryManager::CPart* output = iter->first; + const CCompositeGeometryManager::TJobList& L = iter->second; + + assert(!L.empty()); + + bool zero = L.begin()->eMode == CCompositeGeometryManager::SJob::MODE_SET; + + size_t outx, outy, outz; + output->getDims(outx, outy, outz); + + if (L.begin()->eType == CCompositeGeometryManager::SJob::JOB_NOP) { + // just zero output? + if (zero) { + for (size_t z = 0; z < outz; ++z) { + for (size_t y = 0; y < outy; ++y) { + float* ptr = output->pData->getData(); + ptr += (z + output->subX) * (size_t)output->pData->getHeight() * (size_t)output->pData->getWidth(); + ptr += (y + output->subY) * (size_t)output->pData->getWidth(); + ptr += output->subX; + memset(ptr, 0, sizeof(float) * outx); + } + } + } + return true; + } + + + astraCUDA3d::SSubDimensions3D dstdims; + dstdims.nx = output->pData->getWidth(); + dstdims.pitch = dstdims.nx; + dstdims.ny = output->pData->getHeight(); + dstdims.nz = output->pData->getDepth(); + dstdims.subnx = outx; + dstdims.subny = outy; + dstdims.subnz = outz; + ASTRA_DEBUG("dstdims: %d,%d,%d in %d,%d,%d", dstdims.subnx, dstdims.subny, dstdims.subnz, dstdims.nx, dstdims.ny, dstdims.nz); + dstdims.subx = output->subX; + dstdims.suby = output->subY; + dstdims.subz = output->subZ; + float *dst = output->pData->getData(); + + astraCUDA3d::MemHandle3D outputMem = astraCUDA3d::allocateGPUMemory(outx, outy, outz, zero ? astraCUDA3d::INIT_ZERO : astraCUDA3d::INIT_NO); + bool ok = outputMem; + + for (CCompositeGeometryManager::TJobList::const_iterator i = L.begin(); i != L.end(); ++i) { + const CCompositeGeometryManager::SJob &j = *i; + + assert(j.pInput); + + CCudaProjector3D *projector = dynamic_cast(j.pProjector); + Cuda3DProjectionKernel projKernel = ker3d_default; + int detectorSuperSampling = 1; + int voxelSuperSampling = 1; + if (projector) { + projKernel = projector->getProjectionKernel(); + detectorSuperSampling = projector->getDetectorSuperSampling(); + voxelSuperSampling = projector->getVoxelSuperSampling(); + } + + size_t inx, iny, inz; + j.pInput->getDims(inx, iny, inz); + astraCUDA3d::MemHandle3D inputMem = astraCUDA3d::allocateGPUMemory(inx, iny, inz, astraCUDA3d::INIT_NO); + + astraCUDA3d::SSubDimensions3D srcdims; + srcdims.nx = j.pInput->pData->getWidth(); + srcdims.pitch = srcdims.nx; + srcdims.ny = j.pInput->pData->getHeight(); + srcdims.nz = j.pInput->pData->getDepth(); + srcdims.subnx = inx; + srcdims.subny = iny; + srcdims.subnz = inz; + srcdims.subx = j.pInput->subX; + srcdims.suby = j.pInput->subY; + srcdims.subz = j.pInput->subZ; + const float *src = j.pInput->pData->getDataConst(); + + ok = astraCUDA3d::copyToGPUMemory(src, inputMem, srcdims); + if (!ok) ASTRA_ERROR("Error copying input data to GPU"); + + if (j.eType == CCompositeGeometryManager::SJob::JOB_FP) { + assert(dynamic_cast(j.pInput.get())); + assert(dynamic_cast(j.pOutput.get())); + + ASTRA_DEBUG("CCompositeGeometryManager::doJobs: doing FP"); + + ok = astraCUDA3d::FP(((CCompositeGeometryManager::CProjectionPart*)j.pOutput.get())->pGeom, outputMem, ((CCompositeGeometryManager::CVolumePart*)j.pInput.get())->pGeom, inputMem, detectorSuperSampling, projKernel); + if (!ok) ASTRA_ERROR("Error performing sub-FP"); + ASTRA_DEBUG("CCompositeGeometryManager::doJobs: FP done"); + } else if (j.eType == CCompositeGeometryManager::SJob::JOB_BP) { + assert(dynamic_cast(j.pOutput.get())); + assert(dynamic_cast(j.pInput.get())); + + ASTRA_DEBUG("CCompositeGeometryManager::doJobs: doing BP"); + + ok = astraCUDA3d::BP(((CCompositeGeometryManager::CProjectionPart*)j.pInput.get())->pGeom, inputMem, ((CCompositeGeometryManager::CVolumePart*)j.pOutput.get())->pGeom, outputMem, voxelSuperSampling); + if (!ok) ASTRA_ERROR("Error performing sub-BP"); + ASTRA_DEBUG("CCompositeGeometryManager::doJobs: BP done"); + } else { + assert(false); + } + + ok = astraCUDA3d::freeGPUMemory(inputMem); + if (!ok) ASTRA_ERROR("Error freeing GPU memory"); + + } + + ok = astraCUDA3d::copyFromGPUMemory(dst, outputMem, dstdims); + if (!ok) ASTRA_ERROR("Error copying output data from GPU"); + + ok = astraCUDA3d::freeGPUMemory(outputMem); + if (!ok) ASTRA_ERROR("Error freeing GPU memory"); + + return true; +} + + +class WorkQueue { +public: + WorkQueue(CCompositeGeometryManager::TJobSet &_jobs) : m_jobs(_jobs) { +#ifdef USE_PTHREADS + pthread_mutex_init(&m_mutex, 0); +#endif + m_iter = m_jobs.begin(); + } + bool receive(CCompositeGeometryManager::TJobSet::const_iterator &i) { + lock(); + + if (m_iter == m_jobs.end()) { + unlock(); + return false; + } + + i = m_iter++; + + unlock(); + + return true; + } +#ifdef USE_PTHREADS + void lock() { + // TODO: check mutex op return values + pthread_mutex_lock(&m_mutex); + } + void unlock() { + // TODO: check mutex op return values + pthread_mutex_unlock(&m_mutex); + } +#else + void lock() { + m_mutex.lock(); + } + void unlock() { + m_mutex.unlock(); + } +#endif + +private: + CCompositeGeometryManager::TJobSet &m_jobs; + CCompositeGeometryManager::TJobSet::const_iterator m_iter; +#ifdef USE_PTHREADS + pthread_mutex_t m_mutex; +#else + boost::mutex m_mutex; +#endif +}; + +struct WorkThreadInfo { + WorkQueue* m_queue; + unsigned int m_iGPU; +}; + +#ifndef USE_PTHREADS + +void runEntries_boost(WorkThreadInfo* info) +{ + ASTRA_DEBUG("Launching thread on GPU %d\n", info->m_iGPU); + CCompositeGeometryManager::TJobSet::const_iterator i; + while (info->m_queue->receive(i)) { + ASTRA_DEBUG("Running block on GPU %d\n", info->m_iGPU); + astraCUDA3d::setGPUIndex(info->m_iGPU); + boost::this_thread::interruption_point(); + doJob(i); + boost::this_thread::interruption_point(); + } + ASTRA_DEBUG("Finishing thread on GPU %d\n", info->m_iGPU); +} + + +#else + +void* runEntries_pthreads(void* data) { + WorkThreadInfo* info = (WorkThreadInfo*)data; + + ASTRA_DEBUG("Launching thread on GPU %d\n", info->m_iGPU); + + CCompositeGeometryManager::TJobSet::const_iterator i; + + while (info->m_queue->receive(i)) { + ASTRA_DEBUG("Running block on GPU %d\n", info->m_iGPU); + astraCUDA3d::setGPUIndex(info->m_iGPU); + pthread_testcancel(); + doJob(i); + pthread_testcancel(); + } + ASTRA_DEBUG("Finishing thread on GPU %d\n", info->m_iGPU); + + return 0; +} + +#endif + + +void runWorkQueue(WorkQueue &queue, const std::vector & iGPUIndices) { + int iThreadCount = iGPUIndices.size(); + + std::vector infos; +#ifdef USE_PTHREADS + std::vector threads; +#else + std::vector threads; +#endif + infos.resize(iThreadCount); + threads.resize(iThreadCount); + + for (int i = 0; i < iThreadCount; ++i) { + infos[i].m_queue = &queue; + infos[i].m_iGPU = iGPUIndices[i]; +#ifdef USE_PTHREADS + pthread_create(&threads[i], 0, runEntries_pthreads, (void*)&infos[i]); +#else + threads[i] = new boost::thread(runEntries_boost, &infos[i]); +#endif + } + + // Wait for them to finish + for (int i = 0; i < iThreadCount; ++i) { +#ifdef USE_PTHREADS + pthread_join(threads[i], 0); +#else + threads[i]->join(); + delete threads[i]; + threads[i] = 0; +#endif + } +} + + +void CCompositeGeometryManager::setGPUIndices(const std::vector& GPUIndices) +{ + m_GPUIndices = GPUIndices; +} + bool CCompositeGeometryManager::doJobs(TJobList &jobs) { ASTRA_DEBUG("CCompositeGeometryManager::doJobs"); @@ -859,140 +1132,53 @@ bool CCompositeGeometryManager::doJobs(TJobList &jobs) jobset[i->pOutput.get()].push_back(*i); } - size_t maxSize = astraCUDA3d::availableGPUMemory(); + size_t maxSize = m_iMaxSize; if (maxSize == 0) { - ASTRA_WARN("Unable to get available GPU memory. Defaulting to 1GB."); - maxSize = 1024 * 1024 * 1024; + // Get memory from first GPU. Not optimal... + if (!m_GPUIndices.empty()) + astraCUDA3d::setGPUIndex(m_GPUIndices[0]); + maxSize = astraCUDA3d::availableGPUMemory(); + if (maxSize == 0) { + ASTRA_WARN("Unable to get available GPU memory. Defaulting to 1GB."); + maxSize = 1024 * 1024 * 1024; + } else { + ASTRA_DEBUG("Detected %lu bytes of GPU memory", maxSize); + } } else { - ASTRA_DEBUG("Detected %lu bytes of GPU memory", maxSize); + ASTRA_DEBUG("Set to %lu bytes of GPU memory", maxSize); } maxSize = (maxSize * 9) / 10; maxSize /= sizeof(float); int div = 1; - - // TODO: Multi-GPU support + if (!m_GPUIndices.empty()) + div = m_GPUIndices.size(); // Split jobs to fit TJobSet split; splitJobs(jobset, maxSize, div, split); jobset.clear(); - // Run jobs - - for (TJobSet::iterator iter = split.begin(); iter != split.end(); ++iter) { - - CPart* output = iter->first; - TJobList& L = iter->second; - - assert(!L.empty()); + if (m_GPUIndices.size() <= 1) { - bool zero = L.begin()->eMode == SJob::MODE_SET; + // Run jobs + ASTRA_DEBUG("Running single-threaded"); - size_t outx, outy, outz; - output->getDims(outx, outy, outz); + if (!m_GPUIndices.empty()) + astraCUDA3d::setGPUIndex(m_GPUIndices[0]); - if (L.begin()->eType == SJob::JOB_NOP) { - // just zero output? - if (zero) { - for (size_t z = 0; z < outz; ++z) { - for (size_t y = 0; y < outy; ++y) { - float* ptr = output->pData->getData(); - ptr += (z + output->subX) * (size_t)output->pData->getHeight() * (size_t)output->pData->getWidth(); - ptr += (y + output->subY) * (size_t)output->pData->getWidth(); - ptr += output->subX; - memset(ptr, 0, sizeof(float) * outx); - } - } - } - continue; + for (TJobSet::const_iterator iter = split.begin(); iter != split.end(); ++iter) { + doJob(iter); } + } else { - astraCUDA3d::SSubDimensions3D dstdims; - dstdims.nx = output->pData->getWidth(); - dstdims.pitch = dstdims.nx; - dstdims.ny = output->pData->getHeight(); - dstdims.nz = output->pData->getDepth(); - dstdims.subnx = outx; - dstdims.subny = outy; - dstdims.subnz = outz; - ASTRA_DEBUG("dstdims: %d,%d,%d in %d,%d,%d", dstdims.subnx, dstdims.subny, dstdims.subnz, dstdims.nx, dstdims.ny, dstdims.nz); - dstdims.subx = output->subX; - dstdims.suby = output->subY; - dstdims.subz = output->subZ; - float *dst = output->pData->getData(); - - astraCUDA3d::MemHandle3D outputMem = astraCUDA3d::allocateGPUMemory(outx, outy, outz, zero ? astraCUDA3d::INIT_ZERO : astraCUDA3d::INIT_NO); - bool ok = outputMem; - - for (TJobList::iterator i = L.begin(); i != L.end(); ++i) { - SJob &j = *i; - - assert(j.pInput); - - CCudaProjector3D *projector = dynamic_cast(j.pProjector); - Cuda3DProjectionKernel projKernel = ker3d_default; - int detectorSuperSampling = 1; - int voxelSuperSampling = 1; - if (projector) { - projKernel = projector->getProjectionKernel(); - detectorSuperSampling = projector->getDetectorSuperSampling(); - voxelSuperSampling = projector->getVoxelSuperSampling(); - } - - size_t inx, iny, inz; - j.pInput->getDims(inx, iny, inz); - astraCUDA3d::MemHandle3D inputMem = astraCUDA3d::allocateGPUMemory(inx, iny, inz, astraCUDA3d::INIT_NO); - - astraCUDA3d::SSubDimensions3D srcdims; - srcdims.nx = j.pInput->pData->getWidth(); - srcdims.pitch = srcdims.nx; - srcdims.ny = j.pInput->pData->getHeight(); - srcdims.nz = j.pInput->pData->getDepth(); - srcdims.subnx = inx; - srcdims.subny = iny; - srcdims.subnz = inz; - srcdims.subx = j.pInput->subX; - srcdims.suby = j.pInput->subY; - srcdims.subz = j.pInput->subZ; - const float *src = j.pInput->pData->getDataConst(); - - ok = astraCUDA3d::copyToGPUMemory(src, inputMem, srcdims); - if (!ok) ASTRA_ERROR("Error copying input data to GPU"); - - if (j.eType == SJob::JOB_FP) { - assert(dynamic_cast(j.pInput.get())); - assert(dynamic_cast(j.pOutput.get())); - - ASTRA_DEBUG("CCompositeGeometryManager::doJobs: doing FP"); - - ok = astraCUDA3d::FP(((CProjectionPart*)j.pOutput.get())->pGeom, outputMem, ((CVolumePart*)j.pInput.get())->pGeom, inputMem, detectorSuperSampling, projKernel); - if (!ok) ASTRA_ERROR("Error performing sub-FP"); - ASTRA_DEBUG("CCompositeGeometryManager::doJobs: FP done"); - } else if (j.eType == SJob::JOB_BP) { - assert(dynamic_cast(j.pOutput.get())); - assert(dynamic_cast(j.pInput.get())); - - ASTRA_DEBUG("CCompositeGeometryManager::doJobs: doing BP"); - - ok = astraCUDA3d::BP(((CProjectionPart*)j.pInput.get())->pGeom, inputMem, ((CVolumePart*)j.pOutput.get())->pGeom, outputMem, voxelSuperSampling); - if (!ok) ASTRA_ERROR("Error performing sub-BP"); - ASTRA_DEBUG("CCompositeGeometryManager::doJobs: BP done"); - } else { - assert(false); - } + ASTRA_DEBUG("Running multi-threaded"); - ok = astraCUDA3d::freeGPUMemory(inputMem); - if (!ok) ASTRA_ERROR("Error freeing GPU memory"); + WorkQueue wq(split); - } + runWorkQueue(wq, m_GPUIndices); - ok = astraCUDA3d::copyFromGPUMemory(dst, outputMem, dstdims); - if (!ok) ASTRA_ERROR("Error copying output data from GPU"); - - ok = astraCUDA3d::freeGPUMemory(outputMem); - if (!ok) ASTRA_ERROR("Error freeing GPU memory"); } return true; @@ -1000,6 +1186,26 @@ bool CCompositeGeometryManager::doJobs(TJobList &jobs) + +//static +void CCompositeGeometryManager::setGlobalGPUParams(const SGPUParams& params) +{ + delete s_params; + + s_params = new SGPUParams; + *s_params = params; + + ASTRA_DEBUG("CompositeGeometryManager: Setting global GPU params:"); + std::ostringstream s; + s << "GPU indices:"; + for (unsigned int i = 0; i < params.GPUIndices.size(); ++i) + s << " " << params.GPUIndices[i]; + std::string ss = s.str(); + ASTRA_DEBUG(ss.c_str()); + ASTRA_DEBUG("Memory: %llu", params.memory); +} + + } #endif -- cgit v1.2.3 From 2b0177d66197cb613eed2dabe463b9486428a3e3 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Thu, 21 Jan 2016 11:12:32 +0100 Subject: Fix file permissions --- matlab/mex/astra_mex_direct_c.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 matlab/mex/astra_mex_direct_c.cpp (limited to 'matlab') diff --git a/matlab/mex/astra_mex_direct_c.cpp b/matlab/mex/astra_mex_direct_c.cpp old mode 100755 new mode 100644 -- cgit v1.2.3 From 56809b0359af7e9108adeb1fd21823a225edf6fa Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 20 Jan 2016 18:08:59 +0100 Subject: Remove dependency of libastra on libpython by refactoring PluginAlgorithm --- build/linux/Makefile.in | 2 - include/astra/AstraObjectFactory.h | 7 +- include/astra/PluginAlgorithm.h | 57 ++-- matlab/mex/astra_mex_plugin_c.cpp | 18 +- python/astra/plugin_c.pyx | 17 +- python/astra/src/PythonPluginAlgorithm.cpp | 402 +++++++++++++++++++++++++++++ python/astra/src/PythonPluginAlgorithm.h | 89 +++++++ python/builder.py | 4 + src/PluginAlgorithm.cpp | 367 +------------------------- 9 files changed, 544 insertions(+), 419 deletions(-) create mode 100644 python/astra/src/PythonPluginAlgorithm.cpp create mode 100644 python/astra/src/PythonPluginAlgorithm.h (limited to 'matlab') diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index 3018674..d5644bc 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -62,8 +62,6 @@ PYCPPFLAGS := $(CPPFLAGS) PYCPPFLAGS += -I../include PYLDFLAGS = $(LDFLAGS) PYLDFLAGS += -L$(abs_top_builddir)/.libs -LIBS += -l$(PYLIBVER) -LDFLAGS += -L$(PYLIBDIR) endif # This is below where PYCPPFLAGS copies CPPFLAGS. The python code is built diff --git a/include/astra/AstraObjectFactory.h b/include/astra/AstraObjectFactory.h index 325989e..6af9cd8 100644 --- a/include/astra/AstraObjectFactory.h +++ b/include/astra/AstraObjectFactory.h @@ -155,8 +155,11 @@ class _AstraExport CAlgorithmFactory : public CAstraObjectFactory inline CAlgorithm* CAstraObjectFactory::findPlugin(std::string _sType) { - CPluginAlgorithmFactory *fac = CPluginAlgorithmFactory::getSingletonPtr(); - return fac->getPlugin(_sType); + CPluginAlgorithmFactory *fac = CPluginAlgorithmFactory::getFactory(); + if (fac) + return fac->getPlugin(_sType); + else + return 0; } #endif diff --git a/include/astra/PluginAlgorithm.h b/include/astra/PluginAlgorithm.h index 667e813..cbd80fc 100644 --- a/include/astra/PluginAlgorithm.h +++ b/include/astra/PluginAlgorithm.h @@ -29,62 +29,37 @@ $Id$ #ifndef _INC_ASTRA_PLUGINALGORITHM #define _INC_ASTRA_PLUGINALGORITHM -#ifdef ASTRA_PYTHON - -#include "astra/Algorithm.h" -#include "astra/Singleton.h" -#include "astra/XMLDocument.h" -#include "astra/XMLNode.h" - -// Slightly hackish forward declaration of PyObject -struct _object; -typedef _object PyObject; +#include "astra/Globals.h" +#include +#include namespace astra { -class _AstraExport CPluginAlgorithm : public CAlgorithm { - -public: - - CPluginAlgorithm(PyObject* pyclass); - ~CPluginAlgorithm(); - - bool initialize(const Config& _cfg); - void run(int _iNrIterations); - -private: - PyObject * instance; -}; +class CAlgorithm; -class _AstraExport CPluginAlgorithmFactory : public Singleton { +class _AstraExport CPluginAlgorithmFactory { public: + CPluginAlgorithmFactory() { } + virtual ~CPluginAlgorithmFactory() { } - CPluginAlgorithmFactory(); - ~CPluginAlgorithmFactory(); + virtual CAlgorithm * getPlugin(const std::string &name) = 0; - CPluginAlgorithm * getPlugin(std::string name); + virtual bool registerPlugin(std::string name, std::string className) = 0; + virtual bool registerPlugin(std::string className) = 0; - bool registerPlugin(std::string name, std::string className); - bool registerPlugin(std::string className); - bool registerPluginClass(std::string name, PyObject * className); - bool registerPluginClass(PyObject * className); + virtual std::map getRegisteredMap() = 0; - PyObject * getRegistered(); - std::map getRegisteredMap(); - - std::string getHelp(std::string name); + virtual std::string getHelp(const std::string &name) = 0; + + static void registerFactory(CPluginAlgorithmFactory *factory) { m_factory = factory; } + static CPluginAlgorithmFactory* getFactory() { return m_factory; } private: - PyObject * pluginDict; - PyObject *inspect, *six; + static CPluginAlgorithmFactory *m_factory; }; -PyObject* XMLNode2dict(XMLNode node); - } #endif - -#endif diff --git a/matlab/mex/astra_mex_plugin_c.cpp b/matlab/mex/astra_mex_plugin_c.cpp index 177fcf4..0dc0edf 100644 --- a/matlab/mex/astra_mex_plugin_c.cpp +++ b/matlab/mex/astra_mex_plugin_c.cpp @@ -48,7 +48,11 @@ using namespace astra; */ void astra_mex_plugin_get_registered(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { - astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getSingletonPtr(); + astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getFactory(); + if (!fact) { + mexPrintf("Plugin support not initialized."); + return; + } std::map mp = fact->getRegisteredMap(); for(std::map::iterator it=mp.begin();it!=mp.end();it++){ mexPrintf("%s: %s\n",it->first.c_str(), it->second.c_str()); @@ -62,9 +66,13 @@ void astra_mex_plugin_get_registered(int nlhs, mxArray* plhs[], int nrhs, const */ void astra_mex_plugin_register(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { + astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getFactory(); + if (!fact) { + mexPrintf("Plugin support not initialized."); + return; + } if (2 <= nrhs) { string class_name = mexToString(prhs[1]); - astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getSingletonPtr(); fact->registerPlugin(class_name); }else{ mexPrintf("astra_mex_plugin('register', class_name);\n"); @@ -78,9 +86,13 @@ void astra_mex_plugin_register(int nlhs, mxArray* plhs[], int nrhs, const mxArra */ void astra_mex_plugin_get_help(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { + astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getFactory(); + if (!fact) { + mexPrintf("Plugin support not initialized."); + return; + } if (2 <= nrhs) { string name = mexToString(prhs[1]); - astra::CPluginAlgorithmFactory *fact = astra::CPluginAlgorithmFactory::getSingletonPtr(); mexPrintf((fact->getHelp(name)+"\n").c_str()); }else{ mexPrintf("astra_mex_plugin('get_help', name);\n"); diff --git a/python/astra/plugin_c.pyx b/python/astra/plugin_c.pyx index 8d6816b..775ccd4 100644 --- a/python/astra/plugin_c.pyx +++ b/python/astra/plugin_c.pyx @@ -32,21 +32,25 @@ import inspect from libcpp.string cimport string from libcpp cimport bool -cdef CPluginAlgorithmFactory *fact = getSingletonPtr() +cdef CPythonPluginAlgorithmFactory *fact = getSingletonPtr() from . import utils -cdef extern from "astra/PluginAlgorithm.h" namespace "astra": - cdef cppclass CPluginAlgorithmFactory: +cdef extern from "src/PythonPluginAlgorithm.h" namespace "astra": + cdef cppclass CPythonPluginAlgorithmFactory: bool registerPlugin(string className) bool registerPlugin(string name, string className) bool registerPluginClass(object className) bool registerPluginClass(string name, object className) object getRegistered() - string getHelp(string name) + string getHelp(string &name) + +cdef extern from "src/PythonPluginAlgorithm.h" namespace "astra::CPythonPluginAlgorithmFactory": + cdef CPythonPluginAlgorithmFactory* getSingletonPtr() cdef extern from "astra/PluginAlgorithm.h" namespace "astra::CPluginAlgorithmFactory": - cdef CPluginAlgorithmFactory* getSingletonPtr() + # NB: Using wrong pointer type here for convenience + cdef void registerFactory(CPythonPluginAlgorithmFactory *) def register(className, name=None): if inspect.isclass(className): @@ -65,3 +69,6 @@ def get_registered(): def get_help(name): return utils.wrap_from_bytes(fact.getHelp(six.b(name))) + +# Register python plugin factory with astra +registerFactory(fact) diff --git a/python/astra/src/PythonPluginAlgorithm.cpp b/python/astra/src/PythonPluginAlgorithm.cpp new file mode 100644 index 0000000..1ea858d --- /dev/null +++ b/python/astra/src/PythonPluginAlgorithm.cpp @@ -0,0 +1,402 @@ +/* +----------------------------------------------------------------------- +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 "PythonPluginAlgorithm.h" + +#include "astra/Logging.h" +#include "astra/Utilities.h" +#include +#include +#include +#include +#include + +#include +#include "bytesobject.h" + +namespace astra { + + + +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); + } +} + +CPythonPluginAlgorithmFactory::CPythonPluginAlgorithmFactory(){ + 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"); +} + +CPythonPluginAlgorithmFactory::~CPythonPluginAlgorithmFactory(){ + 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 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 CPythonPluginAlgorithmFactory::getRegisteredMap(){ + std::map 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 CPythonPluginAlgorithmFactory::getHelp(const 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(CPythonPluginAlgorithmFactory); + +#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 rows, row; + boost::split(rows, str, boost::is_any_of(";")); + PyObject *mat = PyList_New(rows.size()); + for(unsigned int i=0; i vec; + boost::split(vec, str, boost::is_any_of(",")); + PyObject *veclist = PyList_New(vec.size()); + for(unsigned int i=0;i 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 diff --git a/python/astra/src/PythonPluginAlgorithm.h b/python/astra/src/PythonPluginAlgorithm.h new file mode 100644 index 0000000..0b1309e --- /dev/null +++ b/python/astra/src/PythonPluginAlgorithm.h @@ -0,0 +1,89 @@ +/* +----------------------------------------------------------------------- +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$ +*/ + +#ifndef _INC_PYTHONPLUGINALGORITHM +#define _INC_PYTHONPLUGINALGORITHM + +#ifdef ASTRA_PYTHON + +#include "astra/Algorithm.h" +#include "astra/Singleton.h" +#include "astra/XMLDocument.h" +#include "astra/XMLNode.h" +#include "astra/PluginAlgorithm.h" + +#include + +namespace astra { +class CPluginAlgorithm : public CAlgorithm { + +public: + + CPluginAlgorithm(PyObject* pyclass); + ~CPluginAlgorithm(); + + bool initialize(const Config& _cfg); + void run(int _iNrIterations); + +private: + PyObject * instance; + +}; + +class CPythonPluginAlgorithmFactory : public CPluginAlgorithmFactory, public Singleton { + +public: + + CPythonPluginAlgorithmFactory(); + virtual ~CPythonPluginAlgorithmFactory(); + + virtual CAlgorithm * getPlugin(const std::string &name); + + virtual bool registerPlugin(std::string name, std::string className); + virtual bool registerPlugin(std::string className); + bool registerPluginClass(std::string name, PyObject * className); + bool registerPluginClass(PyObject * className); + + PyObject * getRegistered(); + virtual std::map getRegisteredMap(); + + virtual std::string getHelp(const std::string &name); + +private: + PyObject * pluginDict; + PyObject *inspect, *six; +}; + +PyObject* XMLNode2dict(XMLNode node); + +} + + +#endif + +#endif diff --git a/python/builder.py b/python/builder.py index 018b26b..9a77ecc 100644 --- a/python/builder.py +++ b/python/builder.py @@ -70,6 +70,10 @@ ext_modules = [ ] ext_modules = cythonize("astra/*.pyx", language_level=2) cmdclass = { 'build_ext': build_ext } +for m in ext_modules: + if m.name == 'astra.plugin_c': + m.sources.append('astra/src/PythonPluginAlgorithm.cpp') + setup (name = 'PyASTRAToolbox', version = '1.7.1', description = 'Python interface to the ASTRA-Toolbox', 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 . $Id$ */ -#ifdef ASTRA_PYTHON - #include "astra/PluginAlgorithm.h" -#include "astra/Logging.h" -#include "astra/Utilities.h" -#include -#include -#include -#include -#include - -#include -#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 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 CPluginAlgorithmFactory::getRegisteredMap(){ - std::map 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 rows, row; - boost::split(rows, str, boost::is_any_of(";")); - PyObject *mat = PyList_New(rows.size()); - for(unsigned int i=0; i vec; - boost::split(vec, str, boost::is_any_of(",")); - PyObject *veclist = PyList_New(vec.size()); - for(unsigned int i=0;i 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 -- cgit v1.2.3 From 7f11ed333cdc93e9e93d4677f857d97ffbbfec87 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Thu, 21 Jan 2016 12:14:44 +0100 Subject: Fix whitespace --- matlab/mex/astra_mex_plugin_c.cpp | 12 ++++++------ python/astra/src/PythonPluginAlgorithm.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_plugin_c.cpp b/matlab/mex/astra_mex_plugin_c.cpp index 0dc0edf..627e34a 100644 --- a/matlab/mex/astra_mex_plugin_c.cpp +++ b/matlab/mex/astra_mex_plugin_c.cpp @@ -128,12 +128,12 @@ void mexFunction(int nlhs, mxArray* plhs[], initASTRAMex(); // SWITCH (MODE) - if (sMode == std::string("get_registered")) { - astra_mex_plugin_get_registered(nlhs, plhs, nrhs, prhs); - }else if (sMode == std::string("get_help")) { - astra_mex_plugin_get_help(nlhs, plhs, nrhs, prhs); - }else if (sMode == std::string("register")) { - astra_mex_plugin_register(nlhs, plhs, nrhs, prhs); + if (sMode == std::string("get_registered")) { + astra_mex_plugin_get_registered(nlhs, plhs, nrhs, prhs); + }else if (sMode == std::string("get_help")) { + astra_mex_plugin_get_help(nlhs, plhs, nrhs, prhs); + }else if (sMode == std::string("register")) { + astra_mex_plugin_register(nlhs, plhs, nrhs, prhs); } else { printHelp(); } diff --git a/python/astra/src/PythonPluginAlgorithm.cpp b/python/astra/src/PythonPluginAlgorithm.cpp index 1ea858d..0100bed 100644 --- a/python/astra/src/PythonPluginAlgorithm.cpp +++ b/python/astra/src/PythonPluginAlgorithm.cpp @@ -238,7 +238,7 @@ CAlgorithm * CPythonPluginAlgorithmFactory::getPlugin(const std::string &name){ CPluginAlgorithm *alg = NULL; if(PyBytes_Check(className)){ std::string str = std::string(PyBytes_AsString(className)); - PyObject *pyclass = getClassFromString(str); + PyObject *pyclass = getClassFromString(str); if(pyclass!=NULL){ alg = new CPluginAlgorithm(pyclass); Py_DECREF(pyclass); -- cgit v1.2.3 From 96fa285132bf88462c33c5b24cc1b241fb3d4d73 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Thu, 21 Jan 2016 14:30:32 +0100 Subject: Initialize Python plugins when available in Matlab --- build/linux/Makefile.in | 10 ++++++++++ matlab/mex/astra_mex_plugin_c.cpp | 25 ++++++++++++++++++++++++- matlab/mex/mexInitFunctions.cpp | 8 ++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) (limited to 'matlab') diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in index d5644bc..57ed8f8 100644 --- a/build/linux/Makefile.in +++ b/build/linux/Makefile.in @@ -95,6 +95,11 @@ ifeq ($(cuda),yes) MEXFLAGS += -DASTRA_CUDA endif +ifeq ($(python),yes) +MEXPYLDFLAGS='$$LDFLAGS $(LDFLAGS) -L$(PYLIBDIR)' +MEXPYLIBS=$(MEXLIBS) -l$(PYLIBVER) +endif + endif LIBDIR=/usr/local/lib @@ -265,6 +270,11 @@ mex: $(MATLAB_MEX) %.$(MEXSUFFIX): %.o $(MATLAB_CXX_OBJECTS) libastra.la $(MEX) LDFLAGS=$(MEXLDFLAGS) $(MEXFLAGS) $(LIBS) $(MEXLIBS) -lastra -output $* $*.o $(MATLAB_CXX_OBJECTS) + +ifeq ($(python),yes) +matlab/mex/astra_mex_plugin_c.$(MEXSUFFIX): matlab/mex/astra_mex_plugin_c.o $(MATLAB_CXX_OBJECTS) libastra.la + $(MEX) LDFLAGS=$(MEXPYLDFLAGS) $(MEXFLAGS) $(LIBS) $(MEXPYLIBS) -lastra -output matlab/mex/astra_mex_plugin_c $< $(MATLAB_CXX_OBJECTS) +endif endif ifeq ($(python),yes) diff --git a/matlab/mex/astra_mex_plugin_c.cpp b/matlab/mex/astra_mex_plugin_c.cpp index 627e34a..9bd4446 100644 --- a/matlab/mex/astra_mex_plugin_c.cpp +++ b/matlab/mex/astra_mex_plugin_c.cpp @@ -37,10 +37,31 @@ $Id$ #include "astra/PluginAlgorithm.h" +#include + using namespace std; using namespace astra; +//----------------------------------------------------------------------------------------- +/** astra_mex_plugin('init'); + * + * Initialize plugin support by initializing python and importing astra + */ +void astra_mex_plugin_init() +{ + if(!Py_IsInitialized()){ + Py_Initialize(); + PyEval_InitThreads(); + } + + // Importing astra may be overkill, since we only need to initialize + // PythonPluginAlgorithmFactory from astra.plugin_c. + PyObject *mod = PyImport_ImportModule("astra"); + Py_DECREF(mod); +} + + //----------------------------------------------------------------------------------------- /** astra_mex_plugin('get_registered'); * @@ -128,7 +149,9 @@ void mexFunction(int nlhs, mxArray* plhs[], initASTRAMex(); // SWITCH (MODE) - if (sMode == std::string("get_registered")) { + if (sMode == "init") { + astra_mex_plugin_init(); + } else if (sMode == std::string("get_registered")) { astra_mex_plugin_get_registered(nlhs, plhs, nrhs, prhs); }else if (sMode == std::string("get_help")) { astra_mex_plugin_get_help(nlhs, plhs, nrhs, prhs); diff --git a/matlab/mex/mexInitFunctions.cpp b/matlab/mex/mexInitFunctions.cpp index bd3df2c..7245af2 100644 --- a/matlab/mex/mexInitFunctions.cpp +++ b/matlab/mex/mexInitFunctions.cpp @@ -23,5 +23,13 @@ void initASTRAMex(){ if(!astra::CLogger::setCallbackScreen(&logCallBack)){ mexErrMsgTxt("Error initializing mex functions."); } + mexIsInitialized=true; + + + // If we have support for plugins, initialize them. + // (NB: Call this after setting mexIsInitialized, to avoid recursively + // calling initASTRAMex) + mexEvalString("if exist('astra_mex_plugin_c') == 3; astra_mex_plugin_c('init'); end"); + } -- cgit v1.2.3 From 5cb48f351fcc1a7c5b11180edcded083176a2431 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 27 Jan 2016 09:28:10 +0100 Subject: Use Py_XDECREF to guard against null --- matlab/mex/astra_mex_plugin_c.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_plugin_c.cpp b/matlab/mex/astra_mex_plugin_c.cpp index 9bd4446..a279df8 100644 --- a/matlab/mex/astra_mex_plugin_c.cpp +++ b/matlab/mex/astra_mex_plugin_c.cpp @@ -58,7 +58,7 @@ void astra_mex_plugin_init() // Importing astra may be overkill, since we only need to initialize // PythonPluginAlgorithmFactory from astra.plugin_c. PyObject *mod = PyImport_ImportModule("astra"); - Py_DECREF(mod); + Py_XDECREF(mod); } -- cgit v1.2.3 From 4a75ab09962015d90acaa3e2be8357a1c917d5eb Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 27 Jan 2016 10:05:57 +0100 Subject: Move fixLapackLoading to astra_mex_plugin --- matlab/mex/astra_mex_plugin_c.cpp | 33 ++++++++++++++++++++++++++++++ python/astra/src/PythonPluginAlgorithm.cpp | 32 ----------------------------- 2 files changed, 33 insertions(+), 32 deletions(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_plugin_c.cpp b/matlab/mex/astra_mex_plugin_c.cpp index a279df8..4ed534e 100644 --- a/matlab/mex/astra_mex_plugin_c.cpp +++ b/matlab/mex/astra_mex_plugin_c.cpp @@ -42,6 +42,35 @@ $Id$ using namespace std; using namespace astra; +static 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); // RTLD_NOW|RTLD_DEEPBIND + if (retVal != NULL) { + PyObject *lapack = PyImport_ImportModule("numpy.linalg.lapack_lite"); + if (lapack != NULL) { + Py_DECREF(lapack); + } + PyObject *retVal2 = PyObject_CallMethod(sys, "setdlopenflags", "O",curFlags); + if (retVal2 != NULL) { + Py_DECREF(retVal2); + } + Py_DECREF(retVal); + } + Py_DECREF(curFlags); + } + Py_DECREF(sys); + } +} //----------------------------------------------------------------------------------------- /** astra_mex_plugin('init'); @@ -55,6 +84,10 @@ void astra_mex_plugin_init() PyEval_InitThreads(); } +#ifndef _MSC_VER + fixLapackLoading(); +#endif + // Importing astra may be overkill, since we only need to initialize // PythonPluginAlgorithmFactory from astra.plugin_c. PyObject *mod = PyImport_ImportModule("astra"); diff --git a/python/astra/src/PythonPluginAlgorithm.cpp b/python/astra/src/PythonPluginAlgorithm.cpp index 61a56ea..e34861a 100644 --- a/python/astra/src/PythonPluginAlgorithm.cpp +++ b/python/astra/src/PythonPluginAlgorithm.cpp @@ -127,43 +127,11 @@ void CPluginAlgorithm::run(int _iNrIterations){ 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 *retVal2 = PyObject_CallMethod(sys, "setdlopenflags", "O",curFlags); - if(retVal2!=NULL){ - Py_DECREF(retVal2); - } - Py_DECREF(retVal); - } - Py_DECREF(curFlags); - } - Py_DECREF(sys); - } -} - CPythonPluginAlgorithmFactory::CPythonPluginAlgorithmFactory(){ 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"); -- cgit v1.2.3 From 8cfe13a410a051e5a6b9835e3a4cd6c808cf5d29 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Tue, 16 Feb 2016 15:34:08 +0100 Subject: Add astra_mex delete/info based on index manager --- include/astra/AstraObjectManager.h | 1 + matlab/mex/astra_mex_c.cpp | 49 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) (limited to 'matlab') diff --git a/include/astra/AstraObjectManager.h b/include/astra/AstraObjectManager.h index 8b9da30..35b4534 100644 --- a/include/astra/AstraObjectManager.h +++ b/include/astra/AstraObjectManager.h @@ -53,6 +53,7 @@ namespace astra { */ class CAstraObjectManagerBase { +public: virtual std::string getInfo(int index) const =0; virtual void remove(int index) =0; virtual std::string getType() const =0; diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp index fdf4f33..a8623be 100644 --- a/matlab/mex/astra_mex_c.cpp +++ b/matlab/mex/astra_mex_c.cpp @@ -36,10 +36,14 @@ $Id$ #include "mexInitFunctions.h" #include "astra/Globals.h" +#include "astra/AstraObjectManager.h" + #ifdef ASTRA_CUDA #include "../cuda/2d/darthelper.h" #include "astra/CompositeGeometryManager.h" #endif + + using namespace std; using namespace astra; @@ -142,6 +146,47 @@ void astra_mex_version(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[ } } +//----------------------------------------------------------------------------------------- + +void astra_mex_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (nrhs < 2) { + mexErrMsgTxt("Usage: astra_mex('info', index/indices);\n"); + return; + } + + for (int i = 1; i < nrhs; i++) { + int iDataID = (int)(mxGetScalar(prhs[i])); + CAstraObjectManagerBase *ptr; + ptr = CAstraIndexManager::getSingleton().get(iDataID); + if (ptr) { + mexPrintf("%s\t%s\n", ptr->getType().c_str(), ptr->getInfo(iDataID).c_str()); + } + } + +} + +//----------------------------------------------------------------------------------------- + +void astra_mex_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (nrhs < 2) { + mexErrMsgTxt("Usage: astra_mex('delete', index/indices);\n"); + return; + } + + for (int i = 1; i < nrhs; i++) { + int iDataID = (int)(mxGetScalar(prhs[i])); + CAstraObjectManagerBase *ptr; + ptr = CAstraIndexManager::getSingleton().get(iDataID); + if (ptr) + ptr->remove(iDataID); + } + +} + + + //----------------------------------------------------------------------------------------- static void printHelp() @@ -178,6 +223,10 @@ void mexFunction(int nlhs, mxArray* plhs[], astra_mex_credits(nlhs, plhs, nrhs, prhs); } else if (sMode == std::string("set_gpu_index")) { astra_mex_set_gpu_index(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("info")) { + astra_mex_info(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("delete")) { + astra_mex_delete(nlhs, plhs, nrhs, prhs); } else { printHelp(); } -- cgit v1.2.3 From da11f9e7c7559eb01cc422ac55c9f7a1cd4bb803 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Mon, 22 Feb 2016 12:17:53 +0100 Subject: Add missing help --- matlab/mex/astra_mex_c.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'matlab') diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp index a8623be..f499528 100644 --- a/matlab/mex/astra_mex_c.cpp +++ b/matlab/mex/astra_mex_c.cpp @@ -192,7 +192,7 @@ void astra_mex_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[] static void printHelp() { mexPrintf("Please specify a mode of operation.\n"); - mexPrintf(" Valid modes: version, use_cuda, credits\n"); + mexPrintf(" Valid modes: version, use_cuda, credits, set_gpu_index, info, delete\n"); } //----------------------------------------------------------------------------------------- -- cgit v1.2.3 From 5a81584cb37fe578d5985b8e78b511076fa75b1c Mon Sep 17 00:00:00 2001 From: Folkert Bleichrodt Date: Wed, 2 Mar 2016 16:47:25 +0100 Subject: opTomo: output type matches input type If opTomo is used to do a forward or backprojection, the precision of the output data now matches the precision of the input data. So the output will be single precision only if the input is stored in single precision. --- matlab/tools/opTomo.m | 86 +++++++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 57 deletions(-) (limited to 'matlab') diff --git a/matlab/tools/opTomo.m b/matlab/tools/opTomo.m index 71dfb1e..33c8565 100644 --- a/matlab/tools/opTomo.m +++ b/matlab/tools/opTomo.m @@ -44,11 +44,9 @@ classdef opTomo < opSpot vol_id fp_alg_id bp_alg_id + proj_id % ASTRA IDs handle astra_handle - % geometries - proj_geom; - vol_geom; end % properties properties ( SetAccess = private, GetAccess = public ) @@ -139,6 +137,17 @@ classdef opTomo < opSpot error(['Only type ' 39 'cuda' 39 ' is supported ' ... 'for 3D geometries.']) end + + % setup projector + cfg = astra_struct('cuda3d'); + cfg.ProjectionGeometry = proj_geom; + cfg.VolumeGeometry = vol_geom; + cfg.option.GPUindex = gpu_index; + + % create projector + op.proj_id = astra_mex_projector3d('create', cfg); + % create handle to ASTRA object, for cleaning up + op.astra_handle = opTomo_helper_handle(op.proj_id); % create a function handle op.funHandle = @opTomo_intrnl3D; @@ -148,8 +157,6 @@ classdef opTomo < opSpot % pass object properties op.proj_size = proj_size; op.vol_size = vol_size; - op.proj_geom = proj_geom; - op.vol_geom = vol_geom; op.cflag = false; op.sweepflag = false; @@ -170,11 +177,6 @@ classdef opTomo < opSpot x = full(x); end - % convert input to single - if isa(x, 'single') == false - x = single(x); - end - % the multiplication y = op.funHandle(op, x, mode); @@ -194,7 +196,7 @@ classdef opTomo < opSpot function y = opTomo_intrnl2D(op,x,mode) if mode == 1 - % X is passed as a vector, reshape it into an image. + % x is passed as a vector, reshape it into an image. x = reshape(x, op.vol_size); % Matlab data copied to ASTRA data @@ -204,9 +206,13 @@ classdef opTomo < opSpot astra_mex_algorithm('iterate', op.fp_alg_id); % retrieve Matlab array - y = astra_mex_data2d('get_single', op.sino_id); + if isa(x, 'single') + y = astra_mex_data2d('get_single', op.sino_id); + else + y = astra_mex_data2d('get', op.sino_id); + end else - % X is passed as a vector, reshape it into a sinogram. + % x is passed as a vector, reshape it into a sinogram. x = reshape(x, op.proj_size); % Matlab data copied to ASTRA data @@ -216,8 +222,13 @@ classdef opTomo < opSpot astra_mex_algorithm('iterate', op.bp_alg_id); % retrieve Matlab array - y = astra_mex_data2d('get_single', op.vol_id); + if isa(x, 'single') + y = astra_mex_data2d('get_single', op.vol_id); + else + y = astra_mex_data2d('get', op.vol_id); + end end + end % opTomo_intrnl2D @@ -225,55 +236,16 @@ classdef opTomo < opSpot function y = opTomo_intrnl3D(op,x,mode) if mode == 1 - % X is passed as a vector, reshape it into an image + % x is passed as a vector, reshape it into an image x = reshape(x, op.vol_size); - % initialize output - y = zeros(op.proj_size, 'single'); - - % link matlab array to ASTRA - vol_id = astra_mex_data3d_c('link', '-vol', op.vol_geom, x, 0); - sino_id = astra_mex_data3d_c('link', '-sino', op.proj_geom, y, 1); - - % initialize fp algorithm - cfg = astra_struct('FP3D_CUDA'); - cfg.ProjectionDataId = sino_id; - cfg.VolumeDataId = vol_id; - - alg_id = astra_mex_algorithm('create', cfg); - % forward projection - astra_mex_algorithm('iterate', alg_id); - - % cleanup - astra_mex_data3d('delete', vol_id); - astra_mex_data3d('delete', sino_id); - astra_mex_algorithm('delete', alg_id); + y = astra_mex_direct('FP3D', op.proj_id, x); else - % X is passed as a vector, reshape it into projection data + % x is passed as a vector, reshape it into projection data x = reshape(x, op.proj_size); - - % initialize output - y = zeros(op.vol_size,'single'); - - % link matlab array to ASTRA - vol_id = astra_mex_data3d_c('link', '-vol', op.vol_geom, y, 1); - sino_id = astra_mex_data3d_c('link', '-sino', op.proj_geom, x, 0); - % initialize bp algorithm - cfg = astra_struct('BP3D_CUDA'); - cfg.ProjectionDataId = sino_id; - cfg.ReconstructionDataId = vol_id; - - alg_id = astra_mex_algorithm('create', cfg); - - % backprojection - astra_mex_algorithm('iterate', alg_id); - - % cleanup - astra_mex_data3d('delete', vol_id); - astra_mex_data3d('delete', sino_id); - astra_mex_algorithm('delete', alg_id); + y = astra_mex_direct('BP3D', op.proj_id, x); end end % opTomo_intrnl3D -- cgit v1.2.3 From 6205f3fcc68be3d49fa5b47a02a65c21ffc53930 Mon Sep 17 00:00:00 2001 From: Folkert Bleichrodt Date: Mon, 14 Mar 2016 13:18:02 +0100 Subject: Removed regression from opTomo --- matlab/tools/opTomo.m | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'matlab') diff --git a/matlab/tools/opTomo.m b/matlab/tools/opTomo.m index 33c8565..04b3634 100644 --- a/matlab/tools/opTomo.m +++ b/matlab/tools/opTomo.m @@ -176,12 +176,23 @@ classdef opTomo < opSpot if issparse(x) x = full(x); end + + if isa(x, 'double') + isdouble = true; + x = single(x); + else + isdouble = false; + end % the multiplication y = op.funHandle(op, x, mode); % make sure output is column vector y = y(:); + + if isdouble + y = double(y); + end end % multiply @@ -206,11 +217,7 @@ classdef opTomo < opSpot astra_mex_algorithm('iterate', op.fp_alg_id); % retrieve Matlab array - if isa(x, 'single') - y = astra_mex_data2d('get_single', op.sino_id); - else - y = astra_mex_data2d('get', op.sino_id); - end + y = astra_mex_data2d('get_single', op.sino_id); else % x is passed as a vector, reshape it into a sinogram. x = reshape(x, op.proj_size); @@ -222,11 +229,7 @@ classdef opTomo < opSpot astra_mex_algorithm('iterate', op.bp_alg_id); % retrieve Matlab array - if isa(x, 'single') - y = astra_mex_data2d('get_single', op.vol_id); - else - y = astra_mex_data2d('get', op.vol_id); - end + y = astra_mex_data2d('get_single', op.vol_id); end end % opTomo_intrnl2D -- cgit v1.2.3