summaryrefslogtreecommitdiffstats
path: root/include/astra
diff options
context:
space:
mode:
Diffstat (limited to 'include/astra')
-rw-r--r--include/astra/Algorithm.h4
-rw-r--r--include/astra/ArtAlgorithm.h4
-rw-r--r--include/astra/AstraObjectFactory.h58
-rw-r--r--include/astra/AstraObjectManager.h121
-rw-r--r--include/astra/CompositeGeometryManager.h181
-rw-r--r--include/astra/ConeProjectionGeometry3D.h10
-rw-r--r--include/astra/ConeVecProjectionGeometry3D.h11
-rw-r--r--include/astra/CudaBackProjectionAlgorithm.h5
-rw-r--r--include/astra/CudaBackProjectionAlgorithm3D.h2
-rw-r--r--include/astra/CudaCglsAlgorithm.h9
-rw-r--r--include/astra/CudaCglsAlgorithm3D.h2
-rw-r--r--include/astra/CudaEMAlgorithm.h10
-rw-r--r--include/astra/CudaFDKAlgorithm3D.h2
-rw-r--r--include/astra/CudaFilteredBackProjectionAlgorithm.h3
-rw-r--r--include/astra/CudaForwardProjectionAlgorithm.h29
-rw-r--r--include/astra/CudaForwardProjectionAlgorithm3D.h1
-rw-r--r--include/astra/CudaProjector2D.h8
-rw-r--r--include/astra/CudaProjector3D.h7
-rw-r--r--include/astra/CudaReconstructionAlgorithm2D.h25
-rw-r--r--include/astra/CudaSartAlgorithm.h19
-rw-r--r--include/astra/CudaSirtAlgorithm.h21
-rw-r--r--include/astra/CudaSirtAlgorithm3D.h5
-rw-r--r--include/astra/DataProjectorPolicies.h4
-rw-r--r--include/astra/DataProjectorPolicies.inl6
-rw-r--r--include/astra/Fourier.h132
-rw-r--r--include/astra/GeometryUtil3D.h70
-rw-r--r--include/astra/Globals.h6
-rw-r--r--include/astra/ParallelProjectionGeometry3D.h11
-rw-r--r--include/astra/ParallelVecProjectionGeometry3D.h10
-rw-r--r--include/astra/PluginAlgorithm.h65
-rw-r--r--include/astra/ProjectionGeometry3D.h19
-rw-r--r--include/astra/Projector2D.h4
-rw-r--r--include/astra/Projector3D.h4
-rw-r--r--include/astra/ReconstructionAlgorithm2D.h3
-rw-r--r--include/astra/SartAlgorithm.h8
-rw-r--r--include/astra/Singleton.h28
-rw-r--r--include/astra/SirtAlgorithm.h9
-rw-r--r--include/astra/Utilities.h114
-rw-r--r--include/astra/XMLNode.h8
39 files changed, 736 insertions, 302 deletions
diff --git a/include/astra/Algorithm.h b/include/astra/Algorithm.h
index 049417c..18c465f 100644
--- a/include/astra/Algorithm.h
+++ b/include/astra/Algorithm.h
@@ -81,7 +81,7 @@ public:
*
* @return initialized
*/
- bool isInitialized();
+ bool isInitialized() const;
/** get a description of the class
*
@@ -133,7 +133,7 @@ private:
// inline functions
inline std::string CAlgorithm::description() const { return "Algorithm"; };
-inline bool CAlgorithm::isInitialized() { return m_bIsInitialized; }
+inline bool CAlgorithm::isInitialized() const { return m_bIsInitialized; }
} // end namespace
diff --git a/include/astra/ArtAlgorithm.h b/include/astra/ArtAlgorithm.h
index d232b95..1ad9f3f 100644
--- a/include/astra/ArtAlgorithm.h
+++ b/include/astra/ArtAlgorithm.h
@@ -59,7 +59,7 @@ namespace astra {
* \astra_xml_item_option{MinConstraintValue, float, 0, Minimum constraint value.}
* \astra_xml_item_option{UseMaxConstraint, bool, false, Use maximum value constraint.}
* \astra_xml_item_option{MaxConstraintValue, float, 255, Maximum constraint value.}
- * \astra_xml_item_option{Lamda, float, 1, The relaxation factor.}
+ * \astra_xml_item_option{Relaxation, float, 1, The relaxation factor.}
* \astra_xml_item_option{RayOrder, string, "sequential", the order in which the rays are updated. 'sequential' or 'custom'}
* \astra_xml_item_option{RayOrderList, n by 2 vector of float, not used, if RayOrder='custom': use this ray order. Each row consist of a projection id and detector id.}
*
@@ -73,7 +73,7 @@ namespace astra {
* cfg.option.UseMinConstraint = 'yes';\n
* cfg.option.UseMaxConstraint = 'yes';\n
* cfg.option.MaxConstraintValue = 1024;\n
- * cfg.option.Lamda = 0.7;\n
+ * cfg.option.Relaxation = 0.7;\n
* cfg.option.RayOrder = 'custom';\n
* cfg.option.RayOrderList = [0\,0; 0\,2; 1\,0];\n
* alg_id = astra_mex_algorithm('create'\, cfg);\n
diff --git a/include/astra/AstraObjectFactory.h b/include/astra/AstraObjectFactory.h
index 1ed4955..6af9cd8 100644
--- a/include/astra/AstraObjectFactory.h
+++ b/include/astra/AstraObjectFactory.h
@@ -40,6 +40,10 @@ $Id$
#include "AlgorithmTypelist.h"
+#ifdef ASTRA_PYTHON
+#include "PluginAlgorithm.h"
+#endif
+
namespace astra {
@@ -59,20 +63,27 @@ public:
*/
~CAstraObjectFactory();
- /** Create, but don't initialize, a new projector object.
+ /** Create, but don't initialize, a new object.
*
- * @param _sType Type of the new projector.
- * @return Pointer to a new, unitialized projector.
+ * @param _sType Type of the new object.
+ * @return Pointer to a new, uninitialized object.
*/
T* create(std::string _sType);
- /** Create and initialize a new projector object.
+ /** Create and initialize a new object.
*
- * @param _cfg Configuration object to create and initialize a new projector.
+ * @param _cfg Configuration object to create and initialize a new object.
* @return Pointer to a new, initialized projector.
*/
T* create(const Config& _cfg);
+ /** Find a plugin.
+ *
+ * @param _sType Name of plugin to find.
+ * @return Pointer to a new, uninitialized object, or NULL if not found.
+ */
+ T* findPlugin(std::string _sType);
+
};
@@ -93,6 +104,15 @@ CAstraObjectFactory<T, TypeList>::~CAstraObjectFactory()
}
+
+//----------------------------------------------------------------------------------------
+// Hook for finding plugin in registered plugins.
+template <typename T, typename TypeList>
+T* CAstraObjectFactory<T, TypeList>::findPlugin(std::string _sType)
+{
+ return NULL;
+}
+
//----------------------------------------------------------------------------------------
// Create
template <typename T, typename TypeList>
@@ -101,6 +121,9 @@ T* CAstraObjectFactory<T, TypeList>::create(std::string _sType)
functor_find<T> finder = functor_find<T>();
finder.tofind = _sType;
CreateObject<TypeList>::find(finder);
+ if (finder.res == NULL) {
+ finder.res = findPlugin(_sType);
+ }
return finder.res;
}
@@ -109,14 +132,11 @@ T* CAstraObjectFactory<T, TypeList>::create(std::string _sType)
template <typename T, typename TypeList>
T* CAstraObjectFactory<T, TypeList>::create(const Config& _cfg)
{
- functor_find<T> finder = functor_find<T>();
- finder.tofind = _cfg.self.getAttribute("type");
- CreateObject<TypeList>::find(finder);
- if (finder.res == NULL) return NULL;
- if (finder.res->initialize(_cfg))
- return finder.res;
-
- delete finder.res;
+ T* object = create(_cfg.self.getAttribute("type"));
+ if (object == NULL) return NULL;
+ if (object->initialize(_cfg))
+ return object;
+ delete object;
return NULL;
}
//----------------------------------------------------------------------------------------
@@ -131,6 +151,18 @@ T* CAstraObjectFactory<T, TypeList>::create(const Config& _cfg)
*/
class _AstraExport CAlgorithmFactory : public CAstraObjectFactory<CAlgorithm, AlgorithmTypeList> {};
+#ifdef ASTRA_PYTHON
+template <>
+inline CAlgorithm* CAstraObjectFactory<CAlgorithm, AlgorithmTypeList>::findPlugin(std::string _sType)
+ {
+ CPluginAlgorithmFactory *fac = CPluginAlgorithmFactory::getFactory();
+ if (fac)
+ return fac->getPlugin(_sType);
+ else
+ return 0;
+ }
+#endif
+
/**
* Class used to create 2D projectors from a string or a config object
*/
diff --git a/include/astra/AstraObjectManager.h b/include/astra/AstraObjectManager.h
index 895f955..9faecbe 100644
--- a/include/astra/AstraObjectManager.h
+++ b/include/astra/AstraObjectManager.h
@@ -52,17 +52,49 @@ namespace astra {
* among all ObjectManagers.
*/
+class CAstraObjectManagerBase {
+public:
+ virtual std::string getInfo(int index) const =0;
+ virtual void remove(int index) =0;
+ virtual std::string getType() const =0;
+};
-class CAstraIndexManager {
-protected:
- /** The index of the previously stored data object.
+
+class _AstraExport CAstraIndexManager : public Singleton<CAstraIndexManager> {
+public:
+ CAstraIndexManager() : m_iLastIndex(0) { }
+
+ int store(CAstraObjectManagerBase* m) {
+ m_table[++m_iLastIndex] = m;
+ return m_iLastIndex;
+ }
+
+ CAstraObjectManagerBase* get(int index) const {
+ std::map<int, CAstraObjectManagerBase*>::const_iterator i;
+ i = m_table.find(index);
+ if (i != m_table.end())
+ return i->second;
+ else
+ return 0;
+ }
+
+ void remove(int index) {
+ std::map<int, CAstraObjectManagerBase*>::iterator i;
+ i = m_table.find(index);
+ if (i != m_table.end())
+ m_table.erase(i);
+ }
+
+private:
+ /** The index last handed out
*/
- static int m_iPreviousIndex;
+ int m_iLastIndex;
+ std::map<int, CAstraObjectManagerBase*> m_table;
};
template <typename T>
-class CAstraObjectManager : public Singleton<CAstraObjectManager<T> >, CAstraIndexManager {
+class CAstraObjectManager : public CAstraObjectManagerBase {
public:
@@ -117,7 +149,11 @@ public:
*/
void clear();
- /** Get info.
+ /** Get info of object.
+ */
+ std::string getInfo(int index) const;
+
+ /** Get list with info of all managed objects.
*/
std::string info();
@@ -149,9 +185,9 @@ CAstraObjectManager<T>::~CAstraObjectManager()
template <typename T>
int CAstraObjectManager<T>::store(T* _pDataObject)
{
- m_iPreviousIndex++;
- m_mIndexToObject[m_iPreviousIndex] = _pDataObject;
- return m_iPreviousIndex;
+ int iIndex = CAstraIndexManager::getSingleton().store(this);
+ m_mIndexToObject[iIndex] = _pDataObject;
+ return iIndex;
}
//----------------------------------------------------------------------------------------
@@ -180,15 +216,16 @@ T* CAstraObjectManager<T>::get(int _iIndex) const
template <typename T>
void CAstraObjectManager<T>::remove(int _iIndex)
{
- if (!hasIndex(_iIndex)) {
- return;
- }
// find data
typename map<int,T*>::iterator it = m_mIndexToObject.find(_iIndex);
+ if (it == m_mIndexToObject.end())
+ return;
// delete data
delete (*it).second;
// delete from map
- m_mIndexToObject.erase(it);
+ m_mIndexToObject.erase(it);
+
+ CAstraIndexManager::getSingleton().remove(_iIndex);
}
//----------------------------------------------------------------------------------------
@@ -220,19 +257,29 @@ void CAstraObjectManager<T>::clear()
//----------------------------------------------------------------------------------------
// Print info to string
template <typename T>
+std::string CAstraObjectManager<T>::getInfo(int index) const {
+ typename map<int,T*>::const_iterator it = m_mIndexToObject.find(index);
+ if (it == m_mIndexToObject.end())
+ return "";
+ const T* pObject = it->second;
+ std::stringstream res;
+ res << index << " \t";
+ if (pObject->isInitialized()) {
+ res << "v ";
+ } else {
+ res << "x ";
+ }
+ res << pObject->description();
+ return res.str();
+}
+
+template <typename T>
std::string CAstraObjectManager<T>::info() {
std::stringstream res;
res << "id init description" << std::endl;
res << "-----------------------------------------" << std::endl;
- for (typename map<int,T*>::iterator it = m_mIndexToObject.begin(); it != m_mIndexToObject.end(); it++) {
- res << (*it).first << " \t";
- T* pObject = m_mIndexToObject[(*it).first];
- if (pObject->isInitialized()) {
- res << "v ";
- } else {
- res << "x ";
- }
- res << pObject->description() << endl;
+ for (typename map<int,T*>::const_iterator it = m_mIndexToObject.begin(); it != m_mIndexToObject.end(); it++) {
+ res << getInfo(it->first) << endl;
}
res << "-----------------------------------------" << std::endl;
return res.str();
@@ -247,42 +294,60 @@ std::string CAstraObjectManager<T>::info() {
* assigned to each data object by which it can be accessed in the future.
* Indices are always >= 1.
*/
-class _AstraExport CProjector2DManager : public CAstraObjectManager<CProjector2D>{};
+class _AstraExport CProjector2DManager : public Singleton<CProjector2DManager>, public CAstraObjectManager<CProjector2D>
+{
+ virtual std::string getType() const { return "projector2d"; }
+};
/**
* This class contains functionality to store 3D projector objects. A unique index handle will be
* assigned to each data object by which it can be accessed in the future.
* Indices are always >= 1.
*/
-class _AstraExport CProjector3DManager : public CAstraObjectManager<CProjector3D>{};
+class _AstraExport CProjector3DManager : public Singleton<CProjector3DManager>, public CAstraObjectManager<CProjector3D>
+{
+ virtual std::string getType() const { return "projector3d"; }
+};
/**
* This class contains functionality to store 2D data objects. A unique index handle will be
* assigned to each data object by which it can be accessed in the future.
* Indices are always >= 1.
*/
-class _AstraExport CData2DManager : public CAstraObjectManager<CFloat32Data2D>{};
+class _AstraExport CData2DManager : public Singleton<CData2DManager>, public CAstraObjectManager<CFloat32Data2D>
+{
+ virtual std::string getType() const { return "data2d"; }
+};
/**
* This class contains functionality to store 3D data objects. A unique index handle will be
* assigned to each data object by which it can be accessed in the future.
* Indices are always >= 1.
*/
-class _AstraExport CData3DManager : public CAstraObjectManager<CFloat32Data3D>{};
+class _AstraExport CData3DManager : public Singleton<CData3DManager>, public CAstraObjectManager<CFloat32Data3D>
+{
+ virtual std::string getType() const { return "data3d"; }
+};
/**
* This class contains functionality to store algorithm objects. A unique index handle will be
* assigned to each data object by which it can be accessed in the future.
* Indices are always >= 1.
*/
-class _AstraExport CAlgorithmManager : public CAstraObjectManager<CAlgorithm>{};
+class _AstraExport CAlgorithmManager : public Singleton<CAlgorithmManager>, public CAstraObjectManager<CAlgorithm>
+{
+ virtual std::string getType() const { return "algorithm"; }
+};
/**
* This class contains functionality to store matrix objects. A unique index handle will be
* assigned to each data object by which it can be accessed in the future.
* Indices are always >= 1.
*/
-class _AstraExport CMatrixManager : public CAstraObjectManager<CSparseMatrix>{};
+class _AstraExport CMatrixManager : public Singleton<CMatrixManager>, public CAstraObjectManager<CSparseMatrix>
+{
+ virtual std::string getType() const { return "matrix"; }
+};
} // end namespace
diff --git a/include/astra/CompositeGeometryManager.h b/include/astra/CompositeGeometryManager.h
new file mode 100644
index 0000000..18dd72f
--- /dev/null
+++ b/include/astra/CompositeGeometryManager.h
@@ -0,0 +1,181 @@
+/*
+-----------------------------------------------------------------------
+Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+ 2014-2015, CWI, Amsterdam
+
+Contact: astra@uantwerpen.be
+Website: http://sf.net/projects/astra-toolbox
+
+This file is part of the ASTRA Toolbox.
+
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+*/
+
+#ifndef _INC_ASTRA_COMPOSITEGEOMETRYMANAGER
+#define _INC_ASTRA_COMPOSITEGEOMETRYMANAGER
+
+#include "Globals.h"
+
+#ifdef ASTRA_CUDA
+
+#include <list>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+
+namespace astra {
+
+class CCompositeVolume;
+class CCompositeProjections;
+class CFloat32Data3DMemory;
+class CFloat32ProjectionData3DMemory;
+class CFloat32VolumeData3DMemory;
+class CVolumeGeometry3D;
+class CProjectionGeometry3D;
+class CProjector3D;
+
+
+struct SGPUParams {
+ std::vector<int> GPUIndices;
+ size_t memory;
+};
+
+
+class _AstraExport CCompositeGeometryManager {
+public:
+ CCompositeGeometryManager();
+
+ class CPart;
+ typedef std::list<boost::shared_ptr<CPart> > TPartList;
+ class CPart {
+ public:
+ CPart() { }
+ CPart(const CPart& other);
+ virtual ~CPart() { }
+
+ enum {
+ PART_VOL, PART_PROJ
+ } eType;
+
+ CFloat32Data3DMemory* pData;
+ unsigned int subX;
+ unsigned int subY;
+ unsigned int subZ;
+
+ bool uploadToGPU();
+ bool downloadFromGPU(/*mode?*/);
+ virtual void splitX(TPartList& out, size_t maxSize, size_t maxDim, int div) = 0;
+ virtual void splitY(TPartList& out, size_t maxSize, size_t maxDim, int div) = 0;
+ virtual void splitZ(TPartList& out, size_t maxSize, size_t maxDim, int div) = 0;
+ virtual CPart* reduce(const CPart *other) = 0;
+ virtual void getDims(size_t &x, size_t &y, size_t &z) = 0;
+ size_t getSize();
+ };
+
+ class CVolumePart : public CPart {
+ public:
+ CVolumePart() { eType = PART_VOL; }
+ CVolumePart(const CVolumePart& other);
+ virtual ~CVolumePart();
+
+ CVolumeGeometry3D* pGeom;
+
+ virtual void splitX(TPartList& out, size_t maxSize, size_t maxDim, int div);
+ virtual void splitY(TPartList& out, size_t maxSize, size_t maxDim, int div);
+ virtual void splitZ(TPartList& out, size_t maxSize, size_t maxDim, int div);
+ virtual CPart* reduce(const CPart *other);
+ virtual void getDims(size_t &x, size_t &y, size_t &z);
+
+ CVolumePart* clone() const;
+ };
+ class CProjectionPart : public CPart {
+ public:
+ CProjectionPart() { eType = PART_PROJ; }
+ CProjectionPart(const CProjectionPart& other);
+ virtual ~CProjectionPart();
+
+ CProjectionGeometry3D* pGeom;
+
+ virtual void splitX(TPartList& out, size_t maxSize, size_t maxDim, int div);
+ virtual void splitY(TPartList& out, size_t maxSize, size_t maxDim, int div);
+ virtual void splitZ(TPartList& out, size_t maxSize, size_t maxDim, int div);
+ virtual CPart* reduce(const CPart *other);
+ virtual void getDims(size_t &x, size_t &y, size_t &z);
+
+ CProjectionPart* clone() const;
+ };
+
+ struct SJob {
+ public:
+ boost::shared_ptr<CPart> pInput;
+ boost::shared_ptr<CPart> pOutput;
+ CProjector3D *pProjector; // For a `global' geometry. It will not match
+ // the geometries of the input and output.
+
+
+ enum {
+ JOB_FP, JOB_BP, JOB_NOP
+ } eType;
+ enum {
+ MODE_ADD, MODE_SET
+ } eMode;
+
+ };
+
+ typedef std::list<SJob> TJobList;
+ // output part -> list of jobs for that output
+ typedef std::map<CPart*, TJobList > TJobSet;
+
+ bool doJobs(TJobList &jobs);
+
+ SJob createJobFP(CProjector3D *pProjector,
+ CFloat32VolumeData3DMemory *pVolData,
+ CFloat32ProjectionData3DMemory *pProjData);
+ SJob createJobBP(CProjector3D *pProjector,
+ CFloat32VolumeData3DMemory *pVolData,
+ CFloat32ProjectionData3DMemory *pProjData);
+
+ // Convenience functions for creating and running a single FP or BP job
+ bool doFP(CProjector3D *pProjector, CFloat32VolumeData3DMemory *pVolData,
+ CFloat32ProjectionData3DMemory *pProjData);
+ bool doBP(CProjector3D *pProjector, CFloat32VolumeData3DMemory *pVolData,
+ CFloat32ProjectionData3DMemory *pProjData);
+
+ bool doFP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3DMemory *>& volData, const std::vector<CFloat32ProjectionData3DMemory *>& projData);
+ bool doBP(CProjector3D *pProjector, const std::vector<CFloat32VolumeData3DMemory *>& volData, const std::vector<CFloat32ProjectionData3DMemory *>& projData);
+
+ void setGPUIndices(const std::vector<int>& GPUIndices);
+
+ static void setGlobalGPUParams(const SGPUParams& params);
+
+protected:
+
+ bool splitJobs(TJobSet &jobs, size_t maxSize, int div, TJobSet &split);
+
+ std::vector<int> m_GPUIndices;
+ size_t m_iMaxSize;
+
+
+ static SGPUParams* s_params;
+};
+
+}
+
+#endif
+
+#endif
diff --git a/include/astra/ConeProjectionGeometry3D.h b/include/astra/ConeProjectionGeometry3D.h
index 00e72ce..dede6e1 100644
--- a/include/astra/ConeProjectionGeometry3D.h
+++ b/include/astra/ConeProjectionGeometry3D.h
@@ -186,9 +186,15 @@ public:
*/
virtual CVector3D getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex) const;
- virtual void projectPoint(float32 fX, float32 fY, float32 fZ,
+ virtual void projectPoint(double fX, double fY, double fZ,
int iAngleIndex,
- float32 &fU, float32 &fV) const;
+ double &fU, double &fV) const;
+ virtual void backprojectPointX(int iAngleIndex, double fU, double fV,
+ double fX, double &fY, double &fZ) const;
+ virtual void backprojectPointY(int iAngleIndex, double fU, double fV,
+ double fY, double &fX, double &fZ) const;
+ virtual void backprojectPointZ(int iAngleIndex, double fU, double fV,
+ double fZ, double &fX, double &fY) const;
};
diff --git a/include/astra/ConeVecProjectionGeometry3D.h b/include/astra/ConeVecProjectionGeometry3D.h
index 71e8010..f76f9dd 100644
--- a/include/astra/ConeVecProjectionGeometry3D.h
+++ b/include/astra/ConeVecProjectionGeometry3D.h
@@ -148,9 +148,16 @@ public:
const SConeProjection* getProjectionVectors() const { return m_pProjectionAngles; }
- virtual void projectPoint(float32 fX, float32 fY, float32 fZ,
+ virtual void projectPoint(double fX, double fY, double fZ,
int iAngleIndex,
- float32 &fU, float32 &fV) const;
+ double &fU, double &fV) const;
+ virtual void backprojectPointX(int iAngleIndex, double fU, double fV,
+ double fX, double &fY, double &fZ) const;
+ virtual void backprojectPointY(int iAngleIndex, double fU, double fV,
+ double fY, double &fX, double &fZ) const;
+ virtual void backprojectPointZ(int iAngleIndex, double fU, double fV,
+ double fZ, double &fX, double &fY) const;
+
};
} // namespace astra
diff --git a/include/astra/CudaBackProjectionAlgorithm.h b/include/astra/CudaBackProjectionAlgorithm.h
index 84899b0..2450376 100644
--- a/include/astra/CudaBackProjectionAlgorithm.h
+++ b/include/astra/CudaBackProjectionAlgorithm.h
@@ -85,13 +85,10 @@ public:
* @param _pProjector Projector Object. (Ignored)
* @param _pSinogram ProjectionData2D object containing the sinogram data.
* @param _pReconstruction VolumeData2D object for storing the reconstructed volume.
- * @param _iGPUindex GPU to use.
- * @param _iPixelSuperSampling Square root of number of samples per voxel, used to compute the backprojection
*/
bool initialize(CProjector2D* _pProjector,
CFloat32ProjectionData2D* _pSinogram,
- CFloat32VolumeData2D* _pReconstruction,
- int _iGPUindex = -1, int _iPixelSuperSampling = 1);
+ CFloat32VolumeData2D* _pReconstruction);
/** Get a description of the class.
*
diff --git a/include/astra/CudaBackProjectionAlgorithm3D.h b/include/astra/CudaBackProjectionAlgorithm3D.h
index 2d98218..74aeec8 100644
--- a/include/astra/CudaBackProjectionAlgorithm3D.h
+++ b/include/astra/CudaBackProjectionAlgorithm3D.h
@@ -147,6 +147,8 @@ protected:
*/
bool m_bSIRTWeighting;
+
+ void initializeFromProjector();
};
// inline functions
diff --git a/include/astra/CudaCglsAlgorithm.h b/include/astra/CudaCglsAlgorithm.h
index c51093c..6aa0343 100644
--- a/include/astra/CudaCglsAlgorithm.h
+++ b/include/astra/CudaCglsAlgorithm.h
@@ -91,18 +91,13 @@ public:
/** Initialize class, use sequential order.
*
- * @param _pProjector Projector Object. (Ignored)
+ * @param _pProjector Projector Object. (Optional)
* @param _pSinogram ProjectionData2D object containing the sinogram
* @param _pReconstruction VolumeData2D for storing the reconstruction
- * @param _iGPUindex Index of GPU to use. (Starting at 0.)
- * @param _iDetectorSuperSampling Supersampling factor for the FP.
- * @param _iPixelSuperSampling Square root of number of samples per voxel, used to compute the backprojection
*/
bool initialize(CProjector2D* _pProjector,
CFloat32ProjectionData2D* _pSinogram,
- CFloat32VolumeData2D* _pReconstruction,
- int _iGPUindex = -1, int _iDetectorSuperSampling = 1,
- int _iPixelSuperSampling = 1);
+ CFloat32VolumeData2D* _pReconstruction);
/** Get a description of the class.
*
diff --git a/include/astra/CudaCglsAlgorithm3D.h b/include/astra/CudaCglsAlgorithm3D.h
index 77c41c1..3e4084b 100644
--- a/include/astra/CudaCglsAlgorithm3D.h
+++ b/include/astra/CudaCglsAlgorithm3D.h
@@ -161,6 +161,8 @@ protected:
bool m_bAstraCGLSInit;
int m_iDetectorSuperSampling;
int m_iVoxelSuperSampling;
+
+ void initializeFromProjector();
};
// inline functions
diff --git a/include/astra/CudaEMAlgorithm.h b/include/astra/CudaEMAlgorithm.h
index 97eb7ca..a9d2711 100644
--- a/include/astra/CudaEMAlgorithm.h
+++ b/include/astra/CudaEMAlgorithm.h
@@ -63,17 +63,13 @@ public:
/** Initialize class.
*
- * @param _pProjector Projector Object. (Ignored)
+ * @param _pProjector Projector Object. (Optional)
* @param _pSinogram ProjectionData2D object containing the sinogram data.
* @param _pReconstruction VolumeData2D object for storing the reconstructed volume.
- * @param _iGPUindex GPU to use.
- * @param _iDetectorSuperSampling Supersampling factor for the FP.
*/
bool initialize(CProjector2D* _pProjector,
- CFloat32ProjectionData2D* _pSinogram,
- CFloat32VolumeData2D* _pReconstruction,
- int _iGPUindex = -1, int _iDetectorSuperSampling = 1,
- int _iPixelSuperSampling = 1);
+ CFloat32ProjectionData2D* _pSinogram,
+ CFloat32VolumeData2D* _pReconstruction);
/** Get a description of the class.
*
diff --git a/include/astra/CudaFDKAlgorithm3D.h b/include/astra/CudaFDKAlgorithm3D.h
index 1b025f1..63f07fd 100644
--- a/include/astra/CudaFDKAlgorithm3D.h
+++ b/include/astra/CudaFDKAlgorithm3D.h
@@ -152,6 +152,8 @@ protected:
int m_iGPUIndex;
int m_iVoxelSuperSampling;
bool m_bShortScan;
+
+ void initializeFromProjector();
};
// inline functions
diff --git a/include/astra/CudaFilteredBackProjectionAlgorithm.h b/include/astra/CudaFilteredBackProjectionAlgorithm.h
index 33445b6..cf1f19f 100644
--- a/include/astra/CudaFilteredBackProjectionAlgorithm.h
+++ b/include/astra/CudaFilteredBackProjectionAlgorithm.h
@@ -85,6 +85,9 @@ protected:
AstraFBP* m_pFBP;
bool m_bAstraFBPInit;
+
+ void initializeFromProjector();
+ virtual bool requiresProjector() const { return false; }
};
// inline functions
diff --git a/include/astra/CudaForwardProjectionAlgorithm.h b/include/astra/CudaForwardProjectionAlgorithm.h
index d172a7a..449a610 100644
--- a/include/astra/CudaForwardProjectionAlgorithm.h
+++ b/include/astra/CudaForwardProjectionAlgorithm.h
@@ -33,16 +33,15 @@ $Id$
#include "Algorithm.h"
-#include "ParallelProjectionGeometry2D.h"
-#include "VolumeGeometry2D.h"
-
-#include "Float32ProjectionData2D.h"
-#include "Float32VolumeData2D.h"
-
#ifdef ASTRA_CUDA
namespace astra {
+class CProjector2D;
+class CProjectionGeometry2D;
+class CFloat32ProjectionData2D;
+class CFloat32VolumeData2D;
+
/**
* \brief
* This class contains a GPU implementation of an algorithm that creates a forward projection
@@ -91,19 +90,15 @@ public:
/** Initialize class.
*
- * @param _pVolumeGeometry Geometry of the volume.
- * @param _pProjectionGeometry Geometry of the projection.
+ * @param _pProjector Projector2D object. (Optional)
* @param _pVolume VolumeData2D object containing the phantom to compute sinogram from
* @param _pSinogram ProjectionData2D object to store sinogram data in.
- * @param _iGPUindex Index of GPU to use. (Starting at 0.)
- * @param _iDetectorSuperSampling Number of samples per detector element, used to compute the forward projection
* @return success
*/
- bool initialize(CProjectionGeometry2D* _pProjectionGeometry,
- CVolumeGeometry2D* _pVolumeGeometry,
- CFloat32VolumeData2D* _pVolume,
- CFloat32ProjectionData2D* _pSinogram,
- int _iGPUindex = -1, int _iDetectorSuperSampling = 1);
+ bool initialize(CProjector2D* _pProjector,
+ CFloat32VolumeData2D* _pVolume,
+ CFloat32ProjectionData2D* _pSinogram);
+
/** Get all information parameters
*
@@ -147,6 +142,9 @@ public:
void setGPUIndex(int _iGPUIndex);
protected:
+ //< Optional Projector2D object
+ CProjector2D* m_pProjector;
+
//< ProjectionData2D object containing the sinogram.
CFloat32ProjectionData2D* m_pSinogram;
//< VolumeData2D object containing the phantom.
@@ -157,6 +155,7 @@ protected:
//< Number of rays per detector element
int m_iDetectorSuperSampling;
+ void initializeFromProjector();
};
// inline functions
diff --git a/include/astra/CudaForwardProjectionAlgorithm3D.h b/include/astra/CudaForwardProjectionAlgorithm3D.h
index bdd1356..4198d56 100644
--- a/include/astra/CudaForwardProjectionAlgorithm3D.h
+++ b/include/astra/CudaForwardProjectionAlgorithm3D.h
@@ -122,6 +122,7 @@ protected:
int m_iGPUIndex;
int m_iDetectorSuperSampling;
+ void initializeFromProjector();
};
// inline functions
diff --git a/include/astra/CudaProjector2D.h b/include/astra/CudaProjector2D.h
index a571851..2b4bacb 100644
--- a/include/astra/CudaProjector2D.h
+++ b/include/astra/CudaProjector2D.h
@@ -121,9 +121,17 @@ public:
virtual std::string description() const;
+ Cuda2DProjectionKernel getProjectionKernel() const { return m_projectionKernel; }
+ int getVoxelSuperSampling() const { return m_iVoxelSuperSampling; }
+ int getDetectorSuperSampling() const { return m_iDetectorSuperSampling; }
+ int getGPUIndex() const { return m_iGPUIndex; }
+
protected:
Cuda2DProjectionKernel m_projectionKernel;
+ int m_iVoxelSuperSampling;
+ int m_iDetectorSuperSampling;
+ int m_iGPUIndex;
};
//----------------------------------------------------------------------------------------
diff --git a/include/astra/CudaProjector3D.h b/include/astra/CudaProjector3D.h
index a181531..da88d6d 100644
--- a/include/astra/CudaProjector3D.h
+++ b/include/astra/CudaProjector3D.h
@@ -115,11 +115,16 @@ public:
Cuda3DProjectionKernel getProjectionKernel() const { return m_projectionKernel; }
+ int getVoxelSuperSampling() const { return m_iVoxelSuperSampling; }
+ int getDetectorSuperSampling() const { return m_iDetectorSuperSampling; }
+ int getGPUIndex() const { return m_iGPUIndex; }
protected:
Cuda3DProjectionKernel m_projectionKernel;
-
+ int m_iVoxelSuperSampling;
+ int m_iDetectorSuperSampling;
+ int m_iGPUIndex;
};
diff --git a/include/astra/CudaReconstructionAlgorithm2D.h b/include/astra/CudaReconstructionAlgorithm2D.h
index e19bb8f..bb5f2a7 100644
--- a/include/astra/CudaReconstructionAlgorithm2D.h
+++ b/include/astra/CudaReconstructionAlgorithm2D.h
@@ -70,28 +70,13 @@ public:
/** Initialize class.
*
- * @param _pProjector Projector Object. (Ignored)
+ * @param _pProjector Projector Object. (Optional)
* @param _pSinogram ProjectionData2D object containing the sinogram data.
* @param _pReconstruction VolumeData2D object for storing the reconstructed volume.
*/
- bool initialize(CProjector2D* _pProjector,
- CFloat32ProjectionData2D* _pSinogram,
- CFloat32VolumeData2D* _pReconstruction);
-
- /** Initialize class.
- *
- * @param _pProjector Projector Object. (Ignored)
- * @param _pSinogram ProjectionData2D object containing the sinogram data.
- * @param _pReconstruction VolumeData2D object for storing the reconstructed volume.
- * @param _iGPUindex GPU to use.
- * @param _iDetectorSuperSampling Supersampling factor for the FP.
- * @param _iPixelSuperSampling Square root of number of samples per voxel, used to compute the backprojection
- */
virtual bool initialize(CProjector2D* _pProjector,
CFloat32ProjectionData2D* _pSinogram,
- CFloat32VolumeData2D* _pReconstruction,
- int _iGPUindex = -1, int _iDetectorSuperSampling = 1,
- int _iPixelSuperSampling = 1);
+ CFloat32VolumeData2D* _pReconstruction);
/** Clear this class.
@@ -156,6 +141,9 @@ protected:
*/
bool setupGeometry();
+ /** Initialize CUDA algorithm. For internal use only.
+ */
+ virtual void initCUDAAlgorithm();
/** The internally used CUDA algorithm object
*/
@@ -166,6 +154,9 @@ protected:
int m_iGPUIndex;
bool m_bAlgoInit;
+
+ void initializeFromProjector();
+ virtual bool requiresProjector() const { return false; }
};
// inline functions
diff --git a/include/astra/CudaSartAlgorithm.h b/include/astra/CudaSartAlgorithm.h
index b370bd0..e5e18f0 100644
--- a/include/astra/CudaSartAlgorithm.h
+++ b/include/astra/CudaSartAlgorithm.h
@@ -46,6 +46,7 @@ namespace astra {
* \astra_xml_item{ProjectionDataId, integer, Identifier of a projection data object as it is stored in the DataManager.}
* \astra_xml_item{ReconstructionDataId, integer, Identifier of a volume data object as it is stored in the DataManager.}
* \astra_xml_item_option{ReconstructionMaskId, integer, not used, Identifier of a volume data object that acts as a reconstruction mask. 0 = reconstruct on this pixel. 1 = don't reconstruct on this pixel.}
+ * \astra_xml_item_option{Relaxation, float, 1, The relaxation factor.}
*
* \par MATLAB example
* \astra_code{
@@ -53,6 +54,7 @@ namespace astra {
* cfg.ProjectionDataId = sino_id;\n
* cfg.ReconstructionDataId = recon_id;\n
* cfg.option.ReconstructionMaskId = mask_id;\n
+ * cfg.option.Relaxation = 1.0;\n
* alg_id = astra_mex_algorithm('create'\, cfg);\n
* astra_mex_algorithm('iterate'\, alg_id\, 10);\n
* astra_mex_algorithm('delete'\, alg_id);\n
@@ -84,22 +86,27 @@ public:
/** Initialize class.
*
- * @param _pProjector Projector Object. (Ignored)
+ * @param _pProjector Projector Object. (Optional)
* @param _pSinogram ProjectionData2D object containing the sinogram data.
* @param _pReconstruction VolumeData2D object for storing the reconstructed volume.
- * @param _iGPUindex GPU to use.
- * @param _iDetectorSuperSampling Supersampling factor for the FP.
*/
bool initialize(CProjector2D* _pProjector,
- CFloat32ProjectionData2D* _pSinogram,
- CFloat32VolumeData2D* _pReconstruction,
- int _iGPUindex = -1, int _iDetectorSuperSampling = 1);
+ CFloat32ProjectionData2D* _pSinogram,
+ CFloat32VolumeData2D* _pReconstruction);
/** Get a description of the class.
*
* @return description string
*/
virtual std::string description() const;
+
+protected:
+
+ /** Relaxation factor
+ */
+ float m_fLambda;
+
+ virtual void initCUDAAlgorithm();
};
// inline functions
diff --git a/include/astra/CudaSirtAlgorithm.h b/include/astra/CudaSirtAlgorithm.h
index 607889a..3cd8acc 100644
--- a/include/astra/CudaSirtAlgorithm.h
+++ b/include/astra/CudaSirtAlgorithm.h
@@ -53,6 +53,7 @@ namespace astra {
* \astra_xml_item{ProjectionDataId, integer, Identifier of a projection data object as it is stored in the DataManager.}
* \astra_xml_item{ReconstructionDataId, integer, Identifier of a volume data object as it is stored in the DataManager.}
* \astra_xml_item_option{ReconstructionMaskId, integer, not used, Identifier of a volume data object that acts as a reconstruction mask. 0 = reconstruct on this pixel. 1 = don't reconstruct on this pixel.}
+ * \astra_xml_item_option{Relaxation, float, 1, Relaxation parameter.}
*
* \par MATLAB example
* \astra_code{
@@ -62,6 +63,7 @@ namespace astra {
* cfg.ProjectionDataId = sino_id;\n
* cfg.ReconstructionDataId = recon_id;\n
* cfg.option.ReconstructionMaskId = mask_id;\n
+ * cfg.option.Relaxation = 1.0;\n
* alg_id = astra_mex_algorithm('create'\, cfg);\n
* astra_mex_algorithm('iterate'\, alg_id\, 10);\n
* astra_mex_algorithm('delete'\, alg_id);\n
@@ -93,22 +95,15 @@ public:
*/
virtual bool initialize(const Config& _cfg);
- virtual void run(int _iNrIterations);
-
/** Initialize class.
*
- * @param _pProjector Projector Object. (Ignored)
+ * @param _pProjector Projector Object. (Optional)
* @param _pSinogram ProjectionData2D object containing the sinogram data.
* @param _pReconstruction VolumeData2D object for storing the reconstructed volume.
- * @param _iGPUindex GPU to use.
- * @param _iDetectorSuperSampling Supersampling factor for the FP.
- * @param _iPixelSuperSampling Square root of number of samples per voxel, used to compute the backprojection
*/
bool initialize(CProjector2D* _pProjector,
- CFloat32ProjectionData2D* _pSinogram,
- CFloat32VolumeData2D* _pReconstruction,
- int _iGPUindex = -1, int _iDetectorSuperSampling = 1,
- int _iPixelSuperSampling = 1);
+ CFloat32ProjectionData2D* _pSinogram,
+ CFloat32VolumeData2D* _pReconstruction);
/** Get a description of the class.
*
@@ -119,6 +114,12 @@ public:
protected:
CFloat32VolumeData2D* m_pMinMask;
CFloat32VolumeData2D* m_pMaxMask;
+
+ /** Relaxation factor
+ */
+ float m_fLambda;
+
+ virtual void initCUDAAlgorithm();
};
// inline functions
diff --git a/include/astra/CudaSirtAlgorithm3D.h b/include/astra/CudaSirtAlgorithm3D.h
index fda4635..60191cd 100644
--- a/include/astra/CudaSirtAlgorithm3D.h
+++ b/include/astra/CudaSirtAlgorithm3D.h
@@ -50,7 +50,7 @@ class AstraSIRT3d;
*
* The update step of pixel \f$v_j\f$ for iteration \f$k\f$ is given by:
* \f[
- * v_j^{(k+1)} = v_j^{(k)} + \alpha \sum_{i=1}^{M} \left( \frac{w_{ij}\left( p_i - \sum_{r=1}^{N} w_{ir}v_r^{(k)}\right)}{\sum_{k=1}^{N} w_{ik}} \right) \frac{1}{\sum_{l=1}^{M}w_{lj}}
+ * v_j^{(k+1)} = v_j^{(k)} + \lambda \sum_{i=1}^{M} \left( \frac{w_{ij}\left( p_i - \sum_{r=1}^{N} w_{ir}v_r^{(k)}\right)}{\sum_{k=1}^{N} w_{ik}} \right) \frac{1}{\sum_{l=1}^{M}w_{lj}}
* \f]
*
* \par XML Configuration
@@ -175,6 +175,9 @@ protected:
bool m_bAstraSIRTInit;
int m_iDetectorSuperSampling;
int m_iVoxelSuperSampling;
+ float m_fLambda;
+
+ void initializeFromProjector();
};
// inline functions
diff --git a/include/astra/DataProjectorPolicies.h b/include/astra/DataProjectorPolicies.h
index c258f5c..acfb36f 100644
--- a/include/astra/DataProjectorPolicies.h
+++ b/include/astra/DataProjectorPolicies.h
@@ -319,10 +319,12 @@ class SIRTBPPolicy {
CFloat32ProjectionData2D* m_pTotalRayLength;
CFloat32VolumeData2D* m_pTotalPixelWeight;
+ float m_fRelaxation;
+
public:
FORCEINLINE SIRTBPPolicy();
- FORCEINLINE SIRTBPPolicy(CFloat32VolumeData2D* _pReconstruction, CFloat32ProjectionData2D* _pSinogram, CFloat32VolumeData2D* _pTotalPixelWeight, CFloat32ProjectionData2D* _pTotalRayLength);
+ FORCEINLINE SIRTBPPolicy(CFloat32VolumeData2D* _pReconstruction, CFloat32ProjectionData2D* _pSinogram, CFloat32VolumeData2D* _pTotalPixelWeight, CFloat32ProjectionData2D* _pTotalRayLength, float _fRelaxation);
FORCEINLINE ~SIRTBPPolicy();
FORCEINLINE bool rayPrior(int _iRayIndex);
diff --git a/include/astra/DataProjectorPolicies.inl b/include/astra/DataProjectorPolicies.inl
index 0c0eddd..f300761 100644
--- a/include/astra/DataProjectorPolicies.inl
+++ b/include/astra/DataProjectorPolicies.inl
@@ -712,12 +712,14 @@ SIRTBPPolicy::SIRTBPPolicy()
SIRTBPPolicy::SIRTBPPolicy(CFloat32VolumeData2D* _pReconstruction,
CFloat32ProjectionData2D* _pSinogram,
CFloat32VolumeData2D* _pTotalPixelWeight,
- CFloat32ProjectionData2D* _pTotalRayLength)
+ CFloat32ProjectionData2D* _pTotalRayLength,
+ float _fRelaxation)
{
m_pReconstruction = _pReconstruction;
m_pSinogram = _pSinogram;
m_pTotalPixelWeight = _pTotalPixelWeight;
m_pTotalRayLength = _pTotalRayLength;
+ m_fRelaxation = _fRelaxation;
}
//----------------------------------------------------------------------------------------
SIRTBPPolicy::~SIRTBPPolicy()
@@ -739,7 +741,7 @@ void SIRTBPPolicy::addWeight(int _iRayIndex, int _iVolumeIndex, float32 _fWeight
{
float32 fGammaBeta = m_pTotalPixelWeight->getData()[_iVolumeIndex] * m_pTotalRayLength->getData()[_iRayIndex];
if ((fGammaBeta > 0.001f) || (fGammaBeta < -0.001f)) {
- m_pReconstruction->getData()[_iVolumeIndex] += _fWeight * m_pSinogram->getData()[_iRayIndex] / fGammaBeta;
+ m_pReconstruction->getData()[_iVolumeIndex] += _fWeight * m_fRelaxation * m_pSinogram->getData()[_iRayIndex] / fGammaBeta;
}
}
//----------------------------------------------------------------------------------------
diff --git a/include/astra/Fourier.h b/include/astra/Fourier.h
index b515dc6..68f9f38 100644
--- a/include/astra/Fourier.h
+++ b/include/astra/Fourier.h
@@ -33,94 +33,50 @@ $Id$
namespace astra {
-
-/**
- * Perform a 1D DFT or inverse DFT.
- *
- * @param iLength number of elements
- * @param pfRealIn real part of input
- * @param pfImaginaryIn imaginary part of input
- * @param pfRealOut real part of output
- * @param pfImaginaryOut imaginary part of output
- * @param iStrideIn distance between elements in pf*In
- * @param iStrideOut distance between elements in pf*Out
- * @param bInverse if true, perform an inverse DFT
- */
-
-void _AstraExport discreteFourierTransform1D(unsigned int iLength,
- const float32* pfRealIn,
- const float32* pfImaginaryIn,
- float32* pfRealOut,
- float32* pfImaginaryOut,
- unsigned int iStrideIn,
- unsigned int iStrideOut,
- bool bInverse);
-
-/**
- * Perform a 2D DFT or inverse DFT.
- *
- * @param iHeight number of rows
- * @param iWidth number of columns
- * @param pfRealIn real part of input
- * @param pfImaginaryIn imaginary part of input
- * @param pfRealOut real part of output
- * @param pfImaginaryOut imaginary part of output
- * @param bInverse if true, perform an inverse DFT
- */
-
-void _AstraExport discreteFourierTransform2D(unsigned int iHeight, unsigned int iWidth,
- const float32* pfRealIn,
- const float32* pfImaginaryIn,
- float32* pfRealOut,
- float32* pfImaginaryOut,
- bool bInverse);
-
-/**
- * Perform a 1D FFT or inverse FFT. The size must be a power of two.
- * This transform can be done in-place, so the input and output pointers
- * may point to the same data.
- *
- * @param iLength number of elements, must be a power of two
- * @param pfRealIn real part of input
- * @param pfImaginaryIn imaginary part of input
- * @param pfRealOut real part of output
- * @param pfImaginaryOut imaginary part of output
- * @param iStrideIn distance between elements in pf*In
- * @param iStrideOut distance between elements in pf*Out
- * @param bInverse if true, perform an inverse DFT
- */
-
-void _AstraExport fastTwoPowerFourierTransform1D(unsigned int iLength,
- const float32* pfRealIn,
- const float32* pfImaginaryIn,
- float32* pfRealOut,
- float32* pfImaginaryOut,
- unsigned int iStrideIn,
- unsigned int iStrideOut,
- bool bInverse);
-
-/**
- * Perform a 2D FFT or inverse FFT. The size must be a power of two.
- * This transform can be done in-place, so the input and output pointers
- * may point to the same data.
- *
- * @param iHeight number of rows, must be a power of two
- * @param iWidth number of columns, must be a power of two
- * @param pfRealIn real part of input
- * @param pfImaginaryIn imaginary part of input
- * @param pfRealOut real part of output
- * @param pfImaginaryOut imaginary part of output
- * @param bInverse if true, perform an inverse DFT
- */
-
-void _AstraExport fastTwoPowerFourierTransform2D(unsigned int iHeight,
- unsigned int iWidth,
- const float32* pfRealIn,
- const float32* pfImaginaryIn,
- float32* pfRealOut,
- float32* pfImaginaryOut,
- bool bInverse);
-
+/*
+-------- Complex DFT (Discrete Fourier Transform) --------
+ [definition]
+ <case1>
+ X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n
+ <case2>
+ X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n
+ (notes: sum_j=0^n-1 is a summation from j=0 to n-1)
+ [usage]
+ <case1>
+ ip[0] = 0; // first time only
+ cdft(2*n, 1, a, ip, w);
+ <case2>
+ ip[0] = 0; // first time only
+ cdft(2*n, -1, a, ip, w);
+ [parameters]
+ 2*n :data length (int)
+ n >= 1, n = power of 2
+ a[0...2*n-1] :input/output data (float32 *)
+ input data
+ a[2*j] = Re(x[j]),
+ a[2*j+1] = Im(x[j]), 0<=j<n
+ output data
+ a[2*k] = Re(X[k]),
+ a[2*k+1] = Im(X[k]), 0<=k<n
+ ip[0...*] :work area for bit reversal (int *)
+ length of ip >= 2+sqrt(n)
+ strictly,
+ length of ip >=
+ 2+(1<<(int)(log(n+0.5)/log(2))/2).
+ ip[0],ip[1] are pointers of the cos/sin table.
+ w[0...n/2-1] :cos/sin table (float32 *)
+ w[],ip[] are initialized if ip[0] == 0.
+ [remark]
+ Inverse of
+ cdft(2*n, -1, a, ip, w);
+ is
+ cdft(2*n, 1, a, ip, w);
+ for (j = 0; j <= 2 * n - 1; j++) {
+ a[j] *= 1.0 / n;
+ }
+ .
+*/
+_AstraExport void cdft(int n, int isgn, float32 *a, int *ip, float32 *w);
}
diff --git a/include/astra/GeometryUtil3D.h b/include/astra/GeometryUtil3D.h
index 698372e..e4d73e4 100644
--- a/include/astra/GeometryUtil3D.h
+++ b/include/astra/GeometryUtil3D.h
@@ -43,6 +43,33 @@ struct SConeProjection {
// the V-edge of a detector pixel
double fDetVX, fDetVY, fDetVZ;
+
+
+
+
+ void translate(double dx, double dy, double dz) {
+ fSrcX += dx;
+ fSrcY += dy;
+ fSrcZ += dz;
+ fDetSX += dx;
+ fDetSY += dy;
+ fDetSZ += dz;
+
+ }
+ void scale(double factor) {
+ fSrcX *= factor;
+ fSrcY *= factor;
+ fSrcZ *= factor;
+ fDetSX *= factor;
+ fDetSY *= factor;
+ fDetSZ *= factor;
+ fDetUX *= factor;
+ fDetUY *= factor;
+ fDetUZ *= factor;
+ fDetVX *= factor;
+ fDetVY *= factor;
+ fDetVZ *= factor;
+ }
};
struct SPar3DProjection {
@@ -57,6 +84,29 @@ struct SPar3DProjection {
// the V-edge of a detector pixel
double fDetVX, fDetVY, fDetVZ;
+
+
+
+
+ void translate(double dx, double dy, double dz) {
+ fDetSX += dx;
+ fDetSY += dy;
+ fDetSZ += dz;
+ }
+ void scale(double factor) {
+ fRayX *= factor;
+ fRayY *= factor;
+ fRayZ *= factor;
+ fDetSX *= factor;
+ fDetSY *= factor;
+ fDetSZ *= factor;
+ fDetUX *= factor;
+ fDetUY *= factor;
+ fDetUZ *= factor;
+ fDetVX *= factor;
+ fDetVY *= factor;
+ fDetVZ *= factor;
+ }
};
void computeBP_UV_Coeffs(const SPar3DProjection& proj,
@@ -68,6 +118,26 @@ void computeBP_UV_Coeffs(const SConeProjection& proj,
double &fVX, double &fVY, double &fVZ, double &fVC,
double &fDX, double &fDY, double &fDZ, double &fDC);
+
+SConeProjection* genConeProjections(unsigned int iProjAngles,
+ unsigned int iProjU,
+ unsigned int iProjV,
+ double fOriginSourceDistance,
+ double fOriginDetectorDistance,
+ double fDetUSize,
+ double fDetVSize,
+ const float *pfAngles);
+
+SPar3DProjection* genPar3DProjections(unsigned int iProjAngles,
+ unsigned int iProjU,
+ unsigned int iProjV,
+ double fDetUSize,
+ double fDetVSize,
+ const float *pfAngles);
+
+
+
+
}
#endif
diff --git a/include/astra/Globals.h b/include/astra/Globals.h
index 9c8ddfb..5dbac83 100644
--- a/include/astra/Globals.h
+++ b/include/astra/Globals.h
@@ -61,9 +61,9 @@ $Id$
// macro's
#define ASTRA_TOOLBOXVERSION_MAJOR 1
-#define ASTRA_TOOLBOXVERSION_MINOR 5
+#define ASTRA_TOOLBOXVERSION_MINOR 7
#define ASTRA_TOOLBOXVERSION ((ASTRA_TOOLBOXVERSION_MAJOR)*100 + (ASTRA_TOOLBOXVERSION_MINOR))
-#define ASTRA_TOOLBOXVERSION_STRING "1.5"
+#define ASTRA_TOOLBOXVERSION_STRING "1.7.1"
#define ASTRA_ASSERT(a) assert(a)
@@ -146,6 +146,8 @@ namespace astra {
const float32 PIdiv2 = PI / 2;
const float32 PIdiv4 = PI / 4;
const float32 eps = 1e-7f;
+
+ extern _AstraExport bool running_in_matlab;
}
//----------------------------------------------------------------------------------------
diff --git a/include/astra/ParallelProjectionGeometry3D.h b/include/astra/ParallelProjectionGeometry3D.h
index 72401e5..d95c050 100644
--- a/include/astra/ParallelProjectionGeometry3D.h
+++ b/include/astra/ParallelProjectionGeometry3D.h
@@ -147,9 +147,16 @@ public:
*/
virtual CVector3D getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex) const;
- virtual void projectPoint(float32 fX, float32 fY, float32 fZ,
+ virtual void projectPoint(double fX, double fY, double fZ,
int iAngleIndex,
- float32 &fU, float32 &fV) const;
+ double &fU, double &fV) const;
+ virtual void backprojectPointX(int iAngleIndex, double fU, double fV,
+ double fX, double &fY, double &fZ) const;
+ virtual void backprojectPointY(int iAngleIndex, double fU, double fV,
+ double fY, double &fX, double &fZ) const;
+ virtual void backprojectPointZ(int iAngleIndex, double fU, double fV,
+ double fZ, double &fX, double &fY) const;
+
/**
* Creates (= allocates) a 2D projection geometry used when projecting one slice using a 2D projector
diff --git a/include/astra/ParallelVecProjectionGeometry3D.h b/include/astra/ParallelVecProjectionGeometry3D.h
index 59238c8..ec91086 100644
--- a/include/astra/ParallelVecProjectionGeometry3D.h
+++ b/include/astra/ParallelVecProjectionGeometry3D.h
@@ -149,9 +149,15 @@ public:
const SPar3DProjection* getProjectionVectors() const { return m_pProjectionAngles; }
- virtual void projectPoint(float32 fX, float32 fY, float32 fZ,
+ virtual void projectPoint(double fX, double fY, double fZ,
int iAngleIndex,
- float32 &fU, float32 &fV) const;
+ double &fU, double &fV) const;
+ virtual void backprojectPointX(int iAngleIndex, double fU, double fV,
+ double fX, double &fY, double &fZ) const;
+ virtual void backprojectPointY(int iAngleIndex, double fU, double fV,
+ double fY, double &fX, double &fZ) const;
+ virtual void backprojectPointZ(int iAngleIndex, double fU, double fV,
+ double fZ, double &fX, double &fY) const;
};
} // namespace astra
diff --git a/include/astra/PluginAlgorithm.h b/include/astra/PluginAlgorithm.h
new file mode 100644
index 0000000..cbd80fc
--- /dev/null
+++ b/include/astra/PluginAlgorithm.h
@@ -0,0 +1,65 @@
+/*
+-----------------------------------------------------------------------
+Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+ 2014-2015, CWI, Amsterdam
+
+Contact: astra@uantwerpen.be
+Website: http://sf.net/projects/astra-toolbox
+
+This file is part of the ASTRA Toolbox.
+
+
+The ASTRA Toolbox is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#ifndef _INC_ASTRA_PLUGINALGORITHM
+#define _INC_ASTRA_PLUGINALGORITHM
+
+#include "astra/Globals.h"
+
+#include <map>
+#include <string>
+
+namespace astra {
+
+class CAlgorithm;
+
+class _AstraExport CPluginAlgorithmFactory {
+
+public:
+ CPluginAlgorithmFactory() { }
+ virtual ~CPluginAlgorithmFactory() { }
+
+ virtual CAlgorithm * getPlugin(const std::string &name) = 0;
+
+ virtual bool registerPlugin(std::string name, std::string className) = 0;
+ virtual bool registerPlugin(std::string className) = 0;
+
+ virtual std::map<std::string, std::string> getRegisteredMap() = 0;
+
+ virtual std::string getHelp(const std::string &name) = 0;
+
+ static void registerFactory(CPluginAlgorithmFactory *factory) { m_factory = factory; }
+ static CPluginAlgorithmFactory* getFactory() { return m_factory; }
+
+private:
+ static CPluginAlgorithmFactory *m_factory;
+};
+
+}
+
+#endif
diff --git a/include/astra/ProjectionGeometry3D.h b/include/astra/ProjectionGeometry3D.h
index 19ac3ab..0b60287 100644
--- a/include/astra/ProjectionGeometry3D.h
+++ b/include/astra/ProjectionGeometry3D.h
@@ -317,9 +317,24 @@ public:
* @param iAngleIndex the index of the angle to use
* @param fU,fV the projected point.
*/
- virtual void projectPoint(float32 fX, float32 fY, float32 fZ,
+ virtual void projectPoint(double fX, double fY, double fZ,
int iAngleIndex,
- float32 &fU, float32 &fV) const = 0;
+ double &fU, double &fV) const = 0;
+
+ /* Backproject a point onto a plane parallel to a coordinate plane.
+ * The 2D point coordinates are the (unrounded) indices of the detector
+ * column and row. The output is in 3D coordinates in units.
+ * are in units. The output fU,fV are the (unrounded) indices of the
+ * detector column and row.
+ * This may fall outside of the actual detector.
+ */
+ virtual void backprojectPointX(int iAngleIndex, double fU, double fV,
+ double fX, double &fY, double &fZ) const = 0;
+ virtual void backprojectPointY(int iAngleIndex, double fU, double fV,
+ double fY, double &fX, double &fZ) const = 0;
+ virtual void backprojectPointZ(int iAngleIndex, double fU, double fV,
+ double fZ, double &fX, double &fY) const = 0;
+
/** Returns true if the type of geometry defined in this class is the one specified in _sType.
*
diff --git a/include/astra/Projector2D.h b/include/astra/Projector2D.h
index a1ea0ce..c7a899d 100644
--- a/include/astra/Projector2D.h
+++ b/include/astra/Projector2D.h
@@ -174,7 +174,7 @@ public:
*
* @return initialized successfully
*/
- bool isInitialized();
+ bool isInitialized() const;
/** get a description of the class
*
@@ -191,7 +191,7 @@ private:
};
// inline functions
-inline bool CProjector2D::isInitialized() { return m_bIsInitialized; }
+inline bool CProjector2D::isInitialized() const { return m_bIsInitialized; }
inline CProjectionGeometry2D* CProjector2D::getProjectionGeometry() { return m_pProjectionGeometry; }
inline CVolumeGeometry2D* CProjector2D::getVolumeGeometry() { return m_pVolumeGeometry; }
diff --git a/include/astra/Projector3D.h b/include/astra/Projector3D.h
index 1ef1ba7..88ca2be 100644
--- a/include/astra/Projector3D.h
+++ b/include/astra/Projector3D.h
@@ -153,7 +153,7 @@ public:
*
* @return initialized successfully
*/
- bool isInitialized();
+ bool isInitialized() const;
/** get a description of the class
*
@@ -174,7 +174,7 @@ private:
};
// inline functions
-inline bool CProjector3D::isInitialized() { return m_bIsInitialized; }
+inline bool CProjector3D::isInitialized() const { return m_bIsInitialized; }
inline CProjectionGeometry3D* CProjector3D::getProjectionGeometry() { return m_pProjectionGeometry; }
inline CVolumeGeometry3D* CProjector3D::getVolumeGeometry() { return m_pVolumeGeometry; }
diff --git a/include/astra/ReconstructionAlgorithm2D.h b/include/astra/ReconstructionAlgorithm2D.h
index 60584e0..ac87c4f 100644
--- a/include/astra/ReconstructionAlgorithm2D.h
+++ b/include/astra/ReconstructionAlgorithm2D.h
@@ -208,6 +208,9 @@ protected:
//< Use the fixed reconstruction mask?
bool m_bUseSinogramMask;
+
+ //< Specify if initialize/check should check for a valid Projector
+ virtual bool requiresProjector() const { return true; }
};
// inline functions
diff --git a/include/astra/SartAlgorithm.h b/include/astra/SartAlgorithm.h
index eb4c61e..cdae029 100644
--- a/include/astra/SartAlgorithm.h
+++ b/include/astra/SartAlgorithm.h
@@ -49,7 +49,7 @@ namespace astra {
*
* The update step of pixel \f$v_j\f$ for projection \f$phi\f$ and iteration \f$k\f$ is given by:
* \f[
- * v_j^{(k+1)} = v_j^{(k)} + \frac{\sum_{p_i \in P_\phi} \left( \lambda \frac{p_i - \sum_{r=1}^{N} w_{ir}v_r^{(k)}} {\sum_{r=1}^{N}w_{ir} } \right)} {\sum_{p_i \in P_\phi}w_{ij}}
+ * v_j^{(k+1)} = v_j^{(k)} + \lambda \frac{\sum_{p_i \in P_\phi} \left( \frac{p_i - \sum_{r=1}^{N} w_{ir}v_r^{(k)}} {\sum_{r=1}^{N}w_{ir} } \right)} {\sum_{p_i \in P_\phi}w_{ij}}
* \f]
*
* \par XML Configuration
@@ -64,6 +64,7 @@ namespace astra {
* \astra_xml_item_option{MaxConstraintValue, float, 255, Maximum constraint value.}
* \astra_xml_item_option{ProjectionOrder, string, "sequential", the order in which the projections are updated. 'sequential', 'random' or 'custom'}
* \astra_xml_item_option{ProjectionOrderList, vector of float, not used, if ProjectionOrder='custom': use this order.}
+ * \astra_xml_item_option{Relaxation, float, 1, The relaxation parameter.}
*
* \par MATLAB example
* \astra_code{
@@ -76,7 +77,8 @@ namespace astra {
* cfg.option.UseMaxConstraint = 'yes';\n
* cfg.option.MaxConstraintValue = 1024;\n
* cfg.option.ProjectionOrder = 'custom';\n
-* cfg.option.ProjectionOrderList = randperm(100);\n
+ * cfg.option.ProjectionOrderList = randperm(100);\n
+ * cfg.option.Relaxation = 1.0;\n
* alg_id = astra_mex_algorithm('create'\, cfg);\n
* astra_mex_algorithm('iterate'\, alg_id\, 10);\n
* astra_mex_algorithm('delete'\, alg_id);\n
@@ -215,6 +217,8 @@ protected:
//< Current index in the projection order array.
int m_iCurrentProjection;
+ //< Relaxation parameter
+ float m_fLambda;
};
// inline functions
diff --git a/include/astra/Singleton.h b/include/astra/Singleton.h
index a256187..9d3c088 100644
--- a/include/astra/Singleton.h
+++ b/include/astra/Singleton.h
@@ -45,11 +45,7 @@ class Singleton {
public:
// constructor
- Singleton() {
- assert(!m_singleton);
- int offset = (uintptr_t)(T*)1 - (uintptr_t)(Singleton<T>*)(T*)1;
- m_singleton = (T*)((uintptr_t)this + offset);
- };
+ Singleton() { }
// destructor
virtual ~Singleton() {
@@ -57,15 +53,17 @@ class Singleton {
m_singleton = 0;
}
+ static void construct();
+
// get singleton
static T& getSingleton() {
if (!m_singleton)
- m_singleton = new T();
+ construct();
return *m_singleton;
}
static T* getSingletonPtr() {
if (!m_singleton)
- m_singleton = new T();
+ construct();
return m_singleton;
}
@@ -76,11 +74,23 @@ class Singleton {
};
-#define DEFINE_SINGLETON(T) template<> T* Singleton<T >::m_singleton = 0
+// We specifically avoid defining construct() in the header.
+// That way, the call to new is always executed by code inside libastra.
+// This avoids the situation where a singleton gets created by a copy
+// of the constructor linked into an object file outside of libastra, such
+// as a .mex file, which would then also cause the vtable to be outside of
+// libastra. This situation would cause issues when .mex files are unloaded.
+
+#define DEFINE_SINGLETON(T) \
+template<> void Singleton<T >::construct() { assert(!m_singleton); m_singleton = new T(); } \
+template<> T* Singleton<T >::m_singleton = 0
+
// This is a hack to support statements like
// DEFINE_SINGLETON2(CTemplatedClass<C1, C2>);
-#define DEFINE_SINGLETON2(A,B) template<> A,B* Singleton<A,B >::m_singleton = 0
+#define DEFINE_SINGLETON2(A,B) \
+template<> void Singleton<A,B >::construct() { assert(!m_singleton); m_singleton = new A,B(); } \
+template<> A,B* Singleton<A,B >::m_singleton = 0
} // end namespace
diff --git a/include/astra/SirtAlgorithm.h b/include/astra/SirtAlgorithm.h
index 05b3fa9..8044d09 100644
--- a/include/astra/SirtAlgorithm.h
+++ b/include/astra/SirtAlgorithm.h
@@ -49,7 +49,7 @@ namespace astra {
*
* The update step of pixel \f$v_j\f$ for iteration \f$k\f$ is given by:
* \f[
- * v_j^{(k+1)} = v_j^{(k)} + \alpha \sum_{i=1}^{M} \left( \frac{w_{ij}\left( p_i - \sum_{r=1}^{N} w_{ir}v_r^{(k)}\right)}{\sum_{k=1}^{N} w_{ik}} \right) \frac{1}{\sum_{l=1}^{M}w_{lj}}
+ * v_j^{(k+1)} = v_j^{(k)} + \lambda \sum_{i=1}^{M} \left( \frac{w_{ij}\left( p_i - \sum_{r=1}^{N} w_{ir}v_r^{(k)}\right)}{\sum_{k=1}^{N} w_{ik}} \right) \frac{1}{\sum_{l=1}^{M}w_{lj}}
* \f]
*
* \par XML Configuration
@@ -62,6 +62,7 @@ namespace astra {
* \astra_xml_item_option{MinConstraintValue, float, 0, Minimum constraint value.}
* \astra_xml_item_option{UseMaxConstraint, bool, false, Use maximum value constraint.}
* \astra_xml_item_option{MaxConstraintValue, float, 255, Maximum constraint value.}
+ * \astra_xml_item_option{Relaxation, float, 1, The relaxation factor.}
*
* \par XML Example
* \astra_code{
@@ -74,6 +75,7 @@ namespace astra {
* &lt;Option key="UseMinConstraint" value="yes"/&gt;\n
* &lt;Option key="UseMaxConstraint" value="yes"/&gt;\n
* &lt;Option key="MaxConstraintValue" value="1024"/&gt;\n
+ * &lt;Option key="Relaxation" value="1"/&gt;\n
* &lt;/Algorithm&gt;
* }
*
@@ -88,6 +90,7 @@ namespace astra {
* cfg.option.UseMinConstraint = 'yes';\n
* cfg.option.UseMaxConstraint = 'yes';\n
* cfg.option.MaxConstraintValue = 1024;\n
+ * cfg.option.Relaxation = 1.0;\n
* alg_id = astra_mex_algorithm('create'\, cfg);\n
* astra_mex_algorithm('iterate'\, alg_id\, 10);\n
* astra_mex_algorithm('delete'\, alg_id);\n
@@ -136,6 +139,10 @@ protected:
*/
int m_iIterationCount;
+ /** Relaxation parameter
+ */
+ float m_fLambda;
+
public:
// type of the algorithm, needed to register with CAlgorithmFactory
diff --git a/include/astra/Utilities.h b/include/astra/Utilities.h
index 68471d0..8d7c44d 100644
--- a/include/astra/Utilities.h
+++ b/include/astra/Utilities.h
@@ -31,89 +31,63 @@ $Id$
#include <string>
#include <vector>
-#include <algorithm>
-#include <sstream>
#include <map>
#include "Globals.h"
namespace astra {
-/**
- * This class contains some usefull static utility functions for std strings.
- */
-class StringUtil {
+
+namespace StringUtil {
+
+// Exception thrown by functions below
+class bad_cast : public std::exception {
public:
- /**
- * Removes whitespace characters such as spaces and tabs at the extremas.
- * Optionally you can specify which extrema to trim (default=both)
- *
- * @param _sString The string to trim.
- * @param _bLeft Trim the left extrema? Default = true.
- * @param _bRight Trim the right extrema? Default = true.
- */
- static void trim(std::string& _sString, bool _bLeft = true, bool _bRight = true);
-
- /**
- * Returns a vector of strings that contains all the substrings delimited by
- * the characters in _sDelims.
- *
- * @param _sString The string to split.
- * @param _sDelims The delimiter string.
- * @return Vector of strings.
- */
- static std::vector<std::string> split(const std::string& _sString, const std::string& _sDelims);
-
- /**
- * Cast a string to an integer.
- *
- * @param _sString The string to cast.
- * @param _iValue Output integer parameter.
- * @return success?
- */
- static bool toInt(const std::string& _sString, int& _iValue);
-
- /**
- * Cast a string to a float32.
- *
- * @param _sString The string to cast.
- * @param _fValue Output float32 parameter.
- * @return success?
- */
- static bool toFloat32(const std::string& _sString, float32& _fValue);
-
- /**
- * Convert a string to lower case.
- *
- * @param _sString The string to convert.
- */
- static void toLowerCase(std::string& _sString);
-
- /**
- * Convert a string to upper case.
- *
- * @param _sString The string to convert.
- */
- static void toUpperCase(std::string& _sString);
+ bad_cast() { }
};
-/**
- * This class contains some usefull static utility functions for std strings.
- */
-class FileSystemUtil {
-public:
- /**
- * Get the extensions of a filename. Always in lower case.
- *
- * @param _sFilename file to get extensions from.
- * @return Extension (lower case). Empty string if filename is a directory or not a valid file format.
- */
- static std::string getExtension(std::string& _sFilename);
+//< Parse string as int.
+//< Throw exception on failure.
+_AstraExport int stringToInt(const std::string& s);
+
+//< Parse string as float.
+//< Throw exception on failure.
+_AstraExport float stringToFloat(const std::string& s);
+
+//< Parse string as double.
+//< Throw exception on failure.
+_AstraExport double stringToDouble(const std::string& s);
+
+template<typename T>
+_AstraExport T stringTo(const std::string& s);
+
+//< Parse comma/semicolon-separated string as float vector.
+//< Throw exception on failure.
+_AstraExport std::vector<float> stringToFloatVector(const std::string& s);
+
+//< Parse comma/semicolon-separated string as double vector.
+//< Throw exception on failure.
+_AstraExport std::vector<double> stringToDoubleVector(const std::string& s);
+
+template<typename T>
+_AstraExport std::vector<T> stringToVector(const std::string& s);
+
+
+
+//< Generate string from float.
+_AstraExport std::string floatToString(float f);
+
+//< Generate string from double.
+_AstraExport std::string doubleToString(double f);
+
+template<typename T>
+_AstraExport std::string toString(T f);
+
+}
-};
template<typename T, typename S>
diff --git a/include/astra/XMLNode.h b/include/astra/XMLNode.h
index 4d29d5c..7d1edf5 100644
--- a/include/astra/XMLNode.h
+++ b/include/astra/XMLNode.h
@@ -101,6 +101,12 @@ public:
*/
string getContent() const;
+ /** Get the content of the XML node as an integer
+ *
+ * @return node content
+ */
+ int getContentInt() const;
+
/** Get the content of the XML node as a numerical.
*
* @return node content
@@ -152,6 +158,7 @@ public:
*/
float32 getAttributeNumerical(string _sName, float32 _fDefaultValue = 0) const;
double getAttributeNumericalDouble(string _sName, double _fDefaultValue = 0) const;
+ int getAttributeInt(string _sName, int _fDefaultValue = 0) const;
/** Get the value of a boolean attribute.
*
@@ -186,6 +193,7 @@ public:
* @return option value, _fDefaultValue if the option doesn't exist
*/
float32 getOptionNumerical(string _sKey, float32 _fDefaultValue = 0) const;
+ int getOptionInt(string _sKey, int _fDefaultValue = 0) const;
/** Get the value of an option within this XML Node
*