diff --git a/src/pyronn_torch/conebeam.py b/src/pyronn_torch/conebeam.py
index 816845d6a45675a21d37f94ed5c5371010b7501c..95791748653e23fdce21546c223f78dcaa353277 100644
--- a/src/pyronn_torch/conebeam.py
+++ b/src/pyronn_torch/conebeam.py
@@ -2,20 +2,20 @@
 # Copyright © 2020 Stephan Seitz <stephan.seitz@fau.de>
 #
 # Distributed under terms of the GPLv3 license.
-
 """
 
 """
 import numpy as np
-import sympy as sp
 import torch
 
 import pyronn_torch
+import sympy as sp
 
 
 class _ForwardProjection(torch.autograd.Function):
-
-    def __init__(self, projection_shape,
+    def __init__(self,
+                 projection_shape,
+                 volume_shape,
                  source_points,
                  inverse_matrices,
                  projection_matrices,
@@ -25,6 +25,7 @@ class _ForwardProjection(torch.autograd.Function):
                  step_size=1.,
                  with_texture=True):
         self.projection_shape = projection_shape
+        self.volume_shape = volume_shape
         self.source_points = source_points
         self.inverse_matrices = inverse_matrices
         self.projection_matrices = projection_matrices
@@ -36,41 +37,31 @@ class _ForwardProjection(torch.autograd.Function):
 
     def forward(self, volume):
         volume = volume.cuda().contiguous()
-        projection = torch.zeros(self.projection_shape, device='cuda', requires_grad=volume.requires_grad)
+        projection = torch.zeros(self.projection_shape,
+                                 device='cuda',
+                                 requires_grad=volume.requires_grad)
 
         assert pyronn_torch.cpp_extension
         if self.with_texture:
             pyronn_torch.cpp_extension.call_Cone_Projection_Kernel_Tex_Interp_Launcher(
-                self.inverse_matrices,
-                projection,
-                self.source_points,
-                self.step_size,
-                volume,
-                *self.volume_spacing)
+                self.inverse_matrices, projection, self.source_points,
+                self.step_size, volume, *self.volume_spacing)
         else:
             pyronn_torch.cpp_extension.call_Cone_Projection_Kernel_Launcher(
-                self.inverse_matrices,
-                projection,
-                self.source_points,
-                self.step_size,
-                volume,
-                *self.volume_spacing)
+                self.inverse_matrices, projection, self.source_points,
+                self.step_size, volume, *self.volume_spacing)
 
         return projection,
 
     def backward(self, *projection_grad):
         projection_grad = projection_grad[0]
-        self.projection_matrices
-        volume_grad = torch.zeros(self.volume_shape, device='cuda')
+        volume_grad = torch.zeros(self.volume_shape, device='cuda', requires_grad=projection_grad.requires_grad)
 
         assert pyronn_torch.cpp_extension
         pyronn_torch.cpp_extension.call_Cone_Backprojection3D_Kernel_Launcher(
-            self.projection_matrices,
-            projection_grad,
-            self.projection_multiplier,
-            volume_grad,
-            self.volume_origin,
-            self.volume_spacing)
+            self.projection_matrices, projection_grad,
+            self.projection_multiplier, volume_grad, *self.volume_origin,
+            *self.volume_spacing)
 
         return volume_grad,
 
@@ -82,14 +73,8 @@ class _BackwardProjection(torch.autograd.Function):
 
 
 class ConeBeamProjector:
-
-    def __init__(self,
-                 volume_shape,
-                 volume_spacing,
-                 volume_origin,
-                 projection_shape,
-                 projection_spacing,
-                 projection_origin,
+    def __init__(self, volume_shape, volume_spacing, volume_origin,
+                 projection_shape, projection_spacing, projection_origin,
                  projection_matrices):
         self._volume_shape = volume_shape
         self._volume_origin = volume_origin
@@ -108,74 +93,82 @@ class ConeBeamProjector:
         volume_spacing = pyconrad.config.get_reco_spacing()
         volume_origin = pyconrad.config.get_reco_origin()
         projection_shape = pyconrad.config.get_sino_shape()
-        projection_spacing = [pyconrad.config.get_geometry().getPixelDimensionY(),
-                              pyconrad.config.get_geometry().getPixelDimensionX()]
-        projection_origin = [pyconrad.config.get_geometry().getDetectorOffsetV(),
-                             pyconrad.config.get_geometry().getDetectorOffsetU()]
+        projection_spacing = [
+            pyconrad.config.get_geometry().getPixelDimensionY(),
+            pyconrad.config.get_geometry().getPixelDimensionX()
+        ]
+        projection_origin = [
+            pyconrad.config.get_geometry().getDetectorOffsetV(),
+            pyconrad.config.get_geometry().getDetectorOffsetU()
+        ]
         projection_matrices = pyconrad.config.get_projection_matrices()
 
-        obj = cls(volume_shape,
-                  volume_spacing,
-                  volume_origin,
-                  projection_shape,
-                  projection_spacing,
-                  projection_origin,
+        obj = cls(volume_shape, volume_spacing, volume_origin,
+                  projection_shape, projection_spacing, projection_origin,
                   projection_matrices)
         return obj
 
     def new_volume_tensor(self, requires_grad=False):
-        return torch.zeros(self._volume_shape, requires_grad=requires_grad).cuda()
+        return torch.zeros(self._volume_shape,
+                           requires_grad=requires_grad).cuda()
 
     def new_projection_tensor(self, requires_grad=False):
-        return torch.zeros(self._projection_shape, requires_grad=requires_grad).cuda()
+        return torch.zeros(self._projection_shape,
+                           requires_grad=requires_grad).cuda()
 
     def project_forward(self, volume, step_size=1., use_texture=True):
-        return _ForwardProjection(self._projection_shape,
-                                  self._source_points,
-                                  self._inverse_matrices,
+        return _ForwardProjection(self._projection_shape, self._volume_shape,
+                                  self._source_points, self._inverse_matrices,
                                   self._projection_matrices,
-                                  self._volume_origin,
-                                  self._volume_shape,
-                                  self._projection_multiplier,
-                                  step_size,
+                                  self._volume_origin, self._volume_spacing,
+                                  self._projection_multiplier, step_size,
                                   use_texture).forward(volume)[0]
 
-    def project_backward(self, projection_stack, step_size=1., use_texture=True):
-        return _BackwardProjection(self._projection_shape,
-                                   self._source_points,
-                                   self._inverse_matrices,
+    def project_backward(self,
+                         projection_stack,
+                         step_size=1.,
+                         use_texture=True):
+        return _BackwardProjection(self._projection_shape, self._volume_shape,
+                                   self._source_points, self._inverse_matrices,
                                    self._projection_matrices,
-                                   self._volume_origin,
-                                   self._volume_shape,
-                                   self._projection_multiplier,
-                                   step_size,
-                                   use_texture).backward(projection_stack)[0]
+                                   self._volume_origin, self._volume_spacing,
+                                   self._projection_multiplier, step_size,
+                                   use_texture).forward(projection_stack)[0]
 
     def _calc_inverse_matrices(self):
         if self._projection_matrices_numpy is None:
             return
-        self._projection_matrices = torch.stack(tuple(
-            map(torch.from_numpy, self._projection_matrices_numpy))).cuda().contiguous()
-
-        inv_spacing = np.array([1/s for s in reversed(self._volume_spacing)], np.float32)
-
-        camera_centers = map(lambda x: np.array(sp.Matrix(x).nullspace(), np.float32), self._projection_matrices_numpy)
-
-        source_points = map(lambda x: (x[0, :3] / x[0, 3] * inv_spacing - np.array(list(reversed(self._volume_origin)))
-                                       * inv_spacing).astype(np.float32), camera_centers)
-
-        inv_matrices = map(lambda x: (np.linalg.inv(x[:3, :3]) *
-                                      inv_spacing).astype(np.float32), self._projection_matrices_numpy)
-
-        self._inverse_matrices = torch.stack(tuple(map(torch.from_numpy, inv_matrices))).cuda().contiguous()
-        self._source_points = torch.stack(tuple(map(torch.from_numpy, source_points))).cuda().contiguous()
+        self._projection_matrices = torch.stack(
+            tuple(torch.from_numpy(p.astype(np.float32)) for p in self._projection_matrices_numpy)).cuda().contiguous()
+
+        inv_spacing = np.array([1 / s for s in reversed(self._volume_spacing)],
+                               np.float32)
+
+        camera_centers = map(
+            lambda x: np.array(sp.Matrix(x).nullspace(), np.float32),
+            self._projection_matrices_numpy)
+
+        source_points = map(
+            lambda x: (x[0, :3] / x[0, 3] * inv_spacing - np.array(
+                list(reversed(self._volume_origin))) * inv_spacing).astype(
+                    np.float32), camera_centers)
+
+        inv_matrices = map(
+            lambda x:
+            (np.linalg.inv(x[:3, :3]) * inv_spacing).astype(np.float32),
+            self._projection_matrices_numpy)
+
+        self._inverse_matrices = torch.stack(
+            tuple(map(torch.from_numpy, inv_matrices))).cuda().contiguous()
+        self._source_points = torch.stack(
+            tuple(map(torch.from_numpy, source_points))).cuda().contiguous()
         self._projection_multiplier = 1.
 
     @property
     def projection_matrices(self):
-         return self._projection_matrices_numpy
+        return self._projection_matrices_numpy
 
     @projection_matrices.setter
     def projection_matrices(self, numpy_matrices):
-         self._projection_matrices_numpy = numpy_matrices
-         self._calc_inverse_matrices()
+        self._projection_matrices_numpy = numpy_matrices
+        self._calc_inverse_matrices()
diff --git a/tests/test_projection.py b/tests/test_projection.py
index 96f815920c1d2d0c186b14c7b653b4cf28c5cda7..35ff398a5842ab16e5617289284ef5b6afa87305 100644
--- a/tests/test_projection.py
+++ b/tests/test_projection.py
@@ -6,7 +6,6 @@
 """
 
 """
-import os
 
 import numpy as np
 import pytest
@@ -73,11 +72,14 @@ def test_projection_backward(with_texture, with_backward):
                    [-9.99847710e-01, -1.74524058e-2,  0.00000000e+0,
                     6.00000000e+2]]])
     )
-
     projection = projector.new_projection_tensor(requires_grad=True if with_backward else False)
 
     projection += 1.
+
     result = projector.project_backward(projection, use_texture=with_texture)
+    import pyconrad.autoinit
+    pyconrad.imshow(result)
+    assert result.shape == projector._volume_shape
 
     assert result is not None
     if with_backward:
@@ -99,6 +101,8 @@ def test_conrad_config(with_backward, with_texture=True):
 
     volume += 1.
     result = projector.project_forward(volume, use_texture=with_texture)
+    import pyconrad.autoinit
+    pyconrad.imshow(result)
 
     assert result is not None
     if with_backward:
@@ -107,3 +111,49 @@ def test_conrad_config(with_backward, with_texture=True):
 
         loss = result.mean()
         loss.backward()
+
+
+def test_projection_backward_conrad(with_texture=True, with_backward=True):
+    import pytest
+    pytest.importorskip("pyconrad")
+
+    projector = pyronn_torch.ConeBeamProjector.from_conrad_config()
+
+    projection = projector.new_projection_tensor(requires_grad=True if with_backward else False)
+
+    projection += 1000.
+
+    result = projector.project_backward(projection, use_texture=with_texture)
+    import pyconrad.autoinit
+    pyconrad.imshow(result)
+    assert result.shape == projector._volume_shape
+
+    assert result is not None
+    if with_backward:
+        assert projection.requires_grad
+        assert result.requires_grad
+
+        loss = result.mean()
+        loss.backward()
+
+
+def test_conrad_forward_backward():
+    import pytest
+    pytest.importorskip("pyconrad")
+
+    projector = pyronn_torch.ConeBeamProjector.from_conrad_config()
+
+    volume = projector.new_volume_tensor()
+
+    volume += 1.
+    result = projector.project_forward(volume)
+
+    reco = projector.project_backward(result)
+    import pyconrad.autoinit
+    pyconrad.imshow(reco)
+
+    assert result is not None
+    assert reco is not None
+
+    while True:
+        pass