99#include " OrientationAnalysis/OrientationAnalysis_test_dirs.hpp"
1010#include " OrientationAnalysisTestUtils.hpp"
1111
12+ #include < algorithm>
1213#include < filesystem>
1314namespace fs = std::filesystem;
1415
@@ -34,6 +35,49 @@ const DataPath k_AvgEulerAnglesPath = k_SmallIN100Path.createChildPath(k_Grain_D
3435const DataPath k_PhasesPath = k_SmallIN100Path.createChildPath(k_Grain_Data).createChildPath(k_Phases);
3536const DataPath k_CrystalStructuresPath = k_SmallIN100Path.createChildPath(k_Phase_Data).createChildPath(k_CrystalStructures);
3637
38+ /* *
39+ * @brief Compares two float32 DataArrays after sorting their tuples, so that row ordering does not affect the comparison.
40+ * This is needed because the GBPD output row order depends on EbsdLib symmetry operator ordering, which may change between versions.
41+ */
42+ void CompareSortedArrays (const DataStructure& dataStructure, const DataPath& exemplarPath, const DataPath& computedPath)
43+ {
44+ REQUIRE_NOTHROW (dataStructure.getDataRefAs <DataArray<float32>>(exemplarPath));
45+ REQUIRE_NOTHROW (dataStructure.getDataRefAs <DataArray<float32>>(computedPath));
46+ const auto & exemplarArray = dataStructure.getDataRefAs <DataArray<float32>>(exemplarPath);
47+ const auto & computedArray = dataStructure.getDataRefAs <DataArray<float32>>(computedPath);
48+ REQUIRE (exemplarArray.getNumberOfTuples () == computedArray.getNumberOfTuples ());
49+ REQUIRE (exemplarArray.getNumberOfComponents () == computedArray.getNumberOfComponents ());
50+
51+ const usize numTuples = exemplarArray.getNumberOfTuples ();
52+ const usize numComps = exemplarArray.getNumberOfComponents ();
53+
54+ auto extractAndSort = [numTuples, numComps](const DataArray<float32>& arr) {
55+ std::vector<std::vector<float32>> rows (numTuples, std::vector<float32>(numComps));
56+ for (usize i = 0 ; i < numTuples; i++)
57+ {
58+ for (usize c = 0 ; c < numComps; c++)
59+ {
60+ rows[i][c] = arr[i * numComps + c];
61+ }
62+ }
63+ std::sort (rows.begin (), rows.end ());
64+ return rows;
65+ };
66+
67+ auto exemplarRows = extractAndSort (exemplarArray);
68+ auto computedRows = extractAndSort (computedArray);
69+
70+ for (usize i = 0 ; i < numTuples; i++)
71+ {
72+ for (usize c = 0 ; c < numComps; c++)
73+ {
74+ float32 diff = std::fabs (exemplarRows[i][c] - computedRows[i][c]);
75+ INFO (fmt::format (" Sorted row {}, comp {}: exemplar={}, computed={}" , i, c, exemplarRows[i][c], computedRows[i][c]));
76+ REQUIRE (diff < UnitTest::EPSILON );
77+ }
78+ }
79+ }
80+
3781const DataPath k_ExemplarDistributionPath ({" 6_6_distribution" });
3882const DataPath k_ExemplarErrorPath ({" 6_6_errors" });
3983const DataPath k_ComputedDistributionPath ({" NX_distribution" });
@@ -157,9 +201,9 @@ TEST_CASE("OrientationAnalysis::ComputeGBPDMetricBasedFilter: Valid Filter Execu
157201 WriteTestDataStructure (dataStructure, fs::path (fmt::format (" {}/Compute_GBPD_Metric_Based.dream3d" , unit_test::k_BinaryTestOutputDir)));
158202#endif
159203
160- // compare results
161- UnitTest::CompareArrays<float32> (dataStructure, k_ExemplarDistributionPath, k_ComputedDistributionPath);
162- UnitTest::CompareArrays<float32> (dataStructure, k_ExemplarErrorPath, k_ComputedErrorPath);
204+ // compare results (sorted to be independent of symmetry operator ordering)
205+ CompareSortedArrays (dataStructure, k_ExemplarDistributionPath, k_ComputedDistributionPath);
206+ CompareSortedArrays (dataStructure, k_ExemplarErrorPath, k_ComputedErrorPath);
163207
164208 UnitTest::CheckArraysInheritTupleDims (dataStructure);
165209}
0 commit comments