Skip to content

Commit

Permalink
Merge pull request #1272 from markus-jehl/issue/1201-test-interpolate…
Browse files Browse the repository at this point in the history
…-projdata-instability

Making interpolate projdata tests more stable
  • Loading branch information
KrisThielemans authored Oct 10, 2023
2 parents 8f5859a + b0dfffe commit be23336
Showing 1 changed file with 47 additions and 5 deletions.
52 changes: 47 additions & 5 deletions src/test/test_interpolate_projdata.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class InterpolationTests : public RunTests

void check_symmetry(const SegmentBySinogram<float>& segment);
void compare_segment(const SegmentBySinogram<float>& segment1, const SegmentBySinogram<float>& segment2, float maxDiff);
void compare_segment_shape(const SegmentBySinogram<float>& shape_segment, const SegmentBySinogram<float>& test_segment, int erosion);
};

void InterpolationTests::check_symmetry(const SegmentBySinogram<float>& segment)
Expand Down Expand Up @@ -147,6 +148,46 @@ void InterpolationTests::compare_segment(const SegmentBySinogram<float>& segment
check_if_less(sumAbsDifference, maxDiff, "difference between segments is larger than expected");
}

void InterpolationTests::compare_segment_shape(const SegmentBySinogram<float>& shape_segment, const SegmentBySinogram<float>& test_segment, int erosion)
{
auto maxTestValue = test_segment.find_max();
// compute difference and compare against empirically found value from visually validated sinograms
auto sumVoxelsOutsideMask = 0U;
for (auto axial = test_segment.get_min_axial_pos_num(); axial <= test_segment.get_max_axial_pos_num(); axial++)
{
for (auto view = test_segment.get_min_view_num(); view <= test_segment.get_max_view_num(); view++)
{
for (auto tang = test_segment.get_min_tangential_pos_num(); tang <= test_segment.get_max_tangential_pos_num(); tang++)
{
if (test_segment[axial][view][tang] < 0.1 * maxTestValue)
continue;

// now go through the erosion neighbourhood of the voxel to see if it is near a non-zero voxel
bool isNearNonZero = false;
for (auto axialShape = std::max(axial - erosion, test_segment.get_min_axial_pos_num());
axialShape <= std::min(axial + erosion, test_segment.get_max_axial_pos_num()); axialShape++)
{
for (auto viewShape = std::max(view - erosion, test_segment.get_min_view_num());
viewShape <= std::min(view + erosion, test_segment.get_max_view_num()); viewShape++)
{
for (auto tangShape = std::max(tang - erosion, test_segment.get_min_tangential_pos_num());
tangShape <= std::min(tang + erosion, test_segment.get_max_tangential_pos_num()); tangShape++)
{
if (shape_segment[axialShape][viewShape][tangShape] > 0)
isNearNonZero = true;
}
}
}
if (isNearNonZero == false)
sumVoxelsOutsideMask++;
}
}
}

// confirm that the difference is smaller than an empirically found value
check_if_equal(sumVoxelsOutsideMask, 0U, "there were non-zero voxels outside the masked area");
}

void InterpolationTests::scatter_interpolation_test_blocks()
{
info("Performing symmetric interpolation test for BlocksOnCylindrical scanner");
Expand All @@ -172,8 +213,9 @@ void InterpolationTests::scatter_interpolation_test_blocks()

// define a cylinder precisely in the middle of the FOV, such that symmetry can be used for validation
auto emission_map = VoxelsOnCartesianGrid<float>(*downsampled_proj_data_info, 1);
auto cylinder = EllipsoidalCylinder(40, 80, 80, CartesianCoordinate3D<float>(emission_map.get_max_z()/2 * emission_map.get_grid_spacing()[1], 0, 0));
auto cylinder = EllipsoidalCylinder(41, 80, 80, CartesianCoordinate3D<float>(emission_map.get_max_z()/2 * emission_map.get_grid_spacing()[1], 0, 0));
cylinder.construct_volume(emission_map, CartesianCoordinate3D<int>(1, 1, 1));
write_to_file("downsampled_cylinder_map", emission_map);

// project the cylinder onto the downsampled scanner proj data
auto pm = ProjMatrixByBinUsingRayTracing();
Expand Down Expand Up @@ -316,7 +358,7 @@ void InterpolationTests::scatter_interpolation_test_blocks_asymmetric()
interpolated_proj_data.write_to_file("interpolated_sino_asym.hs");

// compare to ground truth
compare_segment(interpolated_proj_data.get_segment_by_sinogram(0), full_size_model_sino.get_segment_by_sinogram(0), 4697);
compare_segment_shape(full_size_model_sino.get_segment_by_sinogram(0), interpolated_proj_data.get_segment_by_sinogram(0), 2);
}

void InterpolationTests::scatter_interpolation_test_cyl_asymmetric()
Expand All @@ -333,8 +375,8 @@ void InterpolationTests::scatter_interpolation_test_cyl_asymmetric()
// define the original scanner and a downsampled one, as it would be used for scatter simulation
auto scanner = Scanner(Scanner::User_defined_scanner, "Some_symmetric_scanner", 96, 30, 150, 150, 127, 4.3, 4.0, 8.0, -0.38956 /* 0.0 */,
5, 1, 6, 6, 1, 1, 1, 0.17, 511, "Cylindrical", 4.0, 16.0, 24.0, 96.0);
auto downsampled_scanner = Scanner(Scanner::User_defined_scanner, "Some_symmetric_scanner", 64, 12, 150, 150, 127, 4.3,
10.0, 133 * 3.14 / 64, -0.38956 /* 0.0 */, 1, 1, 12, 64, 1, 1, 1, 0.17, 511, "Cylindrical", 10.0, 12.0, 60.0, 72.0);
auto downsampled_scanner = Scanner(Scanner::User_defined_scanner, "Some_symmetric_scanner", 64, 12, 100, 100, 127, 4.3,
10.0, 12.0 /* 133 * 3.14 / 64 */, -0.38956 /* 0.0 */, 1, 1, 12, 64, 1, 1, 1, 0.17, 511, "Cylindrical", 10.0, 12.0, 60.0, 72.0);

auto proj_data_info = shared_ptr<ProjDataInfo>(std::move(ProjDataInfo::construct_proj_data_info(std::make_shared<Scanner>(scanner), 1, 29, 48, int(150 * 96 / 192), false)));
auto downsampled_proj_data_info = shared_ptr<ProjDataInfo>(std::move(ProjDataInfo::construct_proj_data_info(std::make_shared<Scanner>(downsampled_scanner), 1, 0, 32, int(150 * 64 / 192), false)));
Expand Down Expand Up @@ -384,7 +426,7 @@ void InterpolationTests::scatter_interpolation_test_cyl_asymmetric()
interpolated_proj_data.write_to_file("interpolated_sino_cyl_asym.hs");

// compare to ground truth
compare_segment(interpolated_proj_data.get_segment_by_sinogram(0), full_size_model_sino.get_segment_by_sinogram(0), 17500);
compare_segment_shape(full_size_model_sino.get_segment_by_sinogram(0), interpolated_proj_data.get_segment_by_sinogram(0), 2);
}

void
Expand Down

0 comments on commit be23336

Please sign in to comment.