summaryrefslogtreecommitdiffstats
path: root/matlab
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 /matlab
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
Diffstat (limited to 'matlab')
-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
11 files changed, 407 insertions, 623 deletions
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