// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include #include "../common/DiffractionGeometry.h" #include TEST_CASE("RecipToDetector_1", "[LinearAlgebra][Coord]") { DiffractionExperiment x(DetectorGeometry(8, 2)); x.BeamX_pxl(1024).BeamY_pxl(1024).DetectorDistance_mm(120); float pos_x = 512, pos_y = 512; auto recip = DetectorToRecip(x, pos_x, pos_y); auto [proj_x, proj_y] = RecipToDector(x, recip); REQUIRE(proj_x == Catch::Approx(pos_x)); REQUIRE(proj_y == Catch::Approx(pos_y)); REQUIRE((recip - DetectorToRecip(x, proj_x, proj_y)).Length() < 0.00000001f); REQUIRE(DistFromEwaldSphere(x, recip) < 4e-4); } TEST_CASE("RecipToDetector_2", "[LinearAlgebra][Coord]") { DiffractionExperiment x(DetectorGeometry(8, 2)); x.BeamX_pxl(1024).BeamY_pxl(1024).DetectorDistance_mm(120); float pos_x = 1023, pos_y = 1023; auto recip = DetectorToRecip(x, pos_x, pos_y); auto [proj_x, proj_y] = RecipToDector(x, recip); REQUIRE(proj_x == Catch::Approx(pos_x)); REQUIRE(proj_y == Catch::Approx(pos_y)); REQUIRE((recip - DetectorToRecip(x, proj_x, proj_y)).Length() < 0.00000001f); REQUIRE(DistFromEwaldSphere(x, recip) < 4e-4); } TEST_CASE("RecipToDetector_3", "[LinearAlgebra][Coord]") { DiffractionExperiment x(DetectorGeometry(8, 2)); x.BeamX_pxl(1024).BeamY_pxl(1024).DetectorDistance_mm(120); float pos_x = 30, pos_y = 30; auto recip = DetectorToRecip(x, pos_x, pos_y); auto [proj_x, proj_y] = RecipToDector(x, recip); REQUIRE(proj_x == Catch::Approx(pos_x)); REQUIRE(proj_y == Catch::Approx(pos_y)); REQUIRE((recip - DetectorToRecip(x, proj_x, proj_y)).Length() < 0.00000001f); REQUIRE(DistFromEwaldSphere(x, recip) < 4e-4); } TEST_CASE("Phi","") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36)); x.DetectorDistance_mm(75).IncidentEnergy_keV(WVL_1A_IN_KEV); x.BeamX_pxl(1000).BeamY_pxl(1000); REQUIRE(Phi(x, 2000, 1000) == Catch::Approx(0.0)); REQUIRE(Phi(x, 1000, 2000) == Catch::Approx(M_PI_2)); REQUIRE(Phi(x, 2000, 2000) == Catch::Approx(M_PI_4)); } TEST_CASE("Cos2Theta","") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36)); x.DetectorDistance_mm(75).IncidentEnergy_keV(WVL_1A_IN_KEV); x.BeamX_pxl(1000).BeamY_pxl(1000); // det distance == 1000 pixel // theta = 30 deg // tan(2 * theta) = sqrt(3) REQUIRE(CosTwoTheta(x, 1000, 1000 * (1.0 + sqrt(3))) == Catch::Approx(0.5f)); } TEST_CASE("PxlToRes","") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36)); x.DetectorDistance_mm(75).IncidentEnergy_keV(WVL_1A_IN_KEV); // sin(theta) = 1/2 // theta = 30 deg // tan(2 * theta) = sqrt(3) REQUIRE(PxlToRes(x, 0, 1000 * sqrt(3)) == Catch::Approx(1.0)); // sin(theta) = 1/4 // theta = 14.47 deg // tan(2 * theta) = 0.55328333517 REQUIRE(PxlToRes(x, 1000 * 0.55328333517 * cosf(1), 1000 * 0.55328333517 * sinf(1)) == Catch::Approx(2.0)); } TEST_CASE("ResToPxl","") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36)); x.DetectorDistance_mm(75).IncidentEnergy_keV(WVL_1A_IN_KEV); // sin(theta) = 1/2 // theta = 30 deg // tan(2 * theta) = sqrt(3) REQUIRE(ResToPxl(x, 1.0) == Catch::Approx(1000 * sqrt(3))); // sin(theta) = 1/4 // theta = 14.47 deg // tan(2 * theta) = 0.55328333517 REQUIRE(ResToPxl(x, 2.0) == Catch::Approx(1000 * 0.55328333517)); } TEST_CASE("SolidAngleCorrection","") { DiffractionExperiment x; x.IncidentEnergy_keV(WVL_1A_IN_KEV); x.BeamX_pxl(1000).BeamY_pxl(1000).DetectorDistance_mm(75); REQUIRE(CalcAzIntSolidAngleCorr(x, 0.0) == 1.0f); REQUIRE(CalcAzIntSolidAngleCorr(x, 2 * M_PI) == Catch::Approx(0.5f * 0.5f * 0.5f)); // theta = 30 deg // cos (2 * theta) = 1/2 REQUIRE(CalcAzIntSolidAngleCorr(x, 1000, 1000) == 1.0f); REQUIRE(CalcAzIntSolidAngleCorr(x, 1000 * (1.0 + sqrt(3)), 1000) == Catch::Approx(0.5f * 0.5f * 0.5f)); } TEST_CASE("PolarizationCorrection","") { DiffractionExperiment x; x.IncidentEnergy_keV(WVL_1A_IN_KEV); x.BeamX_pxl(1000).BeamY_pxl(1000).DetectorDistance_mm(75); // Circular polarization 0.5*(1+cos(2theta)^2) x.PolarizationFactor(0); REQUIRE(CalcAzIntPolarizationCorr(x, 1000 * (1.0 + sqrt(3)), 1000, 0) == Catch::Approx(0.5f * (1 + 0.5f * 0.5f))); REQUIRE(CalcAzIntPolarizationCorr(x, 1000, 1000 * (1.0 + sqrt(3)), 0) == Catch::Approx(0.5f * (1 + 0.5f * 0.5f))); // Horizontal polarization x.PolarizationFactor(1); // No correction in vertical direction REQUIRE(CalcAzIntPolarizationCorr(x, 1000, 1000 * (1.0 + sqrt(3)), 1) == Catch::Approx(1.0f)); REQUIRE(CalcAzIntPolarizationCorr(x, 1000, 1000 * (1.0 - sqrt(3)), 1) == Catch::Approx(1.0f)); // cos(2*theta)^2 in horizontal direction REQUIRE(CalcAzIntPolarizationCorr(x, 1000 * (1.0 + sqrt(3)), 1000, 1) == Catch::Approx(0.5f * 0.5f)); REQUIRE(CalcAzIntPolarizationCorr(x, 1000 * (1.0 - sqrt(3)), 1000, 1) == Catch::Approx(0.5f * 0.5f)); }