Skip to content

Commit

Permalink
Add composition to affine deformation field unit test #92
Browse files Browse the repository at this point in the history
  • Loading branch information
onurulgen committed Jan 26, 2024
1 parent db09c2f commit 387139a
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 33 deletions.
2 changes: 1 addition & 1 deletion niftyreg_build_version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
395
396
92 changes: 60 additions & 32 deletions reg-test/reg_test_affineDeformationField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct float3 {

class AffineDeformationFieldTest {
protected:
using TestData = std::tuple<std::string, NiftiImage&, mat44, vector<float3>>;
using TestData = std::tuple<std::string, NiftiImage&, NiftiImage, mat44, vector<float3>>;
using TestCase = std::tuple<std::string, NiftiImage, vector<float3>>;

inline static vector<TestCase> testCases;
Expand All @@ -45,6 +45,7 @@ class AffineDeformationFieldTest {
testData.emplace_back(TestData(
"2D Identity",
reference2d,
NiftiImage(),
identity,
identityResult2d
));
Expand All @@ -55,6 +56,7 @@ class AffineDeformationFieldTest {
testData.emplace_back(TestData(
"3D Identity",
reference3d,
NiftiImage(),
identity,
identityResult3d
));
Expand All @@ -70,6 +72,7 @@ class AffineDeformationFieldTest {
testData.emplace_back(TestData(
"2D Translation",
reference2d,
NiftiImage(),
translation,
std::move(translationResult2d)
));
Expand All @@ -83,57 +86,78 @@ class AffineDeformationFieldTest {
testData.emplace_back(TestData(
"3D Translation",
reference3d,
NiftiImage(),
translation,
std::move(translationResult3d)
));

// Create deformation fields and fill them with random values
NiftiImage defField2d = CreateDeformationField(reference2d);
NiftiImage defField3d = CreateDeformationField(reference3d);
auto defField2dPtr = defField2d.data();
auto defField2dPtrX = defField2d.data(0);
auto defField2dPtrY = defField2d.data(1);
auto defField3dPtr = defField3d.data();
auto defField3dPtrX = defField3d.data(0);
auto defField3dPtrY = defField3d.data(1);
auto defField3dPtrZ = defField3d.data(2);
for (auto i = 0; i < defField2d.nVoxels(); i++)
defField2dPtr[i] = static_cast<float>(rand()) / RAND_MAX;
for (auto i = 0; i < defField3d.nVoxels(); i++)
defField3dPtr[i] = static_cast<float>(rand()) / RAND_MAX;

// Full affine - 2D
// Test order [0,0] [1,0] [0,1] [1,1]
mat44 affine;
reg_mat44_eye(&affine);
affine.m[0][3] = -0.5;
affine.m[1][3] = 1.5;
affine.m[2][3] = 0.75;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
affine.m[i][j] += ((static_cast<float>(rand()) / RAND_MAX) - 0.5f) / 10.f;
vector<float3> affineResult2d(4);
for (int i = 0; i < 4; ++i) {
double x = identityResult2d[i].x;
double y = identityResult2d[i].y;
affineResult2d[i].x = static_cast<float>(affine.m[0][3] + affine.m[0][0] * x + affine.m[0][1] * y);
affineResult2d[i].y = static_cast<float>(affine.m[1][3] + affine.m[1][0] * x + affine.m[1][1] * y);

for (char compose = 0; compose < 2; compose++) {
for (int i = 0; i < 4; i++) {
double x = compose ? defField2dPtrX[i] : identityResult2d[i].x;
double y = compose ? defField2dPtrY[i] : identityResult2d[i].y;
affineResult2d[i].x = static_cast<float>(affine.m[0][3] + affine.m[0][0] * x + affine.m[0][1] * y);
affineResult2d[i].y = static_cast<float>(affine.m[1][3] + affine.m[1][0] * x + affine.m[1][1] * y);
}
testData.emplace_back(TestData(
"2D Affine"s + (compose ? " with Composition" : ""),
reference2d,
compose ? std::move(defField2d) : NiftiImage(),
affine,
affineResult2d
));
}
testData.emplace_back(TestData(
"2D Affine",
reference2d,
affine,
std::move(affineResult2d)
));

// Full affine - 3D
// Test order [0,0,0] [1,0,0] [0,1,0] [1,1,0],[0,0,1] [1,0,1] [0,1,1] [1,1,1]
vector<float3> affineResult3d(8);
for (int i = 0; i < 8; ++i) {
double x = identityResult3d[i].x;
double y = identityResult3d[i].y;
double z = identityResult3d[i].z;
affineResult3d[i].x = static_cast<float>(affine.m[0][3] + affine.m[0][0] * x + affine.m[0][1] * y + affine.m[0][2] * z);
affineResult3d[i].y = static_cast<float>(affine.m[1][3] + affine.m[1][0] * x + affine.m[1][1] * y + affine.m[1][2] * z);
affineResult3d[i].z = static_cast<float>(affine.m[2][3] + affine.m[2][0] * x + affine.m[2][1] * y + affine.m[2][2] * z);
for (char compose = 0; compose < 2; compose++) {
for (int i = 0; i < 8; i++) {
double x = compose ? defField3dPtrX[i] : identityResult3d[i].x;
double y = compose ? defField3dPtrY[i] : identityResult3d[i].y;
double z = compose ? defField3dPtrZ[i] : identityResult3d[i].z;
affineResult3d[i].x = static_cast<float>(affine.m[0][3] + affine.m[0][0] * x + affine.m[0][1] * y + affine.m[0][2] * z);
affineResult3d[i].y = static_cast<float>(affine.m[1][3] + affine.m[1][0] * x + affine.m[1][1] * y + affine.m[1][2] * z);
affineResult3d[i].z = static_cast<float>(affine.m[2][3] + affine.m[2][0] * x + affine.m[2][1] * y + affine.m[2][2] * z);
}
testData.emplace_back(TestData(
"3D Affine"s + (compose ? " with Composition" : ""),
reference3d,
compose ? std::move(defField3d) : NiftiImage(),
affine,
affineResult3d
));
}
testData.emplace_back(TestData(
"3D Affine",
reference3d,
affine,
std::move(affineResult3d)
));

for (auto&& testData : testData) {
for (auto&& platformType : PlatformTypes) {
// Make a copy of the test data
auto [testName, reference, transMat, expRes] = testData;
auto [testName, reference, defField, transMat, expRes] = testData;

// Create the platform
unique_ptr<Platform> platform{ new Platform(platformType) };
Expand All @@ -143,15 +167,19 @@ class AffineDeformationFieldTest {
unique_ptr<AladinContentCreator> aladinContentCreator{ dynamic_cast<AladinContentCreator*>(platform->CreateContentCreator(ContentType::Aladin)) };
unique_ptr<AladinContent> aladinContent{ aladinContentCreator->Create(reference, reference, nullptr, &transMat, sizeof(float)) };

// Set the deformation field if composition is required
if (defField)
aladinContent->SetDeformationField(NiftiImage(defField).disown());

// Do the calculation for Aladin
unique_ptr<Kernel> affineDeformKernel{ platform->CreateKernel(AffineDeformationFieldKernel::GetName(), aladinContent.get()) };
affineDeformKernel->castTo<AffineDeformationFieldKernel>()->Calculate();
affineDeformKernel->castTo<AffineDeformationFieldKernel>()->Calculate(defField);

// Get the result
NiftiImage defField(aladinContent->GetDeformationField(), NiftiImage::Copy::Image);
NiftiImage resDefField(aladinContent->GetDeformationField(), NiftiImage::Copy::Image);

// Save for testing
testCases.push_back({ testName + " - Aladin", std::move(defField), std::move(expRes) });
testCases.push_back({ testName + " - Aladin", std::move(resDefField), std::move(expRes) });
}
}
}
Expand Down

0 comments on commit 387139a

Please sign in to comment.