Commit 5d96e144 authored by David Frank's avatar David Frank Committed by Tobias Lasser

#64 Move geometry to core, use Strong typing in Geometry interface

- Move geometry to core module
- Use strong types for Geometry (Old constructors are kept for now, but are just wrappers, most of them use constexpr)
- Added some convience overloads for RotationAngles3D and GeometryData
- Fixed tests for removing old constructors (CircluarTrajectoryGenerator, Projectors)
parent 4d703b69
Pipeline #277596 passed with stages
in 59 minutes and 23 seconds
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <cstdlib> #include <cstdlib>
using namespace elsa; using namespace elsa;
using namespace elsa::geometry;
static const index_t dimension = 2; static const index_t dimension = 2;
void iterate2D(const Geometry& geo) void iterate2D(const Geometry& geo)
...@@ -48,18 +50,20 @@ TEST_CASE("Ray generation for 2D") ...@@ -48,18 +50,20 @@ TEST_CASE("Ray generation for 2D")
{ {
IndexVector_t volCoeff(2); IndexVector_t volCoeff(2);
volCoeff << 5, 5; volCoeff << 5, 5;
VolumeDescriptor ddVol(volCoeff);
IndexVector_t detCoeff(1); IndexVector_t detCoeff(2);
detCoeff << 5; detCoeff << 5, 1;
VolumeDescriptor ddDet(detCoeff);
real_t s2c = 10; real_t s2c = 10;
real_t c2d = 4; real_t c2d = 4;
auto volData = VolumeData2D{Size2D{volCoeff}};
auto sinoData = SinogramData2D{Size2D{detCoeff}};
GIVEN("Geometry without offset and rotation") GIVEN("Geometry without offset and rotation")
{ {
Geometry g(s2c, c2d, 0, ddVol, ddDet); Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d}, Degree{0},
std::move(volData), std::move(sinoData));
// test outer + central pixels // test outer + central pixels
iterate2D(g); iterate2D(g);
...@@ -67,8 +71,8 @@ TEST_CASE("Ray generation for 2D") ...@@ -67,8 +71,8 @@ TEST_CASE("Ray generation for 2D")
GIVEN("Geometry with offset but no rotation") GIVEN("Geometry with offset but no rotation")
{ {
real_t offset = 2; Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d}, Degree{0},
Geometry g(s2c, c2d, 0, ddVol, ddDet, offset); std::move(volData), std::move(sinoData), PrincipalPointOffset{2});
// test outer + central pixels // test outer + central pixels
iterate2D(g); iterate2D(g);
...@@ -76,8 +80,8 @@ TEST_CASE("Ray generation for 2D") ...@@ -76,8 +80,8 @@ TEST_CASE("Ray generation for 2D")
GIVEN("Geometry at 90°, but no offset") GIVEN("Geometry at 90°, but no offset")
{ {
real_t angle = pi_t / 2; // 90 degrees Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d}, Degree{90},
Geometry g(s2c, c2d, angle, ddVol, ddDet); std::move(volData), std::move(sinoData));
// test outer + central pixels // test outer + central pixels
iterate2D(g); iterate2D(g);
...@@ -85,10 +89,9 @@ TEST_CASE("Ray generation for 2D") ...@@ -85,10 +89,9 @@ TEST_CASE("Ray generation for 2D")
GIVEN("Geometry at 45° with offset") GIVEN("Geometry at 45° with offset")
{ {
real_t angle = pi_t / 4; // 45 degrees Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d}, Degree{45},
real_t cx = -1; std::move(volData), std::move(sinoData), PrincipalPointOffset{0},
real_t cy = 2; RotationOffset2D{-1, 2});
Geometry g(s2c, c2d, angle, ddVol, ddDet, 0, cx, cy);
// test outer + central pixels // test outer + central pixels
iterate2D(g); iterate2D(g);
...@@ -101,16 +104,20 @@ TEST_CASE("Ray generation for 3D") ...@@ -101,16 +104,20 @@ TEST_CASE("Ray generation for 3D")
volCoeff << 5, 5, 5; volCoeff << 5, 5, 5;
VolumeDescriptor ddVol(volCoeff); VolumeDescriptor ddVol(volCoeff);
IndexVector_t detCoeff(2); IndexVector_t detCoeff(3);
detCoeff << 5, 5; detCoeff << 5, 5, 1;
VolumeDescriptor ddDet(detCoeff); VolumeDescriptor ddDet(detCoeff);
real_t s2c = 10; real_t s2c = 10;
real_t c2d = 4; real_t c2d = 4;
auto volData = VolumeData3D{Size3D{volCoeff}};
auto sinoData = SinogramData3D{Size3D{detCoeff}};
GIVEN("Geometry without offset and rotation") GIVEN("Geometry without offset and rotation")
{ {
Geometry g(s2c, c2d, ddVol, ddDet, 0); Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
std::move(volData), std::move(sinoData), RotationAngles3D{Gamma(0)});
// test outer + central pixels // test outer + central pixels
iterate3D(g); iterate3D(g);
...@@ -118,9 +125,9 @@ TEST_CASE("Ray generation for 3D") ...@@ -118,9 +125,9 @@ TEST_CASE("Ray generation for 3D")
GIVEN("Geometry with offset but no rotation") GIVEN("Geometry with offset but no rotation")
{ {
real_t px = -1; Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
real_t py = 3; std::move(volData), std::move(sinoData), RotationAngles3D{Gamma{0}},
Geometry g(s2c, c2d, ddVol, ddDet, 0, 0, 0, px, py); PrincipalPointOffset2D{0, 0}, RotationOffset3D{-1, 3, 0});
// test outer + central pixels // test outer + central pixels
iterate3D(g); iterate3D(g);
...@@ -128,8 +135,8 @@ TEST_CASE("Ray generation for 3D") ...@@ -128,8 +135,8 @@ TEST_CASE("Ray generation for 3D")
GIVEN("Geometry at 90°, but no offset") GIVEN("Geometry at 90°, but no offset")
{ {
real_t angle = pi_t / 2; Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
Geometry g(s2c, c2d, ddVol, ddDet, angle); std::move(volData), std::move(sinoData), RotationAngles3D{Gamma{pi_t / 2}});
// test outer + central pixels // test outer + central pixels
iterate3D(g); iterate3D(g);
...@@ -139,11 +146,11 @@ TEST_CASE("Ray generation for 3D") ...@@ -139,11 +146,11 @@ TEST_CASE("Ray generation for 3D")
{ {
real_t angle1 = pi_t / 4; real_t angle1 = pi_t / 4;
real_t angle2 = pi_t / 2; real_t angle2 = pi_t / 2;
RealVector_t offset(3);
offset << 1, -2, -1;
Geometry g(s2c, c2d, ddVol, ddDet, angle1, angle2, 0, 0, 0, offset[0], offset[1],
offset[2]);
Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
std::move(volData), std::move(sinoData),
RotationAngles3D{Gamma{angle1}, Beta{angle2}}, PrincipalPointOffset2D{0, 0},
RotationOffset3D{1, -2, -1});
// test outer + central pixels // test outer + central pixels
iterate3D(g); iterate3D(g);
} }
...@@ -173,4 +180,4 @@ TEST_CASE("Ray generation for 3D") ...@@ -173,4 +180,4 @@ TEST_CASE("Ray generation for 3D")
// test outer + central pixels // test outer + central pixels
iterate3D(g); iterate3D(g);
} }
} }
\ No newline at end of file
...@@ -24,7 +24,9 @@ set(MODULE_HEADERS ...@@ -24,7 +24,9 @@ set(MODULE_HEADERS
Handlers/DataHandlerMapCPU.h Handlers/DataHandlerMapCPU.h
LinearOperator.h LinearOperator.h
Expression.h Expression.h
ExpressionPredicates.h) ExpressionPredicates.h
Geometry.h
StrongTypes.h)
# list all the code files of the module # list all the code files of the module
set(MODULE_SOURCES set(MODULE_SOURCES
...@@ -37,7 +39,9 @@ set(MODULE_SOURCES ...@@ -37,7 +39,9 @@ set(MODULE_SOURCES
DataContainer.cpp DataContainer.cpp
Handlers/DataHandlerCPU.cpp Handlers/DataHandlerCPU.cpp
Handlers/DataHandlerMapCPU.cpp Handlers/DataHandlerMapCPU.cpp
LinearOperator.cpp) LinearOperator.cpp
Geometry.cpp
StrongTypes.cpp)
if(${ELSA_CUDA_VECTOR}) if(${ELSA_CUDA_VECTOR})
set(MODULE_HEADERS set(MODULE_HEADERS
......
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
namespace elsa namespace elsa
{ {
Geometry::Geometry(real_t sourceToCenterOfRotation, real_t centerOfRotationToDetector, using namespace geometry;
real_t angle, const DataDescriptor& volumeDescriptor,
const DataDescriptor& sinoDescriptor, real_t offset, Geometry::Geometry(SourceToCenterOfRotation sourceToCenterOfRotation,
real_t centerOfRotationOffsetX, real_t centerOfRotationOffsetY) CenterOfRotationToDetector centerOfRotationToDetector, Radian angle,
VolumeData2D&& volData, SinogramData2D&& sinoData,
PrincipalPointOffset offset, RotationOffset2D centerOfRotOffset)
: _objectDimension{2}, : _objectDimension{2},
_P{RealMatrix_t::Identity(2, 2 + 1)}, _P{RealMatrix_t::Identity(2, 2 + 1)},
_Pinv{RealMatrix_t::Identity(2 + 1, 2)}, _Pinv{RealMatrix_t::Identity(2 + 1, 2)},
...@@ -20,35 +22,36 @@ namespace elsa ...@@ -20,35 +22,36 @@ namespace elsa
_S{RealMatrix_t::Identity(2 + 1, 2 + 1)}, _S{RealMatrix_t::Identity(2 + 1, 2 + 1)},
_C{RealVector_t::Zero(2)} _C{RealVector_t::Zero(2)}
{ {
auto [volSpacing, volOrigin] = std::move(volData);
auto [sinoSpacing, sinoOrigin] = std::move(sinoData);
// setup rotation matrix _R // setup rotation matrix _R
real_t c = std::cos(angle); real_t c = std::cos(angle);
real_t s = std::sin(angle); real_t s = std::sin(angle);
_R << c, -s, s, c; _R << c, -s, s, c;
// setup scaling matrix _S // setup scaling matrix _S
_S << volumeDescriptor.getSpacingPerDimension()[0], 0, 0, 0, _S << volSpacing[0], 0, 0, 0, volSpacing[1], 0, 0, 0, 1;
volumeDescriptor.getSpacingPerDimension()[1], 0, 0, 0, 1;
// set the translation _t // set the translation _t
RealVector_t centerOfRotationOffset(_objectDimension); // auto centerOfRotationOffset = static_cast<RealVector_t>(centerOfRotOffset);
centerOfRotationOffset << centerOfRotationOffsetX, centerOfRotationOffsetY; // centerOfRotationOffset << centerOfRotationOffsetX, centerOfRotationOffsetY;
_t = _R * (-centerOfRotationOffset - volumeDescriptor.getLocationOfOrigin()); _t = _R * (-centerOfRotOffset.get() - volOrigin);
_t[_objectDimension - 1] += sourceToCenterOfRotation; _t[_objectDimension - 1] += sourceToCenterOfRotation;
// set the intrinsic parameters _K // set the intrinsic parameters _K
real_t alpha = sinoDescriptor.getSpacingPerDimension()[0]; real_t alpha = sinoSpacing[0];
_K << (sourceToCenterOfRotation + centerOfRotationToDetector) / alpha, _K << (sourceToCenterOfRotation + centerOfRotationToDetector) / alpha,
(sinoDescriptor.getLocationOfOrigin()[0] / alpha + offset), 0, 1; (sinoOrigin[0] / alpha + offset), 0, 1;
buildMatrices(); buildMatrices();
} }
Geometry::Geometry(real_t sourceToCenterOfRotation, real_t centerOfRotationToDetector, Geometry::Geometry(SourceToCenterOfRotation sourceToCenterOfRotation,
const DataDescriptor& volumeDescriptor, const DataDescriptor& sinoDescriptor, CenterOfRotationToDetector centerOfRotationToDetector,
real_t gamma, real_t beta, real_t alpha, real_t px, real_t py, VolumeData3D&& volData, SinogramData3D&& sinoData, RotationAngles3D angles,
real_t centerOfRotationOffsetX, real_t centerOfRotationOffsetY, PrincipalPointOffset2D offset, RotationOffset3D centerOfRotOffset)
real_t centerOfRotationOffsetZ)
: _objectDimension{3}, : _objectDimension{3},
_P{RealMatrix_t::Identity(3, 3 + 1)}, _P{RealMatrix_t::Identity(3, 3 + 1)},
_Pinv{RealMatrix_t::Identity(3 + 1, 3)}, _Pinv{RealMatrix_t::Identity(3 + 1, 3)},
...@@ -58,6 +61,13 @@ namespace elsa ...@@ -58,6 +61,13 @@ namespace elsa
_S{RealMatrix_t::Identity(3 + 1, 3 + 1)}, _S{RealMatrix_t::Identity(3 + 1, 3 + 1)},
_C{RealVector_t::Zero(3)} _C{RealVector_t::Zero(3)}
{ {
auto [volSpacing, volOrigin] = std::move(volData);
auto [sinoSpacing, sinoOrigin] = std::move(sinoData);
real_t alpha = angles.alpha();
real_t beta = angles.beta();
real_t gamma = angles.gamma();
// setup rotation matrix // setup rotation matrix
real_t ca = std::cos(alpha); real_t ca = std::cos(alpha);
real_t sa = std::sin(alpha); real_t sa = std::sin(alpha);
...@@ -72,26 +82,24 @@ namespace elsa ...@@ -72,26 +82,24 @@ namespace elsa
* (RealMatrix_t(3, 3) << ca, 0, sa, 0, 1, 0, -sa, 0, ca).finished(); * (RealMatrix_t(3, 3) << ca, 0, sa, 0, 1, 0, -sa, 0, ca).finished();
// setup scaling matrix _S // setup scaling matrix _S
_S << volumeDescriptor.getSpacingPerDimension()[0], 0, 0, 0, 0, _S << volSpacing[0], 0, 0, 0, 0, volSpacing[1], 0, 0, 0, 0, volSpacing[2], 0, 0, 0, 0, 1;
volumeDescriptor.getSpacingPerDimension()[1], 0, 0, 0, 0,
volumeDescriptor.getSpacingPerDimension()[2], 0, 0, 0, 0, 1;
// setup the translation _t // setup the translation _t
RealVector_t centerOfRotationOffset(_objectDimension); // RealVector_t centerOfRotationOffset(_objectDimension);
centerOfRotationOffset << centerOfRotationOffsetX, centerOfRotationOffsetY, // centerOfRotationOffset << centerOfRotationOffsetX, centerOfRotationOffsetY,
centerOfRotationOffsetZ; // centerOfRotationOffsetZ;
_t = _R * (-centerOfRotationOffset - volumeDescriptor.getLocationOfOrigin()); _t = _R * (-centerOfRotOffset.get() - volOrigin);
_t(_objectDimension - 1) += sourceToCenterOfRotation; _t(_objectDimension - 1) += sourceToCenterOfRotation;
// setup the intrinsic parameters _K // setup the intrinsic parameters _K
real_t alpha1 = sinoDescriptor.getSpacingPerDimension()[0]; real_t alpha1 = sinoSpacing[0];
real_t alpha2 = sinoDescriptor.getSpacingPerDimension()[1]; real_t alpha2 = sinoSpacing[1];
_K << (sourceToCenterOfRotation + centerOfRotationToDetector) / alpha1, 0, _K << (sourceToCenterOfRotation + centerOfRotationToDetector) / alpha1, 0,
sinoDescriptor.getLocationOfOrigin()[0] / alpha1 + px, 0, sinoOrigin[0] / alpha1 + offset[0], 0,
(sourceToCenterOfRotation + centerOfRotationToDetector) / alpha2, (sourceToCenterOfRotation + centerOfRotationToDetector) / alpha2,
sinoDescriptor.getLocationOfOrigin()[1] / alpha2 + py, 0, 0, 1; sinoOrigin[1] / alpha2 + offset[1], 0, 0, 1;
buildMatrices(); buildMatrices();
} }
......
#include "StrongTypes.h"
namespace elsa::geometry::detail
{
// Explicit template instantiation
template class StaticVectorTemplate<1, RealVector_t>;
template class StaticVectorTemplate<2, RealVector_t>;
template class StaticVectorTemplate<3, RealVector_t>;
template class StaticVectorTemplate<4, RealVector_t>;
template class StaticVectorTemplate<1, IndexVector_t>;
template class StaticVectorTemplate<2, IndexVector_t>;
template class StaticVectorTemplate<3, IndexVector_t>;
template class StaticVectorTemplate<4, IndexVector_t>;
template class GeometryData<1>;
template class GeometryData<2>;
template class GeometryData<3>;
template class GeometryData<4>;
} // namespace elsa::geometry::detail
\ No newline at end of file
This diff is collapsed.
...@@ -15,6 +15,8 @@ ELSA_TEST(DataHandlers) ...@@ -15,6 +15,8 @@ ELSA_TEST(DataHandlers)
ELSA_TEST(DataHandlerMap) ELSA_TEST(DataHandlerMap)
ELSA_TEST(LinearOperator) ELSA_TEST(LinearOperator)
ELSA_TEST(ExpressionTemplates) ELSA_TEST(ExpressionTemplates)
ELSA_TEST(Geometry)
ELSA_TEST(StrongTypes)
if(ELSA_BENCHMARKS) if(ELSA_BENCHMARKS)
ELSA_TEST(BenchmarkExpressionTemplates) ELSA_TEST(BenchmarkExpressionTemplates)
......
...@@ -14,14 +14,15 @@ using namespace elsa; ...@@ -14,14 +14,15 @@ using namespace elsa;
SCENARIO("Testing 2D geometries") SCENARIO("Testing 2D geometries")
{ {
using namespace geometry;
GIVEN("some 2D setup") GIVEN("some 2D setup")
{ {
IndexVector_t volCoeff(2); IndexVector_t volCoeff(2);
volCoeff << 5, 5; volCoeff << 5, 5;
VolumeDescriptor ddVol(volCoeff); VolumeDescriptor ddVol(volCoeff);
IndexVector_t detCoeff(1); IndexVector_t detCoeff(2);
detCoeff << 5; detCoeff << 5, 1;
VolumeDescriptor ddDet(detCoeff); VolumeDescriptor ddDet(detCoeff);
real_t s2c = 10; real_t s2c = 10;
...@@ -29,7 +30,8 @@ SCENARIO("Testing 2D geometries") ...@@ -29,7 +30,8 @@ SCENARIO("Testing 2D geometries")
WHEN("testing geometry without rotation/offsets") WHEN("testing geometry without rotation/offsets")
{ {
Geometry g(s2c, c2d, 0, ddVol, ddDet); Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d}, Radian{0},
VolumeData2D{Size2D{volCoeff}}, SinogramData2D{Size2D{detCoeff}});
THEN("a copy is the same") THEN("a copy is the same")
{ {
...@@ -85,7 +87,10 @@ SCENARIO("Testing 2D geometries") ...@@ -85,7 +87,10 @@ SCENARIO("Testing 2D geometries")
WHEN("testing geometry without rotation but with principal point offset") WHEN("testing geometry without rotation but with principal point offset")
{ {
real_t px = 2; real_t px = 2;
Geometry g(s2c, c2d, 0, ddVol, ddDet, px);
Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d}, Radian{0},
VolumeData2D{Size2D{volCoeff}}, SinogramData2D{Size2D{detCoeff}},
PrincipalPointOffset{px});
THEN("a copy is the same") THEN("a copy is the same")
{ {
...@@ -141,8 +146,8 @@ SCENARIO("Testing 2D geometries") ...@@ -141,8 +146,8 @@ SCENARIO("Testing 2D geometries")
WHEN("testing geometry with 90 degree rotation and no offsets") WHEN("testing geometry with 90 degree rotation and no offsets")
{ {
real_t angle = pi_t / 2; // 90 degrees Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d}, Degree{90},
Geometry g(s2c, c2d, angle, ddVol, ddDet); VolumeData2D{Size2D{volCoeff}}, SinogramData2D{Size2D{detCoeff}});
THEN("a copy is the same") THEN("a copy is the same")
{ {
...@@ -201,7 +206,11 @@ SCENARIO("Testing 2D geometries") ...@@ -201,7 +206,11 @@ SCENARIO("Testing 2D geometries")
real_t angle = pi_t / 4; // 45 degrees real_t angle = pi_t / 4; // 45 degrees
real_t cx = -1; real_t cx = -1;
real_t cy = 2; real_t cy = 2;
Geometry g(s2c, c2d, angle, ddVol, ddDet, 0, cx, cy);
Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
Radian{angle}, VolumeData2D{Size2D{volCoeff}},
SinogramData2D{Size2D{detCoeff}}, PrincipalPointOffset{0},
RotationOffset2D{cx, cy});
THEN("a copy is the same") THEN("a copy is the same")
{ {
...@@ -270,14 +279,15 @@ SCENARIO("Testing 2D geometries") ...@@ -270,14 +279,15 @@ SCENARIO("Testing 2D geometries")
SCENARIO("Testing 3D geometries") SCENARIO("Testing 3D geometries")
{ {
using namespace geometry;
GIVEN("some 3D setup") GIVEN("some 3D setup")
{ {
IndexVector_t volCoeff(3); IndexVector_t volCoeff(3);
volCoeff << 5, 5, 5; volCoeff << 5, 5, 5;
VolumeDescriptor ddVol(volCoeff); VolumeDescriptor ddVol(volCoeff);
IndexVector_t detCoeff(2); IndexVector_t detCoeff(3);
detCoeff << 5, 5; detCoeff << 5, 5, 1;
VolumeDescriptor ddDet(detCoeff); VolumeDescriptor ddDet(detCoeff);
real_t s2c = 10; real_t s2c = 10;
...@@ -285,7 +295,9 @@ SCENARIO("Testing 3D geometries") ...@@ -285,7 +295,9 @@ SCENARIO("Testing 3D geometries")
WHEN("testing geometry without rotation/offsets") WHEN("testing geometry without rotation/offsets")
{ {
Geometry g(s2c, c2d, ddVol, ddDet, 0); Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
VolumeData3D{Size3D{volCoeff}}, SinogramData3D{Size3D{detCoeff}},
RotationAngles3D{Radian{0}, Radian{0}, Radian{0}});
THEN("a copy is the same") THEN("a copy is the same")
{ {
...@@ -356,7 +368,11 @@ SCENARIO("Testing 3D geometries") ...@@ -356,7 +368,11 @@ SCENARIO("Testing 3D geometries")
{ {
real_t px = -1; real_t px = -1;
real_t py = 3; real_t py = 3;
Geometry g(s2c, c2d, ddVol, ddDet, 0, 0, 0, px, py);
Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
VolumeData3D{Size3D{volCoeff}}, SinogramData3D{Size3D{detCoeff}},
RotationAngles3D{Radian{0}, Radian{0}, Radian{0}},
PrincipalPointOffset2D{px, py});
THEN("a copy is the same") THEN("a copy is the same")
{ {
...@@ -426,7 +442,10 @@ SCENARIO("Testing 3D geometries") ...@@ -426,7 +442,10 @@ SCENARIO("Testing 3D geometries")
WHEN("testing geometry with 90 degree rotation and no offsets") WHEN("testing geometry with 90 degree rotation and no offsets")
{ {
real_t angle = pi_t / 2; real_t angle = pi_t / 2;
Geometry g(s2c, c2d, ddVol, ddDet, angle);
Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
VolumeData3D{Size3D{volCoeff}}, SinogramData3D{Size3D{detCoeff}},
RotationAngles3D{Radian{angle}, Radian{0}, Radian{0}});
THEN("a copy is the same") THEN("a copy is the same")
{ {
...@@ -501,8 +520,11 @@ SCENARIO("Testing 3D geometries") ...@@ -501,8 +520,11 @@ SCENARIO("Testing 3D geometries")
real_t angle2 = pi_t / 2; real_t angle2 = pi_t / 2;
RealVector_t offset(3); RealVector_t offset(3);
offset << 1, -2, -1; offset << 1, -2, -1;
Geometry g(s2c, c2d, ddVol, ddDet, angle1, angle2, 0, 0, 0, offset[0], offset[1],
offset[2]); Geometry g(SourceToCenterOfRotation{s2c}, CenterOfRotationToDetector{c2d},
VolumeData3D{Size3D{volCoeff}}, SinogramData3D{Size3D{detCoeff}},
RotationAngles3D{Radian{angle1}, Radian{angle2}, Radian{0}},
PrincipalPointOffset2D{0, 0}, RotationOffset3D{offset});
THEN("a copy is the same") THEN("a copy is the same")
{ {
......
This diff is collapsed.
...@@ -12,6 +12,9 @@ namespace elsa ...@@ -12,6 +12,9 @@ namespace elsa
index_t arcDegrees, real_t sourceToCenter, index_t arcDegrees, real_t sourceToCenter,
real_t centerToDetector) real_t centerToDetector)
{ {
// pull in geometry namespace, to reduce cluttering
using namespace geometry;
// sanity check // sanity check
auto dim = volumeDescriptor.getNumberOfDimensions(); auto dim = volumeDescriptor.getNumberOfDimensions();
...@@ -33,6 +36,7 @@ namespace elsa ...@@ -33,6 +36,7 @@ namespace elsa
spacing << volumeDescriptor.getSpacingPerDimension()[0], spacing << volumeDescriptor.getSpacingPerDimension()[0],