From e8765bcdab3be977cd5536531cacb24bf3378a59 Mon Sep 17 00:00:00 2001
From: Wim van Aarle <wimvanaarle@gmail.com>
Date: Thu, 12 Mar 2015 17:32:28 +0100
Subject: added parallel_vec to the python bindings

---
 python/astra/PyIncludes.pxd |  4 ++++
 python/astra/creators.py    | 13 +++++++++++++
 python/astra/data2d_c.pyx   |  4 ++++
 python/astra/functions.py   | 22 +++++++++++++++++++++-
 python/astra/utils.pyx      |  2 ++
 5 files changed, 44 insertions(+), 1 deletion(-)

(limited to 'python/astra')

diff --git a/python/astra/PyIncludes.pxd b/python/astra/PyIncludes.pxd
index fc5980f..5a81844 100644
--- a/python/astra/PyIncludes.pxd
+++ b/python/astra/PyIncludes.pxd
@@ -109,6 +109,10 @@ cdef extern from "astra/FanFlatVecProjectionGeometry2D.h" namespace "astra":
 	cdef cppclass CFanFlatVecProjectionGeometry2D:
 		CFanFlatVecProjectionGeometry2D()
 
+cdef extern from "astra/ParallelVecProjectionGeometry2D.h" namespace "astra":
+	cdef cppclass CParallelVecProjectionGeometry2D:
+		CParallelVecProjectionGeometry2D()
+
 cdef extern from "astra/ParallelProjectionGeometry2D.h" namespace "astra":
 	cdef cppclass CParallelProjectionGeometry2D:
 		CParallelProjectionGeometry2D()
diff --git a/python/astra/creators.py b/python/astra/creators.py
index 9aba464..b5ecd5a 100644
--- a/python/astra/creators.py
+++ b/python/astra/creators.py
@@ -139,6 +139,13 @@ This method can be called in a number of ways:
 :type angles: :class:`numpy.ndarray`
 :returns: A parallel projection geometry.
 
+``create_proj_geom('parallel_vec', det_count, V)``:
+
+:param det_count: Number of detector pixels.
+:type det_count: :class:`int`
+:param V: Vector array.
+:type V: :class:`numpy.ndarray`
+:returns: A parallel-beam projection geometry.
 
 ``create_proj_geom('fanflat', det_width, det_count, angles, source_origin, source_det)``:
 
@@ -226,6 +233,12 @@ This method can be called in a number of ways:
             raise Exception(
                 'not enough variables: astra_create_proj_geom(parallel, detector_spacing, det_count, angles)')
         return {'type': 'parallel', 'DetectorWidth': args[0], 'DetectorCount': args[1], 'ProjectionAngles': args[2]}
+    elif intype == 'parallel_vec':
+        if len(args) < 2:
+            raise Exception('not enough variables: astra_create_proj_geom(parallel_vec, det_count, V)')
+        if not args[1].shape[1] == 6:
+            raise Exception('V should be a Nx6 matrix, with N the number of projections')
+        return {'type':'parallel_vec', 'DetectorCount':args[0], 'Vectors':args[1]}
     elif intype == 'fanflat':
         if len(args) < 5:
             raise Exception('not enough variables: astra_create_proj_geom(fanflat, det_width, det_count, angles, source_origin, source_det)')
diff --git a/python/astra/data2d_c.pyx b/python/astra/data2d_c.pyx
index ec1b478..dbe1c2f 100644
--- a/python/astra/data2d_c.pyx
+++ b/python/astra/data2d_c.pyx
@@ -90,6 +90,8 @@ def create(datatype, geometry, data=None):
             ppGeometry = <CProjectionGeometry2D * >new CFanFlatProjectionGeometry2D()
         elif (tpe == 'fanflat_vec'):
             ppGeometry = <CProjectionGeometry2D * >new CFanFlatVecProjectionGeometry2D()
+        elif (tpe == 'parallel_vec'):
+            ppGeometry = <CProjectionGeometry2D * >new CParallelVecProjectionGeometry2D()
         else:
             ppGeometry = <CProjectionGeometry2D * >new CParallelProjectionGeometry2D()
         if not ppGeometry.initialize(cfg):
@@ -181,6 +183,8 @@ def change_geometry(i, geom):
             ppGeometry = <CProjectionGeometry2D * >new CFanFlatProjectionGeometry2D()
         elif (tpe == 'fanflat_vec'):
             ppGeometry = <CProjectionGeometry2D * >new CFanFlatVecProjectionGeometry2D()
+        elif (tpe == 'parallel_vec'):
+            ppGeometry = <CProjectionGeometry2D * >new CParallelVecProjectionGeometry2D()
         else:
             ppGeometry = <CProjectionGeometry2D * >new CParallelProjectionGeometry2D()
         if not ppGeometry.initialize(cfg):
diff --git a/python/astra/functions.py b/python/astra/functions.py
index 4025468..b9deb66 100644
--- a/python/astra/functions.py
+++ b/python/astra/functions.py
@@ -189,7 +189,27 @@ def geom_2vec(proj_geom):
     :param proj_geom: Projection geometry to convert
     :type proj_geom: :class:`dict`
     """
-    if proj_geom['type'] == 'fanflat':
+
+    if proj_geom['type'] == 'parallel':
+        angles = proj_geom['ProjectionAngles']
+        vectors = np.zeros((len(angles), 6))
+        for i in range(len(angles)):
+
+            # source
+            vectors[i, 0] = np.sin(angles[i])
+            vectors[i, 1] = -np.cos(angles[i])
+
+            # center of detector
+            vectors[i, 2] = 0
+            vectors[i, 3] = 0
+
+            # vector from detector pixel 0 to 1
+            vectors[i, 4] = np.cos(angles[i]) * proj_geom['DetectorWidth']
+            vectors[i, 5] = np.sin(angles[i]) * proj_geom['DetectorWidth']
+        proj_geom_out = ac.create_proj_geom(
+        'parallel_vec', proj_geom['DetectorCount'], vectors)
+
+    elif proj_geom['type'] == 'fanflat':
         angles = proj_geom['ProjectionAngles']
         vectors = np.zeros((len(angles), 6))
         for i in range(len(angles)):
diff --git a/python/astra/utils.pyx b/python/astra/utils.pyx
index 53e84a9..0b8d527 100644
--- a/python/astra/utils.pyx
+++ b/python/astra/utils.pyx
@@ -227,6 +227,8 @@ cdef createProjectionGeometryStruct(CProjectionGeometry2D * geom):
         # dct['Vectors'] = vecs
     if (geom.isOfType(< string > six.b('parallel'))):
         dct["type"] = "parallel"
+    if (geom.isOfType(< string > six.b('parallel_vec'))):
+        dct["type"] = "parallel_vec"        
     elif (geom.isOfType(< string > six.b('fanflat'))):
         raise Exception("Not yet implemented")
         # astra::CFanFlatProjectionGeometry2D* pFanFlatGeom = dynamic_cast<astra::CFanFlatProjectionGeometry2D*>(_pProjGeom)
-- 
cgit v1.2.3