Files
Jungfraujoch/tests/IndexingUnitTest.cpp
2024-11-22 21:25:20 +01:00

104 lines
3.6 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 "../writer/HDF5Objects.h"
#include "../image_analysis/IndexerWrapper.h"
#define make_unit_cell(a1,a2,a3,a4,a5,a6) UnitCell{.a = a1, .b = a2, .c = a3, .alpha = a4, .beta = a5, .gamma = a6}
TEST_CASE("CrystalLattice") {
CrystalLattice l(make_unit_cell(50,60,80, 90, 90, 90));
REQUIRE(l.Vec0().Length() == Catch::Approx(50));
REQUIRE(l.Vec1().Length() == Catch::Approx(60));
REQUIRE(l.Vec2().Length() == Catch::Approx(80));
REQUIRE(angle_deg(l.Vec0(), l.Vec2()) == 90);
REQUIRE(angle_deg(l.Vec0(), l.Vec1()) == 90);
REQUIRE(angle_deg(l.Vec1(), l.Vec2()) == 90);
l = CrystalLattice(make_unit_cell(30, 40, 70, 90, 95, 90));
REQUIRE(l.Vec0().Length() == Catch::Approx(30));
REQUIRE(l.Vec1().Length() == Catch::Approx(40));
REQUIRE(l.Vec2().Length() == Catch::Approx(70));
REQUIRE(angle_deg(l.Vec0(), l.Vec2()) == 95);
REQUIRE(angle_deg(l.Vec0(), l.Vec1()) == 90);
REQUIRE(angle_deg(l.Vec1(), l.Vec2()) == 90);
l = CrystalLattice(make_unit_cell(45, 45, 70, 90, 90, 120));
REQUIRE(l.Vec0().Length() == Catch::Approx(45));
REQUIRE(l.Vec1().Length() == Catch::Approx(45));
REQUIRE(l.Vec2().Length() == Catch::Approx(70));
REQUIRE(angle_deg(l.Vec0(), l.Vec2()) == Catch::Approx(90));
REQUIRE(angle_deg(l.Vec0(), l.Vec1()) == Catch::Approx(120));
REQUIRE(angle_deg(l.Vec1(), l.Vec2()) == Catch::Approx(90));
}
inline double round_err(double x) {
return std::abs(x - std::round(x));
}
#ifdef JFJOCH_USE_CUDA
#include <Eigen/Dense>
TEST_CASE("FastFeedbackIndexer","[Indexing]") {
std::vector<Coord> hkl;
for (int i = 1; i < 7; i++)
for (int j = 1; j<6; j++)
for (int k = 1; k < 4; k++)
hkl.emplace_back(i,j,k);
std::vector<UnitCell> cells;
cells.emplace_back(make_unit_cell(30,40,50,90,90,90));
cells.emplace_back(make_unit_cell(80,80,90,90,90,120));
cells.emplace_back(make_unit_cell(40,45,80,90,82.5,90));
for (auto &c: cells) {
CrystalLattice l(c);
Eigen::Matrix3f m;
m << l.Vec0().x, l.Vec0().y, l.Vec0().z,
l.Vec1().x, l.Vec1().y, l.Vec1().z,
l.Vec2().x, l.Vec2().y, l.Vec2().z;
auto m1 = m.transpose().inverse();
CrystalLattice recip_l;
recip_l.Vec0().x = m1(0,0);
recip_l.Vec0().y = m1(0,1);
recip_l.Vec0().z = m1(0,2);
recip_l.Vec1().x = m1(1,0);
recip_l.Vec1().y = m1(1,1);
recip_l.Vec1().z = m1(1,2);
recip_l.Vec2().x = m1(2,0);
recip_l.Vec2().y = m1(2,1);
recip_l.Vec2().z = m1(2,2);
std::vector<Coord> recip;
recip.reserve(hkl.size());
for (const auto &i: hkl)
recip.emplace_back(i.x * recip_l.Vec0() + i.y * recip_l.Vec1() + i.z * recip_l.Vec2());
IndexerWrapper wrapper;
wrapper.Setup(c);
auto ret = wrapper.Run(recip, 0.05f);
REQUIRE(!ret.empty());
//auto uc = ret[0].GetUnitCell();
//REQUIRE(c.a == Catch::Approx(uc.a));
//REQUIRE(c.b == Catch::Approx(uc.b));
//REQUIRE(c.c == Catch::Approx(uc.c));
double err[3] = {0.0, 0.0, 0.0};
for (const auto &iter: recip) {
err[0] += round_err(ret[0].l.Vec0() * iter);
err[1] += round_err(ret[0].l.Vec1() * iter);
err[2] += round_err(ret[0].l.Vec2() * iter);
}
REQUIRE (err[0] < 0.001 * recip.size());
REQUIRE (err[1] < 0.001 * recip.size());
REQUIRE (err[2] < 0.001 * recip.size());
}
}
#endif