diff options
Diffstat (limited to 'include')
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 {   *		<Option key="UseMinConstraint" value="yes"/>\n   *		<Option key="UseMaxConstraint" value="yes"/>\n   *		<Option key="MaxConstraintValue" value="1024"/>\n + *		<Option key="Relaxation" value="1"/>\n   *		</Algorithm>   * }   * @@ -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  	 * | 
