224 lines
7.5 KiB
C++
224 lines
7.5 KiB
C++
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#include <catch2/catch_all.hpp>
|
|
#include "../common/ROIMap.h"
|
|
#include "../common/DiffractionExperiment.h"
|
|
|
|
TEST_CASE("ROICircle", "[ROIMap]") {
|
|
std::unique_ptr<ROICircle> circle;
|
|
|
|
REQUIRE_THROWS(circle = std::make_unique<ROICircle>("roi1", 200,200,0));
|
|
REQUIRE_THROWS(circle = std::make_unique<ROICircle>("roi1", 200,200,-5.0));
|
|
REQUIRE_NOTHROW(circle = std::make_unique<ROICircle>("roi1", 200,220,2));
|
|
|
|
REQUIRE(circle->GetName() == "roi1");
|
|
REQUIRE(circle->GetX() == 200.0f);
|
|
REQUIRE(circle->GetY() == 220.0f);
|
|
REQUIRE(circle->GetRadius_pxl() == 2.0f);
|
|
}
|
|
|
|
TEST_CASE("ROICircle_MarkROI", "[ROIMap]") {
|
|
DiffractionExperiment x(DetectorGeometry(1));
|
|
|
|
ROICircle c1("roi1", 200,220,2);
|
|
ROICircle c2("roi1", 200,220,1);
|
|
|
|
std::vector<uint16_t> mask(x.GetPixelsNum(), 0);
|
|
REQUIRE_NOTHROW(c1.MarkROI(mask, 15, x.GetXPixelsNum(), x.GetYPixelsNum()));
|
|
REQUIRE_NOTHROW(c2.MarkROI(mask, 1, x.GetXPixelsNum(), x.GetYPixelsNum()));
|
|
REQUIRE (mask[220 * x.GetXPixelsNum() + 200] == ((1<<15) | (1<<1)));
|
|
REQUIRE (mask[218 * x.GetXPixelsNum() + 200] == (1<<15));
|
|
REQUIRE (mask[220 * x.GetXPixelsNum() + 202] == (1<<15));
|
|
REQUIRE (mask[221 * x.GetXPixelsNum() + 201] == (1<<15));
|
|
|
|
REQUIRE (mask[218 * x.GetXPixelsNum() + 202] == 0);
|
|
}
|
|
|
|
TEST_CASE("ROIBox_SwapX", "[ROIMap]") {
|
|
std::unique_ptr<ROIBox> rectangle;
|
|
|
|
REQUIRE_NOTHROW(rectangle = std::make_unique<ROIBox>("roi1", 200, 199, 199, 221));
|
|
REQUIRE(rectangle->GetXMax() == 200);
|
|
REQUIRE(rectangle->GetXMin() == 199);
|
|
REQUIRE(rectangle->GetYMax() == 221);
|
|
REQUIRE(rectangle->GetYMin() == 199);
|
|
}
|
|
|
|
TEST_CASE("ROIBox_SwapY", "[ROIMap]") {
|
|
std::unique_ptr<ROIBox> rectangle;
|
|
|
|
REQUIRE_NOTHROW(rectangle = std::make_unique<ROIBox>("roi1", 200,220,199, 198));
|
|
REQUIRE(rectangle->GetXMax() == 220);
|
|
REQUIRE(rectangle->GetXMin() == 200);
|
|
REQUIRE(rectangle->GetYMax() == 199);
|
|
REQUIRE(rectangle->GetYMin() == 198);
|
|
}
|
|
|
|
TEST_CASE("ROIBox_NegativeBounds", "[ROIMap]") {
|
|
DiffractionExperiment x(DetectorGeometry(1));
|
|
|
|
std::unique_ptr<ROIBox> rectangle;
|
|
|
|
REQUIRE_THROWS(rectangle = std::make_unique<ROIBox>("roi1", -200,220,220, 221));
|
|
REQUIRE_THROWS(rectangle = std::make_unique<ROIBox>("roi1", 200,-220,220, 221));
|
|
}
|
|
|
|
TEST_CASE("ROIBox_MarkROI", "[ROIMap]") {
|
|
DiffractionExperiment x(DetectorGeometry(1));
|
|
|
|
ROIBox r1("roi1", 198,202,218, 222);
|
|
ROIBox r2("roi2", 198,202,222, 250);
|
|
|
|
std::vector<uint16_t> mask(x.GetPixelsNum(), 0);
|
|
REQUIRE_NOTHROW(r1.MarkROI(mask, 12, x.GetXPixelsNum(), x.GetYPixelsNum()));
|
|
REQUIRE_NOTHROW(r2.MarkROI(mask, 13, x.GetXPixelsNum(), x.GetYPixelsNum()));
|
|
|
|
REQUIRE (mask[220 * x.GetXPixelsNum() + 202] == (1<<12));
|
|
REQUIRE (mask[218 * x.GetXPixelsNum() + 198] == (1<<12));
|
|
REQUIRE (mask[218 * x.GetXPixelsNum() + 202] == (1<<12));
|
|
REQUIRE (mask[218 * x.GetXPixelsNum() + 202] == (1<<12));
|
|
REQUIRE (mask[222 * x.GetXPixelsNum() + 201] == ((1<<12) | (1<<13)));
|
|
REQUIRE (mask[223 * x.GetXPixelsNum() + 200] == (1<<13));
|
|
|
|
REQUIRE (mask[218 * x.GetXPixelsNum() + 197] == 0);
|
|
REQUIRE (mask[218 * x.GetXPixelsNum() + 203] == 0);
|
|
REQUIRE (mask[217 * x.GetXPixelsNum() + 200] == 0);
|
|
}
|
|
|
|
TEST_CASE("ROIBox_MarkROI_OutOfBounds", "[ROIMap]") {
|
|
DiffractionExperiment x(DetectorGeometry(1));
|
|
|
|
ROIBox r1("roi1", x.GetXPixelsNum(),x.GetXPixelsNum() + 10,218, 222);
|
|
ROIBox r2("roi2", 198,202,x.GetYPixelsNum(), x.GetYPixelsNum() + 10);
|
|
|
|
std::vector<uint16_t> mask(x.GetPixelsNum() * 4, 0); // Set the array to much more to protect for eventual out-out-bounds access
|
|
REQUIRE_NOTHROW(r1.MarkROI(mask, 12, x.GetXPixelsNum(), x.GetYPixelsNum()));
|
|
REQUIRE_NOTHROW(r2.MarkROI(mask, 13, x.GetXPixelsNum(), x.GetYPixelsNum()));
|
|
|
|
size_t err = 0;
|
|
for (const auto &i: mask) {
|
|
if (i != 0) err++;
|
|
}
|
|
REQUIRE(err == 0);
|
|
}
|
|
|
|
TEST_CASE("ROIBox", "[ROIMap]") {
|
|
std::unique_ptr<ROIBox> rectangle;
|
|
|
|
REQUIRE_NOTHROW(rectangle = std::make_unique<ROIBox>("roi1", 198,202,218, 222));
|
|
|
|
REQUIRE(rectangle->GetName() == "roi1");
|
|
REQUIRE(rectangle->GetXMin() == 198);
|
|
REQUIRE(rectangle->GetXMax() == 202);
|
|
REQUIRE(rectangle->GetYMin() == 218);
|
|
REQUIRE(rectangle->GetYMax() == 222);
|
|
REQUIRE(rectangle->GetWidth() == 4);
|
|
REQUIRE(rectangle->GetHeight() == 4);
|
|
REQUIRE(rectangle->GetArea() == 16);
|
|
}
|
|
|
|
TEST_CASE("ROIAzimuthal", "[ROIMap]") {
|
|
std::unique_ptr<ROIAzimuthal> roi;
|
|
|
|
REQUIRE_NOTHROW(roi = std::make_unique<ROIAzimuthal>("roi1", 3.0, 5.0));
|
|
REQUIRE(roi->GetDMin_A() == 3.0);
|
|
REQUIRE(roi->GetDMax_A() == 5.0);
|
|
}
|
|
|
|
TEST_CASE("ROIAzimuthal_Swap", "[ROIMap]") {
|
|
std::unique_ptr<ROIAzimuthal> roi;
|
|
|
|
REQUIRE_NOTHROW(roi = std::make_unique<ROIAzimuthal>("roi1", 3.0, 2.0));
|
|
REQUIRE(roi->GetDMin_A() == 2.0);
|
|
REQUIRE(roi->GetDMax_A() == 3.0);
|
|
}
|
|
|
|
TEST_CASE("ROIAzimuthal_neg_resolution", "[ROIMap]") {
|
|
std::unique_ptr<ROIAzimuthal> roi;
|
|
|
|
REQUIRE_THROWS(roi = std::make_unique<ROIAzimuthal>("roi1", -1.0, 5.0));
|
|
REQUIRE_THROWS(roi = std::make_unique<ROIAzimuthal>("roi1", 5.0, -5.0));
|
|
REQUIRE_THROWS(roi = std::make_unique<ROIAzimuthal>("roi1", 5.0, 0.0));
|
|
REQUIRE_THROWS(roi = std::make_unique<ROIAzimuthal>("roi1", 0.0, 5.0));
|
|
}
|
|
|
|
TEST_CASE("ROIAzimuthal_ROImark", "[ROIMap]") {
|
|
DiffractionExperiment x(DetectorGeometry(1));
|
|
std::vector<float> resolution_map(x.GetPixelsNum(), 3.0);
|
|
resolution_map[1] = 2.0;
|
|
resolution_map[2] = 1.0;
|
|
resolution_map[3] = 0.0;
|
|
resolution_map[4] = 5.0;
|
|
|
|
ROIAzimuthal r1("roi1", 2.0, 4.0);
|
|
ROIAzimuthal r2("roi2", 3.0, 6.0);
|
|
|
|
std::vector<uint16_t> mask(x.GetPixelsNum(), 0);
|
|
REQUIRE_NOTHROW(r1.MarkROI(mask, 15, x.GetXPixelsNum(), x.GetYPixelsNum(), resolution_map));
|
|
REQUIRE_NOTHROW(r2.MarkROI(mask, 1, x.GetXPixelsNum(), x.GetYPixelsNum(), resolution_map));
|
|
|
|
REQUIRE(mask[0] == ((1<<1) | (1 << 15)));
|
|
REQUIRE(mask[1] == (1<<15));
|
|
REQUIRE(mask[2] == 0);
|
|
REQUIRE(mask[3] == 0);
|
|
REQUIRE(mask[4] == (1<<1));
|
|
|
|
for (int i = 5; i < x.GetPixelsNum(); i++) {
|
|
REQUIRE(mask[i] == ((1<<1) | (1 << 15)));
|
|
}
|
|
}
|
|
|
|
TEST_CASE("ROIMap") {
|
|
DiffractionExperiment x(DetectorGeometry(1));
|
|
|
|
ROIMap mask;
|
|
|
|
REQUIRE(mask.empty());
|
|
mask.SetROI({
|
|
.boxes = {
|
|
ROIBox("roi12", 100, 120, 240, 260),
|
|
ROIBox("roi11", 200, 220, 240, 260)
|
|
},
|
|
.circles = {ROICircle("roi7", 300, 400, 5)}
|
|
});
|
|
|
|
REQUIRE(!mask.empty());
|
|
mask.SetROI({
|
|
.boxes = {ROIBox("roi12", 100, 120, 240, 260)},
|
|
.circles = {ROICircle("roi7", 300, 400, 5)}
|
|
});
|
|
REQUIRE(!mask.empty());
|
|
|
|
// Check arrays are proper size
|
|
REQUIRE(mask.GetROINameMap().size() == 2);
|
|
|
|
auto map = mask.GetROIMap(x.GetDetectorSetup(), x.GetDiffractionGeometry());
|
|
REQUIRE(map.size() == x.GetPixelsNum());
|
|
|
|
auto it1 = mask.GetROINameMap().find("roi12");
|
|
REQUIRE(it1 != mask.GetROINameMap().end());
|
|
REQUIRE(it1->second == 0);
|
|
REQUIRE(map[260 * x.GetXPixelsNum() + 100] == (1<<0));
|
|
|
|
auto it2 = mask.GetROINameMap().find("roi7");
|
|
REQUIRE(it2 != mask.GetROINameMap().end());
|
|
REQUIRE(it2->second == 1);
|
|
REQUIRE(map[405 * x.GetXPixelsNum() + 300] == (1<<1));
|
|
|
|
mask.SetROI({});
|
|
REQUIRE(mask.empty());
|
|
}
|
|
|
|
TEST_CASE("ROIMap_Empty") {
|
|
DiffractionExperiment x(DetectorGeometry(1));
|
|
|
|
REQUIRE(x.ROI().empty());
|
|
size_t err = 0;
|
|
for (const auto &i: x.ExportROIMap()) {
|
|
if (i != 0)
|
|
err++;
|
|
}
|
|
REQUIRE(err == 0);
|
|
}
|