summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWillem Jan Palenstijn <wjp@usecode.org>2015-02-27 11:46:29 +0100
committerWillem Jan Palenstijn <wjp@usecode.org>2015-02-27 11:46:29 +0100
commit03a9dd972ada50eedb83386910cecf02fe8d0e35 (patch)
treef764bff6a8109d42445bdd1db622fd739baf5d4a
parent9e2bb413a937aefe57f4fcf343413543ae57258a (diff)
parent169e912d2633cda7ffc234e78afba1b096e122ea (diff)
downloadastra-03a9dd972ada50eedb83386910cecf02fe8d0e35.tar.gz
astra-03a9dd972ada50eedb83386910cecf02fe8d0e35.tar.bz2
astra-03a9dd972ada50eedb83386910cecf02fe8d0e35.tar.xz
astra-03a9dd972ada50eedb83386910cecf02fe8d0e35.zip
Merge pull request #20 from wvaarle/matlab-get-geometry
'get_geometry' functions in the matlab layer
-rw-r--r--include/astra/ConeProjectionGeometry3D.h20
-rw-r--r--include/astra/ConeVecProjectionGeometry3D.h14
-rw-r--r--include/astra/Config.h3
-rw-r--r--include/astra/FanFlatProjectionGeometry2D.h6
-rw-r--r--include/astra/FanFlatVecProjectionGeometry2D.h15
-rw-r--r--include/astra/ParallelProjectionGeometry2D.h6
-rw-r--r--include/astra/ParallelProjectionGeometry3D.h20
-rw-r--r--include/astra/ParallelVecProjectionGeometry3D.h14
-rw-r--r--include/astra/ProjectionGeometry2D.h6
-rw-r--r--include/astra/ProjectionGeometry3D.h12
-rw-r--r--include/astra/SparseMatrixProjectionGeometry2D.h8
-rw-r--r--include/astra/VolumeGeometry2D.h6
-rw-r--r--include/astra/VolumeGeometry3D.h6
-rw-r--r--include/astra/XMLDocument.h3
-rw-r--r--matlab/mex/astra_mex_algorithm_c.cpp17
-rw-r--r--matlab/mex/astra_mex_c.cpp2
-rw-r--r--matlab/mex/astra_mex_data2d_c.cpp82
-rw-r--r--matlab/mex/astra_mex_data3d_c.cpp88
-rw-r--r--matlab/mex/astra_mex_matrix_c.cpp2
-rw-r--r--matlab/mex/astra_mex_projector3d_c.cpp26
-rw-r--r--matlab/mex/astra_mex_projector_c.cpp18
-rw-r--r--matlab/mex/mexCopyDataHelpFunctions.cpp2
-rw-r--r--matlab/mex/mexDataManagerHelpFunctions.cpp40
-rw-r--r--matlab/mex/mexHelpFunctions.cpp718
-rw-r--r--matlab/mex/mexHelpFunctions.h35
-rw-r--r--src/ConeProjectionGeometry3D.cpp23
-rw-r--r--src/ConeVecProjectionGeometry3D.cpp38
-rw-r--r--src/Config.cpp12
-rw-r--r--src/FanFlatProjectionGeometry2D.cpp14
-rw-r--r--src/FanFlatVecProjectionGeometry2D.cpp24
-rw-r--r--src/ParallelProjectionGeometry2D.cpp14
-rw-r--r--src/ParallelProjectionGeometry3D.cpp22
-rw-r--r--src/ParallelVecProjectionGeometry3D.cpp36
-rw-r--r--src/SparseMatrixProjectionGeometry2D.cpp13
-rw-r--r--src/VolumeGeometry2D.cpp20
-rw-r--r--src/VolumeGeometry3D.cpp23
-rw-r--r--src/XMLDocument.cpp8
-rw-r--r--src/XMLNode.cpp10
38 files changed, 724 insertions, 702 deletions
diff --git a/include/astra/ConeProjectionGeometry3D.h b/include/astra/ConeProjectionGeometry3D.h
index 2a0474d..00e72ce 100644
--- a/include/astra/ConeProjectionGeometry3D.h
+++ b/include/astra/ConeProjectionGeometry3D.h
@@ -40,8 +40,8 @@ namespace astra
* \par XML Configuration
* \astra_xml_item{DetectorRowCount, int, Number of detectors for each projection.}
* \astra_xml_item{DetectorColCount, int, Number of detectors for each projection.}
- * \astra_xml_item{DetectorWidth, float, Width of each detector.}
- * \astra_xml_item{DetectorHeight, float, Width of each detector.}
+ * \astra_xml_item{DetectorSpacingX, float, Width of each detector.}
+ * \astra_xml_item{DetectorSpacingY, float, Width of each detector.}
* \astra_xml_item{ProjectionAngles, vector of float, projection angles in radians.}
* \astra_xml_item{DistanceOriginDetector, float, Distance between the center of rotation and the detectorarray.}
* \astra_xml_item{DistanceOriginSource, float, Distance between the center of rotation the the x-ray source.}
@@ -51,8 +51,8 @@ namespace astra
* proj_geom = astra_struct('cone');\n
* proj_geom.DetectorRowCount = 512;\n
* proj_geom.DetectorColCount = 512;\n
- * proj_geom.DetectorWidth = 1.0;\n
- * proj_geom.DetectorHeight = 1.0;\n
+ * proj_geom.DetectorSpacingX = 1.0;\n
+ * proj_geom.DetectorSpacingY = 1.0;\n
* proj_geom.ProjectionAngles = linspace(0,pi,100);\n
* proj_geom.DistanceOriginDetector = 10000;\n
* proj_geom.DistanceOriginSource = 10000;\n
@@ -148,6 +148,12 @@ public:
*/
virtual bool isEqual(const CProjectionGeometry3D*) const;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
/** Returns true if the type of geometry defined in this class is the one specified in _sType.
*
* @param _sType geometry type to compare to.
@@ -155,12 +161,6 @@ public:
*/
virtual bool isOfType(const std::string& _sType) const;
- /** Turn this object into an XML object.
- *
- * @param _sNode The XML object to fill.
- */
- virtual void toXML(XMLNode* _sNode) const;
-
/** Returns the distance from the origin of the coordinate system to the source.
*
* @return Distance from the origin of the coordinate system to the source
diff --git a/include/astra/ConeVecProjectionGeometry3D.h b/include/astra/ConeVecProjectionGeometry3D.h
index 68a80ef..e82a411 100644
--- a/include/astra/ConeVecProjectionGeometry3D.h
+++ b/include/astra/ConeVecProjectionGeometry3D.h
@@ -56,7 +56,7 @@ namespace astra
* to a single projection, and consists of:
* ( srcX, srcY, srcZ, dX, dY, dZ, uX, uY, uZ, vX, vY, vZ )
* src: the ray source
- * d : the corner of the detector
+ * d : the centre of the detector plane
* u : the vector from detector pixel (0,0) to (0,1)
* v : the vector from detector pixel (0,0) to (1,0)
*/
@@ -128,6 +128,12 @@ public:
*/
virtual bool isEqual(const CProjectionGeometry3D*) const;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
/** Returns true if the type of geometry defined in this class is the one specified in _sType.
*
* @param _sType geometry type to compare to.
@@ -135,12 +141,6 @@ public:
*/
virtual bool isOfType(const std::string& _sType) const;
- /** Turn this object into an XML object.
- *
- * @param _sNode The XML object to fill.
- */
- virtual void toXML(XMLNode* _sNode) const;
-
/**
* Returns a vector giving the projection direction for a projection and detector index
*/
diff --git a/include/astra/Config.h b/include/astra/Config.h
index 647462b..9893c90 100644
--- a/include/astra/Config.h
+++ b/include/astra/Config.h
@@ -31,6 +31,7 @@ $Id$
#include "Globals.h"
#include "XMLNode.h"
+#include "XMLDocument.h"
#include <set>
@@ -46,6 +47,8 @@ struct _AstraExport Config {
Config(XMLNode* _self);
~Config();
+ void initialize(std::string rootname);
+
XMLNode* self;
XMLNode* global;
};
diff --git a/include/astra/FanFlatProjectionGeometry2D.h b/include/astra/FanFlatProjectionGeometry2D.h
index 8f22c35..180fe68 100644
--- a/include/astra/FanFlatProjectionGeometry2D.h
+++ b/include/astra/FanFlatProjectionGeometry2D.h
@@ -140,6 +140,12 @@ public:
*/
virtual bool isOfType(const std::string& _sType);
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
/** Return true if this geometry instance is the same as the one specified.
*
* @return true if this geometry instance is the same as the one specified.
diff --git a/include/astra/FanFlatVecProjectionGeometry2D.h b/include/astra/FanFlatVecProjectionGeometry2D.h
index 85c994f..ee85408 100644
--- a/include/astra/FanFlatVecProjectionGeometry2D.h
+++ b/include/astra/FanFlatVecProjectionGeometry2D.h
@@ -53,6 +53,14 @@ namespace astra
* proj_geom.DetectorCount = 512;\n
* proj_geom.Vectors = V;\n
* }
+ *
+ * \par Vectors
+ * Vectors is a matrix containing the actual geometry. Each row corresponds
+ * to a single projection, and consists of:
+ * ( srcX, srcY, srcZ, dX, dY uX, uY)
+ * src: the ray source
+ * d : the centre of the detector array
+ * u : the vector from detector 0 to detector 1
*/
class _AstraExport CFanFlatVecProjectionGeometry2D : public CProjectionGeometry2D
{
@@ -126,6 +134,13 @@ public:
*/
virtual bool isEqual(CProjectionGeometry2D*) const;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
+
/** Get the value for t and theta, based upon the row and column index.
*
* @param _iRow row index
diff --git a/include/astra/ParallelProjectionGeometry2D.h b/include/astra/ParallelProjectionGeometry2D.h
index ed9d228..2f7d36f 100644
--- a/include/astra/ParallelProjectionGeometry2D.h
+++ b/include/astra/ParallelProjectionGeometry2D.h
@@ -136,6 +136,12 @@ public:
*/
virtual bool isOfType(const std::string& _sType);
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
/**
* Returns a vector describing the direction of a ray belonging to a certain detector,
* the direction is the same for all detectors in one projection
diff --git a/include/astra/ParallelProjectionGeometry3D.h b/include/astra/ParallelProjectionGeometry3D.h
index da60617..72401e5 100644
--- a/include/astra/ParallelProjectionGeometry3D.h
+++ b/include/astra/ParallelProjectionGeometry3D.h
@@ -41,8 +41,8 @@ namespace astra
* \par XML Configuration
* \astra_xml_item{DetectorRowCount, int, Number of detectors for each projection.}
* \astra_xml_item{DetectorColCount, int, Number of detectors for each projection.}
- * \astra_xml_item{DetectorWidth, float, Width of each detector.}
- * \astra_xml_item{DetectorHeight, float, Width of each detector.}
+ * \astra_xml_item{DetectorSpacingX, float, Width of each detector.}
+ * \astra_xml_item{DetectorSpacingY, float, Width of each detector.}
* \astra_xml_item{ProjectionAngles, vector of float, projection angles in radians.}
*
* \par MATLAB example
@@ -50,8 +50,8 @@ namespace astra
* proj_geom = astra_struct('parallel');\n
* proj_geom.DetectorRowCount = 512;\n
* proj_geom.DetectorColCount = 512;\n
- * proj_geom.DetectorWidth = 1.0;\n
- * proj_geom.DetectorHeight = 1.0;\n
+ * proj_geom.DetectorSpacingX = 1.0;\n
+ * proj_geom.DetectorSpacingY = 1.0;\n
* proj_geom.ProjectionAngles = linspace(0,pi,100);\n
* }
*/
@@ -129,6 +129,12 @@ public:
*/
virtual bool isEqual(const CProjectionGeometry3D*) const;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
/** Returns true if the type of geometry defined in this class is the one specified in _sType.
*
* @param _sType geometry type to compare to.
@@ -136,12 +142,6 @@ public:
*/
virtual bool isOfType(const std::string& _sType) const;
- /** Turn this object into an XML object.
- *
- * @param _sNode The XML object to fill.
- */
- virtual void toXML(XMLNode* _sNode) const;
-
/**
* Returns a vector giving the projection direction for a projection and detector index
*/
diff --git a/include/astra/ParallelVecProjectionGeometry3D.h b/include/astra/ParallelVecProjectionGeometry3D.h
index fbc2112..5a63249 100644
--- a/include/astra/ParallelVecProjectionGeometry3D.h
+++ b/include/astra/ParallelVecProjectionGeometry3D.h
@@ -55,7 +55,7 @@ namespace astra
* to a single projection, and consists of:
* ( rayX, rayY, rayZ, dX, dY, dZ, uX, uY, uZ, vX, vY, vZ )
* ray: the ray direction
- * d : the corner of the detector
+ * d : the centre of the detector plane
* u : the vector from detector pixel (0,0) to (0,1)
* v : the vector from detector pixel (0,0) to (1,0)
*/
@@ -128,6 +128,12 @@ public:
*/
virtual bool isEqual(const CProjectionGeometry3D*) const;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
/** Returns true if the type of geometry defined in this class is the one specified in _sType.
*
* @param _sType geometry type to compare to.
@@ -135,12 +141,6 @@ public:
*/
virtual bool isOfType(const std::string& _sType) const;
- /** Turn this object into an XML object.
- *
- * @param _sNode The XML object to fill.
- */
- virtual void toXML(XMLNode* _sNode) const;
-
/**
* Returns a vector giving the projection direction for a projection and detector index
*/
diff --git a/include/astra/ProjectionGeometry2D.h b/include/astra/ProjectionGeometry2D.h
index 303ca0a..b8324e2 100644
--- a/include/astra/ProjectionGeometry2D.h
+++ b/include/astra/ProjectionGeometry2D.h
@@ -157,6 +157,12 @@ public:
*/
virtual bool isEqual(CProjectionGeometry2D*) const = 0;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const = 0;
+
/** Get the number of projection angles.
*
* @return Number of projection angles
diff --git a/include/astra/ProjectionGeometry3D.h b/include/astra/ProjectionGeometry3D.h
index 41b1cb7..19ac3ab 100644
--- a/include/astra/ProjectionGeometry3D.h
+++ b/include/astra/ProjectionGeometry3D.h
@@ -187,6 +187,12 @@ public:
*/
virtual bool isEqual(const CProjectionGeometry3D *) const = 0;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const = 0;
+
/** Get the number of projections.
*
* @return Number of projections
@@ -322,12 +328,6 @@ public:
*/
virtual bool isOfType(const std::string& _sType) const = 0;
- /** Turn this object into an XML object.
- *
- * @param _sNode The XML object to fill.
- */
- virtual void toXML(XMLNode* _sNode) const = 0;
-
/**
* Returns a vector giving the projection direction for a projection and detector index
*/
diff --git a/include/astra/SparseMatrixProjectionGeometry2D.h b/include/astra/SparseMatrixProjectionGeometry2D.h
index 36964be..d56f95e 100644
--- a/include/astra/SparseMatrixProjectionGeometry2D.h
+++ b/include/astra/SparseMatrixProjectionGeometry2D.h
@@ -103,7 +103,6 @@ public:
* @param _pMatrix Pointer to a CSparseMatrix. The caller is responsible for keeping this matrix valid until it is no longer required.
* @return initialization successful?
*/
-
bool setMatrix(CSparseMatrix* _pMatrix);
/** Get a pointer to the associated sparse matrix.
@@ -128,6 +127,13 @@ public:
*/
virtual bool isOfType(const std::string& _sType);
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
+
/**
* Returns a vector describing the direction of a ray belonging to a certain detector
*
diff --git a/include/astra/VolumeGeometry2D.h b/include/astra/VolumeGeometry2D.h
index fa0528d..28703d5 100644
--- a/include/astra/VolumeGeometry2D.h
+++ b/include/astra/VolumeGeometry2D.h
@@ -205,6 +205,12 @@ public:
*/
virtual bool isEqual(CVolumeGeometry2D*) const;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
/** Get the number of columns in the volume grid.
*
* @return Number of columns in the volume grid.
diff --git a/include/astra/VolumeGeometry3D.h b/include/astra/VolumeGeometry3D.h
index d5c8fff..ff94844 100644
--- a/include/astra/VolumeGeometry3D.h
+++ b/include/astra/VolumeGeometry3D.h
@@ -246,6 +246,12 @@ public:
*/
virtual bool isEqual(const CVolumeGeometry3D*) const;
+ /** Get all settings in a Config object.
+ *
+ * @return Configuration Object.
+ */
+ virtual Config* getConfiguration() const;
+
/** Get the number of columns in the volume grid.
*
* @return Number of columns in the volume grid.
diff --git a/include/astra/XMLDocument.h b/include/astra/XMLDocument.h
index c6f1b9a..869e1a3 100644
--- a/include/astra/XMLDocument.h
+++ b/include/astra/XMLDocument.h
@@ -86,6 +86,9 @@ public:
*/
void saveToFile(string sFilename);
+ /** convert and XML DOM tree to a string
+ */
+ std::string toString();
private:
diff --git a/matlab/mex/astra_mex_algorithm_c.cpp b/matlab/mex/astra_mex_algorithm_c.cpp
index be1c89f..669af8c 100644
--- a/matlab/mex/astra_mex_algorithm_c.cpp
+++ b/matlab/mex/astra_mex_algorithm_c.cpp
@@ -78,26 +78,23 @@ void astra_mex_algorithm_create(int nlhs, mxArray* plhs[], int nrhs, const mxArr
}
// turn MATLAB struct to an XML-based Config object
- XMLDocument* xml = struct2XML("Algorithm", prhs[1]);
- Config cfg;
- cfg.self = xml->getRootNode();
+ Config* cfg = structToConfig("Algorithm", prhs[1]);
- CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg.self->getAttribute("type"));
+ CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg->self->getAttribute("type"));
if (!pAlg) {
- delete xml;
+ delete cfg;
mexErrMsgTxt("Unknown algorithm. \n");
return;
}
// create algorithm
- if (!pAlg->initialize(cfg)) {
- delete xml;
+ if (!pAlg->initialize(*cfg)) {
+ delete cfg;
delete pAlg;
mexErrMsgTxt("Algorithm not initialized. \n");
return;
}
-
- delete xml;
+ delete cfg;
// store algorithm
int iIndex = CAlgorithmManager::getSingleton().store(pAlg);
@@ -322,7 +319,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
// INPUT: Mode
string sMode = "";
if (1 <= nrhs) {
- sMode = mex_util_get_string(prhs[0]);
+ sMode = mexToString(prhs[0]);
} else {
printHelp();
return;
diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp
index 2989b7a..760bd51 100644
--- a/matlab/mex/astra_mex_c.cpp
+++ b/matlab/mex/astra_mex_c.cpp
@@ -122,7 +122,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
// INPUT0: Mode
string sMode = "";
if (1 <= nrhs) {
- sMode = mex_util_get_string(prhs[0]);
+ sMode = mexToString(prhs[0]);
} else {
printHelp();
return;
diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp
index b219179..5f79e98 100644
--- a/matlab/mex/astra_mex_data2d_c.cpp
+++ b/matlab/mex/astra_mex_data2d_c.cpp
@@ -98,10 +98,10 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
return;
}
- string sDataType = mex_util_get_string(prhs[1]);
+ string sDataType = mexToString(prhs[1]);
CFloat32Data2D* pDataObject2D = NULL;
- if (nrhs >= 4 && !(mex_is_scalar(prhs[3])|| mxIsDouble(prhs[3]) || mxIsLogical(prhs[3]) || mxIsSingle(prhs[3]) )) {
+ if (nrhs >= 4 && !(mexIsScalar(prhs[3])|| mxIsDouble(prhs[3]) || mxIsLogical(prhs[3]) || mxIsSingle(prhs[3]) )) {
mexErrMsgTxt("Data must be single, double or logical.");
return;
}
@@ -116,23 +116,20 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
if (!mxIsStruct(prhs[2])) {
mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
}
- XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]);
- if (!xml)
- return;
- Config cfg;
- cfg.self = xml->getRootNode();
+
+ Config* cfg = structToConfig("VolumeGeometry", prhs[2]);
CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D();
- if (!pGeometry->initialize(cfg)) {
+ if (!pGeometry->initialize(*cfg)) {
mexErrMsgTxt("Geometry class not initialized. \n");
- delete xml;
+ delete cfg;
delete pGeometry;
return;
}
// If data is specified, check dimensions
- if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+ if (nrhs >= 4 && !mexIsScalar(prhs[3])) {
if (pGeometry->getGridColCount() != mxGetN(prhs[3]) || pGeometry->getGridRowCount() != mxGetM(prhs[3])) {
mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
- delete xml;
+ delete cfg;
delete pGeometry;
return;
}
@@ -140,21 +137,18 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
// Initialize data object
pDataObject2D = new CFloat32VolumeData2D(pGeometry);
delete pGeometry;
- delete xml;
+ delete cfg;
}
else if (sDataType == "-sino") {
// Read geometry
if (!mxIsStruct(prhs[2])) {
mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
}
- XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]);
- if (!xml)
- return;
- Config cfg;
- cfg.self = xml->getRootNode();
+
+ Config* cfg = structToConfig("ProjectionGeometry", prhs[2]);
// FIXME: Change how the base class is created. (This is duplicated
// in 'change_geometry' and Projector2D.cpp.)
- std::string type = cfg.self->getAttribute("type");
+ std::string type = cfg->self->getAttribute("type");
CProjectionGeometry2D* pGeometry;
if (type == "sparse_matrix") {
pGeometry = new CSparseMatrixProjectionGeometry2D();
@@ -168,25 +162,25 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
} else {
pGeometry = new CParallelProjectionGeometry2D();
}
- if (!pGeometry->initialize(cfg)) {
+ if (!pGeometry->initialize(*cfg)) {
mexErrMsgTxt("Geometry class not initialized. \n");
delete pGeometry;
- delete xml;
+ delete cfg;
return;
}
// If data is specified, check dimensions
- if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+ if (nrhs >= 4 && !mexIsScalar(prhs[3])) {
if (pGeometry->getDetectorCount() != mxGetN(prhs[3]) || pGeometry->getProjectionAngleCount() != mxGetM(prhs[3])) {
mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
delete pGeometry;
- delete xml;
+ delete cfg;
return;
}
}
// Initialize data object
pDataObject2D = new CFloat32ProjectionData2D(pGeometry);
delete pGeometry;
- delete xml;
+ delete cfg;
}
else {
mexErrMsgTxt("Invalid datatype. Please specify '-vol' or '-sino'. \n");
@@ -210,7 +204,7 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
// Store data
if (nrhs >= 4) {
// fill with scalar value
- if (mex_is_scalar(prhs[3])) {
+ if (mexIsScalar(prhs[3])) {
float32 fValue = (float32)mxGetScalar(prhs[3]);
for (int i = 0; i < pDataObject2D->getSize(); ++i) {
pDataObject2D->getData()[i] = fValue;
@@ -294,7 +288,7 @@ void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray*
}
int iDataID = (int)(mxGetScalar(prhs[1]));
- if (!(mex_is_scalar(prhs[2]) || mxIsDouble(prhs[2]) || mxIsLogical(prhs[2]) || mxIsSingle(prhs[2]))) {
+ if (!(mexIsScalar(prhs[2]) || mxIsDouble(prhs[2]) || mxIsLogical(prhs[2]) || mxIsSingle(prhs[2]))) {
mexErrMsgTxt("Data must be single, double or logical.");
return;
}
@@ -312,7 +306,7 @@ void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray*
// step3: insert data
// fill with scalar value
- if (mex_is_scalar(prhs[2])) {
+ if (mexIsScalar(prhs[2])) {
float32 fValue = (float32)mxGetScalar(prhs[2]);
for (int i = 0; i < pDataObject->getSize(); ++i) {
pDataObject->getData()[i] = fValue;
@@ -373,7 +367,7 @@ void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray*
*/
void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
- // step1: input
+ // parse input
if (nrhs < 2) {
mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
return;
@@ -384,7 +378,7 @@ void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mx
}
int iDataID = (int)(mxGetScalar(prhs[1]));
- // step2: get data object
+ // fetch data object
CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID);
if (!pDataObject || !pDataObject->isInitialized()) {
mexErrMsgTxt("Data object not found or not initialized properly.\n");
@@ -395,11 +389,11 @@ void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mx
if (1 <= nlhs) {
if (pDataObject->getType() == CFloat32Data2D::PROJECTION) {
CFloat32ProjectionData2D* pDataObject2 = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject);
- plhs[0] = createProjectionGeometryStruct(pDataObject2->getGeometry());
+ plhs[0] = configToStruct(pDataObject2->getGeometry()->getConfiguration());
}
else if (pDataObject->getType() == CFloat32Data2D::VOLUME) {
CFloat32VolumeData2D* pDataObject2 = dynamic_cast<CFloat32VolumeData2D*>(pDataObject);
- plhs[0] = createVolumeGeometryStruct(pDataObject2->getGeometry());
+ plhs[0] = configToStruct(pDataObject2->getGeometry()->getConfiguration());
}
}
}
@@ -440,12 +434,10 @@ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const
if (!mxIsStruct(prhs[2])) {
mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
}
- XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]);
- Config cfg;
- cfg.self = xml->getRootNode();
+ Config* cfg = structToConfig("ProjectionGeometry2D", prhs[2]);
// FIXME: Change how the base class is created. (This is duplicated
// in 'create' and Projector2D.cpp.)
- std::string type = cfg.self->getAttribute("type");
+ std::string type = cfg->self->getAttribute("type");
CProjectionGeometry2D* pGeometry;
if (type == "sparse_matrix") {
pGeometry = new CSparseMatrixProjectionGeometry2D();
@@ -459,24 +451,24 @@ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const
} else {
pGeometry = new CParallelProjectionGeometry2D();
}
- if (!pGeometry->initialize(cfg)) {
+ if (!pGeometry->initialize(*cfg)) {
mexErrMsgTxt("Geometry class not initialized. \n");
delete pGeometry;
- delete xml;
+ delete cfg;
return;
}
// If data is specified, check dimensions
if (pGeometry->getDetectorCount() != pSinogram->getDetectorCount() || pGeometry->getProjectionAngleCount() != pSinogram->getAngleCount()) {
mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
delete pGeometry;
- delete xml;
+ delete cfg;
return;
}
// If ok, change geometry
pSinogram->changeGeometry(pGeometry);
delete pGeometry;
- delete xml;
+ delete cfg;
return;
}
@@ -490,27 +482,25 @@ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const
if (!mxIsStruct(prhs[2])) {
mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
}
- XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]);
- Config cfg;
- cfg.self = xml->getRootNode();
+ Config* cfg = structToConfig("VolumeGeometry2D", prhs[2]);
CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D();
- if (!pGeometry->initialize(cfg)) {
+ if (!pGeometry->initialize(*cfg)) {
mexErrMsgTxt("Geometry class not initialized. \n");
- delete xml;
+ delete cfg;
delete pGeometry;
return;
}
// If data is specified, check dimensions
if (pGeometry->getGridColCount() != pVolume->getWidth() || pGeometry->getGridRowCount() != pVolume->getHeight()) {
mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
- delete xml;
+ delete cfg;
delete pGeometry;
return;
}
// If ok, change geometry
pVolume->changeGeometry(pGeometry);
- delete xml;
+ delete cfg;
delete pGeometry;
}
@@ -639,7 +629,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
// INPUT0: Mode
string sMode = "";
if (1 <= nrhs) {
- sMode = mex_util_get_string(prhs[0]);
+ sMode = mexToString(prhs[0]);
} else {
printHelp();
return;
diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp
index 35a7512..0a3f85d 100644
--- a/matlab/mex/astra_mex_data3d_c.cpp
+++ b/matlab/mex/astra_mex_data3d_c.cpp
@@ -83,7 +83,7 @@ void astra_mex_data3d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
return;
}
- const string sDataType = mex_util_get_string(prhs[1]);
+ const string sDataType = mexToString(prhs[1]);
// step2: Allocate data
CFloat32Data3DMemory* pDataObject3D =
@@ -152,7 +152,7 @@ void astra_mex_data3d_link(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray*
return;
}
- string sDataType = mex_util_get_string(prhs[1]);
+ string sDataType = mexToString(prhs[1]);
// step2: Allocate data
CFloat32Data3DMemory* pDataObject3D =
@@ -266,48 +266,46 @@ void astra_mex_data3d_dimensions(int nlhs, mxArray* plhs[], int nrhs, const mxAr
}
//-----------------------------------------------------------------------------------------
-/**
- * [geom] = astra_mex_data3d('geometry', id);
+/** geom = astra_mex_data3d('get_geometry', id);
+ *
+ * Fetch the geometry of a 3d data object stored in the astra-library.
+ * id: identifier of the 3d data object as stored in the astra-library.
+ * geom: MATLAB-struct containing information about the used geometry.
*/
-void astra_mex_data3d_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+void astra_mex_data3d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
- //// Get input
- //if (nrhs < 2) {
- // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
- // return;
- //}
- //int iDid = (int)(mxGetScalar(prhs[1]));
-
- //// Get data object
- //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
- //if (!pData) {
- // mexErrMsgTxt("DataObject not valid. \n");
- // return;
- //}
-
- //// Projection Data
- //if (pData->getType() == CFloat32Data3D::PROJECTION) {
- // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData);
- // CProjectionGeometry3D* pProjGeom = pData2->getGeometry();
- // XMLDocument* config = pProjGeom->toXML();
-
- // if (1 <= nlhs) {
- // plhs[0] = XML2struct(config);
- // }
- //}
- //// Volume Data
- //else if (pData->getType() == CFloat32Data3D::VOLUME) {
- //// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
- //// CVolumeGeometry2D* pVolGeom = pData2->getGeometry2D(iSliceNr);
- //// if (1 <= nlhs) {
- //// plhs[0] = createVolumeGeometryStruct(pVolGeom);
- //// }
- //}
- //// Error
- //else {
- // mexErrMsgTxt("Type not valid. \n");
- // return;
- //}
+ // parse input
+ if (nrhs < 2) {
+ mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n");
+ return;
+ }
+ if (!mxIsDouble(prhs[1])) {
+ mexErrMsgTxt("Identifier should be a scalar value. \n");
+ return;
+ }
+ int iDataID = (int)(mxGetScalar(prhs[1]));
+
+ // fetch data object
+ CFloat32Data3D* pDataObject = astra::CData3DManager::getSingleton().get(iDataID);
+ if (!pDataObject || !pDataObject->isInitialized()) {
+ mexErrMsgTxt("Data object not found or not initialized properly.\n");
+ return;
+ }
+
+ // create output
+ if (1 <= nlhs) {
+ if (pDataObject->getType() == CFloat32Data3D::PROJECTION) {
+ CFloat32ProjectionData3DMemory* pDataObject2 = dynamic_cast<CFloat32ProjectionData3DMemory*>(pDataObject);
+ plhs[0] = configToStruct(pDataObject2->getGeometry()->getConfiguration());
+
+ }
+ else if (pDataObject->getType() == CFloat32Data3D::VOLUME) {
+ CFloat32VolumeData3DMemory* pDataObject2 = dynamic_cast<CFloat32VolumeData3DMemory*>(pDataObject);
+ plhs[0] = configToStruct(pDataObject2->getGeometry()->getConfiguration());
+ }
+ }
+
+
}
//-----------------------------------------------------------------------------------------
@@ -367,7 +365,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
// INPUT: Mode
string sMode = "";
if (1 <= nrhs) {
- sMode = mex_util_get_string(prhs[0]);
+ sMode = mexToString(prhs[0]);
} else {
printHelp();
return;
@@ -395,8 +393,8 @@ void mexFunction(int nlhs, mxArray* plhs[],
astra_mex_data3d_info(nlhs, plhs, nrhs, prhs);
} else if (sMode == std::string("dimensions")) {
astra_mex_data3d_dimensions(nlhs, plhs, nrhs, prhs);
- } else if (sMode == std::string("geometry")) {
- astra_mex_data3d_geometry(nlhs, plhs, nrhs, prhs);
+ } else if (sMode == std::string("get_geometry")) {
+ astra_mex_data3d_get_geometry(nlhs, plhs, nrhs, prhs);
} else {
printHelp();
}
diff --git a/matlab/mex/astra_mex_matrix_c.cpp b/matlab/mex/astra_mex_matrix_c.cpp
index 016566a..01ad08b 100644
--- a/matlab/mex/astra_mex_matrix_c.cpp
+++ b/matlab/mex/astra_mex_matrix_c.cpp
@@ -406,7 +406,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
// INPUT0: Mode
string sMode = "";
if (1 <= nrhs) {
- sMode = mex_util_get_string(prhs[0]);
+ sMode = mexToString(prhs[0]);
} else {
printHelp();
return;
diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp
index 25980f9..5381cf6 100644
--- a/matlab/mex/astra_mex_projector3d_c.cpp
+++ b/matlab/mex/astra_mex_projector3d_c.cpp
@@ -65,16 +65,16 @@ void astra_mex_projector3d_create(int nlhs, mxArray* plhs[], int nrhs, const mxA
}
// turn MATLAB struct to an XML-based Config object
- XMLDocument* xml = struct2XML("Projector3D", prhs[1]);
- Config cfg;
- cfg.self = xml->getRootNode();
+ Config* cfg = structToConfig("Projector3D", prhs[1]);
// create algorithm
- CProjector3D* pProj = CProjector3DFactory::getSingleton().create(cfg);
+ CProjector3D* pProj = CProjector3DFactory::getSingleton().create(*cfg);
if (pProj == NULL) {
+ delete cfg;
mexErrMsgTxt("Error creating Projector3D. \n");
return;
}
+ delete cfg;
// store projector
int iIndex = CProjector3DManager::getSingleton().store(pProj);
@@ -135,16 +135,16 @@ 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] = createProjectionGeometryStruct(pProjector->getProjectionGeometry());
- //}
+ if (1 <= nlhs) {
+ plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration());
+ }
}
//-----------------------------------------------------------------------------------------
/**
* [recon_geom] = astra_mex_projector3d('get_volume_geometry', pid);
*/
-void astra_mex_projector3d_get_reconstruction_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+void astra_mex_projector3d_get_volume_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
{
// step1: read input
if (nrhs < 2) {
@@ -161,9 +161,9 @@ void astra_mex_projector3d_get_reconstruction_geometry(int nlhs, mxArray* plhs[]
}
// step3: get projection_geometry and turn it into a MATLAB struct
- //if (1 <= nlhs) {
- // plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry());
- //}
+ if (1 <= nlhs) {
+ plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration());
+ }
}
//-----------------------------------------------------------------------------------------
@@ -397,7 +397,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
// INPUT: Mode
string sMode = "";
if (1 <= nrhs) {
- sMode = mex_util_get_string(prhs[0]);
+ sMode = mexToString(prhs[0]);
} else {
printHelp();
return;
@@ -413,7 +413,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
} else if (sMode == "get_projection_geometry") {
astra_mex_projector3d_get_projection_geometry(nlhs, plhs, nrhs, prhs);
} else if (sMode == "get_volume_geometry") {
- astra_mex_projector3d_get_reconstruction_geometry(nlhs, plhs, nrhs, prhs);
+ astra_mex_projector3d_get_volume_geometry(nlhs, plhs, nrhs, prhs);
} else if (sMode == "weights_single_ray") {
astra_mex_projector_weights_single_ray(nlhs, plhs, nrhs, prhs);
//} else if (sMode == "weights_projection") {
diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp
index de73f07..58cd953 100644
--- a/matlab/mex/astra_mex_projector_c.cpp
+++ b/matlab/mex/astra_mex_projector_c.cpp
@@ -74,19 +74,16 @@ void astra_mex_projector_create(int nlhs, mxArray* plhs[], int nrhs, const mxArr
// turn MATLAB struct to an XML-based Config object
- XMLDocument* xml = struct2XML("Projector2D", prhs[1]);
- Config cfg;
- cfg.self = xml->getRootNode();
+ Config* cfg = structToConfig("Projector2D", prhs[1]);
// create algorithm
- CProjector2D* pProj = CProjector2DFactory::getSingleton().create(cfg);
+ CProjector2D* pProj = CProjector2DFactory::getSingleton().create(*cfg);
if (pProj == NULL) {
- delete xml;
+ delete cfg;
mexErrMsgTxt("Error creating projector. \n");
return;
}
-
- delete xml;
+ delete cfg;
// store projector
iIndex = CProjector2DManager::getSingleton().store(pProj);
@@ -162,7 +159,7 @@ 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] = createProjectionGeometryStruct(pProjector->getProjectionGeometry());
+ plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration());
}
}
@@ -191,7 +188,8 @@ 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] = createVolumeGeometryStruct(pProjector->getVolumeGeometry());
+ plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration());
+
}
}
@@ -472,7 +470,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
// INPUT: Mode
string sMode = "";
if (1 <= nrhs) {
- sMode = mex_util_get_string(prhs[0]);
+ sMode = mexToString(prhs[0]);
} else {
printHelp();
return;
diff --git a/matlab/mex/mexCopyDataHelpFunctions.cpp b/matlab/mex/mexCopyDataHelpFunctions.cpp
index 6dfd4a6..80fb834 100644
--- a/matlab/mex/mexCopyDataHelpFunctions.cpp
+++ b/matlab/mex/mexCopyDataHelpFunctions.cpp
@@ -263,7 +263,7 @@ copyMexToCFloat32Array(const mxArray * const in,
#pragma omp parallel
{
// fill with scalar value
- if (mex_is_scalar(in)) {
+ if (mexIsScalar(in)) {
astra::float32 fValue = 0.f;
if (!mxIsEmpty(in)) {
fValue = (astra::float32)mxGetScalar(in);
diff --git a/matlab/mex/mexDataManagerHelpFunctions.cpp b/matlab/mex/mexDataManagerHelpFunctions.cpp
index f9d971c..d482428 100644
--- a/matlab/mex/mexDataManagerHelpFunctions.cpp
+++ b/matlab/mex/mexDataManagerHelpFunctions.cpp
@@ -105,7 +105,7 @@ checkID(const astra::int32 & id, astra::CFloat32Data3DMemory *& pDataObj)
bool
checkDataType(const mxArray * const in)
{
- return (mex_is_scalar(in) || mxIsDouble(in) || mxIsSingle(in) || mxIsLogical(in));
+ return (mexIsScalar(in) || mxIsDouble(in) || mxIsSingle(in) || mxIsLogical(in));
}
//-----------------------------------------------------------------------------------------
@@ -213,7 +213,7 @@ allocateDataObject(const std::string & sDataType,
bool bUnshare = true;
if (unshare)
{
- if (!mex_is_scalar(unshare))
+ if (!mexIsScalar(unshare))
{
mexErrMsgTxt("Argument 5 (read-only) must be scalar");
return NULL;
@@ -225,7 +225,7 @@ allocateDataObject(const std::string & sDataType,
mwIndex iZ = 0;
if (zIndex)
{
- if (!mex_is_scalar(zIndex))
+ if (!mexIsScalar(zIndex))
{
mexErrMsgTxt("Argument 6 (Z) must be scalar");
return NULL;
@@ -237,25 +237,19 @@ allocateDataObject(const std::string & sDataType,
if (sDataType == "-vol")
{
// Read geometry
- astra::XMLDocument* xml = struct2XML("VolumeGeometry", geometry);
- if (!xml) {
- return NULL;
- }
- astra::Config cfg;
- cfg.self = xml->getRootNode();
-
+ astra::Config* cfg = structToConfig("VolumeGeometry3D", geometry);
astra::CVolumeGeometry3D* pGeometry = new astra::CVolumeGeometry3D();
- if (!pGeometry->initialize(cfg))
+ if (!pGeometry->initialize(*cfg))
{
mexErrMsgTxt("Geometry class not initialized. \n");
delete pGeometry;
- delete xml;
+ delete cfg;
return NULL;
}
- delete xml;
+ delete cfg;
// If data is specified, check dimensions
- if (data && !mex_is_scalar(data))
+ if (data && !mexIsScalar(data))
{
if (! (zIndex
? checkDataSize(data, pGeometry, iZ)
@@ -288,16 +282,10 @@ allocateDataObject(const std::string & sDataType,
else if (sDataType == "-sino" || sDataType == "-proj3d" || sDataType == "-sinocone")
{
// Read geometry
- astra::XMLDocument* xml = struct2XML("ProjectionGeometry", geometry);
- if (!xml) {
- return NULL;
- }
- astra::Config cfg;
- cfg.self = xml->getRootNode();
-
+ astra::Config* cfg = structToConfig("ProjectionGeometry3D", geometry);
// FIXME: Change how the base class is created. (This is duplicated
// in Projector3D.cpp.)
- std::string type = cfg.self->getAttribute("type");
+ std::string type = cfg->self->getAttribute("type");
astra::CProjectionGeometry3D* pGeometry = 0;
if (type == "parallel3d") {
pGeometry = new astra::CParallelProjectionGeometry3D();
@@ -312,16 +300,16 @@ allocateDataObject(const std::string & sDataType,
return NULL;
}
- if (!pGeometry->initialize(cfg)) {
+ if (!pGeometry->initialize(*cfg)) {
mexErrMsgTxt("Geometry class not initialized. \n");
delete pGeometry;
- delete xml;
+ delete cfg;
return NULL;
}
- delete xml;
+ delete cfg;
// If data is specified, check dimensions
- if (data && !mex_is_scalar(data))
+ if (data && !mexIsScalar(data))
{
if (! (zIndex
? checkDataSize(data, pGeometry, iZ)
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index e919dd9..c0ac711 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -32,9 +32,11 @@ $Id$
*/
#include "mexHelpFunctions.h"
-#include "astra/SparseMatrixProjectionGeometry2D.h"
-#include "astra/FanFlatVecProjectionGeometry2D.h"
-#include "astra/AstraObjectManager.h"
+#include <algorithm>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
using namespace std;
using namespace astra;
@@ -42,387 +44,148 @@ using namespace astra;
//-----------------------------------------------------------------------------------------
// get string from matlab
-std::string mex_util_get_string(const mxArray* pInput)
+string mexToString(const mxArray* pInput)
{
- if (!mxIsChar(pInput)) {
- return "";
+ // is string?
+ if (mxIsChar(pInput)) {
+ mwSize iLength = mxGetNumberOfElements(pInput) + 1;
+ char* buf = new char[iLength];
+ mxGetString(pInput, buf, iLength);
+ std::string res = std::string(buf);
+ delete[] buf;
+ return res;
}
- mwSize iLength = mxGetNumberOfElements(pInput) + 1;
- char* buf = new char[iLength];
- mxGetString(pInput, buf, iLength);
- std::string res = std::string(buf);
- delete[] buf;
- return res;
+
+ // is scalar?
+ if (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1) {
+ return boost::lexical_cast<string>(mxGetScalar(pInput));
+ }
+
+ return "";
}
//-----------------------------------------------------------------------------------------
-// is option
-bool isOption(std::list<std::string> lOptions, std::string sOption)
+// return true if the argument is a scalar
+bool mexIsScalar(const mxArray* pInput)
{
- return std::find(lOptions.begin(), lOptions.end(), sOption) != lOptions.end();
+ return (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1);
}
//-----------------------------------------------------------------------------------------
-// turn a matlab struct into a c++ map
-std::map<std::string, mxArray*> parseStruct(const mxArray* pInput)
+void get3DMatrixDims(const mxArray* x, mwSize *dims)
{
- std::map<std::string, mxArray*> res;
-
- // check type
- if (!mxIsStruct(pInput)) {
- mexErrMsgTxt("Input must be a struct.");
- return res;
+ const mwSize* mdims = mxGetDimensions(x);
+ mwSize dimCount = mxGetNumberOfDimensions(x);
+ if (dimCount == 1) {
+ dims[0] = mdims[0];
+ dims[1] = 1;
+ dims[2] = 1;
+ } else if (dimCount == 2) {
+ dims[0] = mdims[0];
+ dims[1] = mdims[1];
+ dims[2] = 1;
+ } else if (dimCount == 3) {
+ dims[0] = mdims[0];
+ dims[1] = mdims[1];
+ dims[2] = mdims[2];
+ } else {
+ dims[0] = 0;
+ dims[1] = 0;
+ dims[2] = 0;
}
+}
+
+
+
+
- // get field names
- int nfields = mxGetNumberOfFields(pInput);
- for (int i = 0; i < nfields; i++) {
- std::string sFieldName = std::string(mxGetFieldNameByNumber(pInput, i));
- res[sFieldName] = mxGetFieldByNumber(pInput,0,i);
- }
- return res;
-}
//-----------------------------------------------------------------------------------------
-// turn a c++ map into a matlab struct
-mxArray* buildStruct(std::map<std::string, mxArray*> mInput)
+// turn an std vector<float32> object to an mxArray
+mxArray* vectorToMxArray(std::vector<astra::float32> mInput)
{
- mwSize dims[2] = {1, 1};
- mxArray* res = mxCreateStructArray(2,dims,0,0);
-
- for (std::map<std::string, mxArray*>::iterator it = mInput.begin(); it != mInput.end(); it++) {
- mxAddField(res, (*it).first.c_str());
- mxSetField(res, 0, (*it).first.c_str(), (*it).second);
+ mxArray* res = mxCreateDoubleMatrix(1, mInput.size(), mxREAL);
+ double* pdData = mxGetPr(res);
+ for (unsigned int i = 0; i < mInput.size(); i++) {
+ pdData[i] = mInput[i];
}
return res;
}
//-----------------------------------------------------------------------------------------
-// parse projection geometry data
-astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray* prhs)
+// turn a vector<vector<float32>> object to an mxArray
+mxArray* vector2DToMxArray(std::vector<std::vector<astra::float32> > mInput)
{
- // parse struct
- std::map<string, mxArray*> mStruct = parseStruct(prhs);
-
- // create projection geometry object
- string type = mex_util_get_string(mStruct["type"]);
- if (type == "parallel") {
-
- // detector_width
- float32 fDetWidth = 1.0f;
- mxArray* tmp = mStruct["detector_width"];
- if (tmp != NULL) {
- fDetWidth = (float32)(mxGetScalar(tmp));
- }
-
- // detector_count
- int iDetCount = 100;
- tmp = mStruct["detector_count"];
- if (tmp != NULL) {
- iDetCount = (int)(mxGetScalar(tmp));
- }
-
- // angles
- float32* pfAngles;
- int iAngleCount;
- tmp = mStruct["projection_angles"];
- if (tmp != NULL) {
- double* angleValues = mxGetPr(tmp);
- iAngleCount = mxGetN(tmp) * mxGetM(tmp);
- pfAngles = new float32[iAngleCount];
- for (int i = 0; i < iAngleCount; i++) {
- pfAngles[i] = angleValues[i];
- }
- } else {
- mexErrMsgTxt("'angles' not specified, error.");
- return NULL;
- }
-
- // create projection geometry
- return new astra::CParallelProjectionGeometry2D(iAngleCount, // number of projections
- iDetCount, // number of detectors
- fDetWidth, // width of the detectors
- pfAngles); // angles array
- }
-
- else if (type == "fanflat") {
-
- // detector_width
- float32 fDetWidth = 1.0f;
- mxArray* tmp = mStruct["detector_width"];
- if (tmp != NULL) {
- fDetWidth = (float32)(mxGetScalar(tmp));
- }
-
- // detector_count
- int iDetCount = 100;
- tmp = mStruct["detector_count"];
- if (tmp != NULL) {
- iDetCount = (int)(mxGetScalar(tmp));
- }
-
- // angles
- float32* pfAngles;
- int iAngleCount;
- tmp = mStruct["projection_angles"];
- if (tmp != NULL) {
- double* angleValues = mxGetPr(tmp);
- iAngleCount = mxGetN(tmp) * mxGetM(tmp);
- pfAngles = new float32[iAngleCount];
- for (int i = 0; i < iAngleCount; i++) {
- pfAngles[i] = angleValues[i];
- }
- } else {
- mexErrMsgTxt("'angles' not specified, error.");
- return NULL;
- }
-
- // origin_source_dist
- int iDistOriginSource = 100;
- tmp = mStruct["origin_source_dist"];
- if (tmp != NULL) {
- iDistOriginSource = (int)(mxGetScalar(tmp));
- }
+ unsigned int sizex = mInput.size();
+ if (sizex == 0) return mxCreateString("empty");
+ unsigned int sizey = mInput[0].size();
- // origin_det_dist
- int iDistOriginDet = 100;
- tmp = mStruct["origin_det_dist"];
- if (tmp != NULL) {
- iDistOriginDet = (int)(mxGetScalar(tmp));
+ mxArray* res = mxCreateDoubleMatrix(sizex, sizey, mxREAL);
+ double* pdData = mxGetPr(res);
+ for (unsigned int i = 0; i < sizex; i++) {
+ for (unsigned int j = 0; j < sizey && j < mInput[i].size(); j++) {
+ pdData[j*sizex+i] = mInput[i][j];
}
-
- // create projection geometry
- return new astra::CFanFlatProjectionGeometry2D(iAngleCount, // number of projections
- iDetCount, // number of detectors
- fDetWidth, // width of the detectors
- pfAngles, // angles array
- iDistOriginSource, // distance origin source
- iDistOriginDet); // distance origin detector
- }
-
- else {
- mexPrintf("Only parallel and fanflat projection geometry implemented.");
- return NULL;
}
+ return res;
}
//-----------------------------------------------------------------------------------------
-// create projection geometry data
-mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom)
+// turn a boost::any object to an mxArray
+mxArray* anyToMxArray(boost::any _any)
{
- // temporary map to store the data for the MATLAB struct
- std::map<std::string, mxArray*> mGeometryInfo;
-
- // detectorCount
- mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorCount());
-
- if (!_pProjGeom->isOfType("fanflat_vec")) {
- // detectorWidth
- mGeometryInfo["DetectorWidth"] = mxCreateDoubleScalar(_pProjGeom->getDetectorWidth());
-
- // pfProjectionAngles
- mxArray* pAngles = mxCreateDoubleMatrix(1, _pProjGeom->getProjectionAngleCount(), mxREAL);
- double* out = mxGetPr(pAngles);
- for (int i = 0; i < _pProjGeom->getProjectionAngleCount(); i++) {
- out[i] = _pProjGeom->getProjectionAngle(i);
- }
- mGeometryInfo["ProjectionAngles"] = pAngles;
- }
- else {
- astra::CFanFlatVecProjectionGeometry2D* pVecGeom = dynamic_cast<astra::CFanFlatVecProjectionGeometry2D*>(_pProjGeom);
- mxArray* pVectors = mxCreateDoubleMatrix(1, pVecGeom->getProjectionAngleCount()*6, mxREAL);
- double* out = mxGetPr(pVectors);
- int iDetCount = pVecGeom->getDetectorCount();
- for (int i = 0; i < pVecGeom->getProjectionAngleCount(); i++) {
- const SFanProjection* p = &pVecGeom->getProjectionVectors()[i];
- out[6*i + 0] = p->fSrcX;
- out[6*i + 1] = p->fSrcY;
- out[6*i + 2] = p->fDetSX + 0.5f*iDetCount*p->fDetUX;
- out[6*i + 3] = p->fDetSY + 0.5f*iDetCount*p->fDetUY;
- out[6*i + 4] = p->fDetUX;
- out[6*i + 5] = p->fDetUY;
- }
- mGeometryInfo["Vectors"] = pVectors;
+ if (_any.type() == typeid(std::string)) {
+ std::string str = boost::any_cast<std::string>(_any);
+ return mxCreateString(str.c_str());
}
-
- // parallel specific options
- if (_pProjGeom->isOfType("parallel")) {
- // type
- mGeometryInfo["type"] = mxCreateString("parallel");
+ if (_any.type() == typeid(int)) {
+ return mxCreateDoubleScalar(boost::any_cast<int>(_any));
}
- // fanflat specific options
- else if (_pProjGeom->isOfType("fanflat")) {
- astra::CFanFlatProjectionGeometry2D* pFanFlatGeom = dynamic_cast<astra::CFanFlatProjectionGeometry2D*>(_pProjGeom);
- // detectorCount
- mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginSourceDistance());
- // detectorWidth
- mGeometryInfo["DistanceOriginDetector"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginDetectorDistance());
- // type
- mGeometryInfo["type"] = mxCreateString("fanflat");
+ if (_any.type() == typeid(float32)) {
+ return mxCreateDoubleScalar(boost::any_cast<float32>(_any));
}
- else if (_pProjGeom->isOfType("sparse_matrix")) {
- astra::CSparseMatrixProjectionGeometry2D* pSparseMatrixGeom = dynamic_cast<astra::CSparseMatrixProjectionGeometry2D*>(_pProjGeom);
- mGeometryInfo["type"] = mxCreateString("sparse_matrix");
- mGeometryInfo["MatrixID"] = mxCreateDoubleScalar(CMatrixManager::getSingleton().getIndex(pSparseMatrixGeom->getMatrix()));
+ if (_any.type() == typeid(std::vector<astra::float32>)) {
+ return vectorToMxArray(boost::any_cast<std::vector<float32> >(_any));
}
- else if(_pProjGeom->isOfType("fanflat_vec")) {
- mGeometryInfo["type"] = mxCreateString("fanflat_vec");
+ if (_any.type() == typeid(std::vector<std::vector<astra::float32> >)) {
+ return vector2DToMxArray(boost::any_cast<std::vector<std::vector<float32> > >(_any));
}
-
- // build and return the MATLAB struct
- return buildStruct(mGeometryInfo);
+ return NULL;
}
-//-----------------------------------------------------------------------------------------
-// parse reconstruction geometry data
-astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs)
-{
- // parse struct
- std::map<string, mxArray*> mStruct = parseStruct(prhs);
-
- std::map<string, mxArray*> mOptions = parseStruct(mStruct["option"]);
-
- // GridColCount
- int iWindowColCount = 128;
- mxArray* tmp = mStruct["GridColCount"];
- if (tmp != NULL) {
- iWindowColCount = (int)(mxGetScalar(tmp));
- }
-
- // GridRowCount
- int iWindowRowCount = 128;
- tmp = mStruct["GridRowCount"];
- if (tmp != NULL) {
- iWindowRowCount = (int)(mxGetScalar(tmp));
- }
- // WindowMinX
- float32 fWindowMinX = - iWindowColCount / 2;
- tmp = mOptions["WindowMinX"];
- if (tmp != NULL) {
- fWindowMinX = (float32)(mxGetScalar(tmp));
- }
-
- // WindowMaxX
- float32 fWindowMaxX = iWindowColCount / 2;
- tmp = mOptions["WindowMaxX"];
- if (tmp != NULL) {
- fWindowMaxX = (float32)(mxGetScalar(tmp));
- }
-
- // WindowMinY
- float32 fWindowMinY = - iWindowRowCount / 2;
- tmp = mOptions["WindowMinY"];
- if (tmp != NULL) {
- fWindowMinY = (float32)(mxGetScalar(tmp));
- }
-
- // WindowMaxX
- float32 fWindowMaxY = iWindowRowCount / 2;
- tmp = mOptions["WindowMaxY"];
- if (tmp != NULL) {
- fWindowMaxY = (float32)(mxGetScalar(tmp));
- }
-
- // create and return reconstruction geometry
- return new astra::CVolumeGeometry2D(iWindowColCount, iWindowRowCount,
- fWindowMinX, fWindowMinY,
- fWindowMaxX, fWindowMaxY);
-}
-//-----------------------------------------------------------------------------------------
-// create reconstruction geometry data
-mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom)
-{
- // temporary map to store the data for the MATLAB struct
- std::map<std::string, mxArray*> mGeometryInfo;
- // fill up map
- mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pReconGeom->getGridColCount());
- mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pReconGeom->getGridRowCount());
- std::map<std::string, mxArray*> mGeometryOptions;
- mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pReconGeom->getWindowMinX());
- mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pReconGeom->getWindowMaxX());
- mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pReconGeom->getWindowMinY());
- mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pReconGeom->getWindowMaxY());
- mGeometryInfo["option"] = buildStruct(mGeometryOptions);
- // build and return the MATLAB struct
- return buildStruct(mGeometryInfo);
-}
//-----------------------------------------------------------------------------------------
-string matlab2string(const mxArray* pField)
+// turn a MATLAB struct into a Config object
+Config* structToConfig(string rootname, const mxArray* pStruct)
{
- // is string?
- if (mxIsChar(pField)) {
- return mex_util_get_string(pField);
- }
-
- // is scalar?
- if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) == 1) {
- return boost::lexical_cast<string>(mxGetScalar(pField));
+ if (!mxIsStruct(pStruct)) {
+ mexErrMsgTxt("Input must be a struct.");
+ return NULL;
}
- return "";
-}
-
-//-----------------------------------------------------------------------------------------
-// Options struct to xml node
-bool readOptions(XMLNode* node, const mxArray* pOptionStruct)
-{
- // loop all fields
- int nfields = mxGetNumberOfFields(pOptionStruct);
- for (int i = 0; i < nfields; i++) {
- std::string sFieldName = std::string(mxGetFieldNameByNumber(pOptionStruct, i));
- const mxArray* pField = mxGetFieldByNumber(pOptionStruct, 0, i);
-
- if (node->hasOption(sFieldName)) {
- mexErrMsgTxt("Duplicate option");
- return false;
- }
-
- // string or scalar
- if (mxIsChar(pField) || mex_is_scalar(pField)) {
- string sValue = matlab2string(pField);
- node->addOption(sFieldName, sValue);
- } else
- // numerical array
- if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
- if (!mxIsDouble(pField)) {
- mexErrMsgTxt("Numeric input must be double.");
- return false;
- }
+ // create the document
+ Config* cfg = new Config();
+ cfg->initialize(rootname);
- XMLNode* listbase = node->addChildNode("Option");
- listbase->addAttribute("key", sFieldName);
- listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField));
- double* pdValues = mxGetPr(pField);
- int index = 0;
- for (unsigned int row = 0; row < mxGetM(pField); row++) {
- for (unsigned int col = 0; col < mxGetN(pField); col++) {
- XMLNode* item = listbase->addChildNode("ListItem");
- item->addAttribute("index", index);
- item->addAttribute("value", pdValues[col*mxGetM(pField)+row]);
- index++;
- delete item;
- }
- }
- delete listbase;
- } else {
- mexErrMsgTxt("Unsupported option type");
- return false;
- }
+ // read the struct
+ bool ret = structToXMLNode(cfg->self, pStruct);
+ if (!ret) {
+ delete cfg;
+ mexErrMsgTxt("Error parsing struct.");
+ return NULL;
}
- return true;
+ return cfg;
}
//-----------------------------------------------------------------------------------------
-// struct to xml node
-bool readStruct(XMLNode* root, const mxArray* pStruct)
+bool structToXMLNode(XMLNode* node, const mxArray* pStruct)
{
// loop all fields
int nfields = mxGetNumberOfFields(pStruct);
@@ -434,27 +197,27 @@ bool readStruct(XMLNode* root, const mxArray* pStruct)
// string
if (mxIsChar(pField)) {
- string sValue = matlab2string(pField);
+ string sValue = mexToString(pField);
if (sFieldName == "type") {
- root->addAttribute("type", sValue);
+ node->addAttribute("type", sValue);
} else {
- delete root->addChildNode(sFieldName, sValue);
+ delete node->addChildNode(sFieldName, sValue);
}
}
// scalar
- if (mex_is_scalar(pField)) {
- string sValue = matlab2string(pField);
- delete root->addChildNode(sFieldName, sValue);
+ else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) == 1) {
+ string sValue = mexToString(pField);
+ delete node->addChildNode(sFieldName, sValue);
}
// numerical array
- if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
+ else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
if (!mxIsDouble(pField)) {
mexErrMsgTxt("Numeric input must be double.");
return false;
}
- XMLNode* listbase = root->addChildNode(sFieldName);
+ XMLNode* listbase = node->addChildNode(sFieldName);
listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField));
double* pdValues = mxGetPr(pField);
int index = 0;
@@ -470,16 +233,15 @@ bool readStruct(XMLNode* root, const mxArray* pStruct)
delete listbase;
}
-
// not castable to a single string
- if (mxIsStruct(pField)) {
+ else if (mxIsStruct(pField)) {
if (sFieldName == "options" || sFieldName == "option" || sFieldName == "Options" || sFieldName == "Option") {
- bool ret = readOptions(root, pField);
+ bool ret = optionsToXMLNode(node, pField);
if (!ret)
return false;
} else {
- XMLNode* newNode = root->addChildNode(sFieldName);
- bool ret = readStruct(newNode, pField);
+ XMLNode* newNode = node->addChildNode(sFieldName);
+ bool ret = structToXMLNode(newNode, pField);
delete newNode;
if (!ret)
return false;
@@ -490,109 +252,101 @@ bool readStruct(XMLNode* root, const mxArray* pStruct)
return true;
}
+//-----------------------------------------------------------------------------------------
+// Options struct to xml node
+bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct)
+{
+ // loop all fields
+ int nfields = mxGetNumberOfFields(pOptionStruct);
+ for (int i = 0; i < nfields; i++) {
+ std::string sFieldName = std::string(mxGetFieldNameByNumber(pOptionStruct, i));
+ const mxArray* pField = mxGetFieldByNumber(pOptionStruct, 0, i);
+ if (node->hasOption(sFieldName)) {
+ mexErrMsgTxt("Duplicate option");
+ return false;
+ }
+
+ // string or scalar
+ if (mxIsChar(pField) || mexIsScalar(pField)) {
+ string sValue = mexToString(pField);
+ node->addOption(sFieldName, sValue);
+ }
+ // numerical array
+ else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
+ if (!mxIsDouble(pField)) {
+ mexErrMsgTxt("Numeric input must be double.");
+ return false;
+ }
+
+ XMLNode* listbase = node->addChildNode("Option");
+ listbase->addAttribute("key", sFieldName);
+ listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField));
+ double* pdValues = mxGetPr(pField);
+ int index = 0;
+ for (unsigned int row = 0; row < mxGetM(pField); row++) {
+ for (unsigned int col = 0; col < mxGetN(pField); col++) {
+ XMLNode* item = listbase->addChildNode("ListItem");
+ item->addAttribute("index", index);
+ item->addAttribute("value", pdValues[col*mxGetM(pField)+row]);
+ index++;
+ delete item;
+ }
+ }
+ delete listbase;
+ } else {
+ mexErrMsgTxt("Unsupported option type");
+ return false;
+ }
+ }
+ return true;
+}
//-----------------------------------------------------------------------------------------
-// turn a MATLAB struct into an XML Document
-XMLDocument* struct2XML(string rootname, const mxArray* pStruct)
+// turn a matlab struct into a c++ map
+std::map<std::string, mxArray*> parseStruct(const mxArray* pInput)
{
- if (!mxIsStruct(pStruct)) {
+ std::map<std::string, mxArray*> res;
+
+ // check type
+ if (!mxIsStruct(pInput)) {
mexErrMsgTxt("Input must be a struct.");
- return NULL;
+ return res;
}
- // create the document
- XMLDocument* doc = XMLDocument::createDocument(rootname);
- XMLNode* rootnode = doc->getRootNode();
+ // get field names
+ int nfields = mxGetNumberOfFields(pInput);
+ for (int i = 0; i < nfields; i++) {
+ std::string sFieldName = std::string(mxGetFieldNameByNumber(pInput, i));
+ res[sFieldName] = mxGetFieldByNumber(pInput,0,i);
+ }
+ return res;
+}
+
+
- // read the struct
- bool ret = readStruct(rootnode, pStruct);
- //doc->getRootNode()->print();
- delete rootnode;
- if (!ret) {
- delete doc;
- doc = 0;
- }
- return doc;
-}
-//-----------------------------------------------------------------------------------------
-// turn an std vector<float32> object to an mxArray
-mxArray* vectorToMxArray(std::vector<astra::float32> mInput)
-{
- mxArray* res = mxCreateDoubleMatrix(1, mInput.size(), mxREAL);
- double* pdData = mxGetPr(res);
- for (unsigned int i = 0; i < mInput.size(); i++) {
- pdData[i] = mInput[i];
- }
- return res;
-}
-//-----------------------------------------------------------------------------------------
-// turn a vector<vector<float32>> object to an mxArray
-mxArray* vector2DToMxArray(std::vector<std::vector<astra::float32> > mInput)
-{
- unsigned int sizex = mInput.size();
- if (sizex == 0) return mxCreateString("empty");
- unsigned int sizey = mInput[0].size();
- mxArray* res = mxCreateDoubleMatrix(sizex, sizey, mxREAL);
- double* pdData = mxGetPr(res);
- for (unsigned int i = 0; i < sizex; i++) {
- for (unsigned int j = 0; j < sizey && j < mInput[i].size(); j++) {
- pdData[j*sizex+i] = mInput[i][j];
- }
- }
- return res;
-}
-//-----------------------------------------------------------------------------------------
-// turn a boost::any object to an mxArray
-mxArray* anyToMxArray(boost::any _any)
-{
- if (_any.type() == typeid(std::string)) {
- std::string str = boost::any_cast<std::string>(_any);
- return mxCreateString(str.c_str());
- }
- if (_any.type() == typeid(int)) {
- return mxCreateDoubleScalar(boost::any_cast<int>(_any));
- }
- if (_any.type() == typeid(float32)) {
- return mxCreateDoubleScalar(boost::any_cast<float32>(_any));
- }
- if (_any.type() == typeid(std::vector<astra::float32>)) {
- return vectorToMxArray(boost::any_cast<std::vector<float32> >(_any));
- }
- if (_any.type() == typeid(std::vector<std::vector<astra::float32> >)) {
- return vector2DToMxArray(boost::any_cast<std::vector<std::vector<float32> > >(_any));
- }
- return NULL;
-}
-//-----------------------------------------------------------------------------------------
-// return true ig the argument is a scalar
-bool mex_is_scalar(const mxArray* pInput)
-{
- return (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1);
-}
//-----------------------------------------------------------------------------------------
-mxArray* XML2struct(astra::XMLDocument* xml)
+// turn a Config object into a MATLAB struct
+mxArray* configToStruct(astra::Config* cfg)
{
- XMLNode* node = xml->getRootNode();
- mxArray* str = XMLNode2struct(xml->getRootNode());
- delete node;
- return str;
+ return XMLNodeToStruct(cfg->self);
}
//-----------------------------------------------------------------------------------------
-mxArray* XMLNode2struct(astra::XMLNode* node)
+mxArray* XMLNodeToStruct(astra::XMLNode* node)
{
- std::map<std::string, mxArray*> mList;
+ std::map<std::string, mxArray*> mList;
+ std::map<std::string, mxArray*> mOptions;
// type_attribute
if (node->hasAttribute("type")) {
@@ -602,41 +356,103 @@ mxArray* XMLNode2struct(astra::XMLNode* node)
list<XMLNode*> nodes = node->getNodes();
for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
XMLNode* subnode = (*it);
- // list
- if (subnode->hasAttribute("listsize")) {
- cout << "lkmdsqldqsjkl" << endl;
- cout << " " << node->getContentNumericalArray().size() << endl;
- mList[subnode->getName()] = vectorToMxArray(node->getContentNumericalArray());
+
+ // option
+ if (subnode->getName() == "Option") {
+ mOptions[subnode->getAttribute("key")] = stringToMxArray(subnode->getAttribute("value"));
}
- // string
+
+ // regular content
else {
- mList[subnode->getName()] = mxCreateString(subnode->getContent().c_str());
+ mList[subnode->getName()] = stringToMxArray(subnode->getContent());
}
delete subnode;
}
+ if (mOptions.size() > 0) mList["options"] = buildStruct(mOptions);
return buildStruct(mList);
}
-void get3DMatrixDims(const mxArray* x, mwSize *dims)
+//-----------------------------------------------------------------------------------------
+mxArray* stringToMxArray(std::string input)
{
- const mwSize* mdims = mxGetDimensions(x);
- mwSize dimCount = mxGetNumberOfDimensions(x);
- if (dimCount == 1) {
- dims[0] = mdims[0];
- dims[1] = 1;
- dims[2] = 1;
- } else if (dimCount == 2) {
- dims[0] = mdims[0];
- dims[1] = mdims[1];
- dims[2] = 1;
- } else if (dimCount == 3) {
- dims[0] = mdims[0];
- dims[1] = mdims[1];
- dims[2] = mdims[2];
- } else {
- dims[0] = 0;
- dims[1] = 0;
- dims[2] = 0;
+ // matrix
+ if (input.find(';') != std::string::npos) {
+
+ // split rows
+ std::vector<std::string> row_strings;
+ std::vector<std::string> col_strings;
+ boost::split(row_strings, input, boost::is_any_of(";"));
+ boost::split(col_strings, row_strings[0], boost::is_any_of(","));
+
+ // get dimensions
+ int rows = row_strings.size();
+ int cols = col_strings.size();
+
+ // init matrix
+ mxArray* pMatrix = mxCreateDoubleMatrix(rows, cols, mxREAL);
+ double* out = mxGetPr(pMatrix);
+
+ // loop elements
+ for (unsigned int row = 0; row < rows; row++) {
+ 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<float32>(col_strings[col]);
+ }
+ }
+ return pMatrix;
}
-}
+
+ // vector
+ if (input.find(',') != std::string::npos) {
+
+ // split
+ std::vector<std::string> items;
+ boost::split(items, input, boost::is_any_of(","));
+
+ // init matrix
+ mxArray* pVector = mxCreateDoubleMatrix(1, items.size(), mxREAL);
+ double* out = mxGetPr(pVector);
+
+ // loop elements
+ for (unsigned int i = 0; i < items.size(); i++) {
+ out[i] = boost::lexical_cast<float32>(items[i]);
+ }
+ return pVector;
+ }
+
+ // number
+ char* end;
+ double content = ::strtod(input.c_str(), &end);
+ bool isnumber = !*end;
+ if (isnumber) {
+ return mxCreateDoubleScalar(content);
+ }
+
+ // string
+ return mxCreateString(input.c_str());
+}
+//-----------------------------------------------------------------------------------------
+// turn a c++ map into a matlab struct
+mxArray* buildStruct(std::map<std::string, mxArray*> mInput)
+{
+ mwSize dims[2] = {1, 1};
+ mxArray* res = mxCreateStructArray(2,dims,0,0);
+
+ for (std::map<std::string, mxArray*>::iterator it = mInput.begin(); it != mInput.end(); it++) {
+ mxAddField(res, (*it).first.c_str());
+ mxSetField(res, 0, (*it).first.c_str(), (*it).second);
+ }
+ return res;
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h
index 84372ba..f9ffcf2 100644
--- a/matlab/mex/mexHelpFunctions.h
+++ b/matlab/mex/mexHelpFunctions.h
@@ -43,34 +43,31 @@ $Id$
#include "astra/Globals.h"
#include "astra/Utilities.h"
-#include "astra/ParallelProjectionGeometry2D.h"
-#include "astra/FanFlatProjectionGeometry2D.h"
-#include "astra/VolumeGeometry2D.h"
-
+#include "astra/Config.h"
#include "astra/XMLDocument.h"
#include "astra/XMLNode.h"
-std::string mex_util_get_string(const mxArray* pInput);
-bool isOption(std::list<std::string> lOptions, std::string sOption);
-
-bool mex_is_scalar(const mxArray* pInput);
+// utility functions
+string mexToString(const mxArray* pInput);
+bool mexIsScalar(const mxArray* pInput);
+void get3DMatrixDims(const mxArray* x, mwSize *dims);
-std::map<std::string, mxArray*> parseStruct(const mxArray* pInput);
-mxArray* buildStruct(std::map<std::string, mxArray*> mInput);
+// convert boost::any into a MALTAB object
mxArray* vectorToMxArray(std::vector<astra::float32> mInput);
-
mxArray* anyToMxArray(boost::any _any);
-astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray*);
-mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D*);
-astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray*);
-mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom);
+// turn a MATLAB struct into a Config object
+astra::Config* structToConfig(string rootname, const mxArray* pStruct);
+bool structToXMLNode(astra::XMLNode* node, const mxArray* pStruct);
+bool optionsToXMLNode(astra::XMLNode* node, const mxArray* pOptionStruct);
+std::map<std::string, mxArray*> parseStruct(const mxArray* pInput);
-astra::XMLDocument* struct2XML(string rootname, const mxArray* pStruct);
+// turn a Config object into a MATLAB struct
+mxArray* configToStruct(astra::Config* cfg);
+mxArray* XMLNodeToStruct(astra::XMLNode* xml);
+mxArray* stringToMxArray(std::string input);
+mxArray* buildStruct(std::map<std::string, mxArray*> mInput);
-mxArray* XML2struct(astra::XMLDocument* xml);
-mxArray* XMLNode2struct(astra::XMLNode* xml);
-void get3DMatrixDims(const mxArray* x, mwSize *dims);
#endif
diff --git a/src/ConeProjectionGeometry3D.cpp b/src/ConeProjectionGeometry3D.cpp
index e6999df..eb9adcf 100644
--- a/src/ConeProjectionGeometry3D.cpp
+++ b/src/ConeProjectionGeometry3D.cpp
@@ -186,17 +186,22 @@ bool CConeProjectionGeometry3D::isOfType(const std::string& _sType) const
}
//----------------------------------------------------------------------------------------
-void CConeProjectionGeometry3D::toXML(XMLNode* _sNode) const
+// Get the configuration object
+Config* CConeProjectionGeometry3D::getConfiguration() const
{
- _sNode->addAttribute("type", "cone");
- _sNode->addChildNode("DetectorSpacingX", m_fDetectorSpacingX);
- _sNode->addChildNode("DetectorSpacingY", m_fDetectorSpacingY);
- _sNode->addChildNode("DetectorRowCount", m_iDetectorRowCount);
- _sNode->addChildNode("DetectorColCount", m_iDetectorColCount);
- _sNode->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
- _sNode->addChildNode("DistanceOriginDetector", m_fOriginDetectorDistance);
- _sNode->addChildNode("DistanceOriginSource", m_fOriginSourceDistance);
+ Config* cfg = new Config();
+ cfg->initialize("ProjectionGeometry3D");
+ cfg->self->addAttribute("type", "cone");
+ cfg->self->addChildNode("DetectorSpacingX", m_fDetectorSpacingX);
+ cfg->self->addChildNode("DetectorSpacingY", m_fDetectorSpacingY);
+ cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount);
+ cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount);
+ cfg->self->addChildNode("DistanceOriginDetector", m_fOriginDetectorDistance);
+ cfg->self->addChildNode("DistanceOriginSource", m_fOriginSourceDistance);
+ cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ return cfg;
}
+
//----------------------------------------------------------------------------------------
CVector3D CConeProjectionGeometry3D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex) const
diff --git a/src/ConeVecProjectionGeometry3D.cpp b/src/ConeVecProjectionGeometry3D.cpp
index cf8f76d..a4bd22d 100644
--- a/src/ConeVecProjectionGeometry3D.cpp
+++ b/src/ConeVecProjectionGeometry3D.cpp
@@ -198,18 +198,42 @@ bool CConeVecProjectionGeometry3D::isEqual(const CProjectionGeometry3D * _pGeom2
// is of type
bool CConeVecProjectionGeometry3D::isOfType(const std::string& _sType) const
{
- return (_sType == "cone3d_vec");
+ return (_sType == "cone_vec");
}
//----------------------------------------------------------------------------------------
-void CConeVecProjectionGeometry3D::toXML(XMLNode* _sNode) const
+// Get the configuration object
+Config* CConeVecProjectionGeometry3D::getConfiguration() const
{
- _sNode->addAttribute("type","cone3d_vec");
- _sNode->addChildNode("DetectorRowCount", m_iDetectorRowCount);
- _sNode->addChildNode("DetectorColCount", m_iDetectorColCount);
- // TODO:
- //_sNode->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ Config* cfg = new Config();
+ cfg->initialize("ProjectionGeometry3D");
+
+ cfg->self->addAttribute("type", "cone");
+ cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount);
+ cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount);
+
+ std::string vectors = "";
+ for (int i = 0; i < m_iProjectionAngleCount; ++i) {
+ SConeProjection& p = m_pProjectionAngles[i];
+ vectors += boost::lexical_cast<string>(p.fSrcX) + ",";
+ vectors += boost::lexical_cast<string>(p.fSrcY) + ",";
+ vectors += boost::lexical_cast<string>(p.fSrcZ) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetUX + 0.5f*m_iDetectorColCount*p.fDetVX) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetUY + 0.5f*m_iDetectorColCount*p.fDetVY) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetUZ + 0.5f*m_iDetectorColCount*p.fDetVZ) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetUX) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetUY) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetUZ) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetVX) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetVY) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetVZ);
+ if (i < m_iProjectionAngleCount-1) vectors += ';';
+ }
+ cfg->self->addChildNode("Vectors", vectors);
+
+ return cfg;
}
+//----------------------------------------------------------------------------------------
CVector3D CConeVecProjectionGeometry3D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex) const
{
diff --git a/src/Config.cpp b/src/Config.cpp
index 3a3cb53..653935e 100644
--- a/src/Config.cpp
+++ b/src/Config.cpp
@@ -54,12 +54,24 @@ Config::Config(XMLNode* _self)
self = _self;
}
+//-----------------------------------------------------------------------------
Config::~Config()
{
delete self;
self = 0;
}
+//-----------------------------------------------------------------------------
+void Config::initialize(std::string rootname)
+{
+ if (self == 0) {
+ XMLDocument* doc = XMLDocument::createDocument(rootname);
+ self = doc->getRootNode();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
template <class T>
ConfigStackCheck<T>::ConfigStackCheck(const char *_name, T* _obj, const Config& _cfg)
: object(_obj), cfg(&_cfg), name(_name)
diff --git a/src/FanFlatProjectionGeometry2D.cpp b/src/FanFlatProjectionGeometry2D.cpp
index bfc7fa9..d757f18 100644
--- a/src/FanFlatProjectionGeometry2D.cpp
+++ b/src/FanFlatProjectionGeometry2D.cpp
@@ -204,6 +204,20 @@ CVector3D CFanFlatProjectionGeometry2D::getProjectionDirection(int _iProjectionI
}
//----------------------------------------------------------------------------------------
+// Get the configuration object
+Config* CFanFlatProjectionGeometry2D::getConfiguration() const
+{
+ Config* cfg = new Config();
+ cfg->initialize("ProjectionGeometry2D");
+ cfg->self->addAttribute("type", "fanflat");
+ cfg->self->addChildNode("DetectorCount", getDetectorCount());
+ cfg->self->addChildNode("DetectorWidth", getDetectorWidth());
+ cfg->self->addChildNode("DistanceOriginSource", getOriginSourceDistance());
+ cfg->self->addChildNode("DistanceOriginDetector", getOriginDetectorDistance());
+ cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ return cfg;
+}
+//----------------------------------------------------------------------------------------
} // namespace astra
diff --git a/src/FanFlatVecProjectionGeometry2D.cpp b/src/FanFlatVecProjectionGeometry2D.cpp
index 77f9db7..9c7b596 100644
--- a/src/FanFlatVecProjectionGeometry2D.cpp
+++ b/src/FanFlatVecProjectionGeometry2D.cpp
@@ -194,7 +194,7 @@ bool CFanFlatVecProjectionGeometry2D::isEqual(CProjectionGeometry2D* _pGeom2) co
// Is of type
bool CFanFlatVecProjectionGeometry2D::isOfType(const std::string& _sType)
{
- return (_sType == "fanflat_vec");
+ return (_sType == "fanflat_vec");
}
//----------------------------------------------------------------------------------------
@@ -227,6 +227,28 @@ bool CFanFlatVecProjectionGeometry2D::_check()
//----------------------------------------------------------------------------------------
+// Get the configuration object
+Config* CFanFlatVecProjectionGeometry2D::getConfiguration() const
+{
+ Config* cfg = new Config();
+ cfg->initialize("ProjectionGeometry2D");
+ cfg->self->addAttribute("type", "fanflat_vec");
+ cfg->self->addChildNode("DetectorCount", getDetectorCount());
+ std::string vectors = "";
+ for (int i = 0; i < m_iProjectionAngleCount; ++i) {
+ SFanProjection& p = m_pProjectionAngles[i];
+ vectors += boost::lexical_cast<string>(p.fSrcX) + ",";
+ vectors += boost::lexical_cast<string>(p.fSrcY) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetSX + 0.5f * m_iDetectorCount * p.fDetUX) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetSY + 0.5f * m_iDetectorCount * p.fDetUY) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetUX) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetUY);
+ if (i < m_iProjectionAngleCount-1) vectors += ';';
+ }
+ cfg->self->addChildNode("Vectors", vectors);
+ return cfg;
+}
+//----------------------------------------------------------------------------------------
} // namespace astra
diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp
index 8f8faa4..cac8f30 100644
--- a/src/ParallelProjectionGeometry2D.cpp
+++ b/src/ParallelProjectionGeometry2D.cpp
@@ -27,6 +27,7 @@ $Id$
*/
#include "astra/ParallelProjectionGeometry2D.h"
+#include <boost/lexical_cast.hpp>
#include <cstring>
@@ -168,6 +169,19 @@ bool CParallelProjectionGeometry2D::isOfType(const std::string& _sType)
{
return (_sType == "parallel");
}
+
+//----------------------------------------------------------------------------------------
+// Get the configuration object
+Config* CParallelProjectionGeometry2D::getConfiguration() const
+{
+ Config* cfg = new Config();
+ cfg->initialize("ProjectionGeometry2D");
+ cfg->self->addAttribute("type", "parallel");
+ cfg->self->addChildNode("DetectorCount", getDetectorCount());
+ cfg->self->addChildNode("DetectorWidth", getDetectorWidth());
+ cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ return cfg;
+}
//----------------------------------------------------------------------------------------
CVector3D CParallelProjectionGeometry2D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex /* = 0 */)
diff --git a/src/ParallelProjectionGeometry3D.cpp b/src/ParallelProjectionGeometry3D.cpp
index 8a13f0f..eb200f9 100644
--- a/src/ParallelProjectionGeometry3D.cpp
+++ b/src/ParallelProjectionGeometry3D.cpp
@@ -27,6 +27,7 @@ $Id$
*/
#include "astra/ParallelProjectionGeometry3D.h"
+#include <boost/lexical_cast.hpp>
#include <cstring>
@@ -154,19 +155,24 @@ bool CParallelProjectionGeometry3D::isEqual(const CProjectionGeometry3D * _pGeom
// is of type
bool CParallelProjectionGeometry3D::isOfType(const std::string& _sType) const
{
- return (_sType == "parallel");
+ return (_sType == "parallel3d");
}
//----------------------------------------------------------------------------------------
-void CParallelProjectionGeometry3D::toXML(XMLNode* _sNode) const
+// Get the configuration object
+Config* CParallelProjectionGeometry3D::getConfiguration() const
{
- _sNode->addAttribute("type","parallel3d");
- _sNode->addChildNode("DetectorSpacingX", m_fDetectorSpacingX);
- _sNode->addChildNode("DetectorSpacingY", m_fDetectorSpacingY);
- _sNode->addChildNode("DetectorRowCount", m_iDetectorRowCount);
- _sNode->addChildNode("DetectorColCount", m_iDetectorColCount);
- _sNode->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ Config* cfg = new Config();
+ cfg->initialize("ProjectionGeometry3D");
+ cfg->self->addAttribute("type", "parallel3d");
+ cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount);
+ cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount);
+ cfg->self->addChildNode("DetectorSpacingX", m_fDetectorSpacingX);
+ cfg->self->addChildNode("DetectorSpacingY", m_fDetectorSpacingY);
+ cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ return cfg;
}
+//----------------------------------------------------------------------------------------
CVector3D CParallelProjectionGeometry3D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex) const
{
diff --git a/src/ParallelVecProjectionGeometry3D.cpp b/src/ParallelVecProjectionGeometry3D.cpp
index 17f00a4..cfac485 100644
--- a/src/ParallelVecProjectionGeometry3D.cpp
+++ b/src/ParallelVecProjectionGeometry3D.cpp
@@ -202,14 +202,38 @@ bool CParallelVecProjectionGeometry3D::isOfType(const std::string& _sType) const
}
//----------------------------------------------------------------------------------------
-void CParallelVecProjectionGeometry3D::toXML(XMLNode* _sNode) const
+// Get the configuration object
+Config* CParallelVecProjectionGeometry3D::getConfiguration() const
{
- _sNode->addAttribute("type","parallel3d_vec");
- _sNode->addChildNode("DetectorRowCount", m_iDetectorRowCount);
- _sNode->addChildNode("DetectorColCount", m_iDetectorColCount);
- // TODO:
- //_sNode->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ Config* cfg = new Config();
+ cfg->initialize("ProjectionGeometry3D");
+
+ cfg->self->addAttribute("type", "parallel3d");
+ cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount);
+ cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount);
+
+ std::string vectors = "";
+ for (int i = 0; i < m_iProjectionAngleCount; ++i) {
+ SPar3DProjection& p = m_pProjectionAngles[i];
+ vectors += boost::lexical_cast<string>(p.fRayX) + ",";
+ vectors += boost::lexical_cast<string>(p.fRayY) + ",";
+ vectors += boost::lexical_cast<string>(p.fRayZ) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetUX + 0.5f*m_iDetectorColCount*p.fDetVX) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetUY + 0.5f*m_iDetectorColCount*p.fDetVY) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetUZ + 0.5f*m_iDetectorColCount*p.fDetVZ) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetUX) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetUY) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetUZ) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetVX) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetVY) + ",";
+ vectors += boost::lexical_cast<string>(p.fDetVZ);
+ if (i < m_iProjectionAngleCount-1) vectors += ';';
+ }
+ cfg->self->addChildNode("Vectors", vectors);
+
+ return cfg;
}
+//----------------------------------------------------------------------------------------
CVector3D CParallelVecProjectionGeometry3D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex) const
{
diff --git a/src/SparseMatrixProjectionGeometry2D.cpp b/src/SparseMatrixProjectionGeometry2D.cpp
index 7f14d9d..86357d2 100644
--- a/src/SparseMatrixProjectionGeometry2D.cpp
+++ b/src/SparseMatrixProjectionGeometry2D.cpp
@@ -189,7 +189,20 @@ bool CSparseMatrixProjectionGeometry2D::isOfType(const std::string& _sType)
return (_sType == "sparse_matrix");
}
//----------------------------------------------------------------------------------------
+// Get the configuration object
+Config* CSparseMatrixProjectionGeometry2D::getConfiguration() const
+{
+ Config* cfg = new Config();
+ cfg->initialize("ProjectionGeometry2D");
+ cfg->self->addAttribute("type", "sparse matrix");
+ cfg->self->addChildNode("DetectorCount", getDetectorCount());
+ cfg->self->addChildNode("DetectorWidth", getDetectorWidth());
+ cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ cfg->self->addChildNode("MatrixID", CMatrixManager::getSingleton().getIndex(m_pMatrix));
+ return cfg;
+}
+//----------------------------------------------------------------------------------------
CVector3D CSparseMatrixProjectionGeometry2D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex)
{
CVector3D vOutput(0.0f, 0.0f, 0.0f);
diff --git a/src/VolumeGeometry2D.cpp b/src/VolumeGeometry2D.cpp
index 19aa905..d412914 100644
--- a/src/VolumeGeometry2D.cpp
+++ b/src/VolumeGeometry2D.cpp
@@ -152,7 +152,7 @@ CVolumeGeometry2D* CVolumeGeometry2D::clone()
}
//----------------------------------------------------------------------------------------
-// Initialization witha COnfig object
+// Initialization witha Config object
bool CVolumeGeometry2D::initialize(const Config& _cfg)
{
ASTRA_ASSERT(_cfg.self);
@@ -277,6 +277,24 @@ bool CVolumeGeometry2D::isEqual(CVolumeGeometry2D* _pGeom2) const
return true;
}
+
+//----------------------------------------------------------------------------------------
+// Get the configuration object
+Config* CVolumeGeometry2D::getConfiguration() const
+{
+ Config* cfg = new Config();
+ cfg->initialize("VolumeGeometry2D");
+
+ cfg->self->addChildNode("GridColCount", m_iGridColCount);
+ cfg->self->addChildNode("GridRowCount", m_iGridRowCount);
+
+ cfg->self->addOption("WindowMinX", m_fWindowMinX);
+ cfg->self->addOption("WindowMaxX", m_fWindowMaxX);
+ cfg->self->addOption("WindowMinY", m_fWindowMinY);
+ cfg->self->addOption("WindowMaxY", m_fWindowMaxY);
+
+ return cfg;
+}
//----------------------------------------------------------------------------------------
} // namespace astra
diff --git a/src/VolumeGeometry3D.cpp b/src/VolumeGeometry3D.cpp
index d7a93a9..66e6f0c 100644
--- a/src/VolumeGeometry3D.cpp
+++ b/src/VolumeGeometry3D.cpp
@@ -380,5 +380,28 @@ CVolumeGeometry2D * CVolumeGeometry3D::createVolumeGeometry2D() const
}
//----------------------------------------------------------------------------------------
+// Get the configuration object
+Config* CVolumeGeometry3D::getConfiguration() const
+{
+ Config* cfg = new Config();
+ cfg->initialize("VolumeGeometry3D");
+
+ cfg->self->addChildNode("GridColCount", m_iGridColCount);
+ cfg->self->addChildNode("GridRowCount", m_iGridRowCount);
+ cfg->self->addChildNode("GridSliceCount", m_iGridSliceCount);
+
+ cfg->self->addOption("WindowMinX", m_fWindowMinX);
+ cfg->self->addOption("WindowMaxX", m_fWindowMaxX);
+ cfg->self->addOption("WindowMinY", m_fWindowMinY);
+ cfg->self->addOption("WindowMaxY", m_fWindowMaxY);
+ cfg->self->addOption("WindowMinZ", m_fWindowMinZ);
+ cfg->self->addOption("WindowMaxZ", m_fWindowMaxZ);
+
+ return cfg;
+}
+//----------------------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------------------
} // namespace astra
diff --git a/src/XMLDocument.cpp b/src/XMLDocument.cpp
index b39875b..406564f 100644
--- a/src/XMLDocument.cpp
+++ b/src/XMLDocument.cpp
@@ -109,4 +109,12 @@ void XMLDocument::saveToFile(string sFilename)
}
//-----------------------------------------------------------------------------
+std::string XMLDocument::toString()
+{
+ std::stringstream ss;
+ ss << *fDOMDocument->first_node();
+ return ss.str();
+}
+
+//-----------------------------------------------------------------------------
diff --git a/src/XMLNode.cpp b/src/XMLNode.cpp
index a5b6796..4b2bdf4 100644
--- a/src/XMLNode.cpp
+++ b/src/XMLNode.cpp
@@ -448,13 +448,11 @@ void XMLNode::setContent(float32 _fValue)
// Set content - LIST
void XMLNode::setContent(float32* pfList, int _iSize)
{
- addAttribute("listsize", _iSize);
- for (int i = 0; i < _iSize; i++) {
- XMLNode* item = addChildNode("ListItem");
- item->addAttribute("index", i);
- item->addAttribute("value",pfList[i]);
- delete item;
+ std::string str = (_iSize > 0) ? boost::lexical_cast<std::string>(pfList[0]) : "";
+ for (int i = 1; i < _iSize; i++) {
+ str += "," + boost::lexical_cast<std::string>(pfList[i]);
}
+ setContent(str);
}
//-----------------------------------------------------------------------------