summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/astra/XMLNode.h35
-rw-r--r--matlab/mex/mexHelpFunctions.cpp22
-rw-r--r--python/astra/PyXMLDocument.pxd2
-rw-r--r--python/astra/utils.pyx35
-rw-r--r--src/XMLNode.cpp150
5 files changed, 127 insertions, 117 deletions
diff --git a/include/astra/XMLNode.h b/include/astra/XMLNode.h
index f79c1a8..4d29d5c 100644
--- a/include/astra/XMLNode.h
+++ b/include/astra/XMLNode.h
@@ -119,14 +119,8 @@ public:
*/
vector<string> getContentArray() const;
- /** Get the content of the XML node as a c-array of float32 data.
- *
- * @param _pfData data array, shouldn't be initialized already.
- * @param _iSize number of elements stored in _pfData
- */
- void getContentNumericalArray(float32*& _pfData, int& _iSize) const;
-
/** Get the content of the XML node as a stl container of float32 data.
+ * NB: A 2D matrix is returned as a linear list
*
* @return node content
*/
@@ -259,13 +253,38 @@ public:
*/
void setContent(float32 _fValue);
- /** Add a list of numerical data to the node: &lt;...&gt;_sText&lt;/...&gt;
+ /** Add a list of numerical data to the node
*
* @param _pfList data
* @param _iSize number of elements in the list
*/
void setContent(float32* _pfList, int _iSize);
+ /** Add a list of numerical data to the node
+ *
+ * @param _pfList data
+ * @param _iSize number of elements in the list
+ */
+ void setContent(double* _pfList, int _iSize);
+
+ /** Add a (2D) matrix of numerical data to the node
+ *
+ * @param _pfMatrix data
+ * @param _iWidth width of the matrix
+ * @param _iHeight height of the matrix
+ * @param transposed true is C order, false is Fortran order
+ */
+ void setContent(float32* _pfMatrix, int _iWidth, int _iHeight, bool transposed);
+
+ /** Add a (2D) matrix of numerical data to the node
+ *
+ * @param _pfMatrix data
+ * @param _iWidth width of the matrix
+ * @param _iHeight height of the matrix
+ * @param transposed true is C order, false is Fortran order
+ */
+ void setContent(double* _pfMatrix, int _iWidth, int _iHeight, bool transposed);
+
/** Add an attribute to this node: &lt;... _sName="_sValue"&gt;
*
* @param _sName name of the attribute
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index 00d766f..87a9672 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -218,17 +218,8 @@ bool structToXMLNode(XMLNode node, const mxArray* pStruct)
return false;
}
XMLNode listbase = node.addChildNode(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++;
- }
- }
+ listbase.setContent(pdValues, mxGetN(pField), mxGetM(pField), true);
}
// not castable to a single string
@@ -278,17 +269,8 @@ bool optionsToXMLNode(XMLNode node, const mxArray* pOptionStruct)
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++;
- }
- }
+ listbase.setContent(pdValues, mxGetN(pField), mxGetM(pField), true);
} else {
mexErrMsgTxt("Unsupported option type");
return false;
diff --git a/python/astra/PyXMLDocument.pxd b/python/astra/PyXMLDocument.pxd
index 57c447e..033b8ef 100644
--- a/python/astra/PyXMLDocument.pxd
+++ b/python/astra/PyXMLDocument.pxd
@@ -53,6 +53,8 @@ cdef extern from "astra/XMLNode.h" namespace "astra":
string getAttribute(string)
list[XMLNode] getNodes()
vector[float32] getContentNumericalArray()
+ void setContent(double*, int, int, bool)
+ void setContent(double*, int)
string getContent()
bool hasAttribute(string)
diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx
index 8f1e0b7..ddb37aa 100644
--- a/python/astra/utils.pyx
+++ b/python/astra/utils.pyx
@@ -26,6 +26,7 @@
# distutils: language = c++
# distutils: libraries = astra
+cimport numpy as np
import numpy as np
import six
from libcpp.string cimport string
@@ -85,6 +86,7 @@ cdef void readDict(XMLNode root, _dc):
cdef XMLNode itm
cdef int i
cdef int j
+ cdef double* data
dc = convert_item(_dc)
for item in dc:
@@ -93,21 +95,11 @@ cdef void readDict(XMLNode root, _dc):
if val.size == 0:
break
listbase = root.addChildNode(item)
- listbase.addAttribute(< string > six.b('listsize'), < float32 > val.size)
- index = 0
+ data = <double*>np.PyArray_DATA(np.ascontiguousarray(val,dtype=np.float64))
if val.ndim == 2:
- for i in range(val.shape[0]):
- for j in range(val.shape[1]):
- itm = listbase.addChildNode(six.b('ListItem'))
- itm.addAttribute(< string > six.b('index'), < float32 > index)
- itm.addAttribute( < string > six.b('value'), < float32 > val[i, j])
- index += 1
+ listbase.setContent(data, val.shape[1], val.shape[0], False)
elif val.ndim == 1:
- for i in range(val.shape[0]):
- itm = listbase.addChildNode(six.b('ListItem'))
- itm.addAttribute(< string > six.b('index'), < float32 > index)
- itm.addAttribute(< string > six.b('value'), < float32 > val[i])
- index += 1
+ listbase.setContent(data, val.shape[0])
else:
raise Exception("Only 1 or 2 dimensions are allowed")
elif isinstance(val, dict):
@@ -127,6 +119,7 @@ cdef void readOptions(XMLNode node, dc):
cdef XMLNode itm
cdef int i
cdef int j
+ cdef double* data
for item in dc:
val = dc[item]
if node.hasOption(item):
@@ -136,21 +129,11 @@ cdef void readOptions(XMLNode node, dc):
break
listbase = node.addChildNode(six.b('Option'))
listbase.addAttribute(< string > six.b('key'), < string > item)
- listbase.addAttribute(< string > six.b('listsize'), < float32 > val.size)
- index = 0
+ data = <double*>np.PyArray_DATA(np.ascontiguousarray(val,dtype=np.float64))
if val.ndim == 2:
- for i in range(val.shape[0]):
- for j in range(val.shape[1]):
- itm = listbase.addChildNode(six.b('ListItem'))
- itm.addAttribute(< string > six.b('index'), < float32 > index)
- itm.addAttribute( < string > six.b('value'), < float32 > val[i, j])
- index += 1
+ listbase.setContent(data, val.shape[1], val.shape[0], False)
elif val.ndim == 1:
- for i in range(val.shape[0]):
- itm = listbase.addChildNode(six.b('ListItem'))
- itm.addAttribute(< string > six.b('index'), < float32 > index)
- itm.addAttribute(< string > six.b('value'), < float32 > val[i])
- index += 1
+ listbase.setContent(data, val.shape[0])
else:
raise Exception("Only 1 or 2 dimensions are allowed")
else:
diff --git a/src/XMLNode.cpp b/src/XMLNode.cpp
index 75985cc..0ec701f 100644
--- a/src/XMLNode.cpp
+++ b/src/XMLNode.cpp
@@ -32,6 +32,11 @@ $Id$
#include "rapidxml/rapidxml_print.hpp"
#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+
using namespace rapidxml;
using namespace astra;
@@ -167,77 +172,43 @@ vector<string> XMLNode::getContentArray() const
//-----------------------------------------------------------------------------
// Get node content - NUMERICAL LIST
+// NB: A 2D matrix is returned as a linear list
vector<float32> XMLNode::getContentNumericalArray() const
{
- // is scalar
- if (!hasAttribute("listsize")) {
- vector<float32> res(1);
- res[0] = getContentNumerical();
- return res;
- }
+ string input = getContent();
- int iSize = boost::lexical_cast<int>(getAttribute("listsize"));
- // create result array
- vector<float32> res(iSize);
- // loop all list item nodes
- list<XMLNode> nodes = getNodes("ListItem");
- for (list<XMLNode>::iterator it = nodes.begin(); it != nodes.end(); it++) {
- int iIndex = it->getAttributeNumerical("index");
- float32 fValue = it->getAttributeNumerical("value");
- ASTRA_ASSERT(iIndex < iSize);
- res[iIndex] = fValue;
+ // split
+ std::vector<std::string> items;
+ boost::split(items, input, boost::is_any_of(",;"));
+
+ // init list
+ vector<float32> out;
+ out.resize(items.size());
+
+ // loop elements
+ for (unsigned int i = 0; i < items.size(); i++) {
+ out[i] = boost::lexical_cast<float32>(items[i]);
}
- // return
- return res;
+ return out;
}
vector<double> XMLNode::getContentNumericalArrayDouble() const
{
- // is scalar
- if (!hasAttribute("listsize")) {
- vector<double> res(1);
- res[0] = getContentNumerical();
- return res;
- }
+ string input = getContent();
- int iSize = boost::lexical_cast<int>(getAttribute("listsize"));
- // create result array
- vector<double> res(iSize);
- // loop all list item nodes
- list<XMLNode> nodes = getNodes("ListItem");
- for (list<XMLNode>::iterator it = nodes.begin(); it != nodes.end(); it++) {
- int iIndex = it->getAttributeNumerical("index");
- double fValue = it->getAttributeNumericalDouble("value");
- ASTRA_ASSERT(iIndex < iSize);
- res[iIndex] = fValue;
- }
- // return
- return res;
-}
+ // split
+ std::vector<std::string> items;
+ boost::split(items, input, boost::is_any_of(",;"));
-//-----------------------------------------------------------------------------
-// Get node content - NUMERICAL LIST 2
-void XMLNode::getContentNumericalArray(float32*& _pfData, int& _iSize) const
-{
- // is scalar
- if (!hasAttribute("listsize")) {
- _iSize = 1;
- _pfData = new float32[_iSize];
- _pfData[0] = getContentNumerical();
- return;
- }
- // get listsize
- _iSize = boost::lexical_cast<int>(getAttribute("listsize"));
- // create result array
- _pfData = new float32[_iSize];
- // loop all list item nodes
- list<XMLNode> nodes = getNodes("ListItem");
- for (list<XMLNode>::iterator it = nodes.begin(); it != nodes.end(); it++) {
- int iIndex = it->getAttributeNumerical("index");
- float32 fValue = it->getAttributeNumerical("value");
- ASTRA_ASSERT(iIndex < _iSize);
- _pfData[iIndex] = fValue;
+ // init list
+ vector<double> out;
+ out.resize(items.size());
+
+ // loop elements
+ for (unsigned int i = 0; i < items.size(); i++) {
+ out[i] = boost::lexical_cast<double>(items[i]);
}
+ return out;
}
//-----------------------------------------------------------------------------
@@ -420,16 +391,69 @@ void XMLNode::setContent(float32 _fValue)
//-----------------------------------------------------------------------------
// Set content - LIST
-void XMLNode::setContent(float32* pfList, int _iSize)
-{
+
+template<typename T>
+static std::string setContentList_internal(T* pfList, int _iSize) {
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);
+ return str;
+}
+
+void XMLNode::setContent(float32* pfList, int _iSize)
+{
+ setContent(setContentList_internal<float32>(pfList, _iSize));
+}
+
+void XMLNode::setContent(double* pfList, int _iSize)
+{
+ setContent(setContentList_internal<double>(pfList, _iSize));
}
//-----------------------------------------------------------------------------
+// Set content - MATRIX
+
+template<typename T>
+static std::string setContentMatrix_internal(T* _pfMatrix, int _iWidth, int _iHeight, bool transposed)
+{
+ std::string str = "";
+
+ int s1,s2;
+
+ if (!transposed) {
+ s1 = 1;
+ s2 = _iWidth;
+ } else {
+ s1 = _iHeight;
+ s2 = 1;
+ }
+
+ for (int y = 0; y < _iHeight; ++y) {
+ if (_iWidth > 0)
+ str += boost::lexical_cast<std::string>(_pfMatrix[0*s1 + y*s2]);
+ for (int x = 1; x < _iWidth; x++)
+ str += "," + boost::lexical_cast<std::string>(_pfMatrix[x*s1 + y*s2]);
+
+ if (y != _iHeight-1)
+ str += ";";
+ }
+
+ return str;
+}
+
+void XMLNode::setContent(float32* _pfMatrix, int _iWidth, int _iHeight, bool transposed)
+{
+ setContent(setContentMatrix_internal<float32>(_pfMatrix, _iWidth, _iHeight, transposed));
+}
+
+void XMLNode::setContent(double* _pfMatrix, int _iWidth, int _iHeight, bool transposed)
+{
+ setContent(setContentMatrix_internal<double>(_pfMatrix, _iWidth, _iHeight, transposed));
+}
+
+
+//-----------------------------------------------------------------------------
// Add attribute - STRING
void XMLNode::addAttribute(string _sName, string _sText)
{