From 167ec3f4e1cbe4eb856474cb515291261955b053 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Fri, 22 May 2015 14:56:28 +0200
Subject: Add supersampling options to Cuda Projectors

---
 include/astra/CudaProjector2D.h | 6 ++++++
 include/astra/CudaProjector3D.h | 5 ++++-
 src/CudaProjector2D.cpp         | 8 ++++++++
 src/CudaProjector3D.cpp         | 8 ++++++++
 4 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/include/astra/CudaProjector2D.h b/include/astra/CudaProjector2D.h
index a571851..ecfca41 100644
--- a/include/astra/CudaProjector2D.h
+++ b/include/astra/CudaProjector2D.h
@@ -121,9 +121,15 @@ public:
 	virtual std::string description() const;
 
 
+	Cuda2DProjectionKernel getProjectionKernel() const { return m_projectionKernel; }
+	int getVoxelSuperSampling() const { return m_iVoxelSuperSampling; }
+	int getDetectorSuperSampling() const { return m_iDetectorSuperSampling; }
+
 protected:
 
 	Cuda2DProjectionKernel m_projectionKernel;
+	int m_iVoxelSuperSampling;
+	int m_iDetectorSuperSampling;
 };
 
 //----------------------------------------------------------------------------------------
diff --git a/include/astra/CudaProjector3D.h b/include/astra/CudaProjector3D.h
index a181531..1d570fe 100644
--- a/include/astra/CudaProjector3D.h
+++ b/include/astra/CudaProjector3D.h
@@ -115,11 +115,14 @@ public:
 
 
 	Cuda3DProjectionKernel getProjectionKernel() const { return m_projectionKernel; }
+	int getVoxelSuperSampling() const { return m_iVoxelSuperSampling; }
+	int getDetectorSuperSampling() const { return m_iDetectorSuperSampling; }
 
 protected:
 
 	Cuda3DProjectionKernel m_projectionKernel;
-
+	int m_iVoxelSuperSampling;
+	int m_iDetectorSuperSampling;
 
 };
 
diff --git a/src/CudaProjector2D.cpp b/src/CudaProjector2D.cpp
index fa024c8..a26e32d 100644
--- a/src/CudaProjector2D.cpp
+++ b/src/CudaProjector2D.cpp
@@ -59,6 +59,8 @@ void CCudaProjector2D::_clear()
 	m_bIsInitialized = false;
 
 	m_projectionKernel = ker2d_default;
+	m_iVoxelSuperSampling = 1;
+	m_iDetectorSuperSampling = 1;
 }
 
 //----------------------------------------------------------------------------------------
@@ -117,6 +119,12 @@ bool CCudaProjector2D::initialize(const Config& _cfg)
 	}
 	CC.markNodeParsed("ProjectionKernel");
 
+	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1);
+	CC.markOptionParsed("VoxelSuperSampling");
+ 
+	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
+	CC.markOptionParsed("DetectorSuperSampling");
+
 	m_bIsInitialized = _check();
 	return m_bIsInitialized;
 }
diff --git a/src/CudaProjector3D.cpp b/src/CudaProjector3D.cpp
index 41529a5..d2fd74c 100644
--- a/src/CudaProjector3D.cpp
+++ b/src/CudaProjector3D.cpp
@@ -62,6 +62,8 @@ void CCudaProjector3D::_clear()
 	m_bIsInitialized = false;
 
 	m_projectionKernel = ker3d_default;
+	m_iVoxelSuperSampling = 1;
+	m_iDetectorSuperSampling = 1;
 }
 
 //----------------------------------------------------------------------------------------
@@ -120,6 +122,12 @@ bool CCudaProjector3D::initialize(const Config& _cfg)
 	}
 	CC.markNodeParsed("ProjectionKernel");
 
+	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1);
+	CC.markOptionParsed("VoxelSuperSampling");
+ 
+	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
+	CC.markOptionParsed("DetectorSuperSampling");
+
 	m_bIsInitialized = _check();
 	return m_bIsInitialized;
 }
-- 
cgit v1.2.3


From 0985154228a63db25e9a0a0165994221d9b97a91 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Tue, 26 May 2015 15:36:42 +0200
Subject: Use supersampling options from CudaProjector3D

---
 src/CudaBackProjectionAlgorithm3D.cpp    | 14 +++++++++++++-
 src/CudaCglsAlgorithm3D.cpp              | 22 +++++++++++++++++++---
 src/CudaFDKAlgorithm3D.cpp               | 13 ++++++++++++-
 src/CudaForwardProjectionAlgorithm3D.cpp | 16 +++++++++++++---
 src/CudaSirtAlgorithm3D.cpp              | 23 ++++++++++++++++++++---
 src/ReconstructionAlgorithm3D.cpp        | 18 +++++++++++-------
 6 files changed, 88 insertions(+), 18 deletions(-)

diff --git a/src/CudaBackProjectionAlgorithm3D.cpp b/src/CudaBackProjectionAlgorithm3D.cpp
index fbb8f28..e8e0433 100644
--- a/src/CudaBackProjectionAlgorithm3D.cpp
+++ b/src/CudaBackProjectionAlgorithm3D.cpp
@@ -32,6 +32,7 @@ $Id$
 
 #include "astra/AstraObjectManager.h"
 
+#include "astra/CudaProjector3D.h"
 #include "astra/ConeProjectionGeometry3D.h"
 #include "astra/ParallelProjectionGeometry3D.h"
 #include "astra/ParallelVecProjectionGeometry3D.h"
@@ -102,9 +103,20 @@ bool CCudaBackProjectionAlgorithm3D::initialize(const Config& _cfg)
 		return false;
 	}
 
+	CCudaProjector3D* pCudaProjector = 0;
+	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		// TODO: Report
+	}
+
 	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
 	CC.markOptionParsed("GPUindex");
-	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1);
+
+
+	m_iVoxelSuperSampling = 1;
+	if (pCudaProjector)
+		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);
 	CC.markOptionParsed("VoxelSuperSampling");
 
 	CFloat32ProjectionData3DMemory* pSinoMem = dynamic_cast<CFloat32ProjectionData3DMemory*>(m_pSinogram);
diff --git a/src/CudaCglsAlgorithm3D.cpp b/src/CudaCglsAlgorithm3D.cpp
index 3457b81..f527dc5 100644
--- a/src/CudaCglsAlgorithm3D.cpp
+++ b/src/CudaCglsAlgorithm3D.cpp
@@ -32,6 +32,7 @@ $Id$
 
 #include "astra/AstraObjectManager.h"
 
+#include "astra/CudaProjector3D.h"
 #include "astra/ConeProjectionGeometry3D.h"
 #include "astra/ParallelVecProjectionGeometry3D.h"
 #include "astra/ConeVecProjectionGeometry3D.h"
@@ -106,12 +107,27 @@ bool CCudaCglsAlgorithm3D::initialize(const Config& _cfg)
 		return false;
 	}
 
+	CCudaProjector3D* pCudaProjector = 0;
+	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		// TODO: Report
+	}
+
 	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
 	CC.markOptionParsed("GPUindex");
-	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
-	CC.markOptionParsed("DetectorSuperSampling");
-	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1);
+
+	m_iVoxelSuperSampling = 1;
+	m_iDetectorSuperSampling = 1;
+	if (pCudaProjector) {
+		// New interface
+		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+	}
+	// Deprecated options
+	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);
+	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
 	CC.markOptionParsed("VoxelSuperSampling");
+	CC.markOptionParsed("DetectorSuperSampling");
 
 	m_pCgls = new AstraCGLS3d();
 
diff --git a/src/CudaFDKAlgorithm3D.cpp b/src/CudaFDKAlgorithm3D.cpp
index 467e641..667d926 100644
--- a/src/CudaFDKAlgorithm3D.cpp
+++ b/src/CudaFDKAlgorithm3D.cpp
@@ -32,6 +32,7 @@ $Id$
 
 #include "astra/AstraObjectManager.h"
 
+#include "astra/CudaProjector3D.h"
 #include "astra/ConeProjectionGeometry3D.h"
 
 #include "../cuda/3d/astra3d.h"
@@ -100,9 +101,19 @@ bool CCudaFDKAlgorithm3D::initialize(const Config& _cfg)
 		return false;
 	}
 
+	CCudaProjector3D* pCudaProjector = 0;
+	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		// TODO: Report
+	}
+
 	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
 	CC.markOptionParsed("GPUindex");
-	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1);
+
+	m_iVoxelSuperSampling = 1;
+	if (pCudaProjector)
+		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);
 	CC.markOptionParsed("VoxelSuperSampling");
 
 	m_bShortScan = _cfg.self.getOptionBool("ShortScan", false);
diff --git a/src/CudaForwardProjectionAlgorithm3D.cpp b/src/CudaForwardProjectionAlgorithm3D.cpp
index e29b5a9..46dab12 100644
--- a/src/CudaForwardProjectionAlgorithm3D.cpp
+++ b/src/CudaForwardProjectionAlgorithm3D.cpp
@@ -97,18 +97,28 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg)
 
 	// optional: projector
 	node = _cfg.self.getSingleNode("ProjectorId");
+	CCudaProjector3D* pCudaProjector = 0;
+	m_pProjector = 0;
 	if (node) {
 		id = boost::lexical_cast<int>(node.getContent());
 		m_pProjector = CProjector3DManager::getSingleton().get(id);
-	} else {
-		m_pProjector = 0; // TODO: or manually construct default projector?
+		pCudaProjector = dynamic_cast<CCudaProjector3D*>(CProjector3DManager::getSingleton().get(id));
+		m_pProjector = pCudaProjector;
+		if (!pCudaProjector) {
+			// TODO: Report
+		}
 	}
 	CC.markNodeParsed("ProjectorId");
 
 	// GPU number
 	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
 	CC.markOptionParsed("GPUindex");
-	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
+
+
+	m_iDetectorSuperSampling = 1;
+	if (pCudaProjector)
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
 	CC.markOptionParsed("DetectorSuperSampling");
 
 	// success
diff --git a/src/CudaSirtAlgorithm3D.cpp b/src/CudaSirtAlgorithm3D.cpp
index 5ad131b..abbb9fd 100644
--- a/src/CudaSirtAlgorithm3D.cpp
+++ b/src/CudaSirtAlgorithm3D.cpp
@@ -36,6 +36,7 @@ $Id$
 #include "astra/ParallelProjectionGeometry3D.h"
 #include "astra/ParallelVecProjectionGeometry3D.h"
 #include "astra/ConeVecProjectionGeometry3D.h"
+#include "astra/CudaProjector3D.h"
 
 #include "../cuda/3d/astra3d.h"
 
@@ -107,12 +108,28 @@ bool CCudaSirtAlgorithm3D::initialize(const Config& _cfg)
 		return false;
 	}
 
+	CCudaProjector3D* pCudaProjector = 0;
+	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		// TODO: Report
+	}
+
 	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
 	CC.markOptionParsed("GPUindex");
-	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
-	CC.markOptionParsed("DetectorSuperSampling");
-	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", 1);
+
+
+	m_iVoxelSuperSampling = 1;
+	m_iDetectorSuperSampling = 1;
+	if (pCudaProjector) {
+		// New interface
+		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+	}
+	// Deprecated options
+	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);
+	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
 	CC.markOptionParsed("VoxelSuperSampling");
+	CC.markOptionParsed("DetectorSuperSampling");
 
 	m_pSirt = new AstraSIRT3d();
 
diff --git a/src/ReconstructionAlgorithm3D.cpp b/src/ReconstructionAlgorithm3D.cpp
index 86b8ab2..f975ace 100644
--- a/src/ReconstructionAlgorithm3D.cpp
+++ b/src/ReconstructionAlgorithm3D.cpp
@@ -106,14 +106,18 @@ bool CReconstructionAlgorithm3D::initialize(const Config& _cfg)
 
 	XMLNode node;
 	int id;
-#if 0
+
 	// projector
-	node = _cfg.self->getSingleNode("ProjectorId");
-	ASTRA_CONFIG_CHECK(node, "Reconstruction3D", "No ProjectorId tag specified.");
-	id = boost::lexical_cast<int>(node->getContent());
-	m_pProjector = CProjector3DManager::getSingleton().get(id);
-	ASTRA_DELETE(node);
-#endif
+	node = _cfg.self.getSingleNode("ProjectorId");
+	m_pProjector = 0;
+	if (node) {
+		id = boost::lexical_cast<int>(node.getContent());
+		m_pProjector = CProjector3DManager::getSingleton().get(id);
+		if (!m_pProjector) {
+			// TODO: Report
+		}
+	}
+	CC.markNodeParsed("ProjectorId");
 
 	// sinogram data
 	node = _cfg.self.getSingleNode("ProjectionDataId");
-- 
cgit v1.2.3


From ef47dca509c1c26c5037b9b9024a6a84a3b7fe0b Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Sat, 20 Jun 2015 00:31:15 +0200
Subject: Fix wrong module name in documentation

---
 python/docSRC/operator.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/python/docSRC/operator.rst b/python/docSRC/operator.rst
index f5369fa..65a5a99 100644
--- a/python/docSRC/operator.rst
+++ b/python/docSRC/operator.rst
@@ -1,7 +1,7 @@
 OpTomo class: the :mod:`operator` module
 ==============================================
 
-.. automodule:: astra.operator
+.. automodule:: astra.optomo
     :members:
     :undoc-members:
     :show-inheritance:
-- 
cgit v1.2.3


From ba3629c6c1bc1d03ccdc6ef2aeae6872ea59559f Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Sat, 20 Jun 2015 00:33:23 +0200
Subject: Fix matlab compilation without CUDA

---
 matlab/mex/astra_mex_c.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp
index 4a331f5..a9b9654 100644
--- a/matlab/mex/astra_mex_c.cpp
+++ b/matlab/mex/astra_mex_c.cpp
@@ -36,9 +36,9 @@ $Id$
 #include "mexInitFunctions.h"
 
 #include "astra/Globals.h"
-
+#ifdef ASTRA_CUDA
 #include "../cuda/2d/darthelper.h"
-
+#endif
 using namespace std;
 using namespace astra;
 
-- 
cgit v1.2.3


From f6b6a2f84806a89fe6bacc583e13cb14629fb5dc Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Sat, 20 Jun 2015 00:35:16 +0200
Subject: Actually use the rec_type argument in
 astra_create_reconstruction_cuda

---
 matlab/tools/astra_create_reconstruction_cuda.m | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/matlab/tools/astra_create_reconstruction_cuda.m b/matlab/tools/astra_create_reconstruction_cuda.m
index 7d9e1dd..7d0421c 100644
--- a/matlab/tools/astra_create_reconstruction_cuda.m
+++ b/matlab/tools/astra_create_reconstruction_cuda.m
@@ -45,7 +45,7 @@ if strcmp(rec_type,'')
 end
 
 % configure
-cfg = astra_struct('SIRT_CUDA');
+cfg = astra_struct(rec_type);
 cfg.ProjectionGeometry = proj_geom;
 cfg.ReconstructionGeometry = vol_geom;
 cfg.ProjectionDataId = sinogram_id;
-- 
cgit v1.2.3


From d931a89a97c599d5530f7ce0f83fc0d513842023 Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Sat, 20 Jun 2015 00:41:45 +0200
Subject: Add a .gitignore to ignore build files

---
 .gitignore | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 .gitignore

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ddfb628
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,23 @@
+python/build/*
+python/finalbuild/*
+python/astra/*.pyc
+python/astra/*.cpp
+python/astra/*.c
+python/astra/config.pxi
+
+build/linux/.libs/*
+build/linux/Makefile
+build/linux/aclocal.m4
+build/linux/autom4te.cache/*
+build/linux/config.guess
+build/linux/config.log
+build/linux/config.status
+build/linux/config.sub
+build/linux/configure
+build/linux/cuda/*
+build/linux/install-sh
+build/linux/libastra.la
+build/linux/libtool
+build/linux/ltmain.sh
+build/linux/src/*
+build/linux/matlab/*
-- 
cgit v1.2.3


From 26198f7e1fbed9d294fc2856f796f408c85b66f3 Mon Sep 17 00:00:00 2001
From: Valerii Sokolov <valerii.sokolov@uantwerpen.be>
Date: Tue, 9 Jun 2015 11:26:42 +0200
Subject: Don't take address of temporary.

---
 python/astra/utils.pyx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx
index ddb37aa..a8e9e4e 100644
--- a/python/astra/utils.pyx
+++ b/python/astra/utils.pyx
@@ -95,7 +95,8 @@ cdef void readDict(XMLNode root, _dc):
             if val.size == 0:
                 break
             listbase = root.addChildNode(item)
-            data = <double*>np.PyArray_DATA(np.ascontiguousarray(val,dtype=np.float64)) 
+            contig_data = np.ascontiguousarray(val,dtype=np.float64)
+            data = <double*>np.PyArray_DATA(contig_data) 
             if val.ndim == 2:
                 listbase.setContent(data, val.shape[1], val.shape[0], False)
             elif val.ndim == 1:
@@ -129,7 +130,8 @@ cdef void readOptions(XMLNode node, dc):
                 break
             listbase = node.addChildNode(six.b('Option'))
             listbase.addAttribute(< string > six.b('key'), < string > item)
-            data = <double*>np.PyArray_DATA(np.ascontiguousarray(val,dtype=np.float64)) 
+            contig_data = np.ascontiguousarray(val,dtype=np.float64)
+            data = <double*>np.PyArray_DATA(contig_data)
             if val.ndim == 2:
                 listbase.setContent(data, val.shape[1], val.shape[0], False)
             elif val.ndim == 1:
-- 
cgit v1.2.3


From a9ea08c4a11592378b320cac45be8eede8addd6f Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Mon, 22 Jun 2015 17:54:23 +0200
Subject: Additional module name fix in documentation

---
 python/docSRC/operator.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/python/docSRC/operator.rst b/python/docSRC/operator.rst
index 65a5a99..fe500ba 100644
--- a/python/docSRC/operator.rst
+++ b/python/docSRC/operator.rst
@@ -1,4 +1,4 @@
-OpTomo class: the :mod:`operator` module
+OpTomo class: the :mod:`optomo` module
 ==============================================
 
 .. automodule:: astra.optomo
-- 
cgit v1.2.3


From 8ad46dc9cb28067047838e06770707cf86ef6e56 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Tue, 23 Jun 2015 11:13:08 +0200
Subject: Add some common temporary file patterns to .gitignore.

Also add leading slashes to full paths for consistency.
---
 .gitignore | 52 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/.gitignore b/.gitignore
index ddfb628..ec0eafb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,23 +1,31 @@
-python/build/*
-python/finalbuild/*
-python/astra/*.pyc
-python/astra/*.cpp
-python/astra/*.c
-python/astra/config.pxi
+.*.swp
+.*.swo
+*~
+*.orig
+*.rej
+.nfs*
 
-build/linux/.libs/*
-build/linux/Makefile
-build/linux/aclocal.m4
-build/linux/autom4te.cache/*
-build/linux/config.guess
-build/linux/config.log
-build/linux/config.status
-build/linux/config.sub
-build/linux/configure
-build/linux/cuda/*
-build/linux/install-sh
-build/linux/libastra.la
-build/linux/libtool
-build/linux/ltmain.sh
-build/linux/src/*
-build/linux/matlab/*
+/python/build/*
+/python/finalbuild/*
+/python/dist/*
+/python/astra/*.pyc
+/python/astra/*.cpp
+/python/astra/*.c
+/python/astra/config.pxi
+
+/build/linux/.libs/*
+/build/linux/Makefile
+/build/linux/aclocal.m4
+/build/linux/autom4te.cache/*
+/build/linux/config.guess
+/build/linux/config.log
+/build/linux/config.status
+/build/linux/config.sub
+/build/linux/configure
+/build/linux/cuda/*
+/build/linux/install-sh
+/build/linux/libastra.la
+/build/linux/libtool
+/build/linux/ltmain.sh
+/build/linux/src/*
+/build/linux/matlab/*
-- 
cgit v1.2.3


From e622f453c6ab9de6277611e01cac415e297553f7 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Thu, 4 Jun 2015 17:23:54 +0200
Subject: Use supersampling options from CudaProjector2D

---
 src/CudaFilteredBackProjectionAlgorithm.cpp | 27 ++++++++++++++++--
 src/CudaForwardProjectionAlgorithm.cpp      | 38 +++++++++++++++----------
 src/CudaReconstructionAlgorithm2D.cpp       | 44 +++++++++++++++++------------
 3 files changed, 73 insertions(+), 36 deletions(-)

diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp
index 5d6c166..aac96d6 100644
--- a/src/CudaFilteredBackProjectionAlgorithm.cpp
+++ b/src/CudaFilteredBackProjectionAlgorithm.cpp
@@ -32,6 +32,7 @@ $Id$
 #include <cstring>
 
 #include "astra/AstraObjectManager.h"
+#include "astra/CudaProjector2D.h"
 #include "../cuda/2d/astra.h"
 
 #include "astra/Logging.h"
@@ -77,8 +78,22 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)
 		clear();
 	}
 
+	// Projector
+	XMLNode node = _cfg.self.getSingleNode("ProjectorId");
+	CCudaProjector2D* pCudaProjector = 0;
+	if (node) {
+		int id = boost::lexical_cast<int>(node.getContent());
+		CProjector2D *projector = CProjector2DManager::getSingleton().get(id);
+		pCudaProjector = dynamic_cast<CCudaProjector2D*>(projector);
+		if (!pCudaProjector) {
+			ASTRA_WARN("non-CUDA Projector2D passed");
+		}
+	}
+	CC.markNodeParsed("ProjectorId");
+
+
 	// sinogram data
-	XMLNode node = _cfg.self.getSingleNode("ProjectionDataId");
+	node = _cfg.self.getSingleNode("ProjectionDataId");
 	ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ProjectionDataId tag specified.");
 	int id = boost::lexical_cast<int>(node.getContent());
 	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
@@ -152,10 +167,16 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)
 	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
 	CC.markOptionParsed("GPUindex");
 
-	// Pixel supersampling factor
-	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", 1);
+	m_iPixelSuperSampling = 1;
+	if (pCudaProjector) {
+		// New interface
+		m_iPixelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+	}
+	// Deprecated options
+	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", m_iPixelSuperSampling);
 	CC.markOptionParsed("PixelSuperSampling");
 
+
 	// Fan beam short scan mode
 	if (m_pSinogram && dynamic_cast<CFanFlatProjectionGeometry2D*>(m_pSinogram->getGeometry())) {
 		m_bShortScan = (int)_cfg.self.getOptionBool("ShortScan", false);
diff --git a/src/CudaForwardProjectionAlgorithm.cpp b/src/CudaForwardProjectionAlgorithm.cpp
index 0f97d59..b382f2e 100644
--- a/src/CudaForwardProjectionAlgorithm.cpp
+++ b/src/CudaForwardProjectionAlgorithm.cpp
@@ -71,9 +71,24 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg)
 {
 	ASTRA_ASSERT(_cfg.self);
 	ConfigStackCheck<CAlgorithm> CC("CudaForwardProjectionAlgorithm", this, _cfg);
+
+	// Projector
+	XMLNode node = _cfg.self.getSingleNode("ProjectorId");
+	CCudaProjector2D* pCudaProjector = 0;
+	if (node) {
+		int id = boost::lexical_cast<int>(node.getContent());
+		CProjector2D *projector = CProjector2DManager::getSingleton().get(id);
+		pCudaProjector = dynamic_cast<CCudaProjector2D*>(projector);
+		if (!pCudaProjector) {
+			ASTRA_WARN("non-CUDA Projector2D passed to FP_CUDA");
+		}
+	}
+	CC.markNodeParsed("ProjectorId");
+
+
 	
 	// sinogram data
-	XMLNode node = _cfg.self.getSingleNode("ProjectionDataId");
+	node = _cfg.self.getSingleNode("ProjectionDataId");
 	ASTRA_CONFIG_CHECK(node, "FP_CUDA", "No ProjectionDataId tag specified.");
 	int id = boost::lexical_cast<int>(node.getContent());
 	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
@@ -94,21 +109,14 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg)
 		CC.markOptionParsed("GPUIndex");
 
 	// Detector supersampling factor
-	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
-	CC.markOptionParsed("DetectorSuperSampling");
-
-
-	// This isn't used yet, but passing it is not something to warn about
-	node = _cfg.self.getSingleNode("ProjectorId");
-	if (node) {
-		id = boost::lexical_cast<int>(node.getContent());
-		CProjector2D *projector = CProjector2DManager::getSingleton().get(id);
-		if (!dynamic_cast<CCudaProjector2D*>(projector)) {
-			ASTRA_WARN("non-CUDA Projector2D passed to FP_CUDA");
-		}
+	m_iDetectorSuperSampling = 1;
+	if (pCudaProjector) {
+		// New interface
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
 	}
-	CC.markNodeParsed("ProjectorId");
-	
+	// Deprecated option
+	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
+	CC.markOptionParsed("DetectorSuperSampling");
 
 
 	// return success
diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp
index db99d42..71b6637 100644
--- a/src/CudaReconstructionAlgorithm2D.cpp
+++ b/src/CudaReconstructionAlgorithm2D.cpp
@@ -95,8 +95,22 @@ bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg)
 		clear();
 	}
 
+	// Projector
+	XMLNode node = _cfg.self.getSingleNode("ProjectorId");
+	CCudaProjector2D* pCudaProjector = 0;
+	if (node) {
+		int id = boost::lexical_cast<int>(node.getContent());
+		CProjector2D *projector = CProjector2DManager::getSingleton().get(id);
+		pCudaProjector = dynamic_cast<CCudaProjector2D*>(projector);
+		if (!pCudaProjector) {
+			ASTRA_WARN("non-CUDA Projector2D passed");
+		}
+	}
+	CC.markNodeParsed("ProjectorId");
+
+
 	// sinogram data
-	XMLNode node = _cfg.self.getSingleNode("ProjectionDataId");
+	node = _cfg.self.getSingleNode("ProjectionDataId");
 	ASTRA_CONFIG_CHECK(node, "CudaSirt2", "No ProjectionDataId tag specified.");
 	int id = boost::lexical_cast<int>(node.getContent());
 	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
@@ -161,27 +175,21 @@ bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg)
 	if (!_cfg.self.hasOption("GPUindex"))
 		CC.markOptionParsed("GPUIndex");
 
-	// Detector supersampling factor
-	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
+	// Supersampling factors
+	m_iDetectorSuperSampling = 1;
+	m_iPixelSuperSampling = 1;
+	if (pCudaProjector) {
+		// New interface
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+		m_iPixelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+	}
+	// Deprecated options
+	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
+	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", m_iPixelSuperSampling);
 	CC.markOptionParsed("DetectorSuperSampling");
-
-	// Pixel supersampling factor
-	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", 1);
 	CC.markOptionParsed("PixelSuperSampling");
 
 
-	// This isn't used yet, but passing it is not something to warn about
-	node = _cfg.self.getSingleNode("ProjectorId");
-	if (node) {
-		id = boost::lexical_cast<int>(node.getContent());
-		CProjector2D *projector = CProjector2DManager::getSingleton().get(id);
-		if (!dynamic_cast<CCudaProjector2D*>(projector)) {
-			ASTRA_WARN("non-CUDA Projector2D passed");
-		}
-	}
-	CC.markNodeParsed("ProjectorId");
-
-
 	return _check();
 }
 
-- 
cgit v1.2.3


From 233331b4a192c0149f58af1d4c89526260cd3a58 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Tue, 23 Jun 2015 12:18:47 +0200
Subject: Update sample

---
 samples/matlab/s010_supersampling.m | 28 ++++++++++------------------
 1 file changed, 10 insertions(+), 18 deletions(-)

diff --git a/samples/matlab/s010_supersampling.m b/samples/matlab/s010_supersampling.m
index 80f6f56..148f6ad 100644
--- a/samples/matlab/s010_supersampling.m
+++ b/samples/matlab/s010_supersampling.m
@@ -12,23 +12,15 @@ vol_geom = astra_create_vol_geom(256, 256);
 proj_geom = astra_create_proj_geom('parallel', 3.0, 128, linspace2(0,pi,180));
 P = phantom(256);
 
-% Because the astra_create_sino_gpu wrapper does not have support for
-% all possible algorithm options, we manually create a sinogram
-phantom_id = astra_mex_data2d('create', '-vol', vol_geom, P);
-sinogram_id = astra_mex_data2d('create', '-sino', proj_geom);
-cfg = astra_struct('FP_CUDA');
-cfg.VolumeDataId = phantom_id;
-cfg.ProjectionDataId = sinogram_id;
+% We create a projector set up to use 3 rays per detector element
+cfg_proj = astra_struct('cuda');
+cfg_proj.option.DetectorSuperSampling = 3;
+cfg_proj.ProjectionGeometry = proj_geom;
+cfg_proj.VolumeGeometry = vol_geom;
+proj_id = astra_mex_projector('create', cfg_proj);
 
-% Set up 3 rays per detector element
-cfg.option.DetectorSuperSampling = 3;
 
-alg_id = astra_mex_algorithm('create', cfg);
-astra_mex_algorithm('run', alg_id);
-astra_mex_algorithm('delete', alg_id);
-astra_mex_data2d('delete', phantom_id);
-
-sinogram3 = astra_mex_data2d('get', sinogram_id);
+[sinogram3 sinogram_id] = astra_create_sino(P, proj_id);
 
 figure(1); imshow(P, []);
 figure(2); imshow(sinogram3, []);
@@ -39,14 +31,14 @@ rec_id = astra_mex_data2d('create', '-vol', vol_geom);
 cfg = astra_struct('SIRT_CUDA');
 cfg.ReconstructionDataId = rec_id;
 cfg.ProjectionDataId = sinogram_id;
-% Set up 3 rays per detector element
-cfg.option.DetectorSuperSampling = 3;
+cfg.ProjectorId = proj_id;
+
 
 % There is also an option for supersampling during the backprojection step.
 % This should be used if your detector pixels are smaller than the voxels.
 
 % Set up 2 rays per image pixel dimension, for 4 rays total per image pixel.
-% cfg.option.PixelSuperSampling = 2;
+% cfg_proj.option.PixelSuperSampling = 2;
 
 
 alg_id = astra_mex_algorithm('create', cfg);
-- 
cgit v1.2.3


From 63d78fbaafa7d247347f9052db86f575d89260b7 Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Wed, 24 Jun 2015 20:28:46 +0200
Subject: Fix config to struct/dict translation for array options

---
 matlab/mex/mexHelpFunctions.cpp | 6 +++++-
 python/astra/utils.pyx          | 5 ++++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index 87a9672..58e84d2 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -336,7 +336,11 @@ mxArray* XMLNodeToStruct(astra::XMLNode node)
 
 		// option
 		if (subnode.getName() == "Option") {
-			mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getAttribute("value"));
+			if(subnode.hasAttribute("value")){
+				mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getAttribute("value"));
+			}else{
+				mOptions[subnode.getAttribute("key")] = stringToMxArray(subnode.getContent());
+			}
 		}
 
 		// regular content
diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx
index a8e9e4e..260c308 100644
--- a/python/astra/utils.pyx
+++ b/python/astra/utils.pyx
@@ -204,7 +204,10 @@ cdef XMLNode2dict(XMLNode node):
     while it != nodes.end():
         subnode = deref(it)
         if castString(subnode.getName())=="Option":
-            opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getAttribute('value'))
+            if subnode.hasAttribute('value'):
+                opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getAttribute('value'))
+            else:
+                opts[castString(subnode.getAttribute('key'))] = stringToPythonValue(subnode.getContent())
         else:
             dct[castString(subnode.getName())] = stringToPythonValue(subnode.getContent())
         inc(it)
-- 
cgit v1.2.3


From 26713deae284d6bb793b728c7af2db28a7484054 Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Wed, 24 Jun 2015 20:30:52 +0200
Subject: Include ExtraDetectorOffset in returned configuration

---
 src/ParallelProjectionGeometry2D.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp
index 699e141..5f51d08 100644
--- a/src/ParallelProjectionGeometry2D.cpp
+++ b/src/ParallelProjectionGeometry2D.cpp
@@ -180,6 +180,9 @@ Config* CParallelProjectionGeometry2D::getConfiguration() const
 	cfg->self.addChildNode("DetectorCount", getDetectorCount());
 	cfg->self.addChildNode("DetectorWidth", getDetectorWidth());
 	cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+	XMLNode opt = cfg->self.addChildNode("Option");
+	opt.addAttribute("key","ExtraDetectorOffset");
+	opt.setContent(m_pfExtraDetectorOffset, m_iProjectionAngleCount);
 	return cfg;
 }
 //----------------------------------------------------------------------------------------
-- 
cgit v1.2.3


From f1a8bd8d2b62b089a90fef55268e3300581717ed Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Thu, 25 Jun 2015 21:38:46 +0200
Subject: Add extra null check for ExtraDetectorOffset

---
 src/ParallelProjectionGeometry2D.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp
index 5f51d08..7260b83 100644
--- a/src/ParallelProjectionGeometry2D.cpp
+++ b/src/ParallelProjectionGeometry2D.cpp
@@ -180,9 +180,11 @@ Config* CParallelProjectionGeometry2D::getConfiguration() const
 	cfg->self.addChildNode("DetectorCount", getDetectorCount());
 	cfg->self.addChildNode("DetectorWidth", getDetectorWidth());
 	cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
-	XMLNode opt = cfg->self.addChildNode("Option");
-	opt.addAttribute("key","ExtraDetectorOffset");
-	opt.setContent(m_pfExtraDetectorOffset, m_iProjectionAngleCount);
+	if(m_pfExtraDetectorOffset!=NULL){
+		XMLNode opt = cfg->self.addChildNode("Option");
+		opt.addAttribute("key","ExtraDetectorOffset");
+		opt.setContent(m_pfExtraDetectorOffset, m_iProjectionAngleCount);
+	}
 	return cfg;
 }
 //----------------------------------------------------------------------------------------
-- 
cgit v1.2.3


From 9e3472ea9041b8755050427d8bdb8a4701019c55 Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Thu, 25 Jun 2015 21:52:07 +0200
Subject: Fix memory leak in configuration code

---
 matlab/mex/astra_mex_projector3d_c.cpp |  8 ++++++--
 matlab/mex/astra_mex_projector_c.cpp   |  9 ++++++---
 python/astra/projector3d_c.pyx         | 10 ++++++++--
 python/astra/projector_c.pyx           | 10 ++++++++--
 4 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp
index c3b547f..e25802c 100644
--- a/matlab/mex/astra_mex_projector3d_c.cpp
+++ b/matlab/mex/astra_mex_projector3d_c.cpp
@@ -137,7 +137,9 @@ void astra_mex_projector3d_get_projection_geometry(int nlhs, mxArray* plhs[], in
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
 	if (1 <= nlhs) {
-		plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration());
+		Config *cfg = pProjector->getProjectionGeometry()->getConfiguration();
+		plhs[0] = configToStruct(cfg);
+		delete cfg;
 	}
 }
 
@@ -163,7 +165,9 @@ void astra_mex_projector3d_get_volume_geometry(int nlhs, mxArray* plhs[], int nr
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
 	if (1 <= nlhs) {
-		plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration());
+		Config *cfg = pProjector->getVolumeGeometry()->getConfiguration();
+		plhs[0] = configToStruct(cfg);
+		delete cfg;
 	}
 }
 
diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp
index 204ba8e..bf701af 100644
--- a/matlab/mex/astra_mex_projector_c.cpp
+++ b/matlab/mex/astra_mex_projector_c.cpp
@@ -160,7 +160,9 @@ void astra_mex_projector_projection_geometry(int nlhs, mxArray* plhs[], int nrhs
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
 	if (1 <= nlhs) {
-		plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration());
+		Config *cfg =  pProjector->getProjectionGeometry()->getConfiguration();
+		plhs[0] = configToStruct(cfg);
+		delete cfg;
 	}
 }
 
@@ -189,8 +191,9 @@ void astra_mex_projector_volume_geometry(int nlhs, mxArray* plhs[], int nrhs, co
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
 	if (1 <= nlhs) {
-		plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration());
-
+		Config *cfg = pProjector->getVolumeGeometry()->getConfiguration();
+		plhs[0] = configToStruct(cfg);
+		delete cfg;
 	}
 }
 
diff --git a/python/astra/projector3d_c.pyx b/python/astra/projector3d_c.pyx
index 8b978d7..aec9cde 100644
--- a/python/astra/projector3d_c.pyx
+++ b/python/astra/projector3d_c.pyx
@@ -87,12 +87,18 @@ cdef CProjector3D * getObject(i) except NULL:
 
 def projection_geometry(i):
     cdef CProjector3D * proj = getObject(i)
-    return utils.configToDict(proj.getProjectionGeometry().getConfiguration())
+    cdef Config * cfg = proj.getProjectionGeometry().getConfiguration()
+    dct = utils.configToDict(cfg)
+    del cfg
+    return dct
 
 
 def volume_geometry(i):
     cdef CProjector3D * proj = getObject(i)
-    return utils.configToDict(proj.getVolumeGeometry().getConfiguration())
+    cdef Config * cfg = proj.getVolumeGeometry().getConfiguration()
+    dct = utils.configToDict(cfg)
+    del cfg
+    return dct
 
 
 def weights_single_ray(i, projection_index, detector_index):
diff --git a/python/astra/projector_c.pyx b/python/astra/projector_c.pyx
index 9aa868e..77c64a4 100644
--- a/python/astra/projector_c.pyx
+++ b/python/astra/projector_c.pyx
@@ -91,12 +91,18 @@ cdef CProjector2D * getObject(i) except NULL:
 
 def projection_geometry(i):
     cdef CProjector2D * proj = getObject(i)
-    return utils.configToDict(proj.getProjectionGeometry().getConfiguration())
+    cdef Config * cfg = proj.getProjectionGeometry().getConfiguration()
+    dct = utils.configToDict(cfg)
+    del cfg
+    return dct
 
 
 def volume_geometry(i):
     cdef CProjector2D * proj = getObject(i)
-    return utils.configToDict(proj.getVolumeGeometry().getConfiguration())
+    cdef Config * cfg = proj.getVolumeGeometry().getConfiguration()
+    dct = utils.configToDict(cfg)
+    del cfg
+    return dct
 
 
 def weights_single_ray(i, projection_index, detector_index):
-- 
cgit v1.2.3


From 4d39c35d6c9124c26de64c9d227a25f612903a2a Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Fri, 17 Jul 2015 13:44:59 +0200
Subject: Fix formatting when passing strings to log from high-level code

---
 matlab/mex/astra_mex_log_c.cpp  | 8 ++++----
 matlab/mex/mexInitFunctions.cpp | 2 +-
 python/astra/log_c.pyx          | 8 ++++----
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/matlab/mex/astra_mex_log_c.cpp b/matlab/mex/astra_mex_log_c.cpp
index ea4621e..905612c 100644
--- a/matlab/mex/astra_mex_log_c.cpp
+++ b/matlab/mex/astra_mex_log_c.cpp
@@ -55,7 +55,7 @@ void astra_mex_log_debug(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prh
 	string filename = mexToString(prhs[1]);
 	int linenumber = (int)mxGetScalar(prhs[2]);
 	string message = mexToString(prhs[3]);
-	astra::CLogger::debug(filename.c_str(),linenumber,message.c_str());
+	astra::CLogger::debug(filename.c_str(),linenumber,"%s",message.c_str());
 }
 
 //-----------------------------------------------------------------------------------------
@@ -75,7 +75,7 @@ void astra_mex_log_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs
 	string filename = mexToString(prhs[1]);
 	int linenumber = (int)mxGetScalar(prhs[2]);
 	string message = mexToString(prhs[3]);
-	astra::CLogger::info(filename.c_str(),linenumber,message.c_str());
+	astra::CLogger::info(filename.c_str(),linenumber,"%s",message.c_str());
 }
 
 //-----------------------------------------------------------------------------------------
@@ -95,7 +95,7 @@ void astra_mex_log_warn(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs
 	string filename = mexToString(prhs[1]);
 	int linenumber = (int)mxGetScalar(prhs[2]);
 	string message = mexToString(prhs[3]);
-	astra::CLogger::warn(filename.c_str(),linenumber,message.c_str());
+	astra::CLogger::warn(filename.c_str(),linenumber,"%s",message.c_str());
 }
 
 //-----------------------------------------------------------------------------------------
@@ -115,7 +115,7 @@ void astra_mex_log_error(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prh
 	string filename = mexToString(prhs[1]);
 	int linenumber = (int)mxGetScalar(prhs[2]);
 	string message = mexToString(prhs[3]);
-	astra::CLogger::error(filename.c_str(),linenumber,message.c_str());
+	astra::CLogger::error(filename.c_str(),linenumber,"%s",message.c_str());
 }
 
 //-----------------------------------------------------------------------------------------
diff --git a/matlab/mex/mexInitFunctions.cpp b/matlab/mex/mexInitFunctions.cpp
index d8a50d7..89a31a1 100644
--- a/matlab/mex/mexInitFunctions.cpp
+++ b/matlab/mex/mexInitFunctions.cpp
@@ -8,7 +8,7 @@ bool mexIsInitialized=false;
  *
  */
 void logCallBack(const char *msg, size_t len){
-    mexPrintf(msg);
+    mexPrintf("%s",msg);
 }
 
 /**
diff --git a/python/astra/log_c.pyx b/python/astra/log_c.pyx
index f16329f..55c63e6 100644
--- a/python/astra/log_c.pyx
+++ b/python/astra/log_c.pyx
@@ -53,19 +53,19 @@ cdef extern from "astra/Logging.h" namespace "astra::CLogger":
 
 def log_debug(sfile, sline, message):
     cstr = list(map(six.b,(sfile,message)))
-    debug(cstr[0],sline,cstr[1])
+    debug(cstr[0],sline,"%s",<char*>cstr[1])
 
 def log_info(sfile, sline, message):
     cstr = list(map(six.b,(sfile,message)))
-    info(cstr[0],sline,cstr[1])
+    info(cstr[0],sline,"%s",<char*>cstr[1])
 
 def log_warn(sfile, sline, message):
     cstr = list(map(six.b,(sfile,message)))
-    warn(cstr[0],sline,cstr[1])
+    warn(cstr[0],sline,"%s",<char*>cstr[1])
 
 def log_error(sfile, sline, message):
     cstr = list(map(six.b,(sfile,message)))
-    error(cstr[0],sline,cstr[1])
+    error(cstr[0],sline,"%s",<char*>cstr[1])
 
 def log_enable():
     enable()
-- 
cgit v1.2.3


From 43155c03488ca98c24f8f369e5c8699efa20cca3 Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Thu, 30 Jul 2015 15:28:16 +0200
Subject: Fix Python OpTomo for scipy 0.16

scipy 0.16 also uses .T to define a transpose, which conflicts
with the old OpTomo implementation. OpTomo now also defines the
_transpose() method, which .T will call in scipy 0.16.
---
 python/astra/optomo.py | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/python/astra/optomo.py b/python/astra/optomo.py
index 0108674..19b07e3 100644
--- a/python/astra/optomo.py
+++ b/python/astra/optomo.py
@@ -86,7 +86,15 @@ class OpTomo(scipy.sparse.linalg.LinearOperator):
 
         self.proj_id = proj_id
 
-        self.T = OpTomoTranspose(self)
+        self.transposeOpTomo = OpTomoTranspose(self)
+        try:
+            self.T = self.transposeOpTomo
+        except AttributeError:
+            # Scipy >= 0.16 defines self.T using self._transpose()
+            pass
+
+    def _transpose(self):
+        return self.transposeOpTomo
 
     def __checkArray(self, arr, shp):
         if len(arr.shape)==1:
-- 
cgit v1.2.3


From b4bd441549ea71dd6c34a9f2158bbebc39ba4e9e Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Thu, 30 Jul 2015 15:34:10 +0200
Subject: Define a transpose for the OpTomo transpose as well

Allows for chaining .T calls.
---
 python/astra/optomo.py | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/python/astra/optomo.py b/python/astra/optomo.py
index 19b07e3..4a64150 100644
--- a/python/astra/optomo.py
+++ b/python/astra/optomo.py
@@ -197,6 +197,11 @@ class OpTomoTranspose(scipy.sparse.linalg.LinearOperator):
         self.parent = parent
         self.dtype = np.float32
         self.shape = (parent.shape[1], parent.shape[0])
+        try:
+            self.T = self.parent
+        except AttributeError:
+            # Scipy >= 0.16 defines self.T using self._transpose()
+            pass
 
     def _matvec(self, s):
         return self.parent.rmatvec(s)
@@ -204,6 +209,9 @@ class OpTomoTranspose(scipy.sparse.linalg.LinearOperator):
     def rmatvec(self, v):
         return self.parent.matvec(v)
 
+    def _transpose(self):
+        return self.parent
+
     def __mul__(self,s):
         # Catch the case of a backprojection of 2D/3D data
         if isinstance(s, np.ndarray) and s.shape==self.parent.sshape:
-- 
cgit v1.2.3


From ee790c305942675e94ee66bfd24896d1ef61335a Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Mon, 10 Aug 2015 16:22:19 +0200
Subject: Release the gil in algorithm.run

---
 python/astra/PyIncludes.pxd  | 2 +-
 python/astra/algorithm_c.pyx | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/python/astra/PyIncludes.pxd b/python/astra/PyIncludes.pxd
index 909f58f..35dea5f 100644
--- a/python/astra/PyIncludes.pxd
+++ b/python/astra/PyIncludes.pxd
@@ -143,7 +143,7 @@ cdef extern from "astra/Float32ProjectionData2D.h" namespace "astra":
 cdef extern from "astra/Algorithm.h" namespace "astra":
 	cdef cppclass CAlgorithm:
 		bool initialize(Config)
-		void run(int)
+		void run(int) nogil
 		bool isInitialized()
 
 cdef extern from "astra/ReconstructionAlgorithm2D.h" namespace "astra":
diff --git a/python/astra/algorithm_c.pyx b/python/astra/algorithm_c.pyx
index 966d3d7..3231c1f 100644
--- a/python/astra/algorithm_c.pyx
+++ b/python/astra/algorithm_c.pyx
@@ -73,7 +73,9 @@ cdef CAlgorithm * getAlg(i) except NULL:
 
 def run(i, iterations=0):
     cdef CAlgorithm * alg = getAlg(i)
-    alg.run(iterations)
+    cdef int its = iterations
+    with nogil:
+        alg.run(its)
 
 
 def get_res_norm(i):
-- 
cgit v1.2.3


From 026aa46c5db24ddd687cec0fa6e056a2ee3790c5 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Wed, 12 Aug 2015 15:45:12 +0200
Subject: Fix algorithm object leak in astra_create_fbp_reconstruction.m

---
 matlab/tools/astra_create_fbp_reconstruction.m | 1 +
 1 file changed, 1 insertion(+)

diff --git a/matlab/tools/astra_create_fbp_reconstruction.m b/matlab/tools/astra_create_fbp_reconstruction.m
index 5540f27..a2561b7 100644
--- a/matlab/tools/astra_create_fbp_reconstruction.m
+++ b/matlab/tools/astra_create_fbp_reconstruction.m
@@ -19,6 +19,7 @@ cfg.ProjectorId = proj_id;
 cfg.Options.GPUindex = 0;
 alg_id = astra_mex_algorithm('create', cfg);
 astra_mex_algorithm('run', alg_id);
+astra_mex_algorithm('delete', alg_id);
 
 if numel(sinogram) ~= 1
 	astra_mex_data2d('delete', sinogram_id);
-- 
cgit v1.2.3


From 9cfe943682bd6e02d5fb8493cb9c4c98623cb441 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Fri, 4 Sep 2015 14:16:41 +0200
Subject: Fix algorithm leak in opTomo

---
 matlab/tools/opTomo.m | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/matlab/tools/opTomo.m b/matlab/tools/opTomo.m
index 14128d2..71dfb1e 100644
--- a/matlab/tools/opTomo.m
+++ b/matlab/tools/opTomo.m
@@ -248,6 +248,7 @@ classdef opTomo < opSpot
                 % cleanup
                 astra_mex_data3d('delete', vol_id);
                 astra_mex_data3d('delete', sino_id);
+                astra_mex_algorithm('delete', alg_id);
             else
                 % X is passed as a vector, reshape it into projection data
                 x = reshape(x, op.proj_size);
@@ -272,6 +273,7 @@ classdef opTomo < opSpot
                 % cleanup
                 astra_mex_data3d('delete', vol_id);
                 astra_mex_data3d('delete', sino_id);
+                astra_mex_algorithm('delete', alg_id);
             end 
         end % opTomo_intrnl3D
         
-- 
cgit v1.2.3


From c1713c00c4aeae594913667d868106e8591dd1d1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20H=C3=A4ggstr=C3=B6m?=
 <christian.haggstrom@orexplore.com>
Date: Fri, 31 Oct 2014 14:00:38 +0100
Subject: Silence bogus warning:

Warning: CudaSirtAlgorithm3D: unused configuration options: SinogramMaskId
---
 src/ReconstructionAlgorithm3D.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ReconstructionAlgorithm3D.cpp b/src/ReconstructionAlgorithm3D.cpp
index f975ace..13d4b07 100644
--- a/src/ReconstructionAlgorithm3D.cpp
+++ b/src/ReconstructionAlgorithm3D.cpp
@@ -147,6 +147,7 @@ bool CReconstructionAlgorithm3D::initialize(const Config& _cfg)
 		id = boost::lexical_cast<int>(_cfg.self.getOption("SinogramMaskId"));
 		m_pSinogramMask = dynamic_cast<CFloat32ProjectionData3D*>(CData3DManager::getSingleton().get(id));
 	}
+	CC.markOptionParsed("SinogramMaskId");
 
 	// Constraints - NEW
 	if (_cfg.self.hasOption("MinConstraint")) {
-- 
cgit v1.2.3


From 11717f66b49fbe41faf923f267c6893ce9af46ad Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Thu, 17 Sep 2015 16:54:37 +0200
Subject: Use mxLogical instead of bool.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This should improve compatibility with Octave according to Christian Häggström.
---
 matlab/mex/astra_mex_data2d_c.cpp | 4 ++--
 matlab/mex/astra_mex_matrix_c.cpp | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp
index 909d229..935e476 100644
--- a/matlab/mex/astra_mex_data2d_c.cpp
+++ b/matlab/mex/astra_mex_data2d_c.cpp
@@ -222,7 +222,7 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
 
 			// logical data		
 			if (mxIsLogical(prhs[3])) {
-				bool* pbMatlabData = mxGetLogicals(prhs[3]);
+				mxLogical* pbMatlabData = mxGetLogicals(prhs[3]);
 				int i = 0;
 				int col, row;
 				for (col = 0; col < dims[1]; ++col) {
@@ -322,7 +322,7 @@ void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray*
 
 		// logical data		
 		if (mxIsLogical(prhs[2])) {
-			bool* pbMatlabData = mxGetLogicals(prhs[2]);
+			mxLogical* pbMatlabData = mxGetLogicals(prhs[2]);
 			int i = 0;
 			int col, row;
 			for (col = 0; col < dims[1]; ++col) {
diff --git a/matlab/mex/astra_mex_matrix_c.cpp b/matlab/mex/astra_mex_matrix_c.cpp
index aa31383..e07ddb6 100644
--- a/matlab/mex/astra_mex_matrix_c.cpp
+++ b/matlab/mex/astra_mex_matrix_c.cpp
@@ -112,7 +112,7 @@ static bool matlab_to_astra(const mxArray* _rhs, CSparseMatrix* _pMatrix)
 	mwIndex *colStarts = mxGetJc(_rhs);
 	mwIndex *rowIndices = mxGetIr(_rhs);
 	double *floatValues = 0;
-	bool *boolValues = 0;
+	mxLogical *boolValues = 0;
 	bool bLogical = mxIsLogical(_rhs);
 	if (bLogical)
 		boolValues = mxGetLogicals(_rhs);
-- 
cgit v1.2.3


From 1cc67c1e4d9b6b24c096f52d6f086a3f224ece8a Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Wed, 7 Oct 2015 17:29:20 +0200
Subject: Add astra_mex_direct('FP3D'/'BP3D', ...)

---
 build/linux/Makefile.in           |   3 +-
 matlab/mex/astra_mex_direct_c.cpp | 332 ++++++++++++++++++++++++++++++++++++++
 matlab/tools/astra_mex_direct.m   |  24 +++
 3 files changed, 358 insertions(+), 1 deletion(-)
 create mode 100755 matlab/mex/astra_mex_direct_c.cpp
 create mode 100644 matlab/tools/astra_mex_direct.m

diff --git a/build/linux/Makefile.in b/build/linux/Makefile.in
index 2d862f2..abbebe2 100644
--- a/build/linux/Makefile.in
+++ b/build/linux/Makefile.in
@@ -232,7 +232,8 @@ MATLAB_MEX=\
 	matlab/mex/astra_mex_projector_c.$(MEXSUFFIX) \
 	matlab/mex/astra_mex_projector3d_c.$(MEXSUFFIX) \
 	matlab/mex/astra_mex_log_c.$(MEXSUFFIX) \
-	matlab/mex/astra_mex_data3d_c.$(MEXSUFFIX)
+	matlab/mex/astra_mex_data3d_c.$(MEXSUFFIX) \
+	matlab/mex/astra_mex_direct_c.$(MEXSUFFIX)
 
 
 OBJECT_DIRS = src/ tests/ cuda/2d/ cuda/3d/ matlab/mex/ ./
diff --git a/matlab/mex/astra_mex_direct_c.cpp b/matlab/mex/astra_mex_direct_c.cpp
new file mode 100755
index 0000000..94eb1cd
--- /dev/null
+++ b/matlab/mex/astra_mex_direct_c.cpp
@@ -0,0 +1,332 @@
+/*
+-----------------------------------------------------------------------
+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$
+*/
+
+/** \file astra_mex_direct_c.cpp
+ *
+ *  \brief Utility functions for low-overhead FP and BP calls.
+ */
+#include <mex.h>
+#include "mexHelpFunctions.h"
+#include "mexCopyDataHelpFunctions.h"
+#include "mexDataManagerHelpFunctions.h"
+
+#include <list>
+
+#include "astra/Globals.h"
+
+#include "astra/AstraObjectManager.h"
+
+#include "astra/Float32ProjectionData2D.h"
+#include "astra/Float32VolumeData2D.h"
+#include "astra/CudaProjector3D.h"
+#include "astra/Projector3D.h"
+#include "astra/Float32ProjectionData3DMemory.h"
+#include "astra/Float32VolumeData3DMemory.h"
+
+#include "astra/CudaForwardProjectionAlgorithm3D.h"
+
+#include "astra/CudaBackProjectionAlgorithm3D.h"
+
+using namespace std;
+using namespace astra;
+
+#define USE_MATLAB_UNDOCUMENTED
+
+
+class CFloat32CustomMemory_simple : public astra::CFloat32CustomMemory {
+public:
+	CFloat32CustomMemory_simple(float *ptr) { m_fPtr = ptr; }
+	~CFloat32CustomMemory_simple() { }
+};
+
+#ifdef ASTRA_CUDA
+
+//-----------------------------------------------------------------------------------------
+/**
+ * projection = astra_mex_direct_c('FP3D', projector_id, volume);
+ * Both 'projection' and 'volume' are Matlab arrays.
+ */
+void astra_mex_direct_fp3d(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[])
+{
+	// TODO: Add an optional way of specifying extra options
+
+	if (nrhs < 3) {
+		mexErrMsgTxt("Not enough arguments. Syntax: astra_mex_direct_c('FP3D', projector_id, data)");
+		return;
+	}
+
+	int iPid = (int)(mxGetScalar(prhs[1]));
+	astra::CProjector3D* pProjector;
+	pProjector = astra::CProjector3DManager::getSingleton().get(iPid);
+	if (!pProjector) {
+		mexErrMsgTxt("Projector not found.");
+		return;
+	}
+	if (!pProjector->isInitialized()) {
+		mexErrMsgTxt("Projector not initialized.");
+		return;
+	}
+	bool isCuda = false;
+	if (dynamic_cast<CCudaProjector3D*>(pProjector))
+		isCuda = true;
+	if (!isCuda) {
+		mexErrMsgTxt("Only CUDA projectors are currently supported.");
+		return;
+	}
+
+	astra::CVolumeGeometry3D* pVolGeom = pProjector->getVolumeGeometry();
+	astra::CProjectionGeometry3D* pProjGeom = pProjector->getProjectionGeometry();
+
+	const mxArray* const data = prhs[2];
+	if (!checkDataType(data)) {
+		mexErrMsgTxt("Data must be single or double.");
+		return;
+	}
+
+	if (!checkDataSize(data, pVolGeom)) {
+		mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry.");
+		return;
+	}
+
+
+	// Allocate input data
+	astra::CFloat32VolumeData3DMemory* pInput;
+	if (mxIsSingle(data)) {
+		astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(data));
+		pInput = new astra::CFloat32VolumeData3DMemory(pVolGeom, m);
+	} else {
+		pInput = new astra::CFloat32VolumeData3DMemory(pVolGeom);
+		copyMexToCFloat32Array(data, pInput->getData(), pInput->getSize());
+	}
+
+
+	// Allocate output data
+	// If the input is single, we also allocate single output.
+	// Otherwise, double.
+	astra::CFloat32ProjectionData3DMemory* pOutput;
+	mxArray *pOutputMx;
+	if (mxIsSingle(data)) {
+		mwSize dims[3];
+		dims[0] = pProjGeom->getDetectorColCount();
+		dims[1] = pProjGeom->getProjectionCount();
+		dims[2] = pProjGeom->getDetectorRowCount();
+		pOutputMx = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL);
+
+		astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(pOutputMx));
+		pOutput = new astra::CFloat32ProjectionData3DMemory(pProjGeom, m);
+	} else {
+		pOutput = new astra::CFloat32ProjectionData3DMemory(pProjGeom);
+	}
+
+	// Perform FP
+
+	astra::CCudaForwardProjectionAlgorithm3D* pAlg;
+	pAlg = new astra::CCudaForwardProjectionAlgorithm3D();
+	pAlg->initialize(pProjector, pOutput, pInput);
+
+	if (!pAlg->isInitialized()) {
+		mexErrMsgTxt("Error initializing algorithm.");
+		// TODO: Delete pOutputMx?
+		delete pAlg;
+		delete pInput;
+		delete pOutput;
+		return;
+	}
+
+	pAlg->run();
+
+	delete pAlg;
+
+
+	if (mxIsSingle(data)) {
+
+	} else {
+		pOutputMx = createEquivMexArray<mxDOUBLE_CLASS>(pOutput);
+		copyCFloat32ArrayToMex(pOutput->getData(), pOutputMx);
+	}
+	plhs[0] = pOutputMx;
+
+	delete pOutput;
+	delete pInput;
+}
+//-----------------------------------------------------------------------------------------
+/**
+ * projection = astra_mex_direct_c('BP3D', projector_id, volume);
+ * Both 'projection' and 'volume' are Matlab arrays.
+ */
+void astra_mex_direct_bp3d(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[])
+{
+	// TODO: Add an optional way of specifying extra options
+
+	if (nrhs < 3) {
+		mexErrMsgTxt("Not enough arguments. Syntax: astra_mex_direct_c('BP3D', projector_id, data)");
+		return;
+	}
+
+	int iPid = (int)(mxGetScalar(prhs[1]));
+	astra::CProjector3D* pProjector;
+	pProjector = astra::CProjector3DManager::getSingleton().get(iPid);
+	if (!pProjector) {
+		mexErrMsgTxt("Projector not found.");
+		return;
+	}
+	if (!pProjector->isInitialized()) {
+		mexErrMsgTxt("Projector not initialized.");
+		return;
+	}
+	bool isCuda = false;
+	if (dynamic_cast<CCudaProjector3D*>(pProjector))
+		isCuda = true;
+	if (!isCuda) {
+		mexErrMsgTxt("Only CUDA projectors are currently supported.");
+		return;
+	}
+
+	astra::CVolumeGeometry3D* pVolGeom = pProjector->getVolumeGeometry();
+	astra::CProjectionGeometry3D* pProjGeom = pProjector->getProjectionGeometry();
+
+	const mxArray* const data = prhs[2];
+	if (!checkDataType(data)) {
+		mexErrMsgTxt("Data must be single or double.");
+		return;
+	}
+
+	if (!checkDataSize(data, pProjGeom)) {
+		mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry.");
+		return;
+	}
+
+
+	// Allocate input data
+	astra::CFloat32ProjectionData3DMemory* pInput;
+	if (mxIsSingle(data)) {
+		astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(data));
+		pInput = new astra::CFloat32ProjectionData3DMemory(pProjGeom, m);
+	} else {
+		pInput = new astra::CFloat32ProjectionData3DMemory(pProjGeom);
+		copyMexToCFloat32Array(data, pInput->getData(), pInput->getSize());
+	}
+
+
+	// Allocate output data
+	// If the input is single, we also allocate single output.
+	// Otherwise, double.
+	astra::CFloat32VolumeData3DMemory* pOutput;
+	mxArray *pOutputMx;
+	if (mxIsSingle(data)) {
+		mwSize dims[3];
+		dims[0] = pVolGeom->getGridColCount();
+		dims[1] = pVolGeom->getGridRowCount();
+		dims[2] = pVolGeom->getGridSliceCount();
+		pOutputMx = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL);
+
+		astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(pOutputMx));
+		pOutput = new astra::CFloat32VolumeData3DMemory(pVolGeom, m);
+	} else {
+		pOutput = new astra::CFloat32VolumeData3DMemory(pVolGeom);
+	}
+
+	// Perform BP
+
+	astra::CCudaBackProjectionAlgorithm3D* pAlg;
+	pAlg = new astra::CCudaBackProjectionAlgorithm3D();
+	pAlg->initialize(pProjector, pInput, pOutput);
+
+	if (!pAlg->isInitialized()) {
+		mexErrMsgTxt("Error initializing algorithm.");
+		// TODO: Delete pOutputMx?
+		delete pAlg;
+		delete pInput;
+		delete pOutput;
+		return;
+	}
+
+	pAlg->run();
+
+	delete pAlg;
+
+
+	if (mxIsSingle(data)) {
+
+	} else {
+		pOutputMx = createEquivMexArray<mxDOUBLE_CLASS>(pOutput);
+		copyCFloat32ArrayToMex(pOutput->getData(), pOutputMx);
+	}
+	plhs[0] = pOutputMx;
+
+	delete pOutput;
+	delete pInput;
+}
+
+#endif
+
+//-----------------------------------------------------------------------------------------
+
+static void printHelp()
+{
+	mexPrintf("Please specify a mode of operation.\n");
+	mexPrintf("Valid modes: FP3D, BP3D\n");
+}
+
+
+//-----------------------------------------------------------------------------------------
+/**
+ * ... = astra_mex_direct_c(mode,...);
+ */
+void mexFunction(int nlhs, mxArray* plhs[],
+				 int nrhs, const mxArray* prhs[])
+{
+
+	// INPUT: Mode
+	string sMode;
+	if (1 <= nrhs) {
+		sMode = mexToString(prhs[0]);
+	} else {
+		printHelp();
+		return;
+	}
+
+#ifndef ASTRA_CUDA
+	mexErrMsgTxt("Only CUDA projectors are currently supported.");
+	return;
+#else
+
+	// 3D data
+	if (sMode == "FP3D") {
+		astra_mex_direct_fp3d(nlhs, plhs, nrhs, prhs);
+	} else if (sMode == "BP3D") {
+		astra_mex_direct_bp3d(nlhs, plhs, nrhs, prhs);
+	} else {
+		printHelp();
+	}
+#endif
+
+	return;
+}
+
+
diff --git a/matlab/tools/astra_mex_direct.m b/matlab/tools/astra_mex_direct.m
new file mode 100644
index 0000000..58c4fd2
--- /dev/null
+++ b/matlab/tools/astra_mex_direct.m
@@ -0,0 +1,24 @@
+function [varargout] = astra_mex_direct(varargin)
+%------------------------------------------------------------------------
+% Reference page in Help browser
+%    <a href="matlab:docsearch('astra_mex_direct' )">astra_mex_data3d</a>.
+%------------------------------------------------------------------------
+%------------------------------------------------------------------------
+% This file is part of the ASTRA Toolbox
+% 
+% Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp
+%            2014-2015, CWI, Amsterdam
+% License: Open Source under GPLv3
+% Contact: astra@uantwerpen.be
+% Website: http://sf.net/projects/astra-toolbox
+%------------------------------------------------------------------------
+% $Id$
+if nargout == 0
+    astra_mex_direct_c(varargin{:});
+    if exist('ans','var')
+        varargout{1} = ans;
+    end
+else
+    varargout = cell(1,nargout);
+    [varargout{:}] = astra_mex_direct_c(varargin{:});
+end
-- 
cgit v1.2.3


From 793afbc3fa1cca64292716869e503cb66942606d Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Wed, 7 Oct 2015 17:29:40 +0200
Subject: Build astra_mex_direct in MSVC

---
 astra_vc09.sln                           |  22 ++
 astra_vc11.sln                           |  22 ++
 build/msvc/gen.py                        |  15 +-
 matlab/mex/astra_mex_direct_vc09.vcproj  | 612 +++++++++++++++++++++++++++++++
 matlab/mex/astra_mex_direct_vc11.vcxproj | 306 ++++++++++++++++
 5 files changed, 975 insertions(+), 2 deletions(-)
 create mode 100644 matlab/mex/astra_mex_direct_vc09.vcproj
 create mode 100644 matlab/mex/astra_mex_direct_vc11.vcxproj

diff --git a/astra_vc09.sln b/astra_vc09.sln
index 9b93a0f..371e9b1 100644
--- a/astra_vc09.sln
+++ b/astra_vc09.sln
@@ -48,6 +48,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astra_mex_log", "matlab\mex
 		{12926444-6723-46A8-B388-12E65E0577FA} = {12926444-6723-46A8-B388-12E65E0577FA}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astra_mex_direct", "matlab\mex\astra_mex_direct_vc09.vcproj", "{85FE09A6-FA49-4314-A2B1-59D77C7442A8}"
+	ProjectSection(ProjectDependencies) = postProject
+		{12926444-6723-46A8-B388-12E65E0577FA} = {12926444-6723-46A8-B388-12E65E0577FA}
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug_CUDA|Win32 = Debug_CUDA|Win32
@@ -204,6 +209,22 @@ Global
 		{CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8}.Release|Win32.Build.0 = Release|Win32
 		{CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8}.Release|x64.ActiveCfg = Release|x64
 		{CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8}.Release|x64.Build.0 = Release|x64
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug_CUDA|Win32.ActiveCfg = Debug_CUDA|Win32
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug_CUDA|Win32.Build.0 = Debug_CUDA|Win32
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug_CUDA|x64.ActiveCfg = Debug_CUDA|x64
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug_CUDA|x64.Build.0 = Debug_CUDA|x64
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug|Win32.Build.0 = Debug|Win32
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug|x64.ActiveCfg = Debug|x64
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Debug|x64.Build.0 = Debug|x64
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release_CUDA|Win32.ActiveCfg = Release_CUDA|Win32
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release_CUDA|Win32.Build.0 = Release_CUDA|Win32
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release_CUDA|x64.ActiveCfg = Release_CUDA|x64
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release_CUDA|x64.Build.0 = Release_CUDA|x64
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release|Win32.ActiveCfg = Release|Win32
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release|Win32.Build.0 = Release|Win32
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release|x64.ActiveCfg = Release|x64
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -217,5 +238,6 @@ Global
 		{4DD6056F-8EEE-4C9A-B2A9-923F01A32E97} = {33EF0AC5-B475-40BF-BAE5-67075B204D10}
 		{F94CCD79-AA11-42DF-AC8A-6C9D2238A883} = {33EF0AC5-B475-40BF-BAE5-67075B204D10}
 		{CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8} = {33EF0AC5-B475-40BF-BAE5-67075B204D10}
+		{85FE09A6-FA49-4314-A2B1-59D77C7442A8} = {33EF0AC5-B475-40BF-BAE5-67075B204D10}
 	EndGlobalSection
 EndGlobal
diff --git a/astra_vc11.sln b/astra_vc11.sln
index 2832eab..92fb584 100644
--- a/astra_vc11.sln
+++ b/astra_vc11.sln
@@ -48,6 +48,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astra_mex_log", "matlab\mex
 		{BE9F1326-527C-4284-AE2C-D1E25D539CEA} = {BE9F1326-527C-4284-AE2C-D1E25D539CEA}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "astra_mex_direct", "matlab\mex\astra_mex_direct_vc11.vcxproj", "{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}"
+	ProjectSection(ProjectDependencies) = postProject
+		{BE9F1326-527C-4284-AE2C-D1E25D539CEA} = {BE9F1326-527C-4284-AE2C-D1E25D539CEA}
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug_CUDA|Win32 = Debug_CUDA|Win32
@@ -204,6 +209,22 @@ Global
 		{03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E}.Release|Win32.Build.0 = Release|Win32
 		{03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E}.Release|x64.ActiveCfg = Release|x64
 		{03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E}.Release|x64.Build.0 = Release|x64
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug_CUDA|Win32.ActiveCfg = Debug_CUDA|Win32
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug_CUDA|Win32.Build.0 = Debug_CUDA|Win32
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug_CUDA|x64.ActiveCfg = Debug_CUDA|x64
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug_CUDA|x64.Build.0 = Debug_CUDA|x64
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug|Win32.Build.0 = Debug|Win32
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug|x64.ActiveCfg = Debug|x64
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Debug|x64.Build.0 = Debug|x64
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release_CUDA|Win32.ActiveCfg = Release_CUDA|Win32
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release_CUDA|Win32.Build.0 = Release_CUDA|Win32
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release_CUDA|x64.ActiveCfg = Release_CUDA|x64
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release_CUDA|x64.Build.0 = Release_CUDA|x64
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release|Win32.ActiveCfg = Release|Win32
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release|Win32.Build.0 = Release|Win32
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release|x64.ActiveCfg = Release|x64
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -217,5 +238,6 @@ Global
 		{4DD6056F-8EEE-4C9A-B2A9-923F01A32E97} = {5E99A109-374E-4102-BE9B-99BA1FA8AA30}
 		{F94CCD79-AA11-42DF-AC8A-6C9D2238A883} = {5E99A109-374E-4102-BE9B-99BA1FA8AA30}
 		{03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E} = {5E99A109-374E-4102-BE9B-99BA1FA8AA30}
+		{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7} = {5E99A109-374E-4102-BE9B-99BA1FA8AA30}
 	EndGlobalSection
 EndGlobal
diff --git a/build/msvc/gen.py b/build/msvc/gen.py
index aeca3b0..a9bc494 100644
--- a/build/msvc/gen.py
+++ b/build/msvc/gen.py
@@ -24,6 +24,7 @@ P4 = create_mex_project("astra_mex_matrix", "9D041710-2119-4230-BCF2-5FBE753FDE4
 P5 = create_mex_project("astra_mex_projector", "4DD6056F-8EEE-4C9A-B2A9-923F01A32E97", "4DD6056F-8EEE-4C9A-B2A9-923F01A32E97")
 P6 = create_mex_project("astra_mex_projector3d", "F94CCD79-AA11-42DF-AC8A-6C9D2238A883", "F94CCD79-AA11-42DF-AC8A-6C9D2238A883")
 P7 = create_mex_project("astra_mex_log", "03B833F5-4FD6-4FBE-AAF4-E3305CD56D2E", "CA2840B3-DA68-41B5-AC57-F5DFD20ED8F8")
+P8 = create_mex_project("astra_mex_direct", "0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7", "85FE09A6-FA49-4314-A2B1-59D77C7442A8")
 
 F_astra_mex = { "type": siguid,
                 "name": "astra_mex",
@@ -31,7 +32,7 @@ F_astra_mex = { "type": siguid,
                 "file09": "astra_mex",
                 "uuid11": "5E99A109-374E-4102-BE9B-99BA1FA8AA30",
                 "uuid09": "33EF0AC5-B475-40BF-BAE5-67075B204D10",
-                "entries": [ P0, P1, P2, P3, P4, P5, P6, P7 ] }
+                "entries": [ P0, P1, P2, P3, P4, P5, P6, P7, P8 ] }
 
 
 P0["files"] = [
@@ -98,6 +99,14 @@ P7["files"] = [
 "mexInitFunctions.cpp",
 "mexInitFunctions.h",
 ]
+P8["files"] = [
+"astra_mex_direct_c.cpp",
+"mexHelpFunctions.cpp",
+"mexHelpFunctions.h",
+"mexInitFunctions.cpp",
+"mexInitFunctions.h",
+]
+
 
 
 
@@ -407,7 +416,7 @@ for f in P_astra["filters"]:
   P_astra["files"].extend(P_astra["filters"][f][1:])
 P_astra["files"].sort()
 
-projects = [ P_astra, F_astra_mex, P0, P1, P2, P3, P4, P5, P6, P7 ]
+projects = [ P_astra, F_astra_mex, P0, P1, P2, P3, P4, P5, P6, P7, P8 ]
 
 bom = "\xef\xbb\xbf"
 
@@ -1111,6 +1120,7 @@ if sys.argv[1] in ["vc11", "all"]:
   write_mex_project11(P5)
   write_mex_project11(P6)
   write_mex_project11(P7)
+  write_mex_project11(P8)
 
 if sys.argv[1] in ["vc09", "all"]:
   # HACK
@@ -1126,3 +1136,4 @@ if sys.argv[1] in ["vc09", "all"]:
   write_mex_project09(P5)
   write_mex_project09(P6)
   write_mex_project09(P7)
+  write_mex_project09(P8)
diff --git a/matlab/mex/astra_mex_direct_vc09.vcproj b/matlab/mex/astra_mex_direct_vc09.vcproj
new file mode 100644
index 0000000..04b49ac
--- /dev/null
+++ b/matlab/mex/astra_mex_direct_vc09.vcproj
@@ -0,0 +1,612 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="astra_mex_direct"
+	ProjectGUID="{85FE09A6-FA49-4314-A2B1-59D77C7442A8}"
+	RootNamespace="astraMatlab"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug_CUDA|Win32"
+			OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\include"
+				PreprocessorDefinitions="ASTRA_CUDA;__SSE2__"
+				Optimization="0"
+				RuntimeLibrary="3"
+				EnableEnhancedInstructionSet="2"
+				OpenMP="true"
+				AdditionalOptions="/MP"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib libut.lib"
+				OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+				AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32"
+				ModuleDefinitionFile="mex.def"
+				GenerateDebugInformation="true"
+				TargetMachine="1"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug_CUDA|x64"
+			OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\include"
+				PreprocessorDefinitions="ASTRA_CUDA;__SSE2__"
+				Optimization="0"
+				RuntimeLibrary="3"
+				OpenMP="true"
+				AdditionalOptions="/MP"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib libut.lib"
+				OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+				AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64"
+				ModuleDefinitionFile="mex.def"
+				GenerateDebugInformation="true"
+				TargetMachine="17"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+				PreprocessorDefinitions="__SSE2__"
+				Optimization="0"
+				RuntimeLibrary="3"
+				EnableEnhancedInstructionSet="2"
+				OpenMP="true"
+				AdditionalOptions="/MP"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib libut.lib"
+				OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+				AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32"
+				ModuleDefinitionFile="mex.def"
+				GenerateDebugInformation="true"
+				TargetMachine="1"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+				PreprocessorDefinitions="__SSE2__"
+				Optimization="0"
+				RuntimeLibrary="3"
+				OpenMP="true"
+				AdditionalOptions="/MP"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib libut.lib"
+				OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+				AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64"
+				ModuleDefinitionFile="mex.def"
+				GenerateDebugInformation="true"
+				TargetMachine="17"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release_CUDA|Win32"
+			OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\include"
+				PreprocessorDefinitions="ASTRA_CUDA;__SSE2__"
+				Optimization="2"
+				RuntimeLibrary="2"
+				EnableEnhancedInstructionSet="2"
+				OpenMP="true"
+				AdditionalOptions="/MP"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib libut.lib"
+				OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+				AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32"
+				ModuleDefinitionFile="mex.def"
+				GenerateDebugInformation="false"
+				TargetMachine="1"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release_CUDA|x64"
+			OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;&quot;$(CUDA_INC_PATH)&quot;;..\..\lib\include;..\..\include"
+				PreprocessorDefinitions="ASTRA_CUDA;__SSE2__"
+				Optimization="2"
+				RuntimeLibrary="2"
+				OpenMP="true"
+				AdditionalOptions="/MP"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib libut.lib"
+				OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+				AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64"
+				ModuleDefinitionFile="mex.def"
+				GenerateDebugInformation="false"
+				TargetMachine="17"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+				PreprocessorDefinitions="__SSE2__"
+				Optimization="2"
+				RuntimeLibrary="2"
+				EnableEnhancedInstructionSet="2"
+				OpenMP="true"
+				AdditionalOptions="/MP"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Astra32.lib libmex.lib libmx.lib libut.lib"
+				OutputFile="$(OutDir)\$(ProjectName)_c.mexw32"
+				AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32"
+				ModuleDefinitionFile="mex.def"
+				GenerateDebugInformation="false"
+				TargetMachine="1"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)"
+			IntermediateDirectory="$(OutDir)\obj\$(ProjectName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include"
+				PreprocessorDefinitions="__SSE2__"
+				Optimization="2"
+				RuntimeLibrary="2"
+				OpenMP="true"
+				AdditionalOptions="/MP"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Astra64.lib libmex.lib libmx.lib libut.lib"
+				OutputFile="$(OutDir)\$(ProjectName)_c.mexw64"
+				AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64"
+				ModuleDefinitionFile="mex.def"
+				GenerateDebugInformation="false"
+				TargetMachine="17"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\astra_mex_direct_c.cpp"
+			>
+		</File>
+		<File
+			RelativePath=".\mexHelpFunctions.cpp"
+			>
+		</File>
+		<File
+			RelativePath=".\mexHelpFunctions.h"
+			>
+		</File>
+		<File
+			RelativePath=".\mexInitFunctions.cpp"
+			>
+		</File>
+		<File
+			RelativePath=".\mexInitFunctions.h"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/matlab/mex/astra_mex_direct_vc11.vcxproj b/matlab/mex/astra_mex_direct_vc11.vcxproj
new file mode 100644
index 0000000..15c3c06
--- /dev/null
+++ b/matlab/mex/astra_mex_direct_vc11.vcxproj
@@ -0,0 +1,306 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug_CUDA|Win32">
+      <Configuration>Debug_CUDA</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_CUDA|x64">
+      <Configuration>Debug_CUDA</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release_CUDA|Win32">
+      <Configuration>Release_CUDA</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release_CUDA|x64">
+      <Configuration>Release_CUDA</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectName>astra_mex_direct</ProjectName>
+    <ProjectGuid>{0F68F4E2-BE1B-4A9A-B101-AECF4C069CC7}</ProjectGuid>
+    <RootNamespace>astraMatlab</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_CUDA|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_CUDA|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_CUDA|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_CUDA|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug_CUDA|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug_CUDA|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release_CUDA|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release_CUDA|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>11.0.60610.1</_ProjectFileVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_CUDA|Win32'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <TargetName>$(ProjectName)_c</TargetName>
+    <TargetExt>.mexw32</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_CUDA|x64'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <TargetName>$(ProjectName)_c</TargetName>
+    <TargetExt>.mexw64</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <TargetName>$(ProjectName)_c</TargetName>
+    <TargetExt>.mexw32</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <TargetName>$(ProjectName)_c</TargetName>
+    <TargetExt>.mexw64</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_CUDA|Win32'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <TargetName>$(ProjectName)_c</TargetName>
+    <TargetExt>.mexw32</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_CUDA|x64'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <TargetName>$(ProjectName)_c</TargetName>
+    <TargetExt>.mexw64</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <TargetName>$(ProjectName)_c</TargetName>
+    <TargetExt>.mexw32</TargetExt>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(SolutionDir)bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(OutDir)obj\$(ProjectName)\</IntDir>
+    <TargetName>$(ProjectName)_c</TargetName>
+    <TargetExt>.mexw64</TargetExt>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_CUDA|Win32'">
+    <ClCompile>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <OpenMPSupport>true</OpenMPSupport>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>ASTRA_CUDA;__SSE2__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)$(ProjectName)_c.mexw32</OutputFile>
+      <AdditionalDependencies>AstraCuda32D.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\lib\win32\;..\..\bin\win32\Debug_CUDA;$(MATLAB_ROOT)\extern\lib\win32\microsoft;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>mex.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_CUDA|x64'">
+    <ClCompile>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <OpenMPSupport>true</OpenMPSupport>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>ASTRA_CUDA;__SSE2__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)$(ProjectName)_c.mexw64</OutputFile>
+      <AdditionalDependencies>AstraCuda64D.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\lib\x64\;..\..\bin\x64\Debug_CUDA;$(MATLAB_ROOT)\extern\lib\win64\microsoft;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>mex.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <OpenMPSupport>true</OpenMPSupport>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>__SSE2__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)$(ProjectName)_c.mexw32</OutputFile>
+      <AdditionalDependencies>Astra32D.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\lib\win32\;..\..\bin\win32\Debug;$(MATLAB_ROOT)\extern\lib\win32\microsoft;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>mex.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <OpenMPSupport>true</OpenMPSupport>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>__SSE2__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)$(ProjectName)_c.mexw64</OutputFile>
+      <AdditionalDependencies>Astra64D.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\lib\x64\;..\..\bin\x64\Debug;$(MATLAB_ROOT)\extern\lib\win64\microsoft;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>mex.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_CUDA|Win32'">
+    <ClCompile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <OpenMPSupport>true</OpenMPSupport>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>ASTRA_CUDA;__SSE2__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)$(ProjectName)_c.mexw32</OutputFile>
+      <AdditionalDependencies>AstraCuda32.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\lib\win32\;..\..\bin\win32\Release_CUDA;$(MATLAB_ROOT)\extern\lib\win32\microsoft;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>mex.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_CUDA|x64'">
+    <ClCompile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <OpenMPSupport>true</OpenMPSupport>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>ASTRA_CUDA;__SSE2__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)$(ProjectName)_c.mexw64</OutputFile>
+      <AdditionalDependencies>AstraCuda64.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\lib\x64\;..\..\bin\x64\Release_CUDA;$(MATLAB_ROOT)\extern\lib\win64\microsoft;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>mex.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <OpenMPSupport>true</OpenMPSupport>
+      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>__SSE2__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)$(ProjectName)_c.mexw32</OutputFile>
+      <AdditionalDependencies>Astra32.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\lib\win32\;..\..\bin\win32\Release;$(MATLAB_ROOT)\extern\lib\win32\microsoft;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>mex.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <AdditionalIncludeDirectories>$(MATLAB_ROOT)\extern\include\;$(CUDA_PATH)\include;..\..\lib\include;..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <OpenMPSupport>true</OpenMPSupport>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>__SSE2__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)$(ProjectName)_c.mexw64</OutputFile>
+      <AdditionalDependencies>Astra64.lib;libmex.lib;libmx.lib;libut.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>..\..\lib\x64\;..\..\bin\x64\Release;$(MATLAB_ROOT)\extern\lib\win64\microsoft;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <ModuleDefinitionFile>mex.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="astra_mex_direct_c.cpp" />
+    <ClCompile Include="mexHelpFunctions.cpp" />
+    <ClCompile Include="mexInitFunctions.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="mexHelpFunctions.h" />
+    <ClInclude Include="mexInitFunctions.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
-- 
cgit v1.2.3


From 0ebd8dfe60cc0d1f05d65d3840278defce0da091 Mon Sep 17 00:00:00 2001
From: Nicola Vigano <nicola.vigano@esrf.fr>
Date: Wed, 7 Oct 2015 17:25:06 +0200
Subject: Add options passing to projectors from matlab

Signed-off-by: Nicola Vigano <nicola.vigano@esrf.fr>
---
 matlab/tools/astra_create_projector.m | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/matlab/tools/astra_create_projector.m b/matlab/tools/astra_create_projector.m
index da9c083..9bbef9e 100644
--- a/matlab/tools/astra_create_projector.m
+++ b/matlab/tools/astra_create_projector.m
@@ -1,7 +1,7 @@
-function proj_id = astra_create_projector(type, proj_geom, vol_geom)
+function proj_id = astra_create_projector(type, proj_geom, vol_geom, options)
 
 %--------------------------------------------------------------------------
-% proj_id = astra_create_projector(type, proj_geom, vol_geom)
+% proj_id = astra_create_projector(type, proj_geom, vol_geom, options)
 % 
 % Create a new projector object based on projection and volume geometry.  
 % Used when the default values of each projector are sufficient.  
@@ -9,6 +9,7 @@ function proj_id = astra_create_projector(type, proj_geom, vol_geom)
 % type: type of the projector.  'blob', 'line', 'linear' 'strip', ... See API for more information.
 % proj_geom: MATLAB struct containing the projection geometry.
 % vol_geom: MATLAB struct containing the volume geometry.
+% options: Optional MATLAB struct containing projector options (like: 'GPUindex', 'DetectorSuperSampling', and 'VoxelSuperSampling')
 % proj_id: identifier of the projector as it is now stored in the astra-library.
 %--------------------------------------------------------------------------
 %--------------------------------------------------------------------------
@@ -38,6 +39,10 @@ if strcmp(type,'blob')
 	cfg_proj.Kernel.KernelValues = blob_values;
 end
 
+if exist('options', 'var')
+    cfg_proj.options = options;
+end
+
 if strcmp(type,'linear3d') || strcmp(type,'linearcone') || strcmp(type,'cuda3d')
 	proj_id = astra_mex_projector3d('create', cfg_proj);
 else
-- 
cgit v1.2.3


From 43a38c117405f99e3a1b498f899de4ba6d01a044 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Wed, 7 Oct 2015 18:14:39 +0200
Subject: Improve option passing through CudaProjector3D

Not all constructors were reading options from the projector.
Also allow passing GPUIndex via CudaProjector3D.

Thanks to Nicola Vigano for part of the patch.
---
 include/astra/CudaBackProjectionAlgorithm3D.h    |  2 +
 include/astra/CudaCglsAlgorithm3D.h              |  2 +
 include/astra/CudaFDKAlgorithm3D.h               |  2 +
 include/astra/CudaForwardProjectionAlgorithm3D.h |  1 +
 include/astra/CudaProjector3D.h                  |  2 +
 include/astra/CudaSirtAlgorithm3D.h              |  2 +
 src/CudaBackProjectionAlgorithm3D.cpp            | 43 +++++++++++++++------
 src/CudaCglsAlgorithm3D.cpp                      | 47 +++++++++++++++--------
 src/CudaFDKAlgorithm3D.cpp                       | 40 ++++++++++++++------
 src/CudaForwardProjectionAlgorithm3D.cpp         | 46 +++++++++++++++--------
 src/CudaProjector3D.cpp                          |  7 ++++
 src/CudaSirtAlgorithm3D.cpp                      | 48 +++++++++++++++---------
 12 files changed, 172 insertions(+), 70 deletions(-)

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/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/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/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/CudaProjector3D.h b/include/astra/CudaProjector3D.h
index 1d570fe..da88d6d 100644
--- a/include/astra/CudaProjector3D.h
+++ b/include/astra/CudaProjector3D.h
@@ -117,12 +117,14 @@ 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/CudaSirtAlgorithm3D.h b/include/astra/CudaSirtAlgorithm3D.h
index fda4635..379720e 100644
--- a/include/astra/CudaSirtAlgorithm3D.h
+++ b/include/astra/CudaSirtAlgorithm3D.h
@@ -175,6 +175,8 @@ protected:
 	bool m_bAstraSIRTInit;
 	int m_iDetectorSuperSampling;
 	int m_iVoxelSuperSampling;
+
+	void initializeFromProjector();
 };
 
 // inline functions
diff --git a/src/CudaBackProjectionAlgorithm3D.cpp b/src/CudaBackProjectionAlgorithm3D.cpp
index e8e0433..c9d9447 100644
--- a/src/CudaBackProjectionAlgorithm3D.cpp
+++ b/src/CudaBackProjectionAlgorithm3D.cpp
@@ -38,6 +38,8 @@ $Id$
 #include "astra/ParallelVecProjectionGeometry3D.h"
 #include "astra/ConeVecProjectionGeometry3D.h"
 
+#include "astra/Logging.h"
+
 #include "../cuda/3d/astra3d.h"
 
 using namespace std;
@@ -86,6 +88,24 @@ bool CCudaBackProjectionAlgorithm3D::_check()
 	return true;
 }
 
+//---------------------------------------------------------------------------------------
+void CCudaBackProjectionAlgorithm3D::initializeFromProjector()
+{
+	m_iVoxelSuperSampling = 1;
+	m_iGPUIndex = -1;
+
+	CCudaProjector3D* pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		if (m_pProjector) {
+			ASTRA_WARN("non-CUDA Projector3D passed to BP3D_CUDA");
+		}
+	} else {
+		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
+	}
+
+}
+
 //---------------------------------------------------------------------------------------
 // Initialize - Config
 bool CCudaBackProjectionAlgorithm3D::initialize(const Config& _cfg)
@@ -103,21 +123,18 @@ bool CCudaBackProjectionAlgorithm3D::initialize(const Config& _cfg)
 		return false;
 	}
 
-	CCudaProjector3D* pCudaProjector = 0;
-	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
-	if (!pCudaProjector) {
-		// TODO: Report
-	}
-
-	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
-	CC.markOptionParsed("GPUindex");
-
+	initializeFromProjector();
 
-	m_iVoxelSuperSampling = 1;
-	if (pCudaProjector)
-		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+	// Deprecated options
 	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", m_iGPUIndex);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
 	CC.markOptionParsed("VoxelSuperSampling");
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
+
+
 
 	CFloat32ProjectionData3DMemory* pSinoMem = dynamic_cast<CFloat32ProjectionData3DMemory*>(m_pSinogram);
 	ASTRA_ASSERT(pSinoMem);
@@ -151,6 +168,8 @@ bool CCudaBackProjectionAlgorithm3D::initialize(CProjector3D* _pProjector,
 	m_pSinogram = _pSinogram;
 	m_pReconstruction = _pReconstruction;
 
+	initializeFromProjector();
+
 	// success
 	m_bIsInitialized = _check();
 	return m_bIsInitialized;
diff --git a/src/CudaCglsAlgorithm3D.cpp b/src/CudaCglsAlgorithm3D.cpp
index f527dc5..1cccb6a 100644
--- a/src/CudaCglsAlgorithm3D.cpp
+++ b/src/CudaCglsAlgorithm3D.cpp
@@ -37,6 +37,8 @@ $Id$
 #include "astra/ParallelVecProjectionGeometry3D.h"
 #include "astra/ConeVecProjectionGeometry3D.h"
 
+#include "astra/Logging.h"
+
 #include "../cuda/3d/astra3d.h"
 
 using namespace std;
@@ -89,6 +91,26 @@ bool CCudaCglsAlgorithm3D::_check()
 	return true;
 }
 
+//---------------------------------------------------------------------------------------
+void CCudaCglsAlgorithm3D::initializeFromProjector()
+{
+	m_iVoxelSuperSampling = 1;
+	m_iDetectorSuperSampling = 1;
+	m_iGPUIndex = -1;
+
+	CCudaProjector3D* pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		if (m_pProjector) {
+			ASTRA_WARN("non-CUDA Projector3D passed to CGLS3D_CUDA");
+		}
+	} else {
+		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
+	}
+
+}
+
 //---------------------------------------------------------------------------------------
 // Initialize - Config
 bool CCudaCglsAlgorithm3D::initialize(const Config& _cfg)
@@ -107,27 +129,20 @@ bool CCudaCglsAlgorithm3D::initialize(const Config& _cfg)
 		return false;
 	}
 
-	CCudaProjector3D* pCudaProjector = 0;
-	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
-	if (!pCudaProjector) {
-		// TODO: Report
-	}
+	initializeFromProjector();
 
-	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
-	CC.markOptionParsed("GPUindex");
-
-	m_iVoxelSuperSampling = 1;
-	m_iDetectorSuperSampling = 1;
-	if (pCudaProjector) {
-		// New interface
-		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
-		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
-	}
 	// Deprecated options
 	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);
 	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", m_iGPUIndex);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
 	CC.markOptionParsed("VoxelSuperSampling");
 	CC.markOptionParsed("DetectorSuperSampling");
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
+
+
 
 	m_pCgls = new AstraCGLS3d();
 
@@ -155,6 +170,8 @@ bool CCudaCglsAlgorithm3D::initialize(CProjector3D* _pProjector,
 	m_pSinogram = _pSinogram;
 	m_pReconstruction = _pReconstruction;
 
+	initializeFromProjector();
+
 	m_pCgls = new AstraCGLS3d;
 
 	m_bAstraCGLSInit = false;
diff --git a/src/CudaFDKAlgorithm3D.cpp b/src/CudaFDKAlgorithm3D.cpp
index 667d926..625d02a 100644
--- a/src/CudaFDKAlgorithm3D.cpp
+++ b/src/CudaFDKAlgorithm3D.cpp
@@ -35,6 +35,8 @@ $Id$
 #include "astra/CudaProjector3D.h"
 #include "astra/ConeProjectionGeometry3D.h"
 
+#include "astra/Logging.h"
+
 #include "../cuda/3d/astra3d.h"
 
 using namespace std;
@@ -84,6 +86,24 @@ bool CCudaFDKAlgorithm3D::_check()
 	return true;
 }
 
+//---------------------------------------------------------------------------------------
+void CCudaFDKAlgorithm3D::initializeFromProjector()
+{
+	m_iVoxelSuperSampling = 1;
+	m_iGPUIndex = -1;
+
+	CCudaProjector3D* pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		if (m_pProjector) {
+			ASTRA_WARN("non-CUDA Projector3D passed to FDK_CUDA");
+		}
+	} else {
+		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
+	}
+
+}
+
 //---------------------------------------------------------------------------------------
 // Initialize - Config
 bool CCudaFDKAlgorithm3D::initialize(const Config& _cfg)
@@ -101,20 +121,18 @@ bool CCudaFDKAlgorithm3D::initialize(const Config& _cfg)
 		return false;
 	}
 
-	CCudaProjector3D* pCudaProjector = 0;
-	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
-	if (!pCudaProjector) {
-		// TODO: Report
-	}
-
-	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
-	CC.markOptionParsed("GPUindex");
+	initializeFromProjector();
 
-	m_iVoxelSuperSampling = 1;
-	if (pCudaProjector)
-		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+	// Deprecated options
 	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", m_iGPUIndex);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
 	CC.markOptionParsed("VoxelSuperSampling");
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
+
+
 
 	m_bShortScan = _cfg.self.getOptionBool("ShortScan", false);
 	CC.markOptionParsed("ShortScan");
diff --git a/src/CudaForwardProjectionAlgorithm3D.cpp b/src/CudaForwardProjectionAlgorithm3D.cpp
index 46dab12..6498885 100644
--- a/src/CudaForwardProjectionAlgorithm3D.cpp
+++ b/src/CudaForwardProjectionAlgorithm3D.cpp
@@ -71,6 +71,23 @@ CCudaForwardProjectionAlgorithm3D::~CCudaForwardProjectionAlgorithm3D()
 
 }
 
+//---------------------------------------------------------------------------------------
+void CCudaForwardProjectionAlgorithm3D::initializeFromProjector()
+{
+	m_iDetectorSuperSampling = 1;
+	m_iGPUIndex = -1;
+
+	CCudaProjector3D* pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		if (m_pProjector) {
+			ASTRA_WARN("non-CUDA Projector3D passed to FP3D_CUDA");
+		}
+	} else {
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
+	}
+}
+
 //---------------------------------------------------------------------------------------
 // Initialize - Config
 bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg)
@@ -97,29 +114,21 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(const Config& _cfg)
 
 	// optional: projector
 	node = _cfg.self.getSingleNode("ProjectorId");
-	CCudaProjector3D* pCudaProjector = 0;
 	m_pProjector = 0;
 	if (node) {
 		id = boost::lexical_cast<int>(node.getContent());
 		m_pProjector = CProjector3DManager::getSingleton().get(id);
-		pCudaProjector = dynamic_cast<CCudaProjector3D*>(CProjector3DManager::getSingleton().get(id));
-		m_pProjector = pCudaProjector;
-		if (!pCudaProjector) {
-			// TODO: Report
-		}
 	}
 	CC.markNodeParsed("ProjectorId");
 
-	// GPU number
-	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
-	CC.markOptionParsed("GPUindex");
-
+	initializeFromProjector();
 
-	m_iDetectorSuperSampling = 1;
-	if (pCudaProjector)
-		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+	// Deprecated options
 	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", m_iGPUIndex);
 	CC.markOptionParsed("DetectorSuperSampling");
+	CC.markOptionParsed("GPUindex");
+
 
 	// success
 	m_bIsInitialized = check();
@@ -142,8 +151,15 @@ bool CCudaForwardProjectionAlgorithm3D::initialize(CProjector3D* _pProjector,
 	m_pProjections = _pProjections;
 	m_pVolume = _pVolume;
 
-	m_iDetectorSuperSampling = _iDetectorSuperSampling;
-	m_iGPUIndex = _iGPUindex;
+	CCudaProjector3D* pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		// TODO: Report
+		m_iDetectorSuperSampling = _iDetectorSuperSampling;
+		m_iGPUIndex = _iGPUindex;
+	} else {
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
+	}
 
 	// success
 	m_bIsInitialized = check();
diff --git a/src/CudaProjector3D.cpp b/src/CudaProjector3D.cpp
index d2fd74c..bbfbd34 100644
--- a/src/CudaProjector3D.cpp
+++ b/src/CudaProjector3D.cpp
@@ -64,6 +64,7 @@ void CCudaProjector3D::_clear()
 	m_projectionKernel = ker3d_default;
 	m_iVoxelSuperSampling = 1;
 	m_iDetectorSuperSampling = 1;
+	m_iGPUIndex = -1;
 }
 
 //----------------------------------------------------------------------------------------
@@ -128,6 +129,12 @@ bool CCudaProjector3D::initialize(const Config& _cfg)
 	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
 	CC.markOptionParsed("DetectorSuperSampling");
 
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
+
 	m_bIsInitialized = _check();
 	return m_bIsInitialized;
 }
diff --git a/src/CudaSirtAlgorithm3D.cpp b/src/CudaSirtAlgorithm3D.cpp
index abbb9fd..67594f4 100644
--- a/src/CudaSirtAlgorithm3D.cpp
+++ b/src/CudaSirtAlgorithm3D.cpp
@@ -38,6 +38,8 @@ $Id$
 #include "astra/ConeVecProjectionGeometry3D.h"
 #include "astra/CudaProjector3D.h"
 
+#include "astra/Logging.h"
+
 #include "../cuda/3d/astra3d.h"
 
 using namespace std;
@@ -90,7 +92,27 @@ bool CCudaSirtAlgorithm3D::_check()
 	return true;
 }
 
-//---------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------
+void CCudaSirtAlgorithm3D::initializeFromProjector()
+{
+	m_iVoxelSuperSampling = 1;
+	m_iDetectorSuperSampling = 1;
+	m_iGPUIndex = -1;
+
+	CCudaProjector3D* pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
+	if (!pCudaProjector) {
+		if (m_pProjector) {
+			ASTRA_WARN("non-CUDA Projector3D passed to SIRT3D_CUDA");
+		}
+	} else {
+		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
+	}
+
+}
+
+//--------------------------------------------------------------------------------------
 // Initialize - Config
 bool CCudaSirtAlgorithm3D::initialize(const Config& _cfg)
 {
@@ -108,28 +130,20 @@ bool CCudaSirtAlgorithm3D::initialize(const Config& _cfg)
 		return false;
 	}
 
-	CCudaProjector3D* pCudaProjector = 0;
-	pCudaProjector = dynamic_cast<CCudaProjector3D*>(m_pProjector);
-	if (!pCudaProjector) {
-		// TODO: Report
-	}
+	initializeFromProjector();
 
-	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
-	CC.markOptionParsed("GPUindex");
-
-
-	m_iVoxelSuperSampling = 1;
-	m_iDetectorSuperSampling = 1;
-	if (pCudaProjector) {
-		// New interface
-		m_iVoxelSuperSampling = pCudaProjector->getVoxelSuperSampling();
-		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
-	}
 	// Deprecated options
 	m_iVoxelSuperSampling = (int)_cfg.self.getOptionNumerical("VoxelSuperSampling", m_iVoxelSuperSampling);
 	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", m_iGPUIndex);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
 	CC.markOptionParsed("VoxelSuperSampling");
 	CC.markOptionParsed("DetectorSuperSampling");
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
+
+
 
 	m_pSirt = new AstraSIRT3d();
 
-- 
cgit v1.2.3


From 37dd051faf2a8085c1abb5623eb5e79363471642 Mon Sep 17 00:00:00 2001
From: Nicola Vigano <nicola.vigano@esrf.fr>
Date: Thu, 2 Apr 2015 17:07:25 +0200
Subject: astra_mex_direct: Don't initialize newly allocated mxArray

This avoids letting matlab initialize the memory we will overwrite shortly
after.
---
 matlab/mex/astra_mex_direct_c.cpp | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/matlab/mex/astra_mex_direct_c.cpp b/matlab/mex/astra_mex_direct_c.cpp
index 94eb1cd..38b3f59 100755
--- a/matlab/mex/astra_mex_direct_c.cpp
+++ b/matlab/mex/astra_mex_direct_c.cpp
@@ -135,7 +135,15 @@ void astra_mex_direct_fp3d(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray*
 		dims[0] = pProjGeom->getDetectorColCount();
 		dims[1] = pProjGeom->getProjectionCount();
 		dims[2] = pProjGeom->getDetectorRowCount();
-		pOutputMx = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL);
+
+		// Allocate uninitialized mxArray of size dims.
+		// (It will be zeroed by CudaForwardProjectionAlgorithm3D)
+		const mwSize zero_dims[2] = {0, 0};
+		pOutputMx = mxCreateNumericArray(2, zero_dims, mxSINGLE_CLASS, mxREAL);
+		mxSetDimensions(pOutputMx, dims, 3);
+		const mwSize num_elems = mxGetNumberOfElements(pOutputMx);
+		const mwSize elem_size = mxGetElementSize(pOutputMx);
+		mxSetData(pOutputMx, mxMalloc(elem_size * num_elems));
 
 		astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(pOutputMx));
 		pOutput = new astra::CFloat32ProjectionData3DMemory(pProjGeom, m);
@@ -243,7 +251,15 @@ void astra_mex_direct_bp3d(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray*
 		dims[0] = pVolGeom->getGridColCount();
 		dims[1] = pVolGeom->getGridRowCount();
 		dims[2] = pVolGeom->getGridSliceCount();
-		pOutputMx = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL);
+
+		// Allocate uninitialized mxArray of size dims.
+		// (It will be zeroed by CudaBackProjectionAlgorithm3D)
+		const mwSize zero_dims[2] = {0, 0};
+		pOutputMx = mxCreateNumericArray(2, zero_dims, mxSINGLE_CLASS, mxREAL);
+		mxSetDimensions(pOutputMx, dims, 3);
+		const mwSize num_elems = mxGetNumberOfElements(pOutputMx);
+		const mwSize elem_size = mxGetElementSize(pOutputMx);
+		mxSetData(pOutputMx, mxMalloc(elem_size * num_elems));
 
 		astra::CFloat32CustomMemory* m = new CFloat32CustomMemory_simple((float *)mxGetData(pOutputMx));
 		pOutput = new astra::CFloat32VolumeData3DMemory(pVolGeom, m);
-- 
cgit v1.2.3


From 003663649a191fc5bc011d6e5424496576b5e793 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Thu, 8 Oct 2015 11:24:49 +0200
Subject: Improve option passing through CudaProjector2D

Not all constructors were reading options from the projector.
Also allow passing GPUIndex via CudaProjector2D.

Also refactor CudaReconstructionAlgorithm::initialize/check
to avoid code duplication with ReconstructionAlgorithm.
---
 include/astra/CudaBackProjectionAlgorithm.h        |   5 +-
 include/astra/CudaCglsAlgorithm.h                  |   9 +-
 include/astra/CudaEMAlgorithm.h                    |   8 +-
 .../astra/CudaFilteredBackProjectionAlgorithm.h    |   3 +
 include/astra/CudaForwardProjectionAlgorithm.h     |  27 ++--
 include/astra/CudaProjector2D.h                    |   2 +
 include/astra/CudaReconstructionAlgorithm2D.h      |  22 +--
 include/astra/CudaSartAlgorithm.h                  |   7 +-
 include/astra/CudaSirtAlgorithm.h                  |   9 +-
 include/astra/ReconstructionAlgorithm2D.h          |   3 +
 src/CudaBackProjectionAlgorithm.cpp                |   5 +-
 src/CudaCglsAlgorithm.cpp                          |   6 +-
 src/CudaEMAlgorithm.cpp                            |   6 +-
 src/CudaFilteredBackProjectionAlgorithm.cpp        |  43 ++++--
 src/CudaForwardProjectionAlgorithm.cpp             |  60 ++++----
 src/CudaProjector2D.cpp                            |  17 ++-
 src/CudaReconstructionAlgorithm2D.cpp              | 169 +++++----------------
 src/CudaSartAlgorithm.cpp                          |   5 +-
 src/CudaSirtAlgorithm.cpp                          |   6 +-
 src/ReconstructionAlgorithm2D.cpp                  |  25 ++-
 20 files changed, 169 insertions(+), 268 deletions(-)

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/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/CudaEMAlgorithm.h b/include/astra/CudaEMAlgorithm.h
index 97eb7ca..d313f7c 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);
+					CFloat32VolumeData2D* _pReconstruction);
 
 	/** Get a description of the class.
 	 *
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..097d499 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, 
+	bool initialize(CProjector2D* _pProjector,
 					CFloat32VolumeData2D* _pVolume, 
-					CFloat32ProjectionData2D* _pSinogram,
-					int _iGPUindex = -1, int _iDetectorSuperSampling = 1);
+					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/CudaProjector2D.h b/include/astra/CudaProjector2D.h
index ecfca41..2b4bacb 100644
--- a/include/astra/CudaProjector2D.h
+++ b/include/astra/CudaProjector2D.h
@@ -124,12 +124,14 @@ public:
 	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/CudaReconstructionAlgorithm2D.h b/include/astra/CudaReconstructionAlgorithm2D.h
index e19bb8f..dc93a1a 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.
@@ -166,6 +151,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..53d1e7b 100644
--- a/include/astra/CudaSartAlgorithm.h
+++ b/include/astra/CudaSartAlgorithm.h
@@ -84,16 +84,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);
+					CFloat32VolumeData2D* _pReconstruction);
 
 	/** Get a description of the class.
 	 *
diff --git a/include/astra/CudaSirtAlgorithm.h b/include/astra/CudaSirtAlgorithm.h
index 607889a..751d612 100644
--- a/include/astra/CudaSirtAlgorithm.h
+++ b/include/astra/CudaSirtAlgorithm.h
@@ -97,18 +97,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.
-	 * @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/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/src/CudaBackProjectionAlgorithm.cpp b/src/CudaBackProjectionAlgorithm.cpp
index 365e058..a73f895 100644
--- a/src/CudaBackProjectionAlgorithm.cpp
+++ b/src/CudaBackProjectionAlgorithm.cpp
@@ -76,10 +76,9 @@ bool CCudaBackProjectionAlgorithm::initialize(const Config& _cfg)
 // Initialize - C++
 bool CCudaBackProjectionAlgorithm::initialize(CProjector2D* _pProjector,
                                      CFloat32ProjectionData2D* _pSinogram, 
-                                     CFloat32VolumeData2D* _pReconstruction,
-                                     int _iGPUindex, int _iPixelSuperSampling)
+                                     CFloat32VolumeData2D* _pReconstruction)
 {
-	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction, _iGPUindex, 1, _iPixelSuperSampling);
+	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction);
 
 	if (!m_bIsInitialized)
 		return false;
diff --git a/src/CudaCglsAlgorithm.cpp b/src/CudaCglsAlgorithm.cpp
index 0cedff6..9dd4f78 100644
--- a/src/CudaCglsAlgorithm.cpp
+++ b/src/CudaCglsAlgorithm.cpp
@@ -77,11 +77,9 @@ bool CCudaCglsAlgorithm::initialize(const Config& _cfg)
 // Initialize - C++
 bool CCudaCglsAlgorithm::initialize(CProjector2D* _pProjector,
                                     CFloat32ProjectionData2D* _pSinogram, 
-                                    CFloat32VolumeData2D* _pReconstruction,
-                                    int _iGPUindex, int _iDetectorSuperSampling,
-                                    int _iPixelSuperSampling)
+                                    CFloat32VolumeData2D* _pReconstruction)
 {
-	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction, _iGPUindex, _iDetectorSuperSampling, _iPixelSuperSampling);
+	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction);
 
 	if (!m_bIsInitialized)
 		return false;
diff --git a/src/CudaEMAlgorithm.cpp b/src/CudaEMAlgorithm.cpp
index 5c71f3d..d0afd80 100644
--- a/src/CudaEMAlgorithm.cpp
+++ b/src/CudaEMAlgorithm.cpp
@@ -76,11 +76,9 @@ bool CCudaEMAlgorithm::initialize(const Config& _cfg)
 // Initialize - C++
 bool CCudaEMAlgorithm::initialize(CProjector2D* _pProjector,
                                      CFloat32ProjectionData2D* _pSinogram, 
-                                     CFloat32VolumeData2D* _pReconstruction,
-                                     int _iGPUindex, int _iDetectorSuperSampling,
-                                     int _iPixelSuperSampling)
+                                     CFloat32VolumeData2D* _pReconstruction)
 {
-	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction, _iGPUindex, _iDetectorSuperSampling, _iPixelSuperSampling);
+	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction);
 
 	if (!m_bIsInitialized)
 		return false;
diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp
index aac96d6..8c0659d 100644
--- a/src/CudaFilteredBackProjectionAlgorithm.cpp
+++ b/src/CudaFilteredBackProjectionAlgorithm.cpp
@@ -67,6 +67,24 @@ CCudaFilteredBackProjectionAlgorithm::~CCudaFilteredBackProjectionAlgorithm()
 	}
 }
 
+void CCudaFilteredBackProjectionAlgorithm::initializeFromProjector()
+{
+	m_iPixelSuperSampling = 1;
+	m_iGPUIndex = -1;
+
+	// Projector
+	CCudaProjector2D* pCudaProjector = dynamic_cast<CCudaProjector2D*>(m_pProjector);
+	if (!pCudaProjector) {
+		if (m_pProjector) {
+			ASTRA_WARN("non-CUDA Projector2D passed to FBP_CUDA");
+		}
+	} else {
+		m_iPixelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
+	}
+
+}
+
 bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)
 {
 	ASTRA_ASSERT(_cfg.self);
@@ -163,27 +181,24 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)
 	}
 	CC.markNodeParsed("FilterD"); // TODO: Only for some types!
 
-	// GPU number
-	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
-	CC.markOptionParsed("GPUindex");
-
-	m_iPixelSuperSampling = 1;
-	if (pCudaProjector) {
-		// New interface
-		m_iPixelSuperSampling = pCudaProjector->getVoxelSuperSampling();
-	}
-	// Deprecated options
-	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", m_iPixelSuperSampling);
-	CC.markOptionParsed("PixelSuperSampling");
-
-
 	// Fan beam short scan mode
 	if (m_pSinogram && dynamic_cast<CFanFlatProjectionGeometry2D*>(m_pSinogram->getGeometry())) {
 		m_bShortScan = (int)_cfg.self.getOptionBool("ShortScan", false);
 		CC.markOptionParsed("ShortScan");
 	}
 
+	initializeFromProjector();
 
+	// Deprecated options
+	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", m_iPixelSuperSampling);
+	CC.markOptionParsed("PixelSuperSampling");
+
+	// GPU number
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
 
 
 	m_pFBP = new AstraFBP;
diff --git a/src/CudaForwardProjectionAlgorithm.cpp b/src/CudaForwardProjectionAlgorithm.cpp
index b382f2e..9ca13ae 100644
--- a/src/CudaForwardProjectionAlgorithm.cpp
+++ b/src/CudaForwardProjectionAlgorithm.cpp
@@ -38,8 +38,11 @@ $Id$
 #include <boost/lexical_cast.hpp>
 
 #include "astra/AstraObjectManager.h"
+#include "astra/ParallelProjectionGeometry2D.h"
 #include "astra/FanFlatProjectionGeometry2D.h"
 #include "astra/FanFlatVecProjectionGeometry2D.h"
+#include "astra/Float32ProjectionData2D.h"
+#include "astra/Float32VolumeData2D.h"
 #include "astra/CudaProjector2D.h"
 
 #include "astra/Logging.h"
@@ -65,6 +68,24 @@ CCudaForwardProjectionAlgorithm::~CCudaForwardProjectionAlgorithm()
 
 }
 
+//---------------------------------------------------------------------------------------
+void CCudaForwardProjectionAlgorithm::initializeFromProjector()
+{
+	m_iDetectorSuperSampling = 1;
+	m_iGPUIndex = -1;
+
+	// Projector
+	CCudaProjector2D* pCudaProjector = dynamic_cast<CCudaProjector2D*>(m_pProjector);
+	if (!pCudaProjector) {
+		if (m_pProjector) {
+			ASTRA_WARN("non-CUDA Projector2D passed to FP_CUDA");
+		}
+	} else {
+		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
+	}
+}
+
 //---------------------------------------------------------------------------------------
 // Initialize - Config
 bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg)
@@ -74,14 +95,9 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg)
 
 	// Projector
 	XMLNode node = _cfg.self.getSingleNode("ProjectorId");
-	CCudaProjector2D* pCudaProjector = 0;
 	if (node) {
 		int id = boost::lexical_cast<int>(node.getContent());
-		CProjector2D *projector = CProjector2DManager::getSingleton().get(id);
-		pCudaProjector = dynamic_cast<CCudaProjector2D*>(projector);
-		if (!pCudaProjector) {
-			ASTRA_WARN("non-CUDA Projector2D passed to FP_CUDA");
-		}
+		m_pProjector = CProjector2DManager::getSingleton().get(id);
 	}
 	CC.markNodeParsed("ProjectorId");
 
@@ -101,22 +117,18 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg)
 	m_pVolume = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));
 	CC.markNodeParsed("VolumeDataId");
 
+	initializeFromProjector();
+
+	// Deprecated options
+	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
+	CC.markOptionParsed("DetectorSuperSampling");
 	// GPU number
 	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
 	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
-	CC.markOptionParsed("GPUindex");
-	if (!_cfg.self.hasOption("GPUindex"))
-		CC.markOptionParsed("GPUIndex");
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
 
-	// Detector supersampling factor
-	m_iDetectorSuperSampling = 1;
-	if (pCudaProjector) {
-		// New interface
-		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
-	}
-	// Deprecated option
-	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
-	CC.markOptionParsed("DetectorSuperSampling");
 
 
 	// return success
@@ -125,20 +137,16 @@ bool CCudaForwardProjectionAlgorithm::initialize(const Config& _cfg)
 
 //----------------------------------------------------------------------------------------
 // Initialize - C++
-bool CCudaForwardProjectionAlgorithm::initialize(CProjectionGeometry2D* _pProjectionGeometry,
-												 CVolumeGeometry2D* _pReconstructionGeometry,
+bool CCudaForwardProjectionAlgorithm::initialize(CProjector2D* _pProjector,
 												 CFloat32VolumeData2D* _pVolume,
-												 CFloat32ProjectionData2D* _pSinogram,
-												 int _iGPUindex, int _iDetectorSuperSampling)
+												 CFloat32ProjectionData2D* _pSinogram)
 {
 	// store classes
-	//m_pProjectionGeometry = _pProjectionGeometry;
-	//m_pReconstructionGeometry = _pReconstructionGeometry;
+	m_pProjector = _pProjector;
 	m_pVolume = _pVolume;
 	m_pSinogram = _pSinogram;
 
-	m_iDetectorSuperSampling = _iDetectorSuperSampling;
-	m_iGPUIndex = _iGPUindex;
+	initializeFromProjector();
 
 	// return success
 	return check();
diff --git a/src/CudaProjector2D.cpp b/src/CudaProjector2D.cpp
index a26e32d..acf6000 100644
--- a/src/CudaProjector2D.cpp
+++ b/src/CudaProjector2D.cpp
@@ -61,6 +61,7 @@ void CCudaProjector2D::_clear()
 	m_projectionKernel = ker2d_default;
 	m_iVoxelSuperSampling = 1;
 	m_iDetectorSuperSampling = 1;
+	m_iGPUIndex = -1;
 }
 
 //----------------------------------------------------------------------------------------
@@ -125,18 +126,18 @@ bool CCudaProjector2D::initialize(const Config& _cfg)
 	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", 1);
 	CC.markOptionParsed("DetectorSuperSampling");
 
+	// GPU number
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
+
+
 	m_bIsInitialized = _check();
 	return m_bIsInitialized;
 }
 
-/*
-bool CProjector2D::initialize(astra::CProjectionGeometry2D *, astra::CVolumeGeometry2D *)
-{
-	ASTRA_ASSERT(false);
-
-	return false;
-}
-*/
 
 std::string CCudaProjector2D::description() const
 {
diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp
index 71b6637..bccdb43 100644
--- a/src/CudaReconstructionAlgorithm2D.cpp
+++ b/src/CudaReconstructionAlgorithm2D.cpp
@@ -84,111 +84,51 @@ void CCudaReconstructionAlgorithm2D::_clear()
 }
 
 //---------------------------------------------------------------------------------------
-// Initialize - Config
-bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg)
+void CCudaReconstructionAlgorithm2D::initializeFromProjector()
 {
-	ASTRA_ASSERT(_cfg.self);
-	ConfigStackCheck<CAlgorithm> CC("CudaReconstructionAlgorithm2D", this, _cfg);
-
-	// if already initialized, clear first
-	if (m_bIsInitialized) {
-		clear();
-	}
+	m_iPixelSuperSampling = 1;
+	m_iDetectorSuperSampling = 1;
+	m_iGPUIndex = -1;
 
 	// Projector
-	XMLNode node = _cfg.self.getSingleNode("ProjectorId");
-	CCudaProjector2D* pCudaProjector = 0;
-	if (node) {
-		int id = boost::lexical_cast<int>(node.getContent());
-		CProjector2D *projector = CProjector2DManager::getSingleton().get(id);
-		pCudaProjector = dynamic_cast<CCudaProjector2D*>(projector);
-		if (!pCudaProjector) {
+	CCudaProjector2D* pCudaProjector = dynamic_cast<CCudaProjector2D*>(m_pProjector);
+	if (!pCudaProjector) {
+		if (m_pProjector) {
 			ASTRA_WARN("non-CUDA Projector2D passed");
 		}
-	}
-	CC.markNodeParsed("ProjectorId");
-
-
-	// sinogram data
-	node = _cfg.self.getSingleNode("ProjectionDataId");
-	ASTRA_CONFIG_CHECK(node, "CudaSirt2", "No ProjectionDataId tag specified.");
-	int id = boost::lexical_cast<int>(node.getContent());
-	m_pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
-	CC.markNodeParsed("ProjectionDataId");
-
-	// reconstruction data
-	node = _cfg.self.getSingleNode("ReconstructionDataId");
-	ASTRA_CONFIG_CHECK(node, "CudaSirt2", "No ReconstructionDataId tag specified.");
-	id = boost::lexical_cast<int>(node.getContent());
-	m_pReconstruction = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));
-	CC.markNodeParsed("ReconstructionDataId");
-
-	// fixed mask
-	if (_cfg.self.hasOption("ReconstructionMaskId")) {
-		m_bUseReconstructionMask = true;
-		id = boost::lexical_cast<int>(_cfg.self.getOption("ReconstructionMaskId"));
-		m_pReconstructionMask = dynamic_cast<CFloat32VolumeData2D*>(CData2DManager::getSingleton().get(id));
-		ASTRA_CONFIG_CHECK(m_pReconstructionMask, "CudaReconstruction2D", "Invalid ReconstructionMaskId.");
-	}
-	CC.markOptionParsed("ReconstructionMaskId");
-	// fixed mask
-	if (_cfg.self.hasOption("SinogramMaskId")) {
-		m_bUseSinogramMask = true;
-		id = boost::lexical_cast<int>(_cfg.self.getOption("SinogramMaskId"));
-		m_pSinogramMask = dynamic_cast<CFloat32ProjectionData2D*>(CData2DManager::getSingleton().get(id));
-		ASTRA_CONFIG_CHECK(m_pSinogramMask, "CudaReconstruction2D", "Invalid SinogramMaskId.");
-	}
-	CC.markOptionParsed("SinogramMaskId");
-
-	// Constraints - NEW
-	if (_cfg.self.hasOption("MinConstraint")) {
-		m_bUseMinConstraint = true;
-		m_fMinValue = _cfg.self.getOptionNumerical("MinConstraint", 0.0f);
-		CC.markOptionParsed("MinConstraint");
-	} else {
-		// Constraint - OLD
-		m_bUseMinConstraint = _cfg.self.getOptionBool("UseMinConstraint", false);
-		CC.markOptionParsed("UseMinConstraint");
-		if (m_bUseMinConstraint) {
-			m_fMinValue = _cfg.self.getOptionNumerical("MinConstraintValue", 0.0f);
-			CC.markOptionParsed("MinConstraintValue");
-		}
-	}
-	if (_cfg.self.hasOption("MaxConstraint")) {
-		m_bUseMaxConstraint = true;
-		m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraint", 255.0f);
-		CC.markOptionParsed("MaxConstraint");
 	} else {
-		// Constraint - OLD
-		m_bUseMaxConstraint = _cfg.self.getOptionBool("UseMaxConstraint", false);
-		CC.markOptionParsed("UseMaxConstraint");
-		if (m_bUseMaxConstraint) {
-			m_fMaxValue = _cfg.self.getOptionNumerical("MaxConstraintValue", 0.0f);
-			CC.markOptionParsed("MaxConstraintValue");
-		}
-	}
-
-	// GPU number
-	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
-	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
-	CC.markOptionParsed("GPUindex");
-	if (!_cfg.self.hasOption("GPUindex"))
-		CC.markOptionParsed("GPUIndex");
-
-	// Supersampling factors
-	m_iDetectorSuperSampling = 1;
-	m_iPixelSuperSampling = 1;
-	if (pCudaProjector) {
-		// New interface
 		m_iDetectorSuperSampling = pCudaProjector->getDetectorSuperSampling();
 		m_iPixelSuperSampling = pCudaProjector->getVoxelSuperSampling();
+		m_iGPUIndex = pCudaProjector->getGPUIndex();
 	}
+}
+
+//---------------------------------------------------------------------------------------
+// Initialize - Config
+bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg)
+{
+	ASTRA_ASSERT(_cfg.self);
+	ConfigStackCheck<CAlgorithm> CC("CudaReconstructionAlgorithm2D", this, _cfg);
+
+	m_bIsInitialized = CReconstructionAlgorithm2D::initialize(_cfg);
+
+	if (!m_bIsInitialized)
+		return false;
+
+	initializeFromProjector();
+
 	// Deprecated options
 	m_iDetectorSuperSampling = (int)_cfg.self.getOptionNumerical("DetectorSuperSampling", m_iDetectorSuperSampling);
 	m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", m_iPixelSuperSampling);
 	CC.markOptionParsed("DetectorSuperSampling");
 	CC.markOptionParsed("PixelSuperSampling");
 
+	// GPU number
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1);
+	m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex);
+	CC.markOptionParsed("GPUIndex");
+	if (!_cfg.self.hasOption("GPUIndex"))
+		CC.markOptionParsed("GPUindex");
 
 	return _check();
 }
@@ -198,33 +138,19 @@ bool CCudaReconstructionAlgorithm2D::initialize(const Config& _cfg)
 bool CCudaReconstructionAlgorithm2D::initialize(CProjector2D* _pProjector,
                                      CFloat32ProjectionData2D* _pSinogram, 
                                      CFloat32VolumeData2D* _pReconstruction)
-{
-	return initialize(_pProjector, _pSinogram, _pReconstruction, 0, 1);
-}
-
-//---------------------------------------------------------------------------------------
-// Initialize - C++
-bool CCudaReconstructionAlgorithm2D::initialize(CProjector2D* _pProjector,
-                                     CFloat32ProjectionData2D* _pSinogram, 
-                                     CFloat32VolumeData2D* _pReconstruction,
-                                     int _iGPUindex,
-                                     int _iDetectorSuperSampling,
-                                     int _iPixelSuperSampling)
 {
 	// if already initialized, clear first
 	if (m_bIsInitialized) {
 		clear();
 	}
 	
-	m_pProjector = 0;
+	m_pProjector = _pProjector;
 	
 	// required classes
 	m_pSinogram = _pSinogram;
 	m_pReconstruction = _pReconstruction;
 
-	m_iDetectorSuperSampling = _iDetectorSuperSampling;
-	m_iPixelSuperSampling = _iPixelSuperSampling;
-	m_iGPUIndex = _iGPUindex;
+	initializeFromProjector();
 
 	return _check();
 }
@@ -234,40 +160,13 @@ bool CCudaReconstructionAlgorithm2D::initialize(CProjector2D* _pProjector,
 // Check
 bool CCudaReconstructionAlgorithm2D::_check() 
 {
-	// TODO: CLEAN UP
-
-
-	// check pointers
-	//ASTRA_CONFIG_CHECK(m_pProjector, "Reconstruction2D", "Invalid Projector Object.");
-	ASTRA_CONFIG_CHECK(m_pSinogram, "SIRT_CUDA", "Invalid Projection Data Object.");
-	ASTRA_CONFIG_CHECK(m_pReconstruction, "SIRT_CUDA", "Invalid Reconstruction Data Object.");
-
-	// check initializations
-	//ASTRA_CONFIG_CHECK(m_pProjector->isInitialized(), "Reconstruction2D", "Projector Object Not Initialized.");
-	ASTRA_CONFIG_CHECK(m_pSinogram->isInitialized(), "SIRT_CUDA", "Projection Data Object Not Initialized.");
-	ASTRA_CONFIG_CHECK(m_pReconstruction->isInitialized(), "SIRT_CUDA", "Reconstruction Data Object Not Initialized.");
+	if (!CReconstructionAlgorithm2D::_check())
+		return false;
 
 	ASTRA_CONFIG_CHECK(m_iDetectorSuperSampling >= 1, "SIRT_CUDA", "DetectorSuperSampling must be a positive integer.");
 	ASTRA_CONFIG_CHECK(m_iPixelSuperSampling >= 1, "SIRT_CUDA", "PixelSuperSampling must be a positive integer.");
 	ASTRA_CONFIG_CHECK(m_iGPUIndex >= -1, "SIRT_CUDA", "GPUIndex must be a non-negative integer.");
 
-	// check compatibility between projector and data classes
-//	ASTRA_CONFIG_CHECK(m_pSinogram->getGeometry()->isEqual(m_pProjector->getProjectionGeometry()), "SIRT_CUDA", "Projection Data not compatible with the specified Projector.");
-//	ASTRA_CONFIG_CHECK(m_pReconstruction->getGeometry()->isEqual(m_pProjector->getVolumeGeometry()), "SIRT_CUDA", "Reconstruction Data not compatible with the specified Projector.");
-
-	// todo: turn some of these back on
-
-// 	ASTRA_CONFIG_CHECK(m_pProjectionGeometry, "SIRT_CUDA", "ProjectionGeometry not specified.");
-// 	ASTRA_CONFIG_CHECK(m_pProjectionGeometry->isInitialized(), "SIRT_CUDA", "ProjectionGeometry not initialized.");
-// 	ASTRA_CONFIG_CHECK(m_pReconstructionGeometry, "SIRT_CUDA", "ReconstructionGeometry not specified.");
-// 	ASTRA_CONFIG_CHECK(m_pReconstructionGeometry->isInitialized(), "SIRT_CUDA", "ReconstructionGeometry not initialized.");
-
-	// check dimensions
-	//ASTRA_CONFIG_CHECK(m_pSinogram->getAngleCount() == m_pProjectionGeometry->getProjectionAngleCount(), "SIRT_CUDA", "Sinogram data object size mismatch.");
-	//ASTRA_CONFIG_CHECK(m_pSinogram->getDetectorCount() == m_pProjectionGeometry->getDetectorCount(), "SIRT_CUDA", "Sinogram data object size mismatch.");
-	//ASTRA_CONFIG_CHECK(m_pReconstruction->getWidth() == m_pReconstructionGeometry->getGridColCount(), "SIRT_CUDA", "Reconstruction data object size mismatch.");
-	//ASTRA_CONFIG_CHECK(m_pReconstruction->getHeight() == m_pReconstructionGeometry->getGridRowCount(), "SIRT_CUDA", "Reconstruction data object size mismatch.");
-	
 	// check restrictions
 	// TODO: check restrictions built into cuda code
 
diff --git a/src/CudaSartAlgorithm.cpp b/src/CudaSartAlgorithm.cpp
index 8c0c6d7..d202847 100644
--- a/src/CudaSartAlgorithm.cpp
+++ b/src/CudaSartAlgorithm.cpp
@@ -116,10 +116,9 @@ bool CCudaSartAlgorithm::initialize(const Config& _cfg)
 // Initialize - C++
 bool CCudaSartAlgorithm::initialize(CProjector2D* _pProjector,
                                      CFloat32ProjectionData2D* _pSinogram, 
-                                     CFloat32VolumeData2D* _pReconstruction,
-                                     int _iGPUindex, int _iDetectorSuperSampling)
+                                     CFloat32VolumeData2D* _pReconstruction)
 {
-	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction, _iGPUindex, _iDetectorSuperSampling, 1);
+	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction);
 
 	if (!m_bIsInitialized)
 		return false;
diff --git a/src/CudaSirtAlgorithm.cpp b/src/CudaSirtAlgorithm.cpp
index d424915..ab0a418 100644
--- a/src/CudaSirtAlgorithm.cpp
+++ b/src/CudaSirtAlgorithm.cpp
@@ -98,11 +98,9 @@ bool CCudaSirtAlgorithm::initialize(const Config& _cfg)
 // Initialize - C++
 bool CCudaSirtAlgorithm::initialize(CProjector2D* _pProjector,
                                      CFloat32ProjectionData2D* _pSinogram, 
-                                     CFloat32VolumeData2D* _pReconstruction,
-                                     int _iGPUindex, int _iDetectorSuperSampling,
-                                     int _iPixelSuperSampling)
+                                     CFloat32VolumeData2D* _pReconstruction)
 {
-	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction, _iGPUindex, _iDetectorSuperSampling, _iPixelSuperSampling);
+	m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_pProjector, _pSinogram, _pReconstruction);
 
 	if (!m_bIsInitialized)
 		return false;
diff --git a/src/ReconstructionAlgorithm2D.cpp b/src/ReconstructionAlgorithm2D.cpp
index 767efe6..4575ff7 100644
--- a/src/ReconstructionAlgorithm2D.cpp
+++ b/src/ReconstructionAlgorithm2D.cpp
@@ -85,9 +85,16 @@ bool CReconstructionAlgorithm2D::initialize(const Config& _cfg)
 	
 	// projector
 	XMLNode node = _cfg.self.getSingleNode("ProjectorId");
-	ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectorId tag specified.");
-	int id = boost::lexical_cast<int>(node.getContent());
-	m_pProjector = CProjector2DManager::getSingleton().get(id);
+	if (requiresProjector()) {
+		ASTRA_CONFIG_CHECK(node, "Reconstruction2D", "No ProjectorId tag specified.");
+	}
+	int id;
+	if (node) {
+		id = boost::lexical_cast<int>(node.getContent());
+		m_pProjector = CProjector2DManager::getSingleton().get(id);
+	} else {
+		m_pProjector = 0;
+	}
 	CC.markNodeParsed("ProjectorId");
 
 	// sinogram data
@@ -205,18 +212,22 @@ void CReconstructionAlgorithm2D::setSinogramMask(CFloat32ProjectionData2D* _pMas
 bool CReconstructionAlgorithm2D::_check() 
 {
 	// check pointers
-	ASTRA_CONFIG_CHECK(m_pProjector, "Reconstruction2D", "Invalid Projector Object.");
+	if (requiresProjector())
+		ASTRA_CONFIG_CHECK(m_pProjector, "Reconstruction2D", "Invalid Projector Object.");
 	ASTRA_CONFIG_CHECK(m_pSinogram, "Reconstruction2D", "Invalid Projection Data Object.");
 	ASTRA_CONFIG_CHECK(m_pReconstruction, "Reconstruction2D", "Invalid Reconstruction Data Object.");
 
 	// check initializations
-	ASTRA_CONFIG_CHECK(m_pProjector->isInitialized(), "Reconstruction2D", "Projector Object Not Initialized.");
+	if (requiresProjector())
+		ASTRA_CONFIG_CHECK(m_pProjector->isInitialized(), "Reconstruction2D", "Projector Object Not Initialized.");
 	ASTRA_CONFIG_CHECK(m_pSinogram->isInitialized(), "Reconstruction2D", "Projection Data Object Not Initialized.");
 	ASTRA_CONFIG_CHECK(m_pReconstruction->isInitialized(), "Reconstruction2D", "Reconstruction Data Object Not Initialized.");
 
 	// check compatibility between projector and data classes
-	ASTRA_CONFIG_CHECK(m_pSinogram->getGeometry()->isEqual(m_pProjector->getProjectionGeometry()), "Reconstruction2D", "Projection Data not compatible with the specified Projector.");
-	ASTRA_CONFIG_CHECK(m_pReconstruction->getGeometry()->isEqual(m_pProjector->getVolumeGeometry()), "Reconstruction2D", "Reconstruction Data not compatible with the specified Projector.");
+	if (requiresProjector()) {
+		ASTRA_CONFIG_CHECK(m_pSinogram->getGeometry()->isEqual(m_pProjector->getProjectionGeometry()), "Reconstruction2D", "Projection Data not compatible with the specified Projector.");
+		ASTRA_CONFIG_CHECK(m_pReconstruction->getGeometry()->isEqual(m_pProjector->getVolumeGeometry()), "Reconstruction2D", "Reconstruction Data not compatible with the specified Projector.");
+	}
 
 	// success
 	return true;
-- 
cgit v1.2.3


From 33668f347d7fdcd700fc5e4e34153cbba7889c01 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Fri, 9 Oct 2015 11:46:05 +0200
Subject: Fix whitespace

---
 include/astra/CudaEMAlgorithm.h                | 4 ++--
 include/astra/CudaForwardProjectionAlgorithm.h | 4 ++--
 include/astra/CudaSartAlgorithm.h              | 4 ++--
 include/astra/CudaSirtAlgorithm.h              | 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/astra/CudaEMAlgorithm.h b/include/astra/CudaEMAlgorithm.h
index d313f7c..a9d2711 100644
--- a/include/astra/CudaEMAlgorithm.h
+++ b/include/astra/CudaEMAlgorithm.h
@@ -68,8 +68,8 @@ public:
 	 * @param _pReconstruction	VolumeData2D object for storing the reconstructed volume.
 	 */
 	bool initialize(CProjector2D* _pProjector,
-	                CFloat32ProjectionData2D* _pSinogram, 
-					CFloat32VolumeData2D* _pReconstruction);
+	                CFloat32ProjectionData2D* _pSinogram,
+	                CFloat32VolumeData2D* _pReconstruction);
 
 	/** Get a description of the class.
 	 *
diff --git a/include/astra/CudaForwardProjectionAlgorithm.h b/include/astra/CudaForwardProjectionAlgorithm.h
index 097d499..449a610 100644
--- a/include/astra/CudaForwardProjectionAlgorithm.h
+++ b/include/astra/CudaForwardProjectionAlgorithm.h
@@ -96,8 +96,8 @@ public:
 	 * @return success
 	 */
 	bool initialize(CProjector2D* _pProjector,
-					CFloat32VolumeData2D* _pVolume, 
-					CFloat32ProjectionData2D* _pSinogram);
+	                CFloat32VolumeData2D* _pVolume,
+	                CFloat32ProjectionData2D* _pSinogram);
 
 
 	/** Get all information parameters
diff --git a/include/astra/CudaSartAlgorithm.h b/include/astra/CudaSartAlgorithm.h
index 53d1e7b..c22dc4f 100644
--- a/include/astra/CudaSartAlgorithm.h
+++ b/include/astra/CudaSartAlgorithm.h
@@ -89,8 +89,8 @@ public:
 	 * @param _pReconstruction	VolumeData2D object for storing the reconstructed volume.
 	 */
 	bool initialize(CProjector2D* _pProjector,
-	                CFloat32ProjectionData2D* _pSinogram, 
-					CFloat32VolumeData2D* _pReconstruction);
+	                CFloat32ProjectionData2D* _pSinogram,
+	                CFloat32VolumeData2D* _pReconstruction);
 
 	/** Get a description of the class.
 	 *
diff --git a/include/astra/CudaSirtAlgorithm.h b/include/astra/CudaSirtAlgorithm.h
index 751d612..929ac30 100644
--- a/include/astra/CudaSirtAlgorithm.h
+++ b/include/astra/CudaSirtAlgorithm.h
@@ -102,8 +102,8 @@ public:
 	 * @param _pReconstruction	VolumeData2D object for storing the reconstructed volume.
 	 */
 	bool initialize(CProjector2D* _pProjector,
-	                CFloat32ProjectionData2D* _pSinogram, 
-					CFloat32VolumeData2D* _pReconstruction);
+	                CFloat32ProjectionData2D* _pSinogram,
+	                CFloat32VolumeData2D* _pReconstruction);
 
 	/** Get a description of the class.
 	 *
-- 
cgit v1.2.3


From f7e01f5a3ca7780a29d1fbc3790e527c310cc7f8 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Fri, 9 Oct 2015 15:55:11 +0200
Subject: Fix loop bounds in (unused) Float32ProjectionData3D arithmetic
 functions

---
 src/Float32ProjectionData3D.cpp | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/src/Float32ProjectionData3D.cpp b/src/Float32ProjectionData3D.cpp
index 2bd0447..680ad55 100644
--- a/src/Float32ProjectionData3D.cpp
+++ b/src/Float32ProjectionData3D.cpp
@@ -53,13 +53,13 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator+=(const CFloat32Pro
 	CProjectionGeometry3D * pThisGeometry = getGeometry();
 
 	int iProjectionCount = pThisGeometry->getProjectionCount();
+	int iDetectorCount = pThisGeometry->getDetectorTotCount();
 #ifdef _DEBUG
 	CProjectionGeometry3D * pDataGeometry = _data.getGeometry();
-	int iThisProjectionDetectorCount = pThisGeometry->getDetectorRowCount() * pThisGeometry->getDetectorColCount();
-	int iDataProjectionDetectorCount = pDataGeometry->getDetectorRowCount() * pDataGeometry->getDetectorColCount();
+	int iDataProjectionDetectorCount = pDataGeometry->getDetectorTotCount();
 
 	ASTRA_ASSERT(iProjectionCount == pDataGeometry->getProjectionCount());
-	ASTRA_ASSERT(iThisProjectionDetectorCount == iDataProjectionDetectorCount);
+	ASTRA_ASSERT(iDetectorCount == iDataProjectionDetectorCount);
 #endif
 
 	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
@@ -67,7 +67,7 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator+=(const CFloat32Pro
 		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);
 		CFloat32VolumeData2D * pDataProjection = _data.fetchProjection(iProjectionIndex);
 
-		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
+		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorCount; iDetectorIndex++)
 		{
 			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
 			float32 fDataValue = pDataProjection->getDataConst()[iDetectorIndex];
@@ -91,13 +91,13 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator-=(const CFloat32Pro
 	CProjectionGeometry3D * pThisGeometry = getGeometry();
 
 	int iProjectionCount = pThisGeometry->getProjectionCount();
+	int iDetectorCount = pThisGeometry->getDetectorTotCount();
 #ifdef _DEBUG
 	CProjectionGeometry3D * pDataGeometry = _data.getGeometry();
-	int iThisProjectionDetectorCount = pThisGeometry->getDetectorRowCount() * pThisGeometry->getDetectorColCount();
-	int iDataProjectionDetectorCount = pDataGeometry->getDetectorRowCount() * pDataGeometry->getDetectorColCount();
+	int iDataProjectionDetectorCount = pDataGeometry->getDetectorTotCount();
 
 	ASTRA_ASSERT(iProjectionCount == pDataGeometry->getProjectionCount());
-	ASTRA_ASSERT(iThisProjectionDetectorCount == iDataProjectionDetectorCount);
+	ASTRA_ASSERT(iDetectorCount == iDataProjectionDetectorCount);
 #endif
 
 	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
@@ -105,7 +105,7 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator-=(const CFloat32Pro
 		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);
 		CFloat32VolumeData2D * pDataProjection = _data.fetchProjection(iProjectionIndex);
 
-		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
+		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorCount; iDetectorIndex++)
 		{
 			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
 			float32 fDataValue = pDataProjection->getDataConst()[iDetectorIndex];
@@ -129,13 +129,13 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator*=(const CFloat32Pro
 	CProjectionGeometry3D * pThisGeometry = getGeometry();
 
 	int iProjectionCount = pThisGeometry->getProjectionCount();
+	int iDetectorCount = pThisGeometry->getDetectorTotCount();
 #ifdef _DEBUG
 	CProjectionGeometry3D * pDataGeometry = _data.getGeometry();
-	int iThisProjectionDetectorCount = pThisGeometry->getDetectorRowCount() * pThisGeometry->getDetectorColCount();
-	int iDataProjectionDetectorCount = pDataGeometry->getDetectorRowCount() * pDataGeometry->getDetectorColCount();
+	int iDataProjectionDetectorCount = pDataGeometry->getDetectorTotCount();
 
 	ASTRA_ASSERT(iProjectionCount == pDataGeometry->getProjectionCount());
-	ASTRA_ASSERT(iThisProjectionDetectorCount == iDataProjectionDetectorCount);
+	ASTRA_ASSERT(iDetectorCount == iDataProjectionDetectorCount);
 #endif
 
 	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
@@ -143,7 +143,7 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator*=(const CFloat32Pro
 		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);
 		CFloat32VolumeData2D * pDataProjection = _data.fetchProjection(iProjectionIndex);
 
-		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
+		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorCount; iDetectorIndex++)
 		{
 			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
 			float32 fDataValue = pDataProjection->getDataConst()[iDetectorIndex];
@@ -167,12 +167,13 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator*=(const float32& _f
 	CProjectionGeometry3D * pThisGeometry = getGeometry();
 
 	int iProjectionCount = pThisGeometry->getProjectionCount();
+	int iDetectorCount = pThisGeometry->getDetectorTotCount();
 
 	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
 	{
 		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);
 
-		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
+		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorCount; iDetectorIndex++)
 		{
 			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
 
@@ -194,12 +195,13 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator/=(const float32& _f
 	CProjectionGeometry3D * pThisGeometry = getGeometry();
 
 	int iProjectionCount = pThisGeometry->getProjectionCount();
+	int iDetectorCount = pThisGeometry->getDetectorTotCount();
 
 	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
 	{
 		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);
 
-		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
+		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorCount; iDetectorIndex++)
 		{
 			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
 
@@ -221,12 +223,13 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator+=(const float32& _f
 	CProjectionGeometry3D * pThisGeometry = getGeometry();
 
 	int iProjectionCount = pThisGeometry->getProjectionCount();
+	int iDetectorCount = pThisGeometry->getDetectorTotCount();
 
 	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
 	{
 		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);
 
-		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
+		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorCount; iDetectorIndex++)
 		{
 			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
 
@@ -248,12 +251,13 @@ CFloat32ProjectionData3D& CFloat32ProjectionData3D::operator-=(const float32& _f
 	CProjectionGeometry3D * pThisGeometry = getGeometry();
 
 	int iProjectionCount = pThisGeometry->getProjectionCount();
+	int iDetectorCount = pThisGeometry->getDetectorTotCount();
 
 	for(int iProjectionIndex = 0; iProjectionIndex < iProjectionCount; iProjectionIndex++)
 	{
 		CFloat32VolumeData2D * pThisProjection = fetchProjection(iProjectionIndex);
 
-		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorIndex; iDetectorIndex++)
+		for(int iDetectorIndex = 0; iDetectorIndex < iDetectorCount; iDetectorIndex++)
 		{
 			float32 fThisValue = pThisProjection->getData()[iDetectorIndex];
 
-- 
cgit v1.2.3


From c7128284fdbbfa0d4a5cbc951b9cdeaf8f9b41e0 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Fri, 9 Oct 2015 16:10:45 +0200
Subject: Call check() function after initializing CUDA_FBP

This would cause crashes when specifying invalid data.
---
 src/CudaFilteredBackProjectionAlgorithm.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp
index aac96d6..6353c46 100644
--- a/src/CudaFilteredBackProjectionAlgorithm.cpp
+++ b/src/CudaFilteredBackProjectionAlgorithm.cpp
@@ -189,9 +189,7 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg)
 	m_pFBP = new AstraFBP;
 	m_bAstraFBPInit = false;
 
-	// success
-	m_bIsInitialized = true;
-	return m_bIsInitialized;
+	return check();
 }
 
 bool CCudaFilteredBackProjectionAlgorithm::initialize(CFloat32ProjectionData2D * _pSinogram, CFloat32VolumeData2D * _pReconstruction, E_FBPFILTER _eFilter, const float * _pfFilter /* = NULL */, int _iFilterWidth /* = 0 */, int _iGPUIndex /* = 0 */, float _fFilterParameter /* = -1.0f */)
@@ -241,7 +239,7 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(CFloat32ProjectionData2D *
 
 	m_fFilterParameter = _fFilterParameter;
 
-	return m_bIsInitialized;
+	return check();
 }
 
 void CCudaFilteredBackProjectionAlgorithm::run(int _iNrIterations /* = 0 */)
@@ -361,7 +359,7 @@ bool CCudaFilteredBackProjectionAlgorithm::check()
 	ASTRA_CONFIG_CHECK(m_pReconstruction->isInitialized(), "FBP_CUDA", "Reconstruction Data Object Not Initialized.");
 
 	// check gpu index
-	ASTRA_CONFIG_CHECK(m_iGPUIndex >= -1, "FBP_CUDA", "GPUIndex must be a non-negative integer.");
+	ASTRA_CONFIG_CHECK(m_iGPUIndex >= -1, "FBP_CUDA", "GPUIndex must be a non-negative integer or -1.");
 	// check pixel supersampling
 	ASTRA_CONFIG_CHECK(m_iPixelSuperSampling >= 0, "FBP_CUDA", "PixelSuperSampling must be a non-negative integer.");
 
-- 
cgit v1.2.3


From fb44faa449990400861f1869b52f5afc8fefe01b Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Fri, 9 Oct 2015 16:19:54 +0200
Subject: Fix warning text

---
 src/CudaReconstructionAlgorithm2D.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp
index bccdb43..2d023b7 100644
--- a/src/CudaReconstructionAlgorithm2D.cpp
+++ b/src/CudaReconstructionAlgorithm2D.cpp
@@ -163,9 +163,9 @@ bool CCudaReconstructionAlgorithm2D::_check()
 	if (!CReconstructionAlgorithm2D::_check())
 		return false;
 
-	ASTRA_CONFIG_CHECK(m_iDetectorSuperSampling >= 1, "SIRT_CUDA", "DetectorSuperSampling must be a positive integer.");
-	ASTRA_CONFIG_CHECK(m_iPixelSuperSampling >= 1, "SIRT_CUDA", "PixelSuperSampling must be a positive integer.");
-	ASTRA_CONFIG_CHECK(m_iGPUIndex >= -1, "SIRT_CUDA", "GPUIndex must be a non-negative integer.");
+	ASTRA_CONFIG_CHECK(m_iDetectorSuperSampling >= 1, "CudaReconstructionAlgorithm2D", "DetectorSuperSampling must be a positive integer.");
+	ASTRA_CONFIG_CHECK(m_iPixelSuperSampling >= 1, "CudaReconstructionAlgorithm2D", "PixelSuperSampling must be a positive integer.");
+	ASTRA_CONFIG_CHECK(m_iGPUIndex >= -1, "CudaReconstructionAlgorithm2D", "GPUIndex must be a non-negative integer or -1.");
 
 	// check restrictions
 	// TODO: check restrictions built into cuda code
-- 
cgit v1.2.3


From 4298c2f212aac1e76f1f123ab199749a9a668415 Mon Sep 17 00:00:00 2001
From: Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>
Date: Fri, 9 Oct 2015 16:40:39 +0200
Subject: Give a warning on ignored Min/MaxContraint in some CUDA algorithms.

Previously it would fail an assertion.
---
 src/CudaReconstructionAlgorithm2D.cpp | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp
index 71b6637..18627fc 100644
--- a/src/CudaReconstructionAlgorithm2D.cpp
+++ b/src/CudaReconstructionAlgorithm2D.cpp
@@ -462,10 +462,18 @@ void CCudaReconstructionAlgorithm2D::run(int _iNrIterations)
 
 	ASTRA_ASSERT(ok);
 
-	if (m_bUseMinConstraint)
-		ok &= m_pAlgo->setMinConstraint(m_fMinValue);
-	if (m_bUseMaxConstraint)
-		ok &= m_pAlgo->setMaxConstraint(m_fMaxValue);
+	if (m_bUseMinConstraint) {
+		bool ret = m_pAlgo->setMinConstraint(m_fMinValue);
+		if (!ret) {
+			ASTRA_WARN("This algorithm ignores MinConstraint");
+		}
+	}
+	if (m_bUseMaxConstraint) {
+		bool ret= m_pAlgo->setMaxConstraint(m_fMaxValue);
+		if (!ret) {
+			ASTRA_WARN("This algorithm ignores MaxConstraint");
+		}
+	}
 
 	ok &= m_pAlgo->iterate(_iNrIterations);
 	ASTRA_ASSERT(ok);
-- 
cgit v1.2.3


From 21d08656ead6f974f83b0a02b03b105a7cd617a8 Mon Sep 17 00:00:00 2001
From: "Daniel M. Pelt" <D.M.Pelt@cwi.nl>
Date: Tue, 13 Oct 2015 17:02:09 +0200
Subject: Do not reuse va_list when logging both to screen and file

---
 src/Logging.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 44 insertions(+), 16 deletions(-)

diff --git a/src/Logging.cpp b/src/Logging.cpp
index 8290ca0..cd7e3f0 100644
--- a/src/Logging.cpp
+++ b/src/Logging.cpp
@@ -70,37 +70,65 @@ void CLogger::disable()
 void CLogger::debug(const char *sfile, int sline, const char *fmt, ...)
 {
 	_assureIsInitialized();
-	va_list ap;
-	va_start(ap, fmt);
-	if(m_bEnabledScreen) clog_debug(sfile,sline,0,fmt,ap);
-	if(m_bEnabledFile && m_bFileProvided) clog_debug(sfile,sline,1,fmt,ap);
+	va_list ap, apf;
+	if(m_bEnabledScreen){
+        va_start(ap, fmt);
+        clog_debug(sfile,sline,0,fmt,ap);
+        va_end(ap);
+    }
+	if(m_bEnabledFile && m_bFileProvided){
+        va_start(apf, fmt);
+        clog_debug(sfile,sline,1,fmt,apf);
+        va_end(apf);
+    }
 }
 
 void CLogger::info(const char *sfile, int sline, const char *fmt, ...)
 {
 	_assureIsInitialized();
-	va_list ap;
-	va_start(ap, fmt);
-	if(m_bEnabledScreen) clog_info(sfile,sline,0,fmt,ap);
-	if(m_bEnabledFile && m_bFileProvided) clog_info(sfile,sline,1,fmt,ap);
+	va_list ap, apf;
+	if(m_bEnabledScreen){
+        va_start(ap, fmt);
+        clog_info(sfile,sline,0,fmt,ap);
+        va_end(ap);
+    }
+	if(m_bEnabledFile && m_bFileProvided){
+        va_start(apf, fmt);
+        clog_info(sfile,sline,1,fmt,apf);
+        va_end(apf);
+    }
 }
 
 void CLogger::warn(const char *sfile, int sline, const char *fmt, ...)
 {
 	_assureIsInitialized();
-	va_list ap;
-	va_start(ap, fmt);
-	if(m_bEnabledScreen) clog_warn(sfile,sline,0,fmt,ap);
-	if(m_bEnabledFile && m_bFileProvided) clog_warn(sfile,sline,1,fmt,ap);
+	va_list ap, apf;
+	if(m_bEnabledScreen){
+        va_start(ap, fmt);
+        clog_warn(sfile,sline,0,fmt,ap);
+        va_end(ap);
+    }
+	if(m_bEnabledFile && m_bFileProvided){
+        va_start(apf, fmt);
+        clog_warn(sfile,sline,1,fmt,apf);
+        va_end(apf);
+    }
 }
 
 void CLogger::error(const char *sfile, int sline, const char *fmt, ...)
 {
 	_assureIsInitialized();
-	va_list ap;
-	va_start(ap, fmt);
-	if(m_bEnabledScreen) clog_error(sfile,sline,0,fmt,ap);
-	if(m_bEnabledFile && m_bFileProvided) clog_error(sfile,sline,1,fmt,ap);
+	va_list ap, apf;
+	if(m_bEnabledScreen){
+        va_start(ap, fmt);
+        clog_error(sfile,sline,0,fmt,ap);
+        va_end(ap);
+    }
+	if(m_bEnabledFile && m_bFileProvided){
+        va_start(apf, fmt);
+        clog_error(sfile,sline,1,fmt,apf);
+        va_end(apf);
+    }
 }
 
 void CLogger::_setLevel(int id, log_level m_eLevel)
-- 
cgit v1.2.3